NewGetAMCoeffsTest.c

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright (C) 2006 John Whelan, Reinhard Prix
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with with program; see the file COPYING. If not, write to the 
00017  *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
00018  *  MA  02111-1307  USA
00019  */
00020 
00021 /*********************************************************************************/
00022 /** \author John Whelan (based on code by Reinhard Prix)
00023  * \file 
00024  * \brief Test for LALNewGetAMCoeffs(): compare results to older, well-tested
00025  * (but less efficient, and harder to understand) function LALComputeAM()
00026  *                                                                          
00027  * This routine currently compares LALComputeAM(), LALGetAMCoeffs() and LALNewGetAMCoeffs() to
00028  * each other, by computing average and maximal relative differences between the respective
00029  * a's and b's.
00030  * 
00031  * Detector and sky-location are picked at random each time, which allows a minimal
00032  * Monte-Carlo validation by simply running this script repeatedly.
00033  *                                                                          
00034  *********************************************************************************/
00035 #include <math.h>
00036 #include <sys/times.h>
00037 
00038 #include <lal/ComputeFstat.h>
00039 #include <lal/LALBarycenter.h>
00040 #include <lal/LALInitBarycenter.h>
00041 #include <lal/AVFactories.h>
00042 
00043 NRCSID (NEWGETAMCOEFFSTEST, "$Id: NewGetAMCoeffsTest.c,v 1.6 2006/10/27 15:18:23 reinhard Exp $");
00044 
00045 /** \name Error codes */
00046 /*@{*/
00047 #define NEWGETAMCOEFFSTEST_ENORM        0
00048 #define NEWGETAMCOEFFSTEST_ESUB         1
00049 
00050 #define NEWGETAMCOEFFSTEST_MSGENORM    "Normal exit"
00051 #define NEWGETAMCOEFFSTEST_MSGESUB     "Subroutine failed"
00052 /*@}*/
00053 
00054 
00055 #define RELERROR(x, y) fabs( 2.0 * ((x) - (y)) / ( (x) + (y) ) )
00056 #define SQ(x) ( (x) * (x) )
00057 #define MYMAX(a,b) ( (a) > (b) ? (a) : (b) )
00058 
00059 /*********************************************************************/
00060 /* Macros for printing errors & testing subroutines (from Creighton) */
00061 /*********************************************************************/
00062 
00063 #define ERROR( code, msg, statement )                                \
00064 do {                                                                 \
00065   if ( lalDebugLevel & LALERROR )                                    \
00066     LALPrintError( "Error[0] %d: program %s, file %s, line %d, %s\n" \
00067                    "        %s %s\n", (code), *argv, __FILE__,       \
00068               __LINE__, NEWGETAMCOEFFSTEST, statement ? statement :  \
00069                    "", (msg) );                                      \
00070 } while (0)
00071 
00072 #define INFO( statement )                                            \
00073 do {                                                                 \
00074   if ( lalDebugLevel & LALINFO )                                     \
00075     LALPrintError( "Info[0]: program %s, file %s, line %d, %s\n"     \
00076                    "        %s\n", *argv, __FILE__, __LINE__,        \
00077               NEWGETAMCOEFFSTEST, (statement) );                     \
00078 } while (0)
00079 
00080 #define SUB( func, statusptr )                                       \
00081 do {                                                                 \
00082   if ( (func), (statusptr)->statusCode ) {                           \
00083     ERROR( NEWGETAMCOEFFSTEST_ESUB, NEWGETAMCOEFFSTEST_MSGESUB,              \
00084            "Function call \"" #func "\" failed:" );                  \
00085     return NEWGETAMCOEFFSTEST_ESUB;                                     \
00086   }                                                                  \
00087 } while (0)
00088 
00089 
00090 static const LALStatus empty_status;
00091 static const AMCoeffsParams empty_AMCoeffsParams;
00092 static const AMCoeffs empty_AMCoeffs;
00093 
00094 extern int lalDebugLevel;
00095 
00096 /** Very simple test: pick random skyposition, compute a_i, b_i using
00097  *  once LALComputeAM() and once LALNewGetAMCoeffs(), and look at the errors
00098  *  sum_i (a_i - a_i')^2
00099  */
00100 int main(int argc, char *argv[])
00101 {
00102   LALStatus status = empty_status;
00103 
00104   LIGOTimeGPS startTime = {714180733, 0};
00105   REAL8 duration = 180000;      /* 50 hours */
00106   REAL8 Tsft = 1800;            /* assume 30min SFTs */
00107   LIGOTimeGPSVector *timestamps = NULL;
00108   DetectorStateSeries *detStates = NULL;
00109   SkyPosition skypos = empty_SkyPosition;
00110   EphemerisData edat = empty_EphemerisData;
00111   BarycenterInput baryinput = empty_BarycenterInput;
00112   LALDetector *det = NULL;
00113   AMCoeffs AMold = empty_AMCoeffs, AMnew1 = empty_AMCoeffs, AMnew2 = empty_AMCoeffs;
00114   REAL8 alpha, delta;
00115   AMCoeffsParams amParams = empty_AMCoeffsParams;
00116   EarthState earth;
00117   UINT4 i;
00118   REAL8 maxerr01, maxerr02, maxerr12, averr01, averr02, averr12;
00119   REAL8 tolerance = 1e-2;       /* be generous: allow 1% error */
00120   struct tms buf;
00121 
00122   const CHAR *sites[]   = {"H1", "L1", "V2", "G1", "T1" };
00123   REAL8 sinzeta;        /* zeta = IFO opening angle */
00124   UINT4 pickedSite;
00125   char earthEphem[] = "earth00-04.dat";
00126   char sunEphem[] = "sun00-04.dat";
00127 
00128   /* ----- old testing code to use 9 degree earth rotations ----- */
00129   /* startTime.gpsSeconds = 714275242;
00130   duration = 86164;
00131   Tsft = 2154.1; */
00132 
00133   lalDebugLevel = 0;
00134   if ( argc == 2 && !strcmp(argv[1], "-v1") )
00135     lalDebugLevel = 1;
00136 
00137 
00138   /* init random-generator */
00139   srand ( times(&buf) );
00140 
00141   /* ----- init ephemeris ----- */
00142   edat.ephiles.earthEphemeris = earthEphem;
00143   edat.ephiles.sunEphemeris = sunEphem;
00144   edat.leap = 0;
00145   SUB ( LALInitBarycenter(&status, &edat), &status);
00146 
00147   /* ----- get timestamps ----- */
00148   SUB ( LALMakeTimestamps ( &status, &timestamps, startTime, duration, Tsft ), &status );
00149 
00150   /* ----- allocate memory for AM-coeffs ----- */
00151   AMold.a = XLALCreateREAL4Vector ( timestamps->length );
00152   AMold.b = XLALCreateREAL4Vector ( timestamps->length );
00153   AMnew1.a = XLALCreateREAL4Vector ( timestamps->length );
00154   AMnew1.b = XLALCreateREAL4Vector ( timestamps->length );
00155   AMnew2.a = XLALCreateREAL4Vector ( timestamps->length );
00156   AMnew2.b = XLALCreateREAL4Vector ( timestamps->length );
00157 
00158   /* ----- pick detector-site at random ----- */
00159   pickedSite = floor( 5 * (1.0 * rand() / (RAND_MAX + 1.0) ) );  /* int in [0,5) */
00160 
00161   /* NOTE: contrary to ComputeAM() and LALGetAMCoffs(), the new function LALNewGetAMCoeffs()
00162    * computes 'a * sinzeta' and 'b * sinzeta': for the comparison we therefore need to correct 
00163    * for GEO's opening-angle of 94.33degrees [JKS98]: */ 
00164   if ( ! strcmp ( sites[pickedSite], "G1" ) )
00165     sinzeta = 0.997146;
00166   else
00167     sinzeta = 1;
00168 
00169   if ( ( det = XLALGetSiteInfo ( sites[pickedSite] )) == NULL ) 
00170     {
00171       LALPrintError ("\nCall to XLALGetSiteInfo() has failed for site = '%s'... \n\n", 
00172                      sites[pickedSite]);
00173       return NEWGETAMCOEFFSTEST_ESUB;
00174     }
00175 
00176   /* ----- pick skyposition at random ----- */
00177   alpha = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) );  /* uniform in [0, 2pi) */
00178   delta = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX );        /* sin(delta) uniform in [-1,1] */
00179   /* ----- old testing code to put source overhead ----- */
00180   /*  alpha = det->frDetector.vertexLongitudeRadians;
00181       delta = det->frDetector.vertexLatitudeRadians; */
00182 
00183   /* ===== compute AM-coeffs the 'old way': ===== */
00184   baryinput.site.location[0] = det->location[0]/LAL_C_SI;
00185   baryinput.site.location[1] = det->location[1]/LAL_C_SI;
00186   baryinput.site.location[2] = det->location[2]/LAL_C_SI;
00187   baryinput.alpha = alpha;
00188   baryinput.delta = delta;
00189   baryinput.dInv = 0.e0;
00190 
00191   /* amParams structure to compute a(t) and b(t) */
00192   amParams.das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource));
00193   amParams.das->pSource = (LALSource *)LALMalloc(sizeof(LALSource));
00194   amParams.baryinput = &baryinput;
00195   amParams.earth = &earth; 
00196   amParams.edat = &edat;
00197   amParams.das->pDetector = det;
00198   amParams.das->pSource->equatorialCoords.longitude = alpha;
00199   amParams.das->pSource->equatorialCoords.latitude = delta;
00200   amParams.das->pSource->orientation = 0.0;
00201   amParams.das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
00202   amParams.polAngle = 0; 
00203   amParams.leapAcc = LALLEAPSEC_STRICT;
00204 
00205   SUB (LALComputeAM ( &status, &AMold, timestamps->data, &amParams), &status); 
00206 
00207   /* ===== compute AM-coeffs the 'new way' using LALNewGetAMCoeffs() */
00208 
00209   /* ----- get detector-state series ----- */
00210   SUB ( LALGetDetectorStates (&status, &detStates, timestamps, det, &edat, 0 ), &status );
00211 
00212   skypos.system = COORDINATESYSTEM_EQUATORIAL;
00213   skypos.longitude = alpha;
00214   skypos.latitude = delta;
00215 
00216   /* the 'new' and the 'newer' way ... */
00217   SUB ( LALGetAMCoeffs ( &status, &AMnew1, detStates, skypos ), &status );      /* 'new1' */
00218   SUB ( LALNewGetAMCoeffs ( &status, &AMnew2, detStates, skypos ), &status );   /* 'new2' */
00219 
00220 
00221   /* ===== analyse relative errors ===== */
00222   maxerr01 = maxerr02 = maxerr12 = 0; /* errors between 0='old', 1='new1', 2='new2' */
00223   averr01 = averr02 = averr12 = 0;
00224   for ( i=0; i < timestamps->length; i ++ )
00225     {
00226       /*      printf("GPS time: %d s %d ns; GMST in radians: %f\n",
00227              detStates->data[i].tGPS.gpsSeconds,
00228              detStates->data[i].tGPS.gpsNanoSeconds,
00229              fmod(detStates->data[i].earthState.gmstRad,LAL_TWOPI));
00230              printf("Old AM coeffs: a=%f, b=%f\nNew AM coeffs: a=%f, b=%f\nNEWER AM coeffs: a=%f b=%f",
00231              AMold.a->data[i], AMold.b->data[i],
00232              AMnew.a->data[i], AMnew.b->data[i],
00233              AMnewer.a->data[i], AMnewer.b->data[i]); */
00234       REAL8 thisErr;
00235       /* compare 0-1 */
00236       thisErr = sqrt( SQ ( AMold.a->data[i] -  AMnew1.a->data[i] ) / AMold.A );
00237       averr01 += thisErr;
00238       maxerr01 = MYMAX( thisErr, maxerr01 );
00239       thisErr = sqrt( SQ ( AMold.b->data[i] -  AMnew1.b->data[i] ) / AMold.B );
00240       averr01 += thisErr;
00241       maxerr01 = MYMAX( thisErr, maxerr01 );
00242 
00243       /* compare 0-2 */
00244       thisErr = sqrt( SQ ( AMold.a->data[i] -  AMnew2.a->data[i]/sinzeta ) / AMold.A );
00245       averr02 += thisErr;
00246       maxerr02 = MYMAX( thisErr, maxerr02 );
00247       thisErr = sqrt( SQ ( AMold.b->data[i] -  AMnew2.b->data[i]/sinzeta ) / AMold.B );
00248       averr02 += thisErr;
00249       maxerr02 = MYMAX( thisErr, maxerr02 );
00250 
00251       /* compare 1-2 */
00252       thisErr = sqrt( SQ ( AMnew1.a->data[i] -  AMnew2.a->data[i]/sinzeta ) / AMold.A );
00253       averr12 += thisErr;
00254       maxerr12 = MYMAX( thisErr, maxerr12 );
00255       thisErr = sqrt( SQ ( AMnew1.b->data[i] -  AMnew2.b->data[i]/sinzeta ) / AMold.B );
00256       averr12 += thisErr;
00257       maxerr12 = MYMAX( thisErr, maxerr12 );
00258 
00259     }
00260   averr01 /= 2.0 * timestamps->length;
00261   averr02 /= 2.0 * timestamps->length;
00262   averr12 /= 2.0 * timestamps->length;
00263 
00264   if ( lalDebugLevel ) 
00265     {
00266       printf ("Parameters: IFO = %s, skypos = [%g, %g]\n", sites[pickedSite], alpha, delta );
00267       printf ("Maximal relative errors: maxerr(0-1) = %g %%, maxerr(0-2) = %g %% maxerr(1-2) = %g %%\n", 
00268               100.0 * maxerr01, 100.0 * maxerr02, 100.0 * maxerr12 );
00269       printf ("Average relative errors: averr(0-1)  = %g %%, averr(0-2)  = %g %% averr(1-2)  = %g %%\n",
00270               100.0 * averr01, 100.0 * averr02, 100.0 * averr12 );
00271     }
00272   else
00273     printf ("%d %g %g \t %g %g %g \t %g %g %g\n", pickedSite, alpha, delta, averr01, averr02, averr12, maxerr01, maxerr02, maxerr12);
00274 
00275   if ( (averr01 > tolerance) || (averr02 > tolerance) || (averr12 > tolerance) 
00276        || (maxerr01 > tolerance) ||(maxerr02 > tolerance) || (maxerr12 > tolerance) )
00277     {
00278       LALPrintError ("Maximal error-tolerance of %g %% was exceeded!\n", 100.0 * tolerance );
00279       return 1;
00280     }
00281 
00282   /* ----- free memory ----- */
00283   XLALDestroyTimestampVector ( timestamps );
00284   XLALDestroyREAL4Vector ( AMold.a );
00285   XLALDestroyREAL4Vector ( AMold.b );
00286   XLALDestroyREAL4Vector ( AMnew1.a );
00287   XLALDestroyREAL4Vector ( AMnew1.b );
00288   XLALDestroyREAL4Vector ( AMnew2.a );
00289   XLALDestroyREAL4Vector ( AMnew2.b );
00290   LALFree ( det );
00291   XLALDestroyDetectorStateSeries ( detStates );
00292   LALFree ( amParams.das->pSource );
00293   LALFree ( amParams.das );
00294   
00295   LALFree(edat.ephemE);
00296   LALFree(edat.ephemS);
00297 
00298   
00299   LALCheckMemoryLeaks();
00300 
00301   return 0;     /* OK */
00302 
00303 } /* main() */
00304 
00305 

Generated on Sun Sep 7 03:07:05 2008 for LAL by  doxygen 1.5.2