FrameSeries.c

Go to the documentation of this file.
00001 /**** <lalVerbatim file="FrameSeriesCV">
00002  * Author: Jolien D. E. Creighton
00003  * $Id: FrameSeries.m4,v 1.19 2008/10/08 21:02:36 jclayton Exp $
00004  **** </lalVerbatim> */
00005 
00006 /**** <lalLaTeX>
00007  *
00008  * \subsection{Module \texttt{FrameSeries.c}}
00009  *
00010  * These routines are used to read/write time series data from/to frame files.
00011  *
00012  * \subsubsection*{Prototypes}
00013  * \input{FrameSeriesCP}
00014  * \idx{LALFrGetINT2TimeSeries}
00015  * \idx{LALFrGetINT2TimeSeriesMetadata}
00016  * \idx{LALFrGetINT4TimeSeries}
00017  * \idx{LALFrGetINT4TimeSeriesMetadata}
00018  * \idx{LALFrGetINT8TimeSeries}
00019  * \idx{LALFrGetINT8TimeSeriesMetadata}
00020  * \idx{LALFrGetREAL4TimeSeries}
00021  * \idx{LALFrGetREAL4TimeSeriesMetadata}
00022  * \idx{LALFrGetREAL8TimeSeries}
00023  * \idx{LALFrGetREAL8TimeSeriesMetadata}
00024  * \idx{LALFrGetCOMPLEX8TimeSeries}
00025  * \idx{LALFrGetCOMPLEX8TimeSeriesMetadata}
00026  * \idx{LALFrGetCOMPLEX16TimeSeries}
00027  * \idx{LALFrGetCOMPLEX16TimeSeriesMetadata}
00028  * \idx{LALFrGetINT2FrequencySeries}
00029  * \idx{LALFrGetINT2FrequencySeriesMetadata}
00030  * \idx{LALFrGetINT4FrequencySeries}
00031  * \idx{LALFrGetINT4FrequencySeriesMetadata}
00032  * \idx{LALFrGetINT8FrequencySeries}
00033  * \idx{LALFrGetINT8FrequencySeriesMetadata}
00034  * \idx{LALFrGetREAL4FrequencySeries}
00035  * \idx{LALFrGetREAL4FrequencySeriesMetadata}
00036  * \idx{LALFrGetREAL8FrequencySeries}
00037  * \idx{LALFrGetREAL8FrequencySeriesMetadata}
00038  * \idx{LALFrGetCOMPLEX8FrequencySeries}
00039  * \idx{LALFrGetCOMPLEX8FrequencySeriesMetadata}
00040  * \idx{LALFrGetCOMPLEX16FrequencySeries}
00041  * \idx{LALFrGetCOMPLEX16FrequencySeriesMetadata}
00042  * \idx{LALFrWriteINT2TimeSeries}
00043  * \idx{LALFrWriteINT4TimeSeries}
00044  * \idx{LALFrWriteINT8TimeSeries}
00045  * \idx{LALFrWriteREAL4TimeSeries}
00046  * \idx{LALFrWriteREAL8TimeSeries}
00047  * \idx{LALFrWriteCOMPLEX8TimeSeries}
00048  * \idx{LALFrWriteCOMPLEX16TimeSeries}
00049  * \idx{LALFrGetTimeSeriesType}
00050  *
00051  * \subsubsection*{Description}
00052  *
00053  * The routines
00054  * \texttt{LALFrGet}$\langle\mbox{datatype}\rangle$\texttt{TimeSeries()}
00055  * search the frame for a specified channel.  If the time series supplied has
00056  * data storage allocated, then the specified amount of data is filled from
00057  * the frame stream.  If no space has been allocated (so that the data field
00058  * is \texttt{NULL}), then only the channel information is returned in the
00059  * time series (e.g., the start time of the next data and the time step size).
00060  *
00061  * Because it is good coding practice to not tinker directly with the innards
00062  * of structures like time series, the behaviour described above is undesirable
00063  * whereby the time series reading functions do useful things when part of the
00064  * time series structures passed into them is not initialized.  To address
00065  * this, the routines
00066  * \texttt{LALFrGet}$\langle\mbox{datatype}\rangle$\texttt{TimeSeriesMetadata()}
00067  * are provided.  These routines accept a fully initialized time series
00068  * structure, and poplulate only the metadata from the frame stream.  New code
00069  * should be written to use \emph{these} functions when only the time series
00070  * meta data is desired.
00071  *
00072  * The routine \texttt{LALFrGetTimeSeriesType} returns the type of the time
00073  * series corresponding to the specified channel.  This is needed if it is not
00074  * known in advance what type of data is stored in the channel.
00075  *
00076  * The routines
00077  * \texttt{LALFrWrite}$\langle\mbox{datatype}\rangle$\texttt{TimeSeries()}
00078  * outputs a given time series as a new frame file with the filename
00079  * $\langle\mbox{source}\rangle$\verb+-+$\langle\mbox{description}\rangle$%
00080  * \verb+-+$\langle\mbox{GPS-seconds}\rangle$\verb+-+%
00081  * $\langle\mbox{duration}\rangle$\verb+.gwf+
00082  * where source and description are the specified frame source and description
00083  * identifiers, GPS-seconds is the start time of the data in
00084  * seconds since 0h UTC 6 Jan 1980 (GPS time origin), or the nearest second
00085  * before the start of the data, and duration is the number of seconds between
00086  * value of GPS-seconds and the GPS end time of the data, rounded up.
00087  *
00088  * \vfill{\footnotesize\input{FrameSeriesCV}}
00089  *
00090  **** </lalLaTeX> */ 
00091 
00092 
00093 int rename( const char *from, const char *to );
00094 
00095 
00096 #include <lal/LALFrameIO.h>
00097 
00098 #include <ctype.h>
00099 #include <math.h>
00100 #include <stdio.h>
00101 #include <stdlib.h>
00102 #include <string.h>
00103 #include <lal/LALStdio.h>
00104 #include <lal/LALStdlib.h>
00105 #include <lal/Date.h>
00106 #include <lal/Units.h>
00107 #include <lal/FrameCache.h>
00108 #include <lal/FrameStream.h>
00109 #include <lal/TimeSeries.h>
00110 #include <lal/LALDetectors.h>
00111 #include <lal/LALDatatypes.h>
00112 
00113 NRCSID( FRAMESERIESC, "$Id: FrameSeries.m4,v 1.19 2008/10/08 21:02:36 jclayton Exp $" );
00114 
00115 /* Useful macros */
00116 #define SECNAN_TO_I8TIME( sec, nan ) \
00117   ((INT8)1000000000*(INT8)(sec)+(INT8)(nan))
00118 /* Dangerous!!!: */
00119 #define EPOCH_TO_I8TIME( epoch ) \
00120   SECNAN_TO_I8TIME( (epoch).gpsSeconds, (epoch).gpsNanoSeconds )
00121 #define SET_EPOCH( pepoch, i8time ) \
00122   do { INT8 t=(i8time); LIGOTimeGPS *pe=(pepoch); \
00123     pe->gpsSeconds=t/(INT8)1000000000; pe->gpsNanoSeconds=t%(INT8)1000000000; \
00124   } while( 0 )
00125 
00126 
00127 /*
00128  *
00129  * Routine to load a FrVect associated with a given channel from a given frame.
00130  *
00131  */
00132 static struct FrVect *loadFrVect( FrStream *stream, const char *channel )
00133 {
00134   char        chan[256];
00135   FrAdcData  *adc;
00136   FrSimData  *sim;
00137   FrProcData *proc;
00138   FrChanType  type;
00139   FrVect     *vect;
00140   FrTOCts    *ts;
00141   double      tstart;
00142   strncpy( chan, channel, sizeof( chan ) - 1 );
00143   if ( ! stream->file->toc )
00144   {
00145     if ( FrTOCReadFull( stream->file ) == 0 )
00146     {
00147       stream->state |= LAL_FR_ERR | LAL_FR_TOC;
00148       return NULL;
00149     }
00150   }
00151   stream->file->relocation = FR_NO;
00152   tstart  = stream->file->toc->GTimeS[stream->pos];
00153   tstart += 1e-9 * stream->file->toc->GTimeN[stream->pos];
00154   ts = stream->file->toc->adc;
00155   /* scan adc data channels */
00156   type = LAL_ADC_CHAN;
00157   while ( ts && strcmp( channel, ts->name ) )
00158     ts = ts->next;
00159   if ( ! ts )
00160   {
00161     /* scan sim data channels */
00162     type = LAL_SIM_CHAN;
00163     ts = stream->file->toc->sim;
00164     while ( ts && strcmp( channel, ts->name ) )
00165       ts = ts->next;
00166   }
00167   if ( ! ts )
00168   {
00169     /* scan proc data channels */
00170     type = LAL_PROC_CHAN;
00171     ts = stream->file->toc->proc;
00172     while ( ts && strcmp( channel, ts->name ) )
00173       ts = ts->next;
00174   }
00175   if ( ! ts )
00176     return NULL;
00177 
00178   FrTOCSetPos( stream->file, ts->position[stream->pos] );
00179   switch ( type )
00180   {
00181     case LAL_ADC_CHAN:
00182       adc = FrAdcDataRead( stream->file );
00183       if ( ! adc ) /* only happens if memory allocation error */
00184         return NULL;
00185       adc->next = NULL;
00186       vect = FrVectReadNext( stream->file, tstart, chan );
00187       FrAdcDataFree( adc );
00188       break;
00189     case LAL_SIM_CHAN:
00190       sim = FrSimDataRead( stream->file );
00191       if ( ! sim ) /* only happens if memory allocation error */
00192         return NULL;
00193       sim->next = NULL;
00194       vect = FrVectReadNext( stream->file, tstart, chan );
00195       FrSimDataFree( sim );
00196       break;
00197     case LAL_PROC_CHAN:
00198       proc = FrProcDataRead( stream->file );
00199       if ( ! proc ) /* only happens if memory allocation error */
00200         return NULL;
00201       proc->next = NULL;
00202       vect = FrVectReadNext( stream->file, tstart, chan );
00203       FrProcDataFree( proc );
00204       break;
00205     default:
00206       return NULL;
00207   }
00208   if ( vect && vect->compress )
00209     FrVectExpand( vect );
00210   return vect; 
00211 }
00212 
00213 
00214 /*
00215  *
00216  * Routine to make a 1D FrVect structure and attach it to a frame as the
00217  * appropriate channel type.
00218  *
00219  */
00220 static struct FrVect *makeFrVect1D( struct FrameH *frame, int chtype,
00221     char *name, char *comment, char *unitx, char *unity, int datatype,
00222     double rate, double fshift, double dx, unsigned int npts )
00223 {
00224   struct FrVect *vect = FrVectNew1D( name, datatype, npts, dx, unitx, unity );
00225   if ( ! vect ) return NULL;
00226   if ( chtype == ProcDataChannel )
00227   {
00228     struct FrProcData *proc = calloc( 1, sizeof( *proc ) );
00229     if ( ! proc )
00230     {
00231       FrVectFree( vect );
00232       return NULL;
00233     }
00234     proc->classe = FrProcDataDef();
00235     proc->fShift = fshift;
00236     proc->type = 1; /* time series */
00237     proc->data = vect;
00238     proc->next = frame->procData;
00239     frame->procData = proc;
00240     if ( ! FrStrCpy( &proc->name, name ) ) return NULL;
00241     if ( ! FrStrCpy( &proc->comment, comment ) ) return NULL;
00242   }
00243   else if ( chtype == ADCDataChannel )
00244   {
00245     struct FrAdcData *adc = calloc( 1, sizeof( *adc ) );
00246     struct FrRawData *raw = frame->rawData ? frame->rawData :
00247       FrRawDataNew( frame );
00248     if ( ! adc || ! raw )
00249     {
00250       FrVectFree( vect );
00251       if ( adc ) free( adc );
00252       return NULL;
00253     }
00254     adc->classe = FrAdcDataDef();
00255     adc->sampleRate = rate;
00256     adc->fShift = fshift;
00257     adc->data = vect;
00258     adc->next = raw->firstAdc;
00259     raw->firstAdc = adc;
00260     if ( ! FrStrCpy( &adc->name, name ) ) return NULL;
00261     if ( ! FrStrCpy( &adc->comment, comment ) ) return NULL;
00262     if ( ! FrStrCpy( &adc->units, unity ) ) return NULL;
00263   }
00264   else if ( chtype == SimDataChannel )
00265   {
00266     struct FrSimData *sim = calloc( 1, sizeof( *sim ) );
00267     if ( ! sim )
00268     {
00269       FrVectFree( vect );
00270       return NULL;
00271     }
00272     sim->classe = FrSimDataDef();
00273     sim->sampleRate = rate;
00274     sim->data = vect;
00275     sim->next = frame->simData;
00276     frame->simData = sim;
00277     if ( ! FrStrCpy( &sim->name, name ) ) return NULL;
00278     if ( ! FrStrCpy( &sim->comment, comment ) ) return NULL;
00279   }
00280   else
00281   {
00282     FrVectFree( vect );
00283     return NULL;
00284   }
00285   return vect;
00286 }
00287 
00288 static FrVect * FrVectReadInfo( FrFile *iFile, FRULONG *pos )
00289 {
00290   FrVect *v;
00291   unsigned short type;
00292   FRULONG localpos;
00293   if ( FrFileIGoToNextRecord( iFile ) != iFile->vectorType )
00294     return NULL;
00295   v = calloc( 1, sizeof( FrVect ) );
00296   if ( ! v )
00297   {
00298     iFile->error = FR_ERROR_MALLOC_FAILED;
00299     return NULL;
00300   }
00301   FrReadHeader( iFile, v );
00302   FrReadSChar( iFile, &v->name );
00303   FrReadShortU( iFile, &v->compress );
00304   if ( v->compress == 256 )
00305     v->compress = 0; /* we will swap bytes at reading time */
00306   FrReadShortU( iFile, &type );
00307   v->type = type;
00308   switch ( v->type )
00309   {
00310     case FR_VECT_4R:
00311       v->wSize = sizeof( float );
00312       break;
00313     case FR_VECT_8R:
00314       v->wSize = sizeof( double );
00315       break;
00316     case FR_VECT_C:
00317       v->wSize = sizeof( char );
00318       break;
00319     case FR_VECT_1U:
00320       v->wSize = sizeof( char );
00321       break;
00322     case FR_VECT_2S:
00323       v->wSize = sizeof( short );
00324       break;
00325     case FR_VECT_2U:
00326       v->wSize = sizeof( short );
00327       break;
00328     case FR_VECT_4S:
00329       v->wSize = sizeof( int );
00330       break;
00331     case FR_VECT_4U:
00332       v->wSize = sizeof( int );
00333       break;
00334     case FR_VECT_8S:
00335       v->wSize = sizeof( FRLONG );
00336       break;
00337     case FR_VECT_8U:
00338       v->wSize = sizeof( FRLONG );
00339       break;
00340     case FR_VECT_8C:
00341       v->wSize = 2 * sizeof( float );
00342       break;
00343     case FR_VECT_16C:
00344       v->wSize = 2 * sizeof( double );
00345       break;
00346     case FR_VECT_8H:
00347       v->wSize = 2 * sizeof( float );
00348       break;
00349     case FR_VECT_16H:
00350       v->wSize = 2 * sizeof( double );
00351       break;
00352     default:
00353       v->wSize = 0;
00354   }
00355   if ( iFile->fmtVersion > 5 )
00356   {
00357     FrReadLong( iFile, (FRLONG *)&v->nData );
00358     FrReadLong( iFile, (FRLONG *)&v->nBytes );
00359   }
00360   else
00361   {
00362     unsigned int nData, nBytes;
00363     FrReadIntU( iFile, &nData );
00364     FrReadIntU( iFile, &nBytes );
00365     v->nData  = nData;
00366     v->nBytes = nBytes;
00367   }
00368   v->space = v->nData;
00369 
00370   /* skip the data */
00371   localpos = FrIOTell( iFile->frfd );
00372   if ( pos )
00373     *pos = localpos;
00374   localpos += v->nBytes;
00375   FrIOSet( iFile->frfd, localpos );
00376   FrReadIntU( iFile, &v->nDim );
00377   FrReadVL( iFile, (FRLONG**)&v->nx, v->nDim );
00378   FrReadVD( iFile, &v->dx, v->nDim );
00379   FrReadVD( iFile, &v->startX, v->nDim );
00380   FrReadVQ( iFile, &v->unitX, v->nDim );
00381   FrReadSChar( iFile, &v->unitY );
00382   FrReadStruct( iFile, &v->next );
00383  
00384   if ( pos )
00385     *pos = localpos;
00386   return v;
00387 }
00388 
00389 LALTYPECODE XLALFrGetTimeSeriesType( const char *channel, FrStream *stream )
00390 {
00391   static const char func[] = "XLALFrGetTimeSeriesType";
00392   FrChanType chantype;
00393   FrTOCts    *ts   = NULL;
00394   FrProcData *proc = NULL;
00395   FrAdcData  *adc  = NULL;
00396   FrSimData  *sim  = NULL;
00397   int type = -1;
00398 
00399   if ( ! channel || ! stream )
00400     XLAL_ERROR( func, XLAL_EFAULT );
00401   if ( stream->state & LAL_FR_ERR )
00402     XLAL_ERROR( func, XLAL_EIO );
00403   if ( stream->state & LAL_FR_END )
00404     XLAL_ERROR( func, XLAL_EIO );
00405 
00406   if ( ! stream->file->toc )
00407   {
00408     if ( FrTOCReadFull( stream->file ) == NULL )
00409     {
00410       XLALPrintError( "XLAL Error - %s: could not open frame TOC %s\n",
00411           func, stream->file );
00412       stream->state |= LAL_FR_ERR | LAL_FR_TOC;
00413       XLAL_ERROR( func, XLAL_EIO );
00414     }
00415   }
00416 
00417   /* scan adc channels */
00418   chantype = LAL_ADC_CHAN;
00419   ts = stream->file->toc->adc;
00420   while ( ts && strcmp( channel, ts->name ) )
00421     ts = ts->next;
00422 
00423   if ( ! ts )
00424   {
00425     /* scan sim channels */
00426     chantype = LAL_SIM_CHAN;
00427     ts = stream->file->toc->sim;
00428     while ( ts && strcmp( channel, ts->name ) )
00429       ts = ts->next;
00430   }
00431 
00432   if ( ! ts )
00433   {
00434     /* scan proc channels */
00435     chantype = LAL_PROC_CHAN;
00436     ts = stream->file->toc->proc;
00437     while ( ts && strcmp( channel, ts->name ) )
00438       ts = ts->next;
00439   }
00440 
00441   if ( ts ) /* the channel was found */
00442   {
00443     FrTOCSetPos( stream->file, ts->position[0] );
00444     switch ( chantype )
00445     {
00446       case LAL_ADC_CHAN:
00447         if ( ( adc = FrAdcDataRead( stream->file ) ) )
00448         {
00449           adc->data = FrVectReadInfo( stream->file, NULL );
00450           type = adc->data ? adc->data->type : -1;
00451           FrAdcDataFree( adc );
00452         }
00453         break;
00454       case LAL_SIM_CHAN:
00455         if ( ( sim = FrSimDataRead( stream->file ) ) )
00456         {
00457           sim->data = FrVectReadInfo( stream->file, NULL );
00458           type = sim->data ? sim->data->type : -1;
00459           FrSimDataFree( sim );
00460         }
00461         break;
00462       case LAL_PROC_CHAN:
00463         if ( ( proc = FrProcDataRead( stream->file ) ) )
00464         {
00465           proc->data = FrVectReadInfo( stream->file, NULL );
00466           type = proc->data ? proc->data->type : -1;
00467           FrProcDataFree( proc );
00468         }
00469         break;
00470       default:
00471         type = -1;
00472     }
00473   }
00474 
00475   switch ( type )
00476   {
00477     case FR_VECT_C:
00478       return LAL_CHAR_TYPE_CODE;
00479     case FR_VECT_2S:
00480       return LAL_I2_TYPE_CODE;
00481     case FR_VECT_4S:
00482       return LAL_I4_TYPE_CODE;
00483     case FR_VECT_8S:
00484       return LAL_I8_TYPE_CODE;
00485     case FR_VECT_1U:
00486       return LAL_UCHAR_TYPE_CODE;
00487     case FR_VECT_2U:
00488       return LAL_U2_TYPE_CODE;
00489     case FR_VECT_4U:
00490       return LAL_U4_TYPE_CODE;
00491     case FR_VECT_8U:
00492       return LAL_U8_TYPE_CODE;
00493     case FR_VECT_4R:
00494       return LAL_S_TYPE_CODE;
00495     case FR_VECT_8R:
00496       return LAL_D_TYPE_CODE;
00497     case FR_VECT_C8:
00498       return LAL_C_TYPE_CODE;
00499     case FR_VECT_C16:
00500       return LAL_Z_TYPE_CODE;
00501     default:
00502       XLAL_ERROR( func, XLAL_ETYPE );
00503   }
00504 
00505   XLAL_ERROR( func, XLAL_ETYPE );
00506 }
00507 
00508 
00509 
00510 /* little helper function for getting number of points in a channel */
00511 int XLALFrGetVectorLength ( CHAR *name, FrStream *stream )
00512 {
00513   static const char func[] = "XLALFrGetVectorLength";
00514   struct FrVect *vect;
00515   int ret = -1;
00516 
00517   if ( stream->state & LAL_FR_ERR )
00518     XLAL_ERROR( func, XLAL_EIO );
00519   if ( stream->state & LAL_FR_END )
00520     XLAL_ERROR( func, XLAL_EIO ); 
00521 
00522   vect = loadFrVect( stream, name );
00523   if ( ! vect || ! vect->data )
00524     XLAL_ERROR( func, XLAL_ENAME ); /* couldn't find channel */
00525 
00526   ret = vect->nData;
00527 
00528   FrVectFree(vect);
00529 
00530   return ret;
00531 
00532 }
00533 
00534 
00535 /* <lalVerbatim file="FrameSeriesCP"> */
00536 void
00537 LALFrGetTimeSeriesType(
00538     LALStatus   *status,
00539     LALTYPECODE *output,
00540     FrChanIn    *chanin,
00541     FrStream    *stream
00542     )
00543 { /* </lalVerbatim> */
00544   int type;
00545   INITSTATUS( status, "LALFrGetTimeSeriesType", FRAMESERIESC );  
00546 
00547   ASSERT( output, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00548   ASSERT( stream, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00549   ASSERT( chanin, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00550   ASSERT( chanin->name, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00551 
00552   if ( stream->state & LAL_FR_ERR )
00553   {
00554     ABORT( status, FRAMESTREAMH_ERROR, FRAMESTREAMH_MSGERROR );
00555   }
00556   if ( stream->state & LAL_FR_END )
00557   {
00558     ABORT( status, FRAMESTREAMH_EDONE, FRAMESTREAMH_MSGEDONE );
00559   }
00560 
00561   type = XLALFrGetTimeSeriesType( chanin->name, stream );
00562   if ( type < 0 )
00563   {
00564     int errnum = xlalErrno;
00565     XLALClearErrno();
00566     switch ( errnum )
00567     {
00568       case XLAL_EIO:
00569         ABORT( status, FRAMESTREAMH_EREAD, FRAMESTREAMH_MSGEREAD );
00570       case XLAL_ETYPE:
00571         ABORT( status, FRAMESTREAMH_ETYPE, FRAMESTREAMH_MSGETYPE );      
00572       default:
00573         ABORTXLAL( status );
00574     }
00575   }
00576 
00577   *output = type;
00578   RETURN( status );
00579 }
00580 
00581 
00582 static int copy_FrVect_to_REAL8( REAL8 *data, struct FrVect *vect, size_t ncpy, size_t offset )
00583 {
00584         size_t i;
00585         if ( ncpy + offset > vect->nData )
00586                 return -1;
00587         switch ( vect->type ) {
00588                 case FR_VECT_C:
00589                         for ( i = 0; i < ncpy; ++i )
00590                                 data[i] = vect->data[offset + i];
00591                         break;
00592                 case FR_VECT_1U:
00593                         for ( i = 0; i < ncpy; ++i )
00594                                 data[i] = vect->dataU[offset + i];
00595                         break;
00596                 case FR_VECT_2U:
00597                         for ( i = 0; i < ncpy; ++i )
00598                                 data[i] = vect->dataUS[offset + i];
00599                         break;
00600                 case FR_VECT_4U:
00601                         for ( i = 0; i < ncpy; ++i )
00602                                 data[i] = vect->dataUI[offset + i];
00603                         break;
00604                 case FR_VECT_8U:
00605                         for ( i = 0; i < ncpy; ++i )
00606                                 data[i] = vect->dataUL[offset + i];
00607                         break;
00608                 case FR_VECT_2S:
00609                         for ( i = 0; i < ncpy; ++i )
00610                                 data[i] = vect->dataS[offset + i];
00611                         break;
00612                 case FR_VECT_4S:
00613                         for ( i = 0; i < ncpy; ++i )
00614                                 data[i] = vect->dataI[offset + i];
00615                         break;
00616                 case FR_VECT_8S:
00617                         for ( i = 0; i < ncpy; ++i )
00618                                 data[i] = vect->dataL[offset + i];
00619                         break;
00620                 case FR_VECT_4R:
00621                         for ( i = 0; i < ncpy; ++i )
00622                                 data[i] = vect->dataF[offset + i];
00623                         break;
00624                 case FR_VECT_8R:
00625                         for ( i = 0; i < ncpy; ++i )
00626                                 data[i] = vect->dataD[offset + i];
00627                         break;
00628                 default:
00629                         return -1;
00630         }
00631         return ncpy;
00632 }
00633 
00634 REAL8TimeSeries * XLALFrInputREAL8TimeSeries( FrStream *stream, const char *channel, const LIGOTimeGPS *start, REAL8 duration, size_t lengthlimit )
00635 {
00636         static const char func[] = "XLALFrInputREAL8TimeSeries";
00637         const REAL8 fuzz = 0.1 / 16384.0; /* smallest discernable unit of time */
00638         struct FrVect *vect;
00639         REAL8TimeSeries *series;
00640         LIGOTimeGPS epoch;
00641         UINT4  need;
00642         UINT4  noff;
00643         UINT4  ncpy;
00644         REAL8 *dest;
00645         INT8   tnow;
00646         INT8   tbeg;
00647         INT8   tend;
00648         REAL8  rate;
00649         int    code;
00650 
00651         if ( stream->state & LAL_FR_ERR )
00652                 XLAL_ERROR_NULL( func, XLAL_EIO );
00653         if ( stream->state & LAL_FR_END )
00654                 XLAL_ERROR_NULL( func, XLAL_EIO ); 
00655 
00656         /* seek to the correct place */
00657         if ( XLALFrSeek( stream, start ) )
00658                 XLAL_ERROR_NULL( func, XLAL_EIO ); 
00659 
00660         vect = loadFrVect( stream, channel );
00661         if ( ! vect || ! vect->data )
00662                 XLAL_ERROR_NULL( func, XLAL_ENAME ); /* couldn't find channel */
00663 
00664         tnow = EPOCH_TO_I8TIME( stream->epoch );
00665 #       if defined FR_VERS && FR_VERS >= 5000
00666         tbeg = 1e9 * vect->GTime;
00667 #       else
00668         tbeg = SECNAN_TO_I8TIME( vect->GTimeS, vect->GTimeN );
00669 #       endif
00670         if ( tnow + 1000 < tbeg ) { /* added 1000 ns to account for double precision */
00671                 FrVectFree(vect);
00672                 XLAL_ERROR_NULL( func, XLAL_ETIME ); /* invalid time offset */
00673         }
00674 
00675         /* compute number of points offset very carefully:
00676          * if current time is within fuzz of a sample, get that sample;
00677          * otherwise get the sample just after the requested time */
00678         rate = 1.0 / vect->dx[0];
00679         noff = ceil( ( 1e-9 * ( tnow - tbeg ) - fuzz ) * rate ); 
00680         if ( noff > vect->nData ) {
00681                 FrVectFree(vect);
00682                 XLAL_ERROR_NULL( func, XLAL_ETIME ); /* invalid time offset */
00683         }
00684         need = duration * rate;
00685         if ( lengthlimit && (lengthlimit < need) )
00686                 need = lengthlimit;
00687 
00688         /* adjust current time to be exactly the first sample
00689          * (rounded to nearest nanosecond) */
00690         tnow = tbeg + floor( 1e9 * noff * vect->dx[0] + 0.5 );
00691         SET_EPOCH( &epoch, tnow );
00692 
00693         series = XLALCreateREAL8TimeSeries( channel, &epoch, 0.0, vect->dx[0], &lalADCCountUnit, need );
00694         if ( ! series )
00695                 XLAL_ERROR_NULL( func, XLAL_EFUNC );
00696         dest = series->data->data;
00697 
00698         /* number of points to copy */
00699         ncpy = ( vect->nData - noff < need ) ? ( vect->nData - noff ) : need;
00700         code = copy_FrVect_to_REAL8( dest, vect, ncpy, noff );
00701         if ( code < 0 ) { /* fails if vect has complex data type */
00702                 if(vect) FrVectFree(vect);      
00703                 XLALDestroyREAL8TimeSeries( series );
00704                 XLAL_ERROR_NULL( func, XLAL_ETYPE ); /* data has wrong type */
00705         }
00706 
00707         FrVectFree(vect);
00708         vect = NULL;
00709 
00710         dest += ncpy;
00711         need -= ncpy;
00712 
00713         /* if still data remaining */
00714         while ( need ) {
00715                 if ( XLALFrNext( stream ) < 0 ) {
00716                         if(vect) FrVectFree(vect);      
00717                         XLALDestroyREAL8TimeSeries( series );
00718                         XLAL_ERROR_NULL( func, XLAL_EFUNC );
00719                 }
00720                 if ( stream->state & LAL_FR_END ) {
00721                         if(vect) FrVectFree(vect);      
00722                         XLALDestroyREAL8TimeSeries( series );
00723                         XLAL_ERROR_NULL( func, XLAL_EIO );
00724                 }
00725 
00726                 /* load more data */
00727                 vect = loadFrVect( stream, series->name );
00728                 if ( ! vect || ! vect->data ) { /* channel missing */
00729                         XLALDestroyREAL8TimeSeries( series );
00730                         XLAL_ERROR_NULL( func, XLAL_ENAME );
00731                 }
00732 
00733                 if ( stream->state & LAL_FR_GAP ) { /* failure: gap in data */
00734                         if(vect) FrVectFree(vect);      
00735                         XLALDestroyREAL8TimeSeries( series );
00736                         XLAL_ERROR_NULL( func, XLAL_ETIME );
00737                 }
00738 
00739                 /* copy data */
00740                 ncpy = vect->nData < need ? vect->nData : need;
00741                 code = copy_FrVect_to_REAL8( dest, vect, ncpy, 0 );
00742                 if ( code < 0 ) { /* fails if vect has complex data type */
00743                         if(vect) FrVectFree(vect);      
00744                         XLALDestroyREAL8TimeSeries( series );
00745                         XLAL_ERROR_NULL( func, XLAL_ETYPE );
00746                 }
00747 
00748                 FrVectFree(vect);
00749                 vect=NULL;
00750 
00751                 dest += ncpy;
00752                 need -= ncpy;
00753         }
00754 
00755         /* update stream start time very carefully:
00756          * start time must be the exact time of the next sample, rounded to the
00757          * nearest nanosecond */
00758         SET_EPOCH( &stream->epoch, EPOCH_TO_I8TIME( series->epoch ) + (INT8)floor( 1e9 * series->data->length * series->deltaT + 0.5 ) );
00759 
00760         /* check to see that we are still within current frame */
00761         tend  = SECNAN_TO_I8TIME( stream->file->toc->GTimeS[stream->pos], stream->file->toc->GTimeN[stream->pos] );
00762         tend += (INT8)floor( 1e9 * stream->file->toc->dt[stream->pos] );
00763         if ( tend <= EPOCH_TO_I8TIME( stream->epoch ) ) {
00764                 int keepmode = stream->mode;
00765                 LIGOTimeGPS keep;
00766                 keep = stream->epoch;
00767                 /* advance a frame -- failure is benign */
00768                 stream->mode |= LAL_FR_IGNOREGAP_MODE;
00769                 XLALFrNext( stream );
00770                 if ( ! stream->state & LAL_FR_GAP )
00771                         stream->epoch = keep;
00772                 stream->mode = keepmode;
00773         }
00774 
00775         if ( stream->state & LAL_FR_ERR ) {
00776                 XLALDestroyREAL8TimeSeries( series );
00777                 XLAL_ERROR_NULL( func, XLAL_EIO );
00778         }
00779 
00780         return series;
00781 }
00782 
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 /* <lalVerbatim file="FrameSeriesCP"> */
00812 int XLALFrGetCOMPLEX16FrequencySeries ( COMPLEX16FrequencySeries *series, FrStream *stream )
00813 { /* </lalVerbatim> */
00814   static const char func[] = "XLALFrGetCOMPLEX16FrequencySeries"; 
00815   struct FrVect *vect;
00816 
00817   if ( stream->state & LAL_FR_ERR )
00818     XLAL_ERROR( func, XLAL_EIO );
00819   if ( stream->state & LAL_FR_END )
00820     XLAL_ERROR( func, XLAL_EIO ); 
00821 
00822   vect = loadFrVect( stream, series->name );
00823   if ( ! vect || ! vect->data )
00824     XLAL_ERROR( func, XLAL_ENAME ); /* couldn't find channel */
00825   if ( vect->type != FR_VECT_16C )
00826     XLAL_ERROR( func, XLAL_ETYPE ); /* data has wrong type */
00827 
00828 #if defined FR_VERS && FR_VERS >= 5000
00829   series->epoch.gpsSeconds     = floor( vect->GTime );
00830   series->epoch.gpsNanoSeconds = floor( 1e9 * ( vect->GTime - floor( vect->GTime ) ) );
00831 #else
00832   series->epoch.gpsSeconds     = vect->GTimeS;
00833   series->epoch.gpsNanoSeconds = vect->GTimeN;
00834 #endif
00835   series->deltaF = vect->dx[0];
00836   series->f0 = 0; /* FIXME: should get correct value... */
00837   series->sampleUnits = lalADCCountUnit;
00838   series->data = LALCalloc( 1, sizeof( *series->data ) );
00839   if ( ! series->data )
00840   {
00841     FrVectFree(vect);
00842     XLAL_ERROR( func, XLAL_ENOMEM );
00843   }
00844   series->data->length = vect->nData;
00845   series->data->data = LALMalloc( series->data->length * sizeof( *series->data->data ) );
00846   if ( ! series->data->data )
00847   {
00848     FrVectFree(vect);
00849     XLAL_ERROR( func, XLAL_ENOMEM );
00850   }
00851   memcpy( series->data->data, vect->dataD, series->data->length * sizeof( *series->data->data ) );
00852 
00853   FrVectFree(vect);
00854 
00855   return 0;
00856 }
00857 
00858 
00859 /* <lalVerbatim file="FrameSeriesCP"> */
00860 void
00861 LALFrGetCOMPLEX16FrequencySeries (
00862     LALStatus           *status,
00863     COMPLEX16FrequencySeries    *series,
00864     FrChanIn            *chanin,
00865     FrStream            *stream
00866     )
00867 { /* </lalVerbatim> */
00868   struct FrVect *vect;
00869   INITSTATUS( status, "LALFrGetCOMPLEX16FrequencySeries", FRAMESERIESC );  
00870 
00871   ASSERT( series, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00872   ASSERT( ! series->data, status, FRAMESTREAMH_ENNUL, FRAMESTREAMH_MSGENNUL );
00873   ASSERT( stream, status, FRAMESTREAMH_ENULL, FRAMESTREAMH_MSGENULL );
00874 
00875   if ( stream->state & LAL_FR_ERR )
00876   {
00877     ABORT( status, FRAMESTREAMH_ERROR, FRAMESTREAMH_MSGERROR );
00878   }
00879   if ( stream->state & LAL_FR_END )
00880   {
00881     ABORT( status, FRAMESTREAMH_EDONE, FRAMESTREAMH_MSGEDONE );
00882   }
00883 
00884   strncpy( series->name, chanin->name, sizeof( series->name ) );
00885   vect = loadFrVect( stream, series->name );
00886   if ( ! vect || ! vect->data )
00887   {
00888     ABORT( status, FRAMESTREAMH_ECHAN, FRAMESTREAMH_MSGECHAN );
00889   }
00890   if ( vect->type != FR_VECT_16C )
00891   {
00892     ABORT( status, FRAMESTREAMH_ETYPE, FRAMESTREAMH_MSGETYPE );
00893   }
00894 
00895 #if defined FR_VERS && FR_VERS >= 5000
00896   series->epoch.gpsSeconds     = floor( vect->GTime );
00897   series->epoch.gpsNanoSeconds = floor( 1e9 * ( vect->GTime - floor( vect->GTime ) ) );
00898 #else
00899   series->epoch.gpsSeconds     = vect->GTimeS;
00900   series->epoch.gpsNanoSeconds = vect->GTimeN;
00901 #endif
00902   series->deltaF = vect->dx[0];
00903   series->f0 = 0; /* FIXME: should get correct value... */
00904   series->sampleUnits = lalADCCountUnit;
00905   series->data = LALCalloc( 1, sizeof( *series->data ) );
00906   if ( ! series->data )
00907   {
00908     ABORT( status, FRAMESTREAMH_EALOC, FRAMESTREAMH_MSGEALOC );
00909   }
00910   series->data->length = vect->nData;
00911   series->data->data = LALMalloc( series->data->length * sizeof( *series->data->data ) );
00912   if ( ! series->data->data )
00913   {
00914     ABORT( status, FRAMESTREAMH_EALOC, FRAMESTREAMH_MSGEALOC );
00915   }
00916   memcpy( series->data->data, vect->dataD, series->data->length * sizeof( *series->data->data ) );
00917 
00918   FrVectFree(vect);
00919 
00920   vect=NULL;
00921 
00922   RETURN( status );
00923 }
00924 
00925 
00926 int XLALFrGetCOMPLEX16TimeSeriesMetadata ( COMPLEX16TimeSeries *series, FrStream *stream )
00927 {
00928   static const char func[] = "XLALFrGetCOMPLEX16TimeSeriesMetadata";
00929   const REAL8    fuzz = 0.1 / 16384.0; /* smallest discernable unit of time */
00930   struct FrVect *vect;
00931   UINT4          noff;
00932   INT8           tnow;
00933   INT8           tbeg;
00934   REAL8          rate;
00935 
00936   if ( stream->state & LAL_FR_ERR )
00937     XLAL_ERROR( func, XLAL_EIO );
00938   if ( stream->state & LAL_FR_END )
00939     XLAL_ERROR( func, XLAL_EIO ); 
00940 
00941   vect = loadFrVect( stream, series->name );
00942   if ( ! vect || ! vect->data )
00943     XLAL_ERROR( func, XLAL_ENAME ); /* couldn't find channel */
00944   if ( vect->type != FR_VECT_16C )
00945     XLAL_ERROR( func, XLAL_ETYPE ); /* data has wrong type */
00946 
00947   tnow = EPOCH_TO_I8TIME( stream->epoch );
00948 #if defined FR_VERS && FR_VERS >= 5000
00949   tbeg = 1e9 * vect->GTime;
00950 #else
00951   tbeg = SECNAN_TO_I8TIME( vect->GTimeS, vect->GTimeN );
00952 #endif
00953   if ( tnow + 1000 < tbeg )  /* added 1000 ns to account for double precision */
00954   {
00955     FrVectFree(vect);
00956     XLAL_ERROR( func, XLAL_ETIME ); /* invalid time offset */
00957   }
00958 
00959   /* compute number of points offset very carefully:
00960    * if current time is within fuzz of a sample, get that sample;
00961    * otherwise get the sample just after the requested time */
00962   rate = vect->dx[0] ? 1.0 / vect->dx[0] : 0.0;
00963   noff = ceil( ( 1e-9 * ( tnow - tbeg ) - fuzz ) * rate ); 
00964 
00965   /* adjust current time to be exactly the first sample
00966    * (rounded to nearest nanosecond) */
00967   tnow = tbeg + floor( 1e9 * noff * vect->dx[0] + 0.5 );
00968 
00969   SET_EPOCH( &series->epoch, tnow );
00970   series->deltaT = vect->dx[0];
00971   series->sampleUnits = lalADCCountUnit;
00972 
00973   FrVectFree(vect);
00974   return 0;
00975 }
00976 
00977 
00978 int XLALFrGetCOMPLEX16TimeSeries ( COMPLEX16TimeSeries *series, FrStream *stream )
00979 {
00980   static const char func[] = "XLALFrGetCOMPLEX16TimeSeries";
00981   const REAL8    fuzz = 0.1 / 16384.0; /* smallest discernable unit of time */
00982   struct FrVect *vect;
00983   UINT4          need;
00984   UINT4          noff;
00985   UINT4          mult;
00986   UINT4          ncpy;
00987   COMPLEX16             *dest;
00988   INT8           tnow;
00989   INT8           tbeg;
00990   INT8           tend;
00991   REAL8