IncrementGPS.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Duncan Brown, David Chin, Jolien Creighton, Kipp Cannon, Reinhard Prix, Saikat Ray-Majumder
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 /*
00021  * File Name: IncrementGPS.c
00022  *
00023  * Author: David Chin <dwchin@umich.edu> +1-734-709-9119
00024  *
00025  * Revision: $Id: IncrementGPS.c,v 1.18 2008/04/30 19:02:22 kipp Exp $
00026  *
00027  */
00028 
00029 #if 0
00030 <lalVerbatim file="IncrementGPSCV">
00031 Author: David Chin
00032 $Id: IncrementGPS.c,v 1.18 2008/04/30 19:02:22 kipp Exp $
00033 </lalVerbatim>
00034 
00035 <lalLaTeX>
00036 \subsection{Module \texttt{IncrementGPS.c}}
00037 \label{ss:IncrementGPS.c}
00038 
00039 Routines to perform arithmetic and comparisons on \texttt{LIGOTimeGPS} and
00040 \texttt{LALTimeInterval} data types.
00041 
00042 \subsection*{Prototypes}
00043 \vspace{0.1in}
00044 \input{IncrementGPSCP}
00045 \idx{LALIncrementGPS()}
00046 \idx{LALDecrementGPS()}
00047 \idx{LALAddFloatToGPS()}
00048 \idx{LALDeltaGPS()}
00049 \idx{LALDeltaFloatGPS()}
00050 
00051 \subsubsection*{Description}
00052 
00053 This module contains a few utility routines to perform comparisons and 
00054 arithmetic on \texttt{LIGOTimeGPS} GPS times. These routines do not convert 
00055 the GPS times they operate on into a floating point representation.
00056 
00057 \begin{itemize}
00058   \item \texttt{LALIncrementGPS()} increments a GPS time by a time interval
00059   \item \texttt{LALDecrementGPS()} decrements a GPS time by a time interval
00060   \item \texttt{LALAddFloatToGPS()} adds a REAL8 interval (in seconds) to a GPS time
00061   \item \texttt{LALDeltaGPS()} returns the difference between two GPS times as a \texttt{LALTimeInterval}.
00062   \item \texttt{LALDeltaFloatGPS()} returns the difference between two GPS times in seconds as a \texttt{REAL8}.
00063 \end{itemize}
00064 
00065 \subsubsection*{Algorithm}
00066 
00067 \subsubsection*{Uses}
00068 
00069 \subsubsection*{Notes}
00070 
00071 In the \texttt{LALIncrementGPS()}, \texttt{LALDecrementGPS()} and \texttt{LALAddFloatToGPS()}
00072 routines, it is legal to pass a pointer to the same \texttt{LIGOTimeGPS}
00073 structure as input and output, \textit{e.g.}
00074 
00075 \begin{verbatim}
00076   LALStatus status;
00077   LIGOTimeGPS gps;
00078   LALTimeInterval interval;
00079 
00080   ...
00081 
00082   gps.gpsSeconds = 10;
00083   gps.gpsNanoSeconds = 25;
00084   interval.seconds = 13;
00085   interval.nanoSeconds = 1000;
00086 
00087   LALIncrementGPS(&status, &gps, &gps, &interval);
00088 
00089 \end{verbatim}
00090 
00091 
00092 \vfill{\footnotesize\input{IncrementGPSCV}}
00093 </lalLaTeX>
00094 #endif
00095 
00096 #include <lal/LALStdlib.h>
00097 #include <lal/Date.h>
00098 #include <math.h>
00099 #include <lal/XLALError.h>
00100 
00101 NRCSID( INCREMENTGPSC, "$Id: IncrementGPS.c,v 1.18 2008/04/30 19:02:22 kipp Exp $" );
00102 
00103 /* module-scope constant */
00104 static const INT4 oneBillion = 1000000000;
00105 
00106 /* Increment a GPS time */
00107 /* <lalVerbatim file="IncrementGPSCP"> */
00108 void
00109 LALIncrementGPS (LALStatus             *status,
00110                  LIGOTimeGPS           *pIncrementedGPS, /* output */
00111                  const LIGOTimeGPS     *pInitialGPS, /* input: GPS time */
00112                  const LALTimeInterval *pDeltaT) /* input: interval to increment by */
00113 /*  </lalVerbatim> */
00114 {
00115   LIGOTimeGPS tmp_gps;
00116 
00117   INITSTATUS( status, "LALIncrementGPS", INCREMENTGPSC );
00118   ATTATCHSTATUSPTR(status);
00119 
00120   tmp_gps = *pInitialGPS;
00121 
00122   tmp_gps.gpsSeconds += pDeltaT->seconds;
00123 
00124   if (tmp_gps.gpsNanoSeconds + pDeltaT->nanoSeconds >= oneBillion)
00125     {
00126       ++(tmp_gps.gpsSeconds);
00127       tmp_gps.gpsNanoSeconds += (pDeltaT->nanoSeconds - oneBillion);
00128     }
00129   else
00130     {
00131       tmp_gps.gpsNanoSeconds += pDeltaT->nanoSeconds;
00132     }
00133 
00134    /* assign the computed values */
00135    *pIncrementedGPS = tmp_gps;
00136 
00137   DETATCHSTATUSPTR(status);
00138   RETURN( status );
00139 } /* END: LALIncrementGPS() */
00140 
00141 
00142 
00143 /* Decrement a GPS time */
00144 /* <lalVerbatim file="IncrementGPSCP"> */
00145 void
00146 LALDecrementGPS (LALStatus             *status,
00147                  LIGOTimeGPS           *pDecrementedGPS, /* output */
00148                  const LIGOTimeGPS     *pInitialGPS, /* input: GPS time */
00149                  const LALTimeInterval *pDeltaT) /* input: interval to decrement by */
00150 /* </lalVerbatim> */
00151 {
00152   LIGOTimeGPS         deltaT_gps;
00153   LIGOTimeGPS         tmp_gps;    /* tmp so that we can use a call like:
00154                                      LALDecrementGPS(&stat, &gps, &gps, &interval)*/
00155   LALGPSCompareResult comparison_result;
00156   
00157   INITSTATUS( status, "LALDecrementGPS", INCREMENTGPSC );
00158   ATTATCHSTATUSPTR(status);
00159 
00160   ASSERT(pDecrementedGPS, status, DATEH_ENULLOUTPUT, DATEH_MSGENULLOUTPUT);
00161   ASSERT(pInitialGPS, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00162   ASSERT(pDeltaT, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00163 
00164   tmp_gps = *pInitialGPS;
00165 
00166   /* Need to try to prevent going into negative GPS times, which
00167      are undefined; can do this easily by making the DeltaT into a GPS time
00168      and making sure that it is not later than the InitialGPS */
00169   deltaT_gps.gpsSeconds     = pDeltaT->seconds;
00170   deltaT_gps.gpsNanoSeconds = pDeltaT->nanoSeconds;
00171 
00172   TRY( LALCompareGPS(status->statusPtr, &comparison_result, &deltaT_gps,
00173                      pInitialGPS), status);
00174 
00175   ASSERT (comparison_result != LALGPS_LATER, status,
00176           DATEH_EDECRTIMETOOLARGE, DATEH_MSGEDECRTIMETOOLARGE);
00177 
00178   if (pInitialGPS->gpsNanoSeconds < pDeltaT->nanoSeconds)
00179     {
00180       tmp_gps.gpsNanoSeconds = oneBillion
00181         + pInitialGPS->gpsNanoSeconds - pDeltaT->nanoSeconds;
00182       tmp_gps.gpsSeconds = pInitialGPS->gpsSeconds - 1
00183         - pDeltaT->seconds;
00184     }
00185   else
00186     {
00187       tmp_gps.gpsNanoSeconds = pInitialGPS->gpsNanoSeconds
00188         - pDeltaT->nanoSeconds;
00189       tmp_gps.gpsSeconds = pInitialGPS->gpsSeconds
00190         - pDeltaT->seconds;
00191     }
00192 
00193   /* assign the computed values */
00194   *pDecrementedGPS = tmp_gps;
00195 
00196   DETATCHSTATUSPTR(status);
00197   RETURN(status);
00198 }
00199 
00200 
00201 
00202 /* Return GPS1 - GPS2 */
00203 /* <lalVerbatim file="IncrementGPSCP"> */
00204 void
00205 LALDeltaGPS (LALStatus         *status,
00206              LALTimeInterval   *pDeltaGPS, /* output: GPS1 - GPS2 */
00207              const LIGOTimeGPS *pGPS1, /* input: GPS1 */
00208              const LIGOTimeGPS *pGPS2) /* input: GPS2 */
00209 /* </lalVerbatim> */
00210 {
00211   INITSTATUS( status, "LALDeltaGPS", INCREMENTGPSC );
00212   ATTATCHSTATUSPTR(status);
00213 
00214   ASSERT(pDeltaGPS, status, DATEH_ENULLOUTPUT, DATEH_MSGENULLOUTPUT);
00215   ASSERT(pGPS1, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00216   ASSERT(pGPS2, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00217 
00218   /* 6 possibilities:
00219 
00220      1. GPS1.gpsSeconds == GPS2.gpsSeconds
00221 
00222         a. GPS1.gpsNanoSeconds >= GPS2.gpsNanoSeconds
00223 
00224            => GPS1 >= GPS2
00225 
00226         b. GPS1.gpsNanoSeconds < GPS2.gpsNanoSeconds
00227 
00228            => GPS1 < GPS2
00229 
00230      2. GPS1.gpsSeconds != GPS2.gpsSeconds
00231 
00232         a. GPS1.gpsSeconds > GPS2.gpsSeconds
00233 
00234            => GPS1 > GPS2
00235 
00236            i.  GPS1.gpsNanoSeconds >= GPS2.gpsNanoSeconds
00237            ii. GPS1.gpsNanoSeconds <  GPS2.gpsNanoSeconds
00238 
00239         b. GPS1.gpsSeconds < GPS2.gpsSeconds
00240 
00241            => GPS1 < GPS2
00242 
00243            i.  GPS1.gpsNanoSeconds > GPS2.gpsNanoSeconds
00244            ii. GPS1.gpsNanoSeconds <=  GPS2.gpsNanoSeconds
00245   */
00246 
00247   if (pGPS1->gpsSeconds == pGPS2->gpsSeconds) /* 1 */
00248     {
00249       if (pGPS1->gpsNanoSeconds >= pGPS2->gpsNanoSeconds) /* a */
00250         {
00251           pDeltaGPS->seconds = 0;
00252           pDeltaGPS->nanoSeconds = pGPS1->gpsNanoSeconds
00253             - pGPS2->gpsNanoSeconds;
00254         }
00255       else /* b */
00256         {
00257           pDeltaGPS->seconds = 0;
00258           pDeltaGPS->nanoSeconds = -(pGPS2->gpsNanoSeconds
00259                                      - pGPS1->gpsNanoSeconds);
00260         }
00261     }
00262   else /* 2 */
00263     {
00264       if (pGPS1->gpsSeconds > pGPS2->gpsSeconds) /* a */
00265         {
00266           if (pGPS1->gpsNanoSeconds >= pGPS2->gpsNanoSeconds) /* i */
00267             {
00268               pDeltaGPS->seconds = pGPS1->gpsSeconds - pGPS2->gpsSeconds;
00269               pDeltaGPS->nanoSeconds = pGPS1->gpsNanoSeconds
00270                 - pGPS2->gpsNanoSeconds;
00271             }
00272           else /* ii */
00273             {
00274               pDeltaGPS->seconds = pGPS1->gpsSeconds - pGPS2->gpsSeconds
00275                 - 1;
00276               pDeltaGPS->nanoSeconds = pGPS1->gpsNanoSeconds + oneBillion
00277                 - pGPS2->gpsNanoSeconds;
00278             }
00279         }
00280       else /* b */
00281         {
00282           if (pGPS1->gpsNanoSeconds > pGPS2->gpsNanoSeconds) /* i */
00283             {
00284               pDeltaGPS->seconds = - (pGPS2->gpsSeconds - pGPS1->gpsSeconds
00285                                       - 1);
00286               pDeltaGPS->nanoSeconds = - (pGPS2->gpsNanoSeconds + oneBillion
00287                                           - pGPS1->gpsNanoSeconds);
00288             }
00289           else /* ii */
00290             {
00291               pDeltaGPS->seconds = - (pGPS2->gpsSeconds - pGPS1->gpsSeconds);
00292               pDeltaGPS->nanoSeconds = - (pGPS2->gpsNanoSeconds -
00293                                           pGPS1->gpsNanoSeconds);
00294             }
00295         }
00296     }
00297 
00298   DETATCHSTATUSPTR(status);
00299   RETURN( status );
00300 } /* END: LALDeltaGPS() */
00301 
00302 
00303 
00304 
00305 /* <lalVerbatim file="IncrementGPSCP"> */
00306 void
00307 LALCompareGPS(LALStatus           *status,
00308               LALGPSCompareResult *pResult, /* output: -1 => GPS1 < GPS2
00309                                                         0 => GPS1 = GPS2
00310                                                         1 => GPS1 > GPS2 */
00311               const LIGOTimeGPS   *pGPS1, /* input: GPS1 */
00312               const LIGOTimeGPS   *pGPS2) /* input: GPS2 */
00313 /* </lalVerbatim> */
00314 {
00315   INITSTATUS( status, "LALCompareGPS", INCREMENTGPSC );
00316   ATTATCHSTATUSPTR(status);
00317 
00318   ASSERT(pResult, status, DATEH_ENULLOUTPUT, DATEH_MSGENULLOUTPUT);
00319   ASSERT(pGPS1, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00320   ASSERT(pGPS2, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00321 
00322   XLALPrintDeprecationWarning("LALCompareGPS", "XLALGPSCmp");
00323 
00324   *pResult = XLALGPSCmp(pGPS1, pGPS2);
00325 
00326   DETATCHSTATUSPTR(status);
00327   RETURN( status );
00328 } /* END: LALCompareGPS() */
00329 
00330 
00331 
00332 /* Increment a GPS time by a float-interval */
00333 /* <lalVerbatim file="IncrementGPSCP"> */
00334 void
00335 LALAddFloatToGPS(
00336     LALStatus          *status,
00337     LIGOTimeGPS        *outputGPS, /* outputGPS = startGPS + deltaT */
00338     const LIGOTimeGPS  *startGPS,  /* input: GPS time */
00339     REAL8               deltaT     /* input: interval to increment by in sec */
00340     )
00341 /*  </lalVerbatim> */
00342 {
00343   INITSTATUS( status, "LALAddFloatToGPS", INCREMENTGPSC );
00344 
00345   XLALPrintDeprecationWarning("LALAddFloatToGPS", "XLALGPSAdd");
00346 
00347   *outputGPS = *startGPS;
00348   XLALGPSAdd(outputGPS, deltaT);
00349 
00350   RETURN( status );
00351 
00352 } /* LALAddFloatToGPS() */
00353 
00354 
00355 /* Return GPS1 - GPS2 as a REAL8 !*/
00356 /* <lalVerbatim file="IncrementGPSCP"> */
00357 void
00358 LALDeltaFloatGPS (LALStatus    *status,
00359                   REAL8         *deltaT,        /* GPS1 - GPS2 */
00360                   const LIGOTimeGPS *GPS1,      /* input: GPS1 */
00361                   const LIGOTimeGPS *GPS2)      /* input: GPS2 */
00362 /* </lalVerbatim> */
00363 {
00364 
00365   INITSTATUS( status, "LALDeltaFloatGPS", INCREMENTGPSC );
00366 
00367   ASSERT(deltaT, status, DATEH_ENULLOUTPUT, DATEH_MSGENULLOUTPUT);
00368   ASSERT(GPS1, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00369   ASSERT(GPS2, status, DATEH_ENULLINPUT, DATEH_MSGENULLINPUT);
00370 
00371   XLALPrintDeprecationWarning("LALDeltaFloatGPS", "XLALGPSDiff");
00372   
00373   *deltaT = XLALGPSDiff(GPS1, GPS2);
00374 
00375   RETURN( status );
00376 
00377 } /* LALDeltaFloatGPS() */
00378 

Generated on Tue Oct 14 02:31:51 2008 for LAL by  doxygen 1.5.2