diff --git a/.github/workflows/lgm-ci.yml b/.github/workflows/lgm-ci.yml index 172505348..060443847 100644 --- a/.github/workflows/lgm-ci.yml +++ b/.github/workflows/lgm-ci.yml @@ -14,7 +14,11 @@ jobs: basic-suite: runs-on: ubuntu-20.04 steps: - - name: Install dependencies + - name: Install python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Install dependencies for C lib run: | sudo apt-get update -qq sudo apt-get install -y make gcc g++ autotools-dev autoconf check @@ -22,8 +26,12 @@ jobs: sudo apt-get install -y libhdf5-dev libperl-dev gcc --version gsl-config --version + python -m pip install cpplint - name: Checkout uses: actions/checkout@v2 + - name: Code style checks + run: | + cpplint --filter=-whitespace,-readability,+build,-build/include_subdir,-build/header_guard,-build/include_what_you_use,-legal,+runtime,-runtime/int,-runtime/printf,-runtime/threadsafe_fn --linelength=120 --exclude=Examples/KdTree/magConj.c Examples/*/*.h Examples/*/*.c Tools/*.c libLanlGeoMag/Lgm_* libLanlGeoMag/Lgm/Lgm_* - name: compile_test run: | autoreconf -i diff --git a/Examples/AE8_AP8/AE8_AP8.c b/Examples/AE8_AP8/AE8_AP8.c index 76a4427e7..dd59ac0f3 100644 --- a/Examples/AE8_AP8/AE8_AP8.c +++ b/Examples/AE8_AP8/AE8_AP8.c @@ -1,5 +1,5 @@ -#include #include +#include #include int main( ) { diff --git a/Examples/FluxToPSD/CDFUtils.c b/Examples/FluxToPSD/CDFUtils.c index 8a1cee269..28d3ef3af 100644 --- a/Examples/FluxToPSD/CDFUtils.c +++ b/Examples/FluxToPSD/CDFUtils.c @@ -1,13 +1,13 @@ -#include "CDFUtils.h" -#include #include #include -#include -#include #include -#include #include +#include #include +#include +#include +#include +#include "CDFUtils.h" /* diff --git a/Examples/FluxToPSD/CDFUtils.h b/Examples/FluxToPSD/CDFUtils.h index 4dfa88691..4aa3cf44b 100644 --- a/Examples/FluxToPSD/CDFUtils.h +++ b/Examples/FluxToPSD/CDFUtils.h @@ -2,8 +2,8 @@ #define CDF_UTILS_H #include -#include #include +#include /* diff --git a/Examples/FluxToPSD/DumpSvg.c b/Examples/FluxToPSD/DumpSvg.c index 0b3021c79..a8f277e44 100644 --- a/Examples/FluxToPSD/DumpSvg.c +++ b/Examples/FluxToPSD/DumpSvg.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include typedef struct CoordInfo { diff --git a/Examples/FluxToPSD/FluxToPSD.c b/Examples/FluxToPSD/FluxToPSD.c index b4f80aa58..628e0f71b 100755 --- a/Examples/FluxToPSD/FluxToPSD.c +++ b/Examples/FluxToPSD/FluxToPSD.c @@ -3,26 +3,26 @@ CHECK ME FOR MEMORY LEAKS..... THIS ALSO eeds some argument changes... e.g. The Mu's K's instead of pitch angles... */ -#include "CDFUtils.h" -#include +#include +#include +#include +#include #include -#include -#include +#include #include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CDFUtils.h" diff --git a/Examples/FluxToPSD/MuTest.c b/Examples/FluxToPSD/MuTest.c index 23ecd2e58..902b020fe 100644 --- a/Examples/FluxToPSD/MuTest.c +++ b/Examples/FluxToPSD/MuTest.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include int main( ) { diff --git a/Examples/FluxToPSD/f2p.c b/Examples/FluxToPSD/f2p.c index df8f51d12..3cb9cb035 100644 --- a/Examples/FluxToPSD/f2p.c +++ b/Examples/FluxToPSD/f2p.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include int main( ) { diff --git a/Examples/FluxToPSD/f2p_v2.c b/Examples/FluxToPSD/f2p_v2.c index 8b8debf25..e5f5b46eb 100644 --- a/Examples/FluxToPSD/f2p_v2.c +++ b/Examples/FluxToPSD/f2p_v2.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include void DumpSvg( int, char * ); diff --git a/Examples/KdTree/DstNNs.c b/Examples/KdTree/DstNNs.c index 821941231..fb4241688 100644 --- a/Examples/KdTree/DstNNs.c +++ b/Examples/KdTree/DstNNs.c @@ -1,11 +1,11 @@ -#include #include +#include +#include +#include #include -#include #include +#include #include -#include -#include int main( ) { Lgm_ElapsedTimeInfo t; double *q, **u, **B, *Dst, DstIndex, dum1, dum2, dum3; diff --git a/Examples/KdTree/TLE_NNs.c b/Examples/KdTree/TLE_NNs.c index 60586f0cb..139b3b57a 100644 --- a/Examples/KdTree/TLE_NNs.c +++ b/Examples/KdTree/TLE_NNs.c @@ -1,12 +1,12 @@ -#include #include +#include +#include +#include +#include #include #include -#include #include #include -#include -#include int main( ) { Lgm_ElapsedTimeInfo t; double *q, **u, **B, DstIndex, dum1, dum2, dum3; diff --git a/Examples/KdTree/magConj.c b/Examples/KdTree/magConj.c index 95c811577..d83910c2a 100644 --- a/Examples/KdTree/magConj.c +++ b/Examples/KdTree/magConj.c @@ -1,15 +1,15 @@ -#include -#include -#include -#include -#include #include +#include +#include +#include #include -#include +#include +#include #include +#include +#include #include #include -#include void StringSplit( char *Str, char *StrArray[], int len, int *n ); diff --git a/Examples/KdTree/test.c b/Examples/KdTree/test.c index 19ea24f2d..deb72d62a 100644 --- a/Examples/KdTree/test.c +++ b/Examples/KdTree/test.c @@ -1,9 +1,9 @@ -#include #include +#include +#include #include #include #include -#include int main( ) { Lgm_ElapsedTimeInfo t; double **q, **u, **B; diff --git a/Examples/LCDS/LCDS.c b/Examples/LCDS/LCDS.c index a9ebef2b3..dcf11e4fb 100644 --- a/Examples/LCDS/LCDS.c +++ b/Examples/LCDS/LCDS.c @@ -1,15 +1,15 @@ +#include #include #include #include -#include -#include #include -#include -#include +#include +#include #include #include -#include +#include #include +#include #define MAIN #define TRACE_TOL 1e-7 diff --git a/Examples/Lstar/Lstar.c b/Examples/Lstar/Lstar.c index d7dda09f6..d08ace57a 100644 --- a/Examples/Lstar/Lstar.c +++ b/Examples/Lstar/Lstar.c @@ -1,7 +1,7 @@ -#include -#include -#include #include +#include +#include +#include #include #include diff --git a/Examples/LstarDipoleTest/ComputeLstarVersusPA.c b/Examples/LstarDipoleTest/ComputeLstarVersusPA.c index d84f14bcd..824a32a46 100644 --- a/Examples/LstarDipoleTest/ComputeLstarVersusPA.c +++ b/Examples/LstarDipoleTest/ComputeLstarVersusPA.c @@ -1,13 +1,13 @@ -#include -#include -#include +#include #include #include #include -#include -#include #include -#include +#include +#include +#include +#include +#include #define TRACE_TOL 1e-7 #define KP_DEFAULT 1 diff --git a/Examples/LstarDipoleTest/DynamicMemory.h b/Examples/LstarDipoleTest/DynamicMemory.h index fabc50c83..7cbe965b3 100644 --- a/Examples/LstarDipoleTest/DynamicMemory.h +++ b/Examples/LstarDipoleTest/DynamicMemory.h @@ -1,6 +1,6 @@ -#include -#include #include +#include +#include /* * Macros for dynamically allocating/freeing 1D arrays of any type diff --git a/Examples/LstarDipoleTest/LstarVersusPA.c b/Examples/LstarDipoleTest/LstarVersusPA.c index 1b6747230..af65c4109 100644 --- a/Examples/LstarDipoleTest/LstarVersusPA.c +++ b/Examples/LstarDipoleTest/LstarVersusPA.c @@ -1,8 +1,8 @@ #define MAIN -#include -#include -#include #include +#include +#include +#include #include #include diff --git a/Examples/LstarDipoleTest/MagEphemInfo.h b/Examples/LstarDipoleTest/MagEphemInfo.h index ecce42cf0..e6a4845e3 100644 --- a/Examples/LstarDipoleTest/MagEphemInfo.h +++ b/Examples/LstarDipoleTest/MagEphemInfo.h @@ -1,8 +1,8 @@ #ifndef MAGEPHEMINFO_H #define MAGEPHEMINFO_H -#include #include +#include #define MAX_PITCH_ANGLES 900 diff --git a/Examples/LstarDipoleTest_omp/ComputeLstarVersusPA.c b/Examples/LstarDipoleTest_omp/ComputeLstarVersusPA.c index 3367d0b36..d7a22afa0 100644 --- a/Examples/LstarDipoleTest_omp/ComputeLstarVersusPA.c +++ b/Examples/LstarDipoleTest_omp/ComputeLstarVersusPA.c @@ -1,13 +1,13 @@ -#include -#include -#include +#include #include #include #include -#include -#include #include -#include +#include +#include +#include +#include +#include #define TRACE_TOL 1e-7 #define KP_DEFAULT 1 diff --git a/Examples/LstarDipoleTest_omp/DynamicMemory.h b/Examples/LstarDipoleTest_omp/DynamicMemory.h index fabc50c83..7cbe965b3 100644 --- a/Examples/LstarDipoleTest_omp/DynamicMemory.h +++ b/Examples/LstarDipoleTest_omp/DynamicMemory.h @@ -1,6 +1,6 @@ -#include -#include #include +#include +#include /* * Macros for dynamically allocating/freeing 1D arrays of any type diff --git a/Examples/LstarDipoleTest_omp/LstarVersusPA.c b/Examples/LstarDipoleTest_omp/LstarVersusPA.c index 5ed88ce13..917b92dc3 100644 --- a/Examples/LstarDipoleTest_omp/LstarVersusPA.c +++ b/Examples/LstarDipoleTest_omp/LstarVersusPA.c @@ -1,8 +1,8 @@ #define MAIN -#include -#include -#include #include +#include +#include +#include #include #include diff --git a/Examples/LstarDipoleTest_omp/MagEphemInfo.h b/Examples/LstarDipoleTest_omp/MagEphemInfo.h index ecce42cf0..5e4e2343b 100644 --- a/Examples/LstarDipoleTest_omp/MagEphemInfo.h +++ b/Examples/LstarDipoleTest_omp/MagEphemInfo.h @@ -1,8 +1,8 @@ #ifndef MAGEPHEMINFO_H #define MAGEPHEMINFO_H -#include -#include +#include +#include #define MAX_PITCH_ANGLES 900 diff --git a/Examples/LstarVersusPA_omp/ComputeLstarVersusPA.c b/Examples/LstarVersusPA_omp/ComputeLstarVersusPA.c index cf29aeeb7..630a32034 100644 --- a/Examples/LstarVersusPA_omp/ComputeLstarVersusPA.c +++ b/Examples/LstarVersusPA_omp/ComputeLstarVersusPA.c @@ -1,13 +1,13 @@ -#include -#include -#include +#include #include #include #include -#include -#include #include -#include +#include +#include +#include +#include +#include #define TRACE_TOL 1e-7 #define KP_DEFAULT 1 diff --git a/Examples/LstarVersusPA_omp/LstarVersusPA.c b/Examples/LstarVersusPA_omp/LstarVersusPA.c index 5573d5e08..92e5c884b 100644 --- a/Examples/LstarVersusPA_omp/LstarVersusPA.c +++ b/Examples/LstarVersusPA_omp/LstarVersusPA.c @@ -1,8 +1,8 @@ #define MAIN -#include -#include -#include #include +#include +#include +#include #include #include diff --git a/Examples/MagEphem/MagEphemFromFile.c b/Examples/MagEphem/MagEphemFromFile.c index ca992d176..419f319fb 100644 --- a/Examples/MagEphem/MagEphemFromFile.c +++ b/Examples/MagEphem/MagEphemFromFile.c @@ -1,22 +1,22 @@ -#include +#include +#include +#include #include +#include #include -#include -#include +#include #include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include void StringSplit( char *Str, char *StrArray[], int len, int *n ); diff --git a/Examples/MagEphem/Run_MagEphemFromFile.c b/Examples/MagEphem/Run_MagEphemFromFile.c index 03561c3c3..bf2360e33 100644 --- a/Examples/MagEphem/Run_MagEphemFromFile.c +++ b/Examples/MagEphem/Run_MagEphemFromFile.c @@ -1,12 +1,12 @@ -#include -#include +#include #include +#include +#include #include -#include #include -#include +#include #include -#include +#include #include #include diff --git a/Examples/McIlwain_L/McIlwain_L.c b/Examples/McIlwain_L/McIlwain_L.c index de3d189a2..24bb0157f 100644 --- a/Examples/McIlwain_L/McIlwain_L.c +++ b/Examples/McIlwain_L/McIlwain_L.c @@ -1,11 +1,11 @@ -#include -#include +#include #include #include -#include -#include #include -#include +#include +#include +#include +#include int main(){ diff --git a/Examples/McIlwain_L/McIlwain_L_2.c b/Examples/McIlwain_L/McIlwain_L_2.c index 6b348aea9..ea0b6a468 100644 --- a/Examples/McIlwain_L/McIlwain_L_2.c +++ b/Examples/McIlwain_L/McIlwain_L_2.c @@ -1,10 +1,10 @@ -#include +#include #include #include -#include -#include #include -#include +#include +#include +#include static double glat[] = { 17.0, 27.0, 38.0, 48.0, 57.0 }; static double glon[] = { 192.0, 193.0, 195.0, 198.0, 201.0 }; diff --git a/Examples/McIlwain_L/McIlwain_L_3.c b/Examples/McIlwain_L/McIlwain_L_3.c index f38d1f5a0..f23edd592 100644 --- a/Examples/McIlwain_L/McIlwain_L_3.c +++ b/Examples/McIlwain_L/McIlwain_L_3.c @@ -1,10 +1,10 @@ -#include +#include #include #include -#include -#include #include -#include +#include +#include +#include static double glat[] = { 0.0, 20.0, 40.0, 60.0, 80.0 }; static double glon[] = { 0.0, 135.0, 225.0 }; diff --git a/Examples/McIlwain_L/McIlwain_L_4.c b/Examples/McIlwain_L/McIlwain_L_4.c index af7ddacf6..5b95521be 100644 --- a/Examples/McIlwain_L/McIlwain_L_4.c +++ b/Examples/McIlwain_L/McIlwain_L_4.c @@ -1,10 +1,10 @@ -#include +#include #include #include -#include -#include #include -#include +#include +#include +#include int main(){ long int Date, n; diff --git a/Examples/McIlwain_L/McIlwain_L_Test.c b/Examples/McIlwain_L/McIlwain_L_Test.c index 7ae02dc52..9d0412941 100644 --- a/Examples/McIlwain_L/McIlwain_L_Test.c +++ b/Examples/McIlwain_L/McIlwain_L_Test.c @@ -1,11 +1,11 @@ -#include +#include #include #include -#include -#include #include +#include +#include +#include #include -#include int main(){ diff --git a/Examples/QuadPack/ex1.c b/Examples/QuadPack/ex1.c index 739a4cc9b..d6cfc4780 100644 --- a/Examples/QuadPack/ex1.c +++ b/Examples/QuadPack/ex1.c @@ -1,8 +1,8 @@ /* * Examples showing how to use the Quadpack routines to do simple integrals. */ -#include #include +#include #include typedef struct MyInfo { diff --git a/Examples/SummersDiffCoeff/DumpGif.c b/Examples/SummersDiffCoeff/DumpGif.c index 9562ba581..adafd7925 100644 --- a/Examples/SummersDiffCoeff/DumpGif.c +++ b/Examples/SummersDiffCoeff/DumpGif.c @@ -1,6 +1,6 @@ -#include -#include #include +#include +#include #define TRUE 1 #define FALSE 0 typedef unsigned char byte; // needed for gif writer diff --git a/Examples/TLE/TwoLineElements.c b/Examples/TLE/TwoLineElements.c index 55deaec14..3828671a7 100644 --- a/Examples/TLE/TwoLineElements.c +++ b/Examples/TLE/TwoLineElements.c @@ -1,8 +1,8 @@ -#include #include +#include #include -#include #include +#include /* * This example shows how to compute positions of objects from TLEs diff --git a/Examples/TLE/TwoLineElementsFromFile.c b/Examples/TLE/TwoLineElementsFromFile.c index 2663fae02..bbd6e414f 100644 --- a/Examples/TLE/TwoLineElementsFromFile.c +++ b/Examples/TLE/TwoLineElementsFromFile.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include diff --git a/Examples/Trace/MagTrace.c b/Examples/Trace/MagTrace.c index 935efd62a..39addc7f9 100644 --- a/Examples/Trace/MagTrace.c +++ b/Examples/Trace/MagTrace.c @@ -1,11 +1,11 @@ -#include -#include #include +#include +#include +#include #include -#include #include #include -#include +#include void DumpImage( char *FilenameBase, int W, int H, double **Image ){ diff --git a/Tools/LastClosedDriftShell.c b/Tools/LastClosedDriftShell.c index 660fb4050..8c4433432 100644 --- a/Tools/LastClosedDriftShell.c +++ b/Tools/LastClosedDriftShell.c @@ -1,11 +1,11 @@ +#include +#include #include #include #include -#include -#include -#include #include -#include +#include +#include #include #include #include diff --git a/Tools/MagEphemFromSpiceKernel.c b/Tools/MagEphemFromSpiceKernel.c index d81b5e87a..0bac25d36 100644 --- a/Tools/MagEphemFromSpiceKernel.c +++ b/Tools/MagEphemFromSpiceKernel.c @@ -1,14 +1,15 @@ -#include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include -#include -#include -#include +#include #include -#include +#include #include #include #include @@ -18,9 +19,8 @@ #include #include #include -#include "SpiceUsr.h" -#include #include +#include "SpiceUsr.h" #define EARTH_ID 399 #define MOON_ID 301 diff --git a/Tools/MagEphemFromTLE.c b/Tools/MagEphemFromTLE.c index e5436ef7e..4d5b0febc 100644 --- a/Tools/MagEphemFromTLE.c +++ b/Tools/MagEphemFromTLE.c @@ -1,25 +1,25 @@ -#include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include -#include -#include -#include +#include #include -#include +#include #include -#include -#include #include +#include #include -#include -#include #include -#include -#include +#include +#include #include +#include +#include #define EARTH_ID 399 #define MOON_ID 301 diff --git a/libLanlGeoMag/Lgm/Lgm_AE8_AP8.h b/libLanlGeoMag/Lgm/Lgm_AE8_AP8.h index fc9309618..4d751307c 100644 --- a/libLanlGeoMag/Lgm/Lgm_AE8_AP8.h +++ b/libLanlGeoMag/Lgm/Lgm_AE8_AP8.h @@ -1,8 +1,8 @@ #ifndef LGM_AE8_H #define LGM_AE8_H -#include -#include +#include "Lgm/Lgm_MagModelInfo.h" +#include "Lgm/Lgm_Vec.h" /* * Lgm_AE8.h diff --git a/libLanlGeoMag/Lgm/Lgm_CTrans.h b/libLanlGeoMag/Lgm/Lgm_CTrans.h index e0ada3ecb..2bd7ed299 100644 --- a/libLanlGeoMag/Lgm/Lgm_CTrans.h +++ b/libLanlGeoMag/Lgm/Lgm_CTrans.h @@ -10,13 +10,13 @@ #endif +#include #include #include #include -#include +#include "Lgm_JPLeph.h" #include "Lgm_Vec.h" #include "Lgm_WGS84.h" -#include "Lgm_JPLeph.h" #define DegPerRad 57.295779513082320876798154814105 #define RadPerDeg 0.017453292519943295769236907568 diff --git a/libLanlGeoMag/Lgm/Lgm_DynamicMemory.h b/libLanlGeoMag/Lgm/Lgm_DynamicMemory.h index 7d7f60e25..c5bd699d5 100644 --- a/libLanlGeoMag/Lgm/Lgm_DynamicMemory.h +++ b/libLanlGeoMag/Lgm/Lgm_DynamicMemory.h @@ -110,11 +110,11 @@ */ -#include -#include #if !defined(__APPLE__) #include #endif +#include +#include /* * Macros for dynamically allocating/freeing 1D arrays of any type diff --git a/libLanlGeoMag/Lgm/Lgm_Eop.h b/libLanlGeoMag/Lgm/Lgm_Eop.h index 66d4b7099..4f4b420e1 100644 --- a/libLanlGeoMag/Lgm/Lgm_Eop.h +++ b/libLanlGeoMag/Lgm/Lgm_Eop.h @@ -1,8 +1,8 @@ #ifndef LGM_EOP_H #define LGM_EOP_H -#include #include #include +#include #ifndef M_2PI diff --git a/libLanlGeoMag/Lgm/Lgm_FastPowPoly.h b/libLanlGeoMag/Lgm/Lgm_FastPowPoly.h index c10469e29..3a9679d1d 100644 --- a/libLanlGeoMag/Lgm/Lgm_FastPowPoly.h +++ b/libLanlGeoMag/Lgm/Lgm_FastPowPoly.h @@ -1,10 +1,9 @@ #ifndef LGM_FASTPOWPOLY_H #define LGM_FASTPOWPOLY_H - -#include #include #include +#include #include #define EXP_POLY_DEGREE 3 diff --git a/libLanlGeoMag/Lgm/Lgm_HDF5.h b/libLanlGeoMag/Lgm/Lgm_HDF5.h index a08a89566..4b377282a 100644 --- a/libLanlGeoMag/Lgm/Lgm_HDF5.h +++ b/libLanlGeoMag/Lgm/Lgm_HDF5.h @@ -1,16 +1,16 @@ #ifndef LGM_HDF5_H #define LGM_HDF5_H -#include -#include -#include -#include -#include -#include #include -#include "Lgm_DynamicMemory.h" +#include //#define H5_NO_DEPRECATED_SYMBOLS #include +#include +#include +#include +#include +#include +#include "Lgm_DynamicMemory.h" diff --git a/libLanlGeoMag/Lgm/Lgm_JPLeph.h b/libLanlGeoMag/Lgm/Lgm_JPLeph.h index 51bd74c19..135dca7b7 100644 --- a/libLanlGeoMag/Lgm/Lgm_JPLeph.h +++ b/libLanlGeoMag/Lgm/Lgm_JPLeph.h @@ -16,6 +16,8 @@ * The nutations and librations are stored in units of radians. */ +#include "Lgm_Vec.h" + #ifndef TRUE #define TRUE 1 #endif diff --git a/libLanlGeoMag/Lgm/Lgm_LstarInfo.h b/libLanlGeoMag/Lgm/Lgm_LstarInfo.h index 3b1181db2..96bc13371 100644 --- a/libLanlGeoMag/Lgm/Lgm_LstarInfo.h +++ b/libLanlGeoMag/Lgm/Lgm_LstarInfo.h @@ -1,11 +1,11 @@ #ifndef LGM_LSTAR_INFO_H #define LGM_LSTAR_INFO_H +#include +#include #include #include "Lgm_QuadPack.h" #include "Lgm_MagModelInfo.h" -#include -#include #define ELECTRON_MASS (9.10938188e-31) /* Electron Mass , kg */ #define AMU (1.660538e-27) /* kg */ diff --git a/libLanlGeoMag/Lgm/Lgm_MagEphemInfo.h b/libLanlGeoMag/Lgm/Lgm_MagEphemInfo.h index 1ff33b904..000affeba 100644 --- a/libLanlGeoMag/Lgm/Lgm_MagEphemInfo.h +++ b/libLanlGeoMag/Lgm/Lgm_MagEphemInfo.h @@ -2,14 +2,14 @@ #define MAGEPHEMINFO_H #include "Lgm_MagModelInfo.h" -#include "Lgm_LstarInfo.h" -#include +#include #include -#include -#include +#include #include -#include +#include +#include #include "Lgm_HDF5.h" +#include "Lgm_LstarInfo.h" #define MAX_PITCH_ANGLES 90 diff --git a/libLanlGeoMag/Lgm/Lgm_Metadata.h b/libLanlGeoMag/Lgm/Lgm_Metadata.h index 494f30fcd..57ec47387 100644 --- a/libLanlGeoMag/Lgm/Lgm_Metadata.h +++ b/libLanlGeoMag/Lgm/Lgm_Metadata.h @@ -1,13 +1,17 @@ - #ifndef LGM_JSONHEADER_H #define LGM_JSONHEADER_H -#include - #define Lgm_metadata_SUCCESS 1 #define Lgm_metadata_FAILURE 0 +#include +#include +#include +#include + +#include "Lgm/Lgm_DynamicMemory.h" +#include "Lgm/Lgm_Metadata.h" typedef struct Lgm_metadata_attr { int array; // boolean for if this is an array of metadata @@ -26,14 +30,6 @@ typedef struct Lgm_metadata_variable { } Lgm_metadata_variable; -#include -#include -#include -#include - -#include "Lgm/Lgm_Metadata.h" -#include "Lgm/Lgm_DynamicMemory.h" - #define Lgm_metadata_MAXHEADERLEN 100000 #define Lgm_metadata_MAXSINGLEVARHEADER 10000 #define Lgm_metadata_TABCHAR " " diff --git a/libLanlGeoMag/Lgm/Lgm_Misc.h b/libLanlGeoMag/Lgm/Lgm_Misc.h index ae1f0894a..97ce1effc 100644 --- a/libLanlGeoMag/Lgm/Lgm_Misc.h +++ b/libLanlGeoMag/Lgm/Lgm_Misc.h @@ -1,8 +1,8 @@ #ifndef LGM_MISC_H #define LGM_MISC_H -#include #include +#include #include diff --git a/libLanlGeoMag/Lgm/Lgm_NrlMsise00.h b/libLanlGeoMag/Lgm/Lgm_NrlMsise00.h index 33bafd833..d7515d8c3 100644 --- a/libLanlGeoMag/Lgm/Lgm_NrlMsise00.h +++ b/libLanlGeoMag/Lgm/Lgm_NrlMsise00.h @@ -1,10 +1,10 @@ #ifndef LGM_NRLMSISE00_H #define LGM_NRLMSISE00_H +#include #include #include #include -#include #define AMOD(A,P) ( (A-((int)((double)A/(double)P)*P)) ) #define AMIN1(A,B) ( ((A -#include #include -#include +#include #include +#include +#include #define LGM_POLYROOTS_MAXITER 500 diff --git a/libLanlGeoMag/Lgm/Lgm_QuadPack.h b/libLanlGeoMag/Lgm/Lgm_QuadPack.h index a5b7248cf..4a3559864 100644 --- a/libLanlGeoMag/Lgm/Lgm_QuadPack.h +++ b/libLanlGeoMag/Lgm/Lgm_QuadPack.h @@ -1,9 +1,9 @@ #ifndef LGM_QUADPACK_H #define LGM_QUADPACK_H 1 -#include -#include #include +#include +#include /* * QuadPack.h diff --git a/libLanlGeoMag/Lgm/Lgm_RBF.h b/libLanlGeoMag/Lgm/Lgm_RBF.h index 62fd5e3cd..d87a2c7ee 100644 --- a/libLanlGeoMag/Lgm/Lgm_RBF.h +++ b/libLanlGeoMag/Lgm/Lgm_RBF.h @@ -1,15 +1,15 @@ #ifndef LGM_RBF #define LGM_RBF -#include "Lgm_Vec.h" #include "Lgm_RBF.h" +#include +#include +#include +#include +#include #include "Lgm_DynamicMemory.h" +#include "Lgm_Vec.h" #include "uthash.h" -#include -#include -#include -#include -#include #define LGM_CHOLESKY_DECOMP 0 #define LGM_PLU_DECOMP 1 diff --git a/libLanlGeoMag/Lgm/Lgm_SummersDiffCoeff.h b/libLanlGeoMag/Lgm/Lgm_SummersDiffCoeff.h index 911928c3a..bc18b3c00 100644 --- a/libLanlGeoMag/Lgm/Lgm_SummersDiffCoeff.h +++ b/libLanlGeoMag/Lgm/Lgm_SummersDiffCoeff.h @@ -1,12 +1,12 @@ #ifndef LGM_SUMMERS_DIFF_COEFF_H #define LGM_SUMMERS_DIFF_COEFF_H -#include #include #include +#include +#include "Lgm_Constants.h" #include "Lgm_CTrans.h" -#include "Lgm_QuadPack.h" #include "Lgm_PolyRoots.h" -#include "Lgm_Constants.h" +#include "Lgm_QuadPack.h" #ifndef M_CDIP diff --git a/libLanlGeoMag/Lgm/Lgm_TA2016.h b/libLanlGeoMag/Lgm/Lgm_TA2016.h index 115bac4e8..1a68c9f3e 100644 --- a/libLanlGeoMag/Lgm/Lgm_TA2016.h +++ b/libLanlGeoMag/Lgm/Lgm_TA2016.h @@ -1,9 +1,9 @@ #ifndef LGM_TA2016_H #define LGM_TA2016_H -#include -#include #include +#include +#include /* * Define a structure to hold all of the info needed in TA16 diff --git a/libLanlGeoMag/Lgm/Lgm_TabularBessel.h b/libLanlGeoMag/Lgm/Lgm_TabularBessel.h index 99f31c3e0..d871089a4 100644 --- a/libLanlGeoMag/Lgm/Lgm_TabularBessel.h +++ b/libLanlGeoMag/Lgm/Lgm_TabularBessel.h @@ -2,10 +2,10 @@ #define LGM_TABULARBESSEL #include "Lgm_DynamicMemory.h" -#include +#include #include #include -#include +#include /* * For doing tabular Bessel Functions of orders 0-14 (needed in TS07 model). diff --git a/libLanlGeoMag/Lgm/Lgm_Tsyg1996.h b/libLanlGeoMag/Lgm/Lgm_Tsyg1996.h index bfe252486..1bd01d2cd 100644 --- a/libLanlGeoMag/Lgm/Lgm_Tsyg1996.h +++ b/libLanlGeoMag/Lgm/Lgm_Tsyg1996.h @@ -1,9 +1,9 @@ #ifndef LGM_TSYG1996_H #define LGM_TSYG1996_H -#include -#include #include +#include +#include /* * Lgm_Tsyg1996.h diff --git a/libLanlGeoMag/Lgm/Lgm_Tsyg2001.h b/libLanlGeoMag/Lgm/Lgm_Tsyg2001.h index 539aff5b0..aaff20b57 100644 --- a/libLanlGeoMag/Lgm/Lgm_Tsyg2001.h +++ b/libLanlGeoMag/Lgm/Lgm_Tsyg2001.h @@ -1,9 +1,9 @@ #ifndef LGM_TSYG2001_H #define LGM_TSYG2001_H -#include -#include #include +#include +#include /* * Lgm_Tsyg2001.h diff --git a/libLanlGeoMag/Lgm/Lgm_Tsyg2004.h b/libLanlGeoMag/Lgm/Lgm_Tsyg2004.h index eb7a6ae77..b28bfb1e6 100644 --- a/libLanlGeoMag/Lgm/Lgm_Tsyg2004.h +++ b/libLanlGeoMag/Lgm/Lgm_Tsyg2004.h @@ -1,9 +1,9 @@ #ifndef LGM_TSYG2004_H #define LGM_TSYG2004_H -#include -#include #include +#include +#include /* * Lgm_Tsyg2004.h diff --git a/libLanlGeoMag/Lgm/Lgm_Tsyg2007.h b/libLanlGeoMag/Lgm/Lgm_Tsyg2007.h index 507ae0888..a30bdabe7 100644 --- a/libLanlGeoMag/Lgm/Lgm_Tsyg2007.h +++ b/libLanlGeoMag/Lgm/Lgm_Tsyg2007.h @@ -1,9 +1,9 @@ #ifndef LGM_TSYG2007_H #define LGM_TSYG2007_H -#include -#include #include +#include +#include #include "Lgm_TabularBessel.h" /* diff --git a/libLanlGeoMag/Lgm_AE8_AP8.c b/libLanlGeoMag/Lgm_AE8_AP8.c index 93e2ef483..ba363c70a 100644 --- a/libLanlGeoMag/Lgm_AE8_AP8.c +++ b/libLanlGeoMag/Lgm_AE8_AP8.c @@ -12,13 +12,13 @@ * */ +#include #include #include #include -#include +#include "Lgm/Lgm_AE8_AP8.h" #include "Lgm/Lgm_CTrans.h" #include "Lgm/Lgm_MagModelInfo.h" -#include "Lgm/Lgm_AE8_AP8.h" static int AE8MIN_IHEAD[] = { 0, 8, 4, 1964, 6400, 2100, 1024, 1024, 13168 }; static int AE8MIN_MAP[] = { 0, diff --git a/libLanlGeoMag/Lgm_AE_index.c b/libLanlGeoMag/Lgm_AE_index.c index 65f6782ff..8ac83b45a 100644 --- a/libLanlGeoMag/Lgm_AE_index.c +++ b/libLanlGeoMag/Lgm_AE_index.c @@ -8,11 +8,11 @@ * */ -#include +#include #include -#include #include -#include +#include +#include #include "Lgm/Lgm_AE_index.h" /** diff --git a/libLanlGeoMag/Lgm_AlphaOfK.c b/libLanlGeoMag/Lgm_AlphaOfK.c index dc32a659b..cf0463417 100644 --- a/libLanlGeoMag/Lgm_AlphaOfK.c +++ b/libLanlGeoMag/Lgm_AlphaOfK.c @@ -10,13 +10,13 @@ * * */ -#include -#include -#include "Lgm/Lgm_QuadPack.h" -#include "Lgm/Lgm_MagModelInfo.h" #include #include +#include +#include #include +#include "Lgm/Lgm_MagModelInfo.h" +#include "Lgm/Lgm_QuadPack.h" #define TRACE_TOL 1e-7 #define GOLD 0.38197 diff --git a/libLanlGeoMag/Lgm_B_FromScatteredData.c b/libLanlGeoMag/Lgm_B_FromScatteredData.c index 5617957d9..696496072 100644 --- a/libLanlGeoMag/Lgm_B_FromScatteredData.c +++ b/libLanlGeoMag/Lgm_B_FromScatteredData.c @@ -5,9 +5,9 @@ * */ +#include "Lgm/Lgm_KdTree.h" #include "Lgm/Lgm_MagModelInfo.h" #include "Lgm/Lgm_Octree.h" -#include "Lgm/Lgm_KdTree.h" #include "Lgm/Lgm_RBF.h" #include "Lgm/qsort.h" diff --git a/libLanlGeoMag/Lgm_CTrans.c b/libLanlGeoMag/Lgm_CTrans.c index 5bd3f28b2..8db30e1f9 100644 --- a/libLanlGeoMag/Lgm_CTrans.c +++ b/libLanlGeoMag/Lgm_CTrans.c @@ -1,68 +1,66 @@ /*! \file Lgm_CTrans.c * - * \brief Collection of numerous routines used for coordinate system transformations and ephemeris calculations. + * \brief Collection of numerous routines used for coordinate system + * transformations and ephemeris calculations. * */ - /* * FAQ on coordinate transformations.... - * + * * * A general method for constructing transformation matrices from one * system to another (each with same origin): * * 1) Lets take an example where we want to go from a spacecraft - * coordinate system,"sc" to gsm. + * coordinate system,"sc" to gsm. * * 2) Let u_sc be a vector in spacecraft coordinates. I.e. the first - * component is the projection of the vector onto the Xsc axis, and so - * on. + * component is the projection of the vector onto the Xsc axis, and + * so on. * * 3) Let u_gsm be the same vector in gsm coordinates. I.e. first * component is projection of the vector onto the GSM X axis, etc... * - * 4) Now, if we want to compute the x component of the vector relative to the SC frame, - * this is just the projection of the vector, u onto the SC X-axis. This is just a dot product; - * x_sc = Xsc-hat dot u - * The right hand side is a dot product between two vectors in - * space. To evaluate, both vectors need to be defined relative to - * the same coord system. Thus, if u is in gsm coords, then Xsc-hat needs to be in gsm coords. - * In other words; - * x_sc = Xsc-hat_gsm dot u_gsm - * similarly, - * y_sc = Ysc-hat_gsm dot u_gsm - * z_sc = Zsc-hat_gsm dot u_gsm - * Or, in matrix notation; - * [ x ] [ Xsc-hat_gsm ] [ x ] - * | y | = | Ysc-hat_gsm | | y | - * [ z ]sc [ Zsc-hat_gsm ] [ z ]gsm + * 4) Now, if we want to compute the x component of the vector relative + * to the SC frame, this is just the projection of the vector, u onto the SC + * X-axis. This is just a dot product; x_sc = Xsc-hat dot u The right hand side + * is a dot product between two vectors in space. To evaluate, both vectors need + * to be defined relative to the same coord system. Thus, if u is in gsm coords, + * then Xsc-hat needs to be in gsm coords. In other words; x_sc = Xsc-hat_gsm + * dot u_gsm similarly, y_sc = Ysc-hat_gsm dot u_gsm z_sc = Zsc-hat_gsm dot + * u_gsm Or, in matrix notation; [ x ] [ Xsc-hat_gsm ] [ x ] | y | = | + * Ysc-hat_gsm | | y | [ z ]sc [ Zsc-hat_gsm ] [ z ]gsm * * Or, - * [ x ] [ Xsc-hat_xgsm Xsc-hat_ygsm Xsc-hat_zgsm ] [ x ] - * | y | = | Ysc-hat_xgsm Ysc-hat_ygsm Ysc-hat_zgsm | | y | - * [ z ]sc [ Zsc-hat_xgsm Zsc-hat_ygsm Zsc-hat_zgsm ] [ z ]gsm + * [ x ] [ Xsc-hat_xgsm Xsc-hat_ygsm + * Xsc-hat_zgsm ] [ x ] | y | = | Ysc-hat_xgsm Ysc-hat_ygsm Ysc-hat_zgsm | + * | y | [ z ]sc [ Zsc-hat_xgsm Zsc-hat_ygsm Zsc-hat_zgsm ] [ z ]gsm * * u_sc = A_gsm_to_sc * u_gsm * - * where, A_gsm_to_sc is a 3x3 trans matrix that is formed by taking as; + * where, A_gsm_to_sc is a 3x3 trans matrix that is formed by + * taking as; * - * a) the first row is Xsc-hat in gsm coords. I.e. the x-axis of the SC frame in gsm coords. - * b) the second row is Ysc-hat in gsm coords. I.e. the y-axis of the SC frame in gsm coords. - * z) the third row is Zsc-hat in gsm coords. I.e. the z-axis of the SC frame in gsm coords. + * a) the first row is Xsc-hat in gsm coords. I.e. the + * x-axis of the SC frame in gsm coords. b) the second row is Ysc-hat in gsm + * coords. I.e. the y-axis of the SC frame in gsm coords. z) the third row is + * Zsc-hat in gsm coords. I.e. the z-axis of the SC frame in gsm coords. * - * 5) Define the matrix A_gsm_to_sc and use Lgm_MatTimeVec to perform the matrix product. - * Once you are in a frame we know about, its easy to go to any other. + * 5) Define the matrix A_gsm_to_sc and use Lgm_MatTimeVec to perform + * the matrix product. Once you are in a frame we know about, its easy to go to + * any other. * - * 6) This schem works in general and is pretty easy to implement on a case-by-case basis.... + * 6) This schem works in general and is pretty easy to implement on a + * case-by-case basis.... */ -#include "Lgm/Lgm_CTrans.h" -#include "Lgm/Lgm_Quat.h" -#include "Lgm/Lgm_Misc.h" -#include "config.h" +#include "Lgm/Lgm_CTrans.h" #include #include +#include "config.h" +#include "Lgm/Lgm_Misc.h" +#include "Lgm/Lgm_Quat.h" /* #ifndef LGM_EOP_DATA_DIR @@ -71,32 +69,29 @@ #endif */ #ifndef LGM_EOP_DATA_DIR -#define LGM_EOP_DATA_DIR DATADIR/LanlGeoMag/EopData +#define LGM_EOP_DATA_DIR DATADIR / LanlGeoMag / EopData #endif - -void Lgm_free_ctrans_children( Lgm_CTrans *c ) { - - if ( c->jpl_initialized ) { - Lgm_FreeJPLephemInfo( c->jpl ); +void Lgm_free_ctrans_children(Lgm_CTrans* c) { + if (c->jpl_initialized) { + Lgm_FreeJPLephemInfo(c->jpl); } - free( c->l.LeapSecondDates ); - free( c->l.LeapSecondJDs ); - free( c->l.LeapSeconds ); + free(c->l.LeapSecondDates); + free(c->l.LeapSecondJDs); + free(c->l.LeapSeconds); } -void Lgm_free_ctrans( Lgm_CTrans *c ) { +void Lgm_free_ctrans(Lgm_CTrans* c) { Lgm_free_ctrans_children(c); free(c); } - -void Lgm_ctransDefaults(Lgm_CTrans *c, int Verbose) { +void Lgm_ctransDefaults(Lgm_CTrans* c, int Verbose) { /* Load Leap Seconds Stuff */ - Lgm_LoadLeapSeconds( c ); + Lgm_LoadLeapSeconds(c); - c->Verbose = Verbose; + c->Verbose = Verbose; c->jpl_initialized = FALSE; /* Set Number of Nutation series terms to 106 */ @@ -112,25 +107,21 @@ void Lgm_ctransDefaults(Lgm_CTrans *c, int Verbose) { * less accurate defaults if EOP data is unavailable or not * needed/desired. */ - c->DUT1 = 0.0; // seconds - c->xp = 0.0; // radians - c->yp = 0.0; // radians - c->ddPsi = 0.0; // radians - c->ddEps = 0.0; // radians - + c->DUT1 = 0.0; // seconds + c->xp = 0.0; // radians + c->yp = 0.0; // radians + c->ddPsi = 0.0; // radians + c->ddEps = 0.0; // radians } +Lgm_CTrans* Lgm_init_ctrans(int Verbose) { + Lgm_CTrans* c; -Lgm_CTrans *Lgm_init_ctrans( int Verbose ) { - - Lgm_CTrans *c; - - c = (Lgm_CTrans *) calloc (1, sizeof(*c)); + c = (Lgm_CTrans*)calloc(1, sizeof(*c)); Lgm_ctransDefaults(c, Verbose); - //printf("LGM_EOP_DATA_DIR = %s\n", LGM_EOP_DATA_DIR); + // printf("LGM_EOP_DATA_DIR = %s\n", LGM_EOP_DATA_DIR); return c; - } /** @@ -138,21 +129,19 @@ Lgm_CTrans *Lgm_init_ctrans( int Verbose ) { * asignments (e.g. *t = *s) are dangerous. Here we make sure that * the target gets an independent copy of the structure. */ -Lgm_CTrans *Lgm_CopyCTrans( Lgm_CTrans *s ) { - - Lgm_CTrans *t; - int n; - +Lgm_CTrans* Lgm_CopyCTrans(Lgm_CTrans* s) { + Lgm_CTrans* t; + int n; - if ( s == NULL) { + if (s == NULL) { printf("Lgm_CopyCTrans: Error, source structure is NULL\n"); - return((Lgm_CTrans *) NULL); + return ((Lgm_CTrans*)NULL); } /* * Allocate memory for target */ - t = (Lgm_CTrans *)calloc( 1, sizeof(Lgm_CTrans) ); + t = (Lgm_CTrans*)calloc(1, sizeof(Lgm_CTrans)); /* * Do memcpy. Note that for things that are dynamically allocated in @@ -161,39 +150,34 @@ Lgm_CTrans *Lgm_CopyCTrans( Lgm_CTrans *s ) { * so we need to allocate our own memory for those and then do a memcpy on * the contents. */ - memcpy( t, s, sizeof(Lgm_CTrans) ); + memcpy(t, s, sizeof(Lgm_CTrans)); /* * Now, copy the LeapSeconds stuff properly (they were dyn. allocated). * (memcpy's args are (dest, src, size)) */ n = t->l.nLeapSecondDates = s->l.nLeapSecondDates; - t->l.LeapSecondDates = (long int *) malloc( n*sizeof(long int) ); - t->l.LeapSecondJDs = (double *) malloc( n*sizeof(double) ); - t->l.LeapSeconds = (double *) malloc( n*sizeof(double) ); - memcpy( t->l.LeapSecondDates, s->l.LeapSecondDates, n*sizeof(long int) ); - memcpy( t->l.LeapSecondJDs, s->l.LeapSecondJDs, n*sizeof(double) ); - memcpy( t->l.LeapSeconds, s->l.LeapSeconds, n*sizeof(double) ); - - return( t ); - + t->l.LeapSecondDates = (long int*)malloc(n * sizeof(long int)); + t->l.LeapSecondJDs = (double*)malloc(n * sizeof(double)); + t->l.LeapSeconds = (double*)malloc(n * sizeof(double)); + memcpy(t->l.LeapSecondDates, s->l.LeapSecondDates, n * sizeof(long int)); + memcpy(t->l.LeapSecondJDs, s->l.LeapSecondJDs, n * sizeof(double)); + memcpy(t->l.LeapSeconds, s->l.LeapSeconds, n * sizeof(double)); + + return (t); } - - /** * \brief * Converts RA and DEC to unit vector in cartesian coords */ -void Lgm_Radec_to_Cart(double ra, double dec, Lgm_Vector *r) { - - double CosDec; - +void Lgm_Radec_to_Cart(double ra, double dec, Lgm_Vector* r) { + double CosDec; /* * Convert ra/dec from degrees to radians */ - ra *= RadPerDeg; + ra *= RadPerDeg; dec *= RadPerDeg; CosDec = cos(dec); @@ -204,168 +188,159 @@ void Lgm_Radec_to_Cart(double ra, double dec, Lgm_Vector *r) { r->x = CosDec * cos(ra); r->y = CosDec * sin(ra); r->z = sin(dec); - } double Lgm_angle2pi(double angle) { - int n; double a = M_2PI; - if (angle < 0.0){ - n = (int)(angle/a) - 1; - return(angle-n*a); - } else if (angle > a){ - n = (int)(angle/a); - return(angle-n*a); - } else{ - return(angle); + if (angle < 0.0) { + n = (int)(angle / a) - 1; + return (angle - n * a); + } else if (angle > a) { + n = (int)(angle / a); + return (angle - n * a); + } else { + return (angle); } - } double Lgm_angle360(double angle) { - int n; - if (angle < 0.0){ - n = (int)(angle/360.0) - 1; - return(angle-n*360.0); - } else if (angle > 360.0){ - n = (int)(angle/360.0); - return(angle-n*360.0); - } else{ - return(angle); + if (angle < 0.0) { + n = (int)(angle / 360.0) - 1; + return (angle - n * 360.0); + } else if (angle > 360.0) { + n = (int)(angle / 360.0); + return (angle - n * 360.0); + } else { + return (angle); } - } - - /** * \brief * Compute the Julian Day number for the given date. * Julian Date is the number of days since noon of Jan 1 4713 B.C. */ -long int Lgm_JD_to_Date(double jd, int *ny, int *nm, int *nd, double *UT) { - - long int I, A, B, C, D, E, G, Date; - double F; +long int Lgm_JD_to_Date(double jd, int* ny, int* nm, int* nd, double* UT) { + long int I, A, B, C, D, E, G, Date; + double F; jd += 0.5; I = (int)jd; F = jd - (double)I; - if ( I > 2299160 ) { - A = (int)( ((double)I - 1867216.25)/36524.25 ); - B = I+1+A-(int)( (double)A/4.0 ); + if (I > 2299160) { + A = (int)(((double)I - 1867216.25) / 36524.25); + B = I + 1 + A - (int)((double)A / 4.0); } else { B = I; } - C = B+1524; + C = B + 1524; - D = (int)( ((double)C - 122.1)/365.25 ); - E = (int)( 365.25*D ); + D = (int)(((double)C - 122.1) / 365.25); + E = (int)(365.25 * D); - G = (int)( ((double)C-(double)E)/30.6001 ); + G = (int)(((double)C - (double)E) / 30.6001); /* * Day of month */ - *nd = C - E - (int)( 30.6001*G ); - *UT = 24.0*F; + *nd = C - E - (int)(30.6001 * G); + *UT = 24.0 * F; - if ( G <= 13 ) { - *nm = G-1; - } else if ( G > 13 ) { - *nm = G-13; + if (G <= 13) { + *nm = G - 1; + } else if (G > 13) { + *nm = G - 13; } - if ( *nm > 2 ) { - *ny = D-4716; - } else if ( *nm <= 2 ) { - *ny = D-4715; + if (*nm > 2) { + *ny = D - 4716; + } else if (*nm <= 2) { + *ny = D - 4715; } - Date = *ny*10000 + *nm*100 + *nd; - - return( Date ); + Date = *ny * 10000 + *nm * 100 + *nd; + return (Date); } -long int Lgm_MJD_to_Date(double mjd, int *ny, int *nm, int *nd, double *UT) { - return( Lgm_JD_to_Date( mjd+2400000.5, ny, nm, nd, UT ) ); +long int Lgm_MJD_to_Date(double mjd, int* ny, int* nm, int* nd, double* UT) { + return (Lgm_JD_to_Date(mjd + 2400000.5, ny, nm, nd, UT)); } double Lgm_hour24(double hour) { int n; - if (hour < 0.0){ - n = (int)(hour/24.0) - 1; - return(hour-n*24.0); - } else if (hour > 24.0){ - n = (int)(hour/24.0); - return(hour-n*24.0); - } else{ - return(hour); + if (hour < 0.0) { + n = (int)(hour / 24.0) - 1; + return (hour - n * 24.0); + } else if (hour > 24.0) { + n = (int)(hour / 24.0); + return (hour - n * 24.0); + } else { + return (hour); } } - /* * \brief * This routine solve's Kepler's equation for eccentric anomaly * */ double Lgm_kepler(double M, double e) { - int n=0; - double E, Eold, eps = 1.0e-8; + int n = 0; + double E, Eold, eps = 1.0e-8; // M is mean anomaly (radians), e is eccentricity of orbit // E is the eccentric anomaly (radians) - E = M + e*sin(M); - do{ - Eold = E; - E = Eold + (M-Eold+e*sin(Eold)) / (1.0-e*cos(Eold)); - ++n; - } while( (fabs(E-Eold) > eps) && (n < 100) ); - return(E); + E = M + e * sin(M); + do { + Eold = E; + E = Eold + (M - Eold + e * sin(Eold)) / (1.0 - e * cos(Eold)); + ++n; + } while ((fabs(E - Eold) > eps) && (n < 100)); + return (E); } /* * \brief - * This routine outputs the dipole tilt angle as computed in Lgm_Set_Coord_Transforms + * This routine outputs the dipole tilt angle as computed in + * Lgm_Set_Coord_Transforms * * Date -- (long int) containing date ( e.g. YYYYMMDD or YYYYDDD ) * UT -- (double) decimal UT in hours ( e.g. 12.0 is noon ). - * + * */ double Lgm_Dipole_Tilt(long int date, double UTC) { - Lgm_CTrans *c = Lgm_init_ctrans(0); - Lgm_Set_Coord_Transforms(date, UTC, c); - return c->psi; + Lgm_CTrans* c = Lgm_init_ctrans(0); + Lgm_Set_Coord_Transforms(date, UTC, c); + return c->psi; } -void Lgm_Set_CTrans_Options( int ephModel, int pnModel, Lgm_CTrans *c ) { +void Lgm_Set_CTrans_Options(int ephModel, int pnModel, Lgm_CTrans* c) { switch (ephModel) { - case LGM_EPH_HIGH_ACCURACY: case LGM_EPH_DE: - c->ephModel = ephModel; //ephemerides model for Sun and Moon : LGM_DE_421, USE_HIGH_ACCURACY_SUN + c->ephModel = ephModel; // ephemerides model for Sun and Moon : + // LGM_DE_421, USE_HIGH_ACCURACY_SUN break; case LGM_EPH_LOW_ACCURACY: default: c->ephModel = LGM_EPH_LOW_ACCURACY; break; - } - c->pnModel = LGM_PN_IAU76; //precession and nutation model : LGM_PN_IAU76, LGM_PN_IAU06 (not impl.) + c->pnModel = LGM_PN_IAU76; // precession and nutation model : LGM_PN_IAU76, + // LGM_PN_IAU06 (not impl.) } -/** +/** * \brief * This routine takes date and time and sets up all the transformation * matrices to do coord transformations. @@ -377,12 +352,15 @@ void Lgm_Set_CTrans_Options( int ephModel, int pnModel, Lgm_CTrans *c ) { * YYYYMMDD or a 7-digit long int of the form YYYYDDD (Year/DayOfYear). * To discriminate between these two formats, the routine assumes the * following ranges of validity; - * - yyyyddd (where yyyy is assumed to be between 1000 A.D. and 9999 A.D.) - * - yyyymmdd (where yyyy is assumed to be between 1000 A.D. and 9999 A.D.) + * - yyyyddd (where yyyy is assumed to be between 1000 A.D. and 9999 + * A.D.) + * - yyyymmdd (where yyyy is assumed to be between 1000 A.D. and 9999 + * A.D.) * - * \param[in] date The date represented as an 8-digit long int in the form YYYYMMDD (or a 7-digit date in the form YYYYDDD.) - * \param[in] UTC The UTC time of the day in decimal hours. - * \param[in,out] c Pointer to an Lgm_CTrans structure. + * \param[in] date The date represented as an 8-digit long int in the + * form YYYYMMDD (or a 7-digit date in the form YYYYDDD.) \param[in] UTC + * The UTC time of the day in decimal hours. \param[in,out] c Pointer to + * an Lgm_CTrans structure. * * * \returns void @@ -391,117 +369,128 @@ void Lgm_Set_CTrans_Options( int ephModel, int pnModel, Lgm_CTrans *c ) { * \date 2013 * */ -void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { - - int year, month, day, doy; - double TU, gmst, gast, sn, cs, Time; - double varep, varpi, spsi; - double eccen, epsilon; - double days, M, E, nu, lambnew; - double RA, DEC; - double gclat, glon, psi; - double g[14][14], h[14][14], Tmp[3][3]; - double varep90, varpi90; - double Zeta, Theta, Zee; - double SinZee, CosZee, SinZeta, CosZeta, SinTheta, CosTheta; - Lgm_Vector S, K, Y, Z, D, Dmod, Dgsm, u_mod, u_tod, u_gei, Zgeo, X; - double RA_tod, DEC_tod; - double RA_gei, DEC_gei; - double sxp, cxp, syp, cyp; - double sdp, cdp, se, ce, set, cet; - double T_UT1, T2_UT1, T3_UT1, T_TT, T2_TT, T3_TT, T4_TT, T5_TT; - double cos_epsilon, sin_epsilon, sin_lambnew, sin_b, cos_b, sin_l, tmp; - int i, j, N, sgn; - +void Lgm_Set_Coord_Transforms(long int date, double UTC, Lgm_CTrans* c) { + int year, month, day, doy; + double TU, gmst, gast, sn, cs, Time; + double varep, varpi, spsi; + double eccen, epsilon; + double days, M, E, nu, lambnew; + double RA, DEC; + double gclat, glon, psi; + double g[14][14], h[14][14], Tmp[3][3]; + double varep90, varpi90; + double Zeta, Theta, Zee; + double SinZee, CosZee, SinZeta, CosZeta, SinTheta, CosTheta; + Lgm_Vector S, K, Y, Z, D, Dmod, Dgsm, u_mod, u_tod, u_gei, Zgeo, X; + double RA_tod, DEC_tod; + double RA_gei, DEC_gei; + double sxp, cxp, syp, cyp; + double sdp, cdp, se, ce, set, cet; + double T_UT1, T2_UT1, T3_UT1, T_TT, T2_TT, T3_TT, T4_TT, T5_TT; + double cos_epsilon, sin_epsilon, sin_lambnew, sin_b, cos_b, sin_l, tmp; + int i, j, N, sgn; /* * Set UTC values */ - Lgm_Doy( date, &year, &month, &day, &doy); - date = year*10000+month*100+day; - c->UTC.Date = date; - c->UTC.Time = UTC; - c->UTC.Year = year; - c->UTC.Month = month; - c->UTC.Day = day; - c->UTC.Doy = doy; - c->UTC.Dow = Lgm_DayOfWeek( year, month, day, c->UTC.DowStr ); - c->UTC.JD = Lgm_JD( c->UTC.Year, c->UTC.Month, c->UTC.Day, c->UTC.Time, LGM_TIME_SYS_UTC, c ); - c->UTC.T = (c->UTC.JD - 2451545.0)/36525.0; - c->UTC.fYear = (double)c->UTC.Year + ((double)c->UTC.Doy - 1.0 + c->UTC.Time/24.0)/(365.0 + (double)Lgm_LeapYear(c->UTC.Year)); - Lgm_UT_to_HMSd( UTC, &sgn, &(c->UTC.Hour), &(c->UTC.Minute), &(c->UTC.Second) ); + Lgm_Doy(date, &year, &month, &day, &doy); + date = year * 10000 + month * 100 + day; + c->UTC.Date = date; + c->UTC.Time = UTC; + c->UTC.Year = year; + c->UTC.Month = month; + c->UTC.Day = day; + c->UTC.Doy = doy; + c->UTC.Dow = Lgm_DayOfWeek(year, month, day, c->UTC.DowStr); + c->UTC.JD = Lgm_JD(c->UTC.Year, c->UTC.Month, c->UTC.Day, c->UTC.Time, + LGM_TIME_SYS_UTC, c); + c->UTC.T = (c->UTC.JD - 2451545.0) / 36525.0; + c->UTC.fYear = + (double)c->UTC.Year + ((double)c->UTC.Doy - 1.0 + c->UTC.Time / 24.0) / + (365.0 + (double)Lgm_LeapYear(c->UTC.Year)); + Lgm_UT_to_HMSd(UTC, &sgn, &(c->UTC.Hour), &(c->UTC.Minute), + &(c->UTC.Second)); // set DAT - c->DAT = Lgm_GetLeapSeconds( c->UTC.JD, c ); - + c->DAT = Lgm_GetLeapSeconds(c->UTC.JD, c); /* * Set UT1 values */ - c->UT1 = c->UTC; // initially make DateTime structures the same - c->UT1.Time = c->UTC.Time + c->DUT1/3600.0; - c->UT1.JD = Lgm_JD( c->UT1.Year, c->UT1.Month, c->UT1.Day, c->UT1.Time, LGM_TIME_SYS_UT1, c ); - c->UT1.Date = Lgm_JD_to_Date( c->UT1.JD, &c->UT1.Year, &c->UT1.Month, &c->UT1.Day, &Time ); - c->UT1.Time = Lgm_hour24( c->UT1.Time ); // Keep the time we had rather than gettingm it back from Lgm_JD_to_Date(). This limits roundoff error - c->UT1.T = (c->UT1.JD - 2451545.0)/36525.0; - T_UT1 = c->UT1.T; - T2_UT1 = T_UT1*T_UT1; - T3_UT1 = T_UT1*T2_UT1; - + c->UT1 = c->UTC; // initially make DateTime structures the same + c->UT1.Time = c->UTC.Time + c->DUT1 / 3600.0; + c->UT1.JD = Lgm_JD(c->UT1.Year, c->UT1.Month, c->UT1.Day, c->UT1.Time, + LGM_TIME_SYS_UT1, c); + c->UT1.Date = Lgm_JD_to_Date(c->UT1.JD, &c->UT1.Year, &c->UT1.Month, + &c->UT1.Day, &Time); + c->UT1.Time = Lgm_hour24( + c->UT1.Time); // Keep the time we had rather than gettingm it back from + // Lgm_JD_to_Date(). This limits roundoff error + c->UT1.T = (c->UT1.JD - 2451545.0) / 36525.0; + T_UT1 = c->UT1.T; + T2_UT1 = T_UT1 * T_UT1; + T3_UT1 = T_UT1 * T2_UT1; /* * Set TAI values */ - c->TAI = c->UTC; // initially make DateTime structures the same - c->TAI.Time = c->UTC.Time + c->DAT/3600.0; - c->TAI.JD = Lgm_JD( c->TAI.Year, c->TAI.Month, c->TAI.Day, c->TAI.Time, LGM_TIME_SYS_TAI, c ); - c->TAI.Date = Lgm_JD_to_Date( c->TAI.JD, &c->TAI.Year, &c->TAI.Month, &c->TAI.Day, &Time ); - c->TAI.Time = Lgm_hour24( c->TAI.Time ); // Keep the time we had rather than gettingm it back from Lgm_JD_to_Date(). This limits roundoff error - c->TAI.T = (c->TAI.JD - 2451545.0)/36525.0; - + c->TAI = c->UTC; // initially make DateTime structures the same + c->TAI.Time = c->UTC.Time + c->DAT / 3600.0; + c->TAI.JD = Lgm_JD(c->TAI.Year, c->TAI.Month, c->TAI.Day, c->TAI.Time, + LGM_TIME_SYS_TAI, c); + c->TAI.Date = Lgm_JD_to_Date(c->TAI.JD, &c->TAI.Year, &c->TAI.Month, + &c->TAI.Day, &Time); + c->TAI.Time = Lgm_hour24( + c->TAI.Time); // Keep the time we had rather than gettingm it back from + // Lgm_JD_to_Date(). This limits roundoff error + c->TAI.T = (c->TAI.JD - 2451545.0) / 36525.0; /* * Set TT values */ - c->TT = c->TAI; // initially make DateTime structure the same as TAI - c->TT.Time = c->TAI.Time + 32.184/3600.0; - c->TT.JD = Lgm_JD( c->TT.Year, c->TT.Month, c->TT.Day, c->TT.Time, LGM_TIME_SYS_TT, c ); - c->TT.Date = Lgm_JD_to_Date( c->TT.JD, &c->TT.Year, &c->TT.Month, &c->TT.Day, &Time ); - c->TT.Time = Lgm_hour24( c->TT.Time ); // Keep the time we had rather than gettingm it back from Lgm_JD_to_Date(). This limits roundoff error - c->TT.T = (c->TT.JD - 2451545.0)/36525.0; - T_TT = c->TT.T; - T2_TT = T_TT*T_TT; - T3_TT = T_TT*T2_TT; - T4_TT = T2_TT*T2_TT; - T5_TT = T3_TT*T2_TT; - - Lgm_TT_to_TDB( &c->TT, &c->TDB, c ); + c->TT = c->TAI; // initially make DateTime structure the same as TAI + c->TT.Time = c->TAI.Time + 32.184 / 3600.0; + c->TT.JD = Lgm_JD(c->TT.Year, c->TT.Month, c->TT.Day, c->TT.Time, + LGM_TIME_SYS_TT, c); + c->TT.Date = + Lgm_JD_to_Date(c->TT.JD, &c->TT.Year, &c->TT.Month, &c->TT.Day, &Time); + c->TT.Time = Lgm_hour24( + c->TT.Time); // Keep the time we had rather than gettingm it back from + // Lgm_JD_to_Date(). This limits roundoff error + c->TT.T = (c->TT.JD - 2451545.0) / 36525.0; + T_TT = c->TT.T; + T2_TT = T_TT * T_TT; + T3_TT = T_TT * T2_TT; + T4_TT = T2_TT * T2_TT; + T5_TT = T3_TT * T2_TT; + + Lgm_TT_to_TDB(&c->TT, &c->TDB, c); /* Test here for LGM_EPH_DE - if set, make a JPLephemInfo */ - if ( ( c->ephModel == LGM_EPH_DE ) && ( !(c->jpl_initialized) ) ){ - - c->jpl = Lgm_InitJPLephemInfo( 421, LGM_DE_SUN|LGM_DE_EARTHMOON, 1); - Lgm_ReadJPLephem( c->jpl ); + if ((c->ephModel == LGM_EPH_DE) && (!(c->jpl_initialized))) { + c->jpl = Lgm_InitJPLephemInfo(421, LGM_DE_SUN | LGM_DE_EARTHMOON, 1); + Lgm_ReadJPLephem(c->jpl); c->jpl_initialized = TRUE; - } else { - -// We should check to see if its initialized already. It may be that usewr has switched -// from LGM_EPH_DE -- we dont want to lose the memory in that case... - //c->jpl = NULL; - + // We should check to see if its initialized already. It may be that + // usewr has switched from LGM_EPH_DE -- we dont want to lose the memory + // in that case... + // c->jpl = NULL; } /* * Compute Greenwich Mean Sidereal Time (gmst) - * T0 = number of Julian centuries since 2000 January 1.5 to 0h on the date we are interested in. - * T = number of Julian centuries since 2000 January 1.5 to the UT on the date we are interested in. - * (See Astronomical Almanac or e.g. Vallado.) + * T0 = number of Julian centuries since 2000 January 1.5 to 0h on the date + * we are interested in. T = number of Julian centuries since 2000 + * January 1.5 to the UT on the date we are interested in. (See Astronomical + * Almanac or e.g. Vallado.) */ - c->gmst = fmod( (67310.54841 + (876600.0*3600.0 + 8640184.812866)*T_UT1 + 0.093104*T2_UT1 - 6.2e-6*T3_UT1)/3600.0, 24.0); - gmst = c->gmst*15.0*RadPerDeg; // convert to radians for ease later on - + c->gmst = fmod((67310.54841 + (876600.0 * 3600.0 + 8640184.812866) * T_UT1 + + 0.093104 * T2_UT1 - 6.2e-6 * T3_UT1) / + 3600.0, + 24.0); + gmst = c->gmst * 15.0 * RadPerDeg; // convert to radians for ease later on /* * @@ -516,25 +505,29 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { * The TU here is the number of Julian centuries since * 1900 January 0.0 (= 2415020.0) */ -//UPDATE THIS TO IAU-76/FK-5 (Done?) - TU = ( c->TT.JD - 2415020.0 )/36525.0; - varep = (279.6966778 + 36000.76892*TU + 0.0003025*TU*TU)*RadPerDeg; - varpi = (281.2208444 + 1.719175*TU + 0.000452778*TU*TU)*RadPerDeg; - eccen = 0.01675104 - 0.0000418*TU - 0.000000126*TU*TU; + // UPDATE THIS TO IAU-76/FK-5 (Done?) + TU = (c->TT.JD - 2415020.0) / 36525.0; + varep = (279.6966778 + 36000.76892 * TU + 0.0003025 * TU * TU) * RadPerDeg; + varpi = (281.2208444 + 1.719175 * TU + 0.000452778 * TU * TU) * RadPerDeg; + eccen = 0.01675104 - 0.0000418 * TU - 0.000000126 * TU * TU; c->eccentricity = eccen; - /* * Compute the Obliquity of the Ecliptic at epoch TU * w.r.t. mean equator of date * The TU in this formula is the number of Julian * centuries since epoch 2000 January 1.5 */ - c->epsilon = 84381.448 - 46.8150*T_TT - 0.00059*T2_TT + 0.001813*T3_TT; // IAU-76/FK5 value (arcsec) IAU 1980 model, fit to DE200 - epsilon = c->epsilon*RadPerArcSec; // radians - //c->epsilon = 84381.406 - 46.836769*T_TT - 0.0001831*T2_TT + 0.00200340*T3_TT - 0.0000576*T4_TT - 4.34e-8*T5_TT; // IAU 2006 model - //Ref: Petit, G., and B. Luzum, IERS Conventions (2010), IERS Technical Note No. 36, International Earth Rotation and Reference Systems Service (IERS), ISSN: 1019-4568, 2010. - + c->epsilon = + 84381.448 - 46.8150 * T_TT - 0.00059 * T2_TT + + 0.001813 * + T3_TT; // IAU-76/FK5 value (arcsec) IAU 1980 model, fit to DE200 + epsilon = c->epsilon * RadPerArcSec; // radians + // c->epsilon = 84381.406 - 46.836769*T_TT - 0.0001831*T2_TT + + // 0.00200340*T3_TT - 0.0000576*T4_TT - 4.34e-8*T5_TT; // IAU 2006 model Ref: + // Petit, G., and B. Luzum, IERS Conventions (2010), IERS Technical Note No. + // 36, International Earth Rotation and Reference Systems Service (IERS), + // ISSN: 1019-4568, 2010. /* * Compute: @@ -543,105 +536,157 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { * The True Anomaly (nu) * The Eccentric Anomaly via Keplers equation (E) */ - days = c->TT.JD - 2447891.5; - varep90 = 279.403303*RadPerDeg; - varpi90 = 282.768422*RadPerDeg; - M = Lgm_angle2pi(M_2PI/365.242191*days ); - M = Lgm_angle2pi( M + varep90 - varpi90 ); - E = Lgm_kepler(M, eccen); - nu = 2.0*atan( sqrt((1.0+eccen)/(1.0-eccen))*tan(E/2.0) ); + days = c->TT.JD - 2447891.5; + varep90 = 279.403303 * RadPerDeg; + varpi90 = 282.768422 * RadPerDeg; + M = Lgm_angle2pi(M_2PI / 365.242191 * days); + M = Lgm_angle2pi(M + varep90 - varpi90); + E = Lgm_kepler(M, eccen); + nu = 2.0 * atan(sqrt((1.0 + eccen) / (1.0 - eccen)) * tan(E / 2.0)); lambnew = Lgm_angle2pi(nu + varpi90); c->mean_anomaly = M; c->true_anomaly = nu; c->lambda_sun = lambnew; /* - * Compute Precession angles to go from J2000 Epoch (we call this GEI here) to Mean Of Date (MOD) system. - * Mean of Date has corrections for precession, but not nutation. - * (e.g. see "Reduction for Precession -- rigorous formulae" in Astronomical Almanac 2004 page B18) + * Compute Precession angles to go from J2000 Epoch (we call this GEI here) + * to Mean Of Date (MOD) system. Mean of Date has corrections for + * precession, but not nutation. (e.g. see "Reduction for Precession -- + * rigorous formulae" in Astronomical Almanac 2004 page B18) */ -// TU = (Lgm_JD( year, month, day, TDT, c ) - 2451545.0)/36525.0; -// TU2 = TU*TU; -// TU3 = TU*TU2; - c->Zeta = 0.6406161*T_TT + 0.0000839*T2_TT + 5.0e-6*T3_TT; // degrees - c->Zee = 0.6406161*T_TT + 0.0003041*T2_TT + 5.1e-6*T3_TT; // degrees - c->Theta = 0.5567530*T_TT - 0.0001185*T2_TT - 1.16e-5*T3_TT; // degrees - Zeta = c->Zeta*RadPerDeg; Theta = c->Theta*RadPerDeg; Zee = c->Zee*RadPerDeg; - SinZee = sin(Zee); CosZee = cos(Zee); - SinZeta = sin(Zeta); CosZeta = cos(Zeta); - SinTheta = sin(Theta); CosTheta = cos(Theta); - c->Agei_to_mod[0][0] = CosZeta*CosTheta*CosZee-SinZeta*SinZee; c->Agei_to_mod[1][0] = -SinZeta*CosTheta*CosZee-CosZeta*SinZee; c->Agei_to_mod[2][0] = -SinTheta*CosZee; - c->Agei_to_mod[0][1] = CosZeta*CosTheta*SinZee+SinZeta*CosZee; c->Agei_to_mod[1][1] = -SinZeta*CosTheta*SinZee+CosZeta*CosZee; c->Agei_to_mod[2][1] = -SinTheta*SinZee; - c->Agei_to_mod[0][2] = CosZeta*SinTheta; c->Agei_to_mod[1][2] = -SinZeta*SinTheta; c->Agei_to_mod[2][2] = CosTheta; - for (i=0; i<3; i++){ - for (j=0; j<3; j++){ + // TU = (Lgm_JD( year, month, day, TDT, c ) - 2451545.0)/36525.0; + // TU2 = TU*TU; + // TU3 = TU*TU2; + c->Zeta = 0.6406161 * T_TT + 0.0000839 * T2_TT + 5.0e-6 * T3_TT; // degrees + c->Zee = 0.6406161 * T_TT + 0.0003041 * T2_TT + 5.1e-6 * T3_TT; // degrees + c->Theta = + 0.5567530 * T_TT - 0.0001185 * T2_TT - 1.16e-5 * T3_TT; // degrees + Zeta = c->Zeta * RadPerDeg; + Theta = c->Theta * RadPerDeg; + Zee = c->Zee * RadPerDeg; + SinZee = sin(Zee); + CosZee = cos(Zee); + SinZeta = sin(Zeta); + CosZeta = cos(Zeta); + SinTheta = sin(Theta); + CosTheta = cos(Theta); + c->Agei_to_mod[0][0] = CosZeta * CosTheta * CosZee - SinZeta * SinZee; + c->Agei_to_mod[1][0] = -SinZeta * CosTheta * CosZee - CosZeta * SinZee; + c->Agei_to_mod[2][0] = -SinTheta * CosZee; + c->Agei_to_mod[0][1] = CosZeta * CosTheta * SinZee + SinZeta * CosZee; + c->Agei_to_mod[1][1] = -SinZeta * CosTheta * SinZee + CosZeta * CosZee; + c->Agei_to_mod[2][1] = -SinTheta * SinZee; + c->Agei_to_mod[0][2] = CosZeta * SinTheta; + c->Agei_to_mod[1][2] = -SinZeta * SinTheta; + c->Agei_to_mod[2][2] = CosTheta; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { c->Amod_to_gei[i][j] = c->Agei_to_mod[j][i]; } } /* Hand off to function to get Sun position by specified method */ - Lgm_ComputeSun( c ); - + Lgm_ComputeSun(c); /* MMS-specific GSE2000 from GEI2000 */ - K.x = 0.0; K.y = -0.39777715575399; K.z = 0.917482062146321; //ecliptic pole at J2000 epoch, Seidelmann, Suppl. to Astron. Almanac, 2006. Eq 3.222-1 + K.x = 0.0; + K.y = -0.39777715575399; + K.z = 0.917482062146321; // ecliptic pole at J2000 epoch, Seidelmann, + // Suppl. to Astron. Almanac, 2006. Eq 3.222-1 Lgm_CrossProduct(&K, &c->SunJ2000, &Y); Lgm_NormalizeVector(&Y); Lgm_CrossProduct(&c->SunJ2000, &Y, &Z); - c->Agei_to_gse2000[0][0] = c->SunJ2000.x, c->Agei_to_gse2000[1][0] = c->SunJ2000.y, c->Agei_to_gse2000[2][0] = c->SunJ2000.z; - c->Agei_to_gse2000[0][1] = Y.x, c->Agei_to_gse2000[1][1] = Y.y, c->Agei_to_gse2000[2][1] = Y.z; - c->Agei_to_gse2000[0][2] = Z.x, c->Agei_to_gse2000[1][2] = Z.y, c->Agei_to_gse2000[2][2] = Z.z; - - c->Agse2000_to_gei[0][0] = c->SunJ2000.x, c->Agse2000_to_gei[1][0] = Y.x, c->Agse2000_to_gei[2][0] = Z.x; - c->Agse2000_to_gei[0][1] = c->SunJ2000.y, c->Agse2000_to_gei[1][1] = Y.y, c->Agse2000_to_gei[2][1] = Z.y; - c->Agse2000_to_gei[0][2] = c->SunJ2000.z, c->Agse2000_to_gei[1][2] = Y.z, c->Agse2000_to_gei[2][2] = Z.z; - + c->Agei_to_gse2000[0][0] = c->SunJ2000.x, + c->Agei_to_gse2000[1][0] = c->SunJ2000.y, + c->Agei_to_gse2000[2][0] = c->SunJ2000.z; + c->Agei_to_gse2000[0][1] = Y.x, c->Agei_to_gse2000[1][1] = Y.y, + c->Agei_to_gse2000[2][1] = Y.z; + c->Agei_to_gse2000[0][2] = Z.x, c->Agei_to_gse2000[1][2] = Z.y, + c->Agei_to_gse2000[2][2] = Z.z; + + c->Agse2000_to_gei[0][0] = c->SunJ2000.x, c->Agse2000_to_gei[1][0] = Y.x, + c->Agse2000_to_gei[2][0] = Z.x; + c->Agse2000_to_gei[0][1] = c->SunJ2000.y, c->Agse2000_to_gei[1][1] = Y.y, + c->Agse2000_to_gei[2][1] = Z.y; + c->Agse2000_to_gei[0][2] = c->SunJ2000.z, c->Agse2000_to_gei[1][2] = Y.z, + c->Agse2000_to_gei[2][2] = Z.z; /* * Set up transformation to go from MOD->TOD * This requires calculating nutation quantities. * Here we do the full 106-term series. Could limit this if its too slow... */ -// c->OmegaMoon = (450160.398036 - 6962890.5431*T_TT + 7.4722*T2_TT + 0.007702*T3_TT - 0.00005939*T4_TT)*RadPerArcSec; - c->OmegaMoon = fmod( 125.04455501 - (5.0*360.0 + 134.1361851)*T_TT + 0.0020756*T2_TT + 2.139e-6*T3_TT, 360.0); // degrees + // c->OmegaMoon = (450160.398036 - 6962890.5431*T_TT + 7.4722*T2_TT + + // 0.007702*T3_TT - 0.00005939*T4_TT)*RadPerArcSec; + c->OmegaMoon = fmod(125.04455501 - (5.0 * 360.0 + 134.1361851) * T_TT + + 0.0020756 * T2_TT + 2.139e-6 * T3_TT, + 360.0); // degrees // Get dPSi and dEps in arcsec - Lgm_Nutation( c->TT.T, c->nNutationTerms, &(c->dPsi), &(c->dEps) ); // does 106-term nutation series - c->dPsi += c->ddPsi; // apply EOP corrections (arcsec) - c->dEps += c->ddEps; // apply EOP corrections (arcsec) + Lgm_Nutation(c->TT.T, c->nNutationTerms, &(c->dPsi), + &(c->dEps)); // does 106-term nutation series + c->dPsi += c->ddPsi; // apply EOP corrections (arcsec) + c->dEps += c->ddEps; // apply EOP corrections (arcsec) // Equation of the equinoxes EQ_Eq - c->EQ_Eq = c->dPsi*cos(epsilon) + 0.00264*sin( c->OmegaMoon*RadPerDeg ) + 0.000063*sin( 2.0*c->OmegaMoon*RadPerDeg ); // arcsec + c->EQ_Eq = c->dPsi * cos(epsilon) + + 0.00264 * sin(c->OmegaMoon * RadPerDeg) + + 0.000063 * sin(2.0 * c->OmegaMoon * RadPerDeg); // arcsec // true obliquity of ecliptic c->epsilon_true = c->dEps + c->epsilon; // arcsec -//printf("c->epsilon_true/3600.0 = %15.10lf\n", c->epsilon_true/3600.0); -//printf("c->dEps/3600.0 + c->epsilon/3600.0 = %15.10lf\n", c->dEps/3600.0 + c->epsilon/3600.0); - tmp = c->dPsi*RadPerArcSec; sdp = sin( tmp ); cdp = cos( tmp ); - tmp = c->epsilon*RadPerArcSec; se = sin( tmp ); ce = cos( tmp ); - tmp = c->epsilon_true*RadPerArcSec; set = sin( tmp ); cet = cos( tmp ); - c->Atod_to_mod[0][0] = cdp; c->Atod_to_mod[1][0] = sdp*cet; c->Atod_to_mod[2][0] = set*sdp; - c->Atod_to_mod[0][1] = -sdp*ce; c->Atod_to_mod[1][1] = cet*cdp*ce + set*se; c->Atod_to_mod[2][1] = set*cdp*ce - se*cet; - c->Atod_to_mod[0][2] = -sdp*se; c->Atod_to_mod[1][2] = cet*cdp*se - set*ce; c->Atod_to_mod[2][2] = set*se*cdp + cet*ce; - for (i=0; i<3; i++){ - for (j=0; j<3; j++){ + // printf("c->epsilon_true/3600.0 = %15.10lf\n", c->epsilon_true/3600.0); + // printf("c->dEps/3600.0 + c->epsilon/3600.0 = %15.10lf\n", c->dEps/3600.0 + // + c->epsilon/3600.0); + tmp = c->dPsi * RadPerArcSec; + sdp = sin(tmp); + cdp = cos(tmp); + tmp = c->epsilon * RadPerArcSec; + se = sin(tmp); + ce = cos(tmp); + tmp = c->epsilon_true * RadPerArcSec; + set = sin(tmp); + cet = cos(tmp); + c->Atod_to_mod[0][0] = cdp; + c->Atod_to_mod[1][0] = sdp * cet; + c->Atod_to_mod[2][0] = set * sdp; + c->Atod_to_mod[0][1] = -sdp * ce; + c->Atod_to_mod[1][1] = cet * cdp * ce + set * se; + c->Atod_to_mod[2][1] = set * cdp * ce - se * cet; + c->Atod_to_mod[0][2] = -sdp * se; + c->Atod_to_mod[1][2] = cet * cdp * se - set * ce; + c->Atod_to_mod[2][2] = set * se * cdp + cet * ce; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { c->Amod_to_tod[i][j] = c->Atod_to_mod[j][i]; } } - /* * Set up transformation between PEF and TOD * Need to compute True (Aparent?) Sidereal Time GAST */ - c->gast = c->gmst*15.0 + c->EQ_Eq/3600.0; - gast = c->gast*RadPerDeg; cs = cos( gast ); sn = sin( gast ); - c->Atod_to_pef[0][0] = cs; c->Atod_to_pef[1][0] = sn; c->Atod_to_pef[2][0] = 0.0; - c->Atod_to_pef[0][1] = -sn; c->Atod_to_pef[1][1] = cs; c->Atod_to_pef[2][1] = 0.0; - c->Atod_to_pef[0][2] = 0.0; c->Atod_to_pef[1][2] = 0.0; c->Atod_to_pef[2][2] = 1.0; - - c->Apef_to_tod[0][0] = cs; c->Apef_to_tod[1][0] = -sn; c->Apef_to_tod[2][0] = 0.0; - c->Apef_to_tod[0][1] = sn; c->Apef_to_tod[1][1] = cs; c->Apef_to_tod[2][1] = 0.0; - c->Apef_to_tod[0][2] = 0.0; c->Apef_to_tod[1][2] = 0.0; c->Apef_to_tod[2][2] = 1.0; - + c->gast = c->gmst * 15.0 + c->EQ_Eq / 3600.0; + gast = c->gast * RadPerDeg; + cs = cos(gast); + sn = sin(gast); + c->Atod_to_pef[0][0] = cs; + c->Atod_to_pef[1][0] = sn; + c->Atod_to_pef[2][0] = 0.0; + c->Atod_to_pef[0][1] = -sn; + c->Atod_to_pef[1][1] = cs; + c->Atod_to_pef[2][1] = 0.0; + c->Atod_to_pef[0][2] = 0.0; + c->Atod_to_pef[1][2] = 0.0; + c->Atod_to_pef[2][2] = 1.0; + + c->Apef_to_tod[0][0] = cs; + c->Apef_to_tod[1][0] = -sn; + c->Apef_to_tod[2][0] = 0.0; + c->Apef_to_tod[0][1] = sn; + c->Apef_to_tod[1][1] = cs; + c->Apef_to_tod[2][1] = 0.0; + c->Apef_to_tod[0][2] = 0.0; + c->Apef_to_tod[1][2] = 0.0; + c->Apef_to_tod[2][2] = 1.0; /* * Set up transformation between TOD and TEME @@ -649,66 +694,99 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { * CHECK THIS. Do we use Full equation of equinoxes??? * OR just dPsi*cos( eps )???? */ - //sn = sin( c->dPsiCosEps ); cs = cos( c->dPsiCosEps ); -// double ang = c->dPsi * cos(c->epsilon_true); -// sn = sin( ang ); cs = cos( ang ); -// c->Ateme_to_tod[0][0] = cs; c->Ateme_to_tod[1][0] = sn; c->Ateme_to_tod[2][0] = 0.0; -// c->Ateme_to_tod[0][1] = -sn; c->Ateme_to_tod[1][1] = cs; c->Ateme_to_tod[2][1] = 0.0; -// c->Ateme_to_tod[0][2] = 0.0; c->Ateme_to_tod[1][2] = 0.0; c->Ateme_to_tod[2][2] = 1.0; -// -// c->Atod_to_teme[0][0] = cs; c->Atod_to_teme[1][0] = -sn; c->Atod_to_teme[2][0] = 0.0; -// c->Atod_to_teme[0][1] = sn; c->Atod_to_teme[1][1] = cs; c->Atod_to_teme[2][1] = 0.0; -// c->Atod_to_teme[0][2] = 0.0; c->Atod_to_teme[1][2] = 0.0; c->Atod_to_teme[2][2] = 1.0; + // sn = sin( c->dPsiCosEps ); cs = cos( c->dPsiCosEps ); + // double ang = c->dPsi * cos(c->epsilon_true); + // sn = sin( ang ); cs = cos( ang ); + // c->Ateme_to_tod[0][0] = cs; c->Ateme_to_tod[1][0] = sn; + // c->Ateme_to_tod[2][0] = 0.0; c->Ateme_to_tod[0][1] = -sn; + // c->Ateme_to_tod[1][1] = cs; c->Ateme_to_tod[2][1] = 0.0; + // c->Ateme_to_tod[0][2] = 0.0; c->Ateme_to_tod[1][2] = 0.0; + // c->Ateme_to_tod[2][2] = 1.0; + // + // c->Atod_to_teme[0][0] = cs; c->Atod_to_teme[1][0] = -sn; + // c->Atod_to_teme[2][0] = 0.0; c->Atod_to_teme[0][1] = sn; + // c->Atod_to_teme[1][1] = cs; c->Atod_to_teme[2][1] = 0.0; + // c->Atod_to_teme[0][2] = 0.0; c->Atod_to_teme[1][2] = 0.0; + // c->Atod_to_teme[2][2] = 1.0; /* - * Lets set this up differently because Vallado and others just arent clear on how exactly to - * go from TEME to TOD (too many approximations seem to be available). Instead, follow Vallado's - * recommendation and go the PEF instead. This is also good because we have gmst already! - * See Vallado's book and his article "Revisiting Spacetrack Report #3". - * Upef = Rz( gmst82 ) Uteme + * Lets set this up differently because Vallado and others just arent clear + * on how exactly to go from TEME to TOD (too many approximations seem to be + * available). Instead, follow Vallado's recommendation and go the PEF + * instead. This is also good because we have gmst already! See Vallado's + * book and his article "Revisiting Spacetrack Report #3". Upef = Rz( gmst82 + * ) Uteme */ - sn = sin( gmst ); cs = cos( gmst ); - c->Ateme_to_pef[0][0] = cs; c->Ateme_to_pef[1][0] = sn; c->Ateme_to_pef[2][0] = 0.0; - c->Ateme_to_pef[0][1] = -sn; c->Ateme_to_pef[1][1] = cs; c->Ateme_to_pef[2][1] = 0.0; - c->Ateme_to_pef[0][2] = 0.0; c->Ateme_to_pef[1][2] = 0.0; c->Ateme_to_pef[2][2] = 1.0; - - c->Apef_to_teme[0][0] = cs; c->Apef_to_teme[1][0] = -sn; c->Apef_to_teme[2][0] = 0.0; - c->Apef_to_teme[0][1] = sn; c->Apef_to_teme[1][1] = cs; c->Apef_to_teme[2][1] = 0.0; - c->Apef_to_teme[0][2] = 0.0; c->Apef_to_teme[1][2] = 0.0; c->Apef_to_teme[2][2] = 1.0; - + sn = sin(gmst); + cs = cos(gmst); + c->Ateme_to_pef[0][0] = cs; + c->Ateme_to_pef[1][0] = sn; + c->Ateme_to_pef[2][0] = 0.0; + c->Ateme_to_pef[0][1] = -sn; + c->Ateme_to_pef[1][1] = cs; + c->Ateme_to_pef[2][1] = 0.0; + c->Ateme_to_pef[0][2] = 0.0; + c->Ateme_to_pef[1][2] = 0.0; + c->Ateme_to_pef[2][2] = 1.0; + + c->Apef_to_teme[0][0] = cs; + c->Apef_to_teme[1][0] = -sn; + c->Apef_to_teme[2][0] = 0.0; + c->Apef_to_teme[0][1] = sn; + c->Apef_to_teme[1][1] = cs; + c->Apef_to_teme[2][1] = 0.0; + c->Apef_to_teme[0][2] = 0.0; + c->Apef_to_teme[1][2] = 0.0; + c->Apef_to_teme[2][2] = 1.0; /* * Set up transformation between WGS84 and PEF * Uwgs84 = Ry( -xp )Rz( -yp ) Upef */ - sxp = sin( c->xp*RadPerArcSec ); cxp = cos( c->xp*RadPerArcSec ); - syp = sin( c->yp*RadPerArcSec ); cyp = cos( c->yp*RadPerArcSec ); - c->Apef_to_wgs84[0][0] = cxp; c->Apef_to_wgs84[1][0] = sxp*syp; c->Apef_to_wgs84[2][0] = sxp*cyp; - c->Apef_to_wgs84[0][1] = 0.0; c->Apef_to_wgs84[1][1] = cyp; c->Apef_to_wgs84[2][1] = -syp; - c->Apef_to_wgs84[0][2] = -sxp; c->Apef_to_wgs84[1][2] = cxp*syp; c->Apef_to_wgs84[2][2] = cxp*cyp; - - c->Awgs84_to_pef[0][0] = cxp; c->Awgs84_to_pef[1][0] = 0.0; c->Awgs84_to_pef[2][0] = -sxp; - c->Awgs84_to_pef[0][1] = sxp*syp; c->Awgs84_to_pef[1][1] = cyp; c->Awgs84_to_pef[2][1] = cxp*syp; - c->Awgs84_to_pef[0][2] = sxp*cyp; c->Awgs84_to_pef[1][2] = -syp; c->Awgs84_to_pef[2][2] = cxp*cyp; - - -// c->Apef_to_wgs84[0][0] = 1.0; c->Apef_to_wgs84[1][0] = 0.0; c->Apef_to_wgs84[2][0] = c->xp; -// c->Apef_to_wgs84[0][1] = 0.0; c->Apef_to_wgs84[1][1] = 1.0; c->Apef_to_wgs84[2][1] = -c->yp; -// c->Apef_to_wgs84[0][2] = -c->xp; c->Apef_to_wgs84[1][2] = c->yp; c->Apef_to_wgs84[2][2] = 1.0; -// -// c->Awgs84_to_pef[0][0] = 1.0; c->Awgs84_to_pef[1][0] = 0.0; c->Awgs84_to_pef[2][0] = -c->xp; -// c->Awgs84_to_pef[0][1] = 0.0; c->Awgs84_to_pef[1][1] = 1.0; c->Awgs84_to_pef[2][1] = c->yp; -// c->Awgs84_to_pef[0][2] = c->xp; c->Awgs84_to_pef[1][2] = -c->yp; c->Awgs84_to_pef[2][2] = 1.0; - + sxp = sin(c->xp * RadPerArcSec); + cxp = cos(c->xp * RadPerArcSec); + syp = sin(c->yp * RadPerArcSec); + cyp = cos(c->yp * RadPerArcSec); + c->Apef_to_wgs84[0][0] = cxp; + c->Apef_to_wgs84[1][0] = sxp * syp; + c->Apef_to_wgs84[2][0] = sxp * cyp; + c->Apef_to_wgs84[0][1] = 0.0; + c->Apef_to_wgs84[1][1] = cyp; + c->Apef_to_wgs84[2][1] = -syp; + c->Apef_to_wgs84[0][2] = -sxp; + c->Apef_to_wgs84[1][2] = cxp * syp; + c->Apef_to_wgs84[2][2] = cxp * cyp; + + c->Awgs84_to_pef[0][0] = cxp; + c->Awgs84_to_pef[1][0] = 0.0; + c->Awgs84_to_pef[2][0] = -sxp; + c->Awgs84_to_pef[0][1] = sxp * syp; + c->Awgs84_to_pef[1][1] = cyp; + c->Awgs84_to_pef[2][1] = cxp * syp; + c->Awgs84_to_pef[0][2] = sxp * cyp; + c->Awgs84_to_pef[1][2] = -syp; + c->Awgs84_to_pef[2][2] = cxp * cyp; + + // c->Apef_to_wgs84[0][0] = 1.0; c->Apef_to_wgs84[1][0] = 0.0; + // c->Apef_to_wgs84[2][0] = c->xp; c->Apef_to_wgs84[0][1] = 0.0; + // c->Apef_to_wgs84[1][1] = 1.0; c->Apef_to_wgs84[2][1] = -c->yp; + // c->Apef_to_wgs84[0][2] = -c->xp; c->Apef_to_wgs84[1][2] = c->yp; + // c->Apef_to_wgs84[2][2] = 1.0; + // + // c->Awgs84_to_pef[0][0] = 1.0; c->Awgs84_to_pef[1][0] = 0.0; + // c->Awgs84_to_pef[2][0] = -c->xp; c->Awgs84_to_pef[0][1] = 0.0; + // c->Awgs84_to_pef[1][1] = 1.0; c->Awgs84_to_pef[2][1] = c->yp; + // c->Awgs84_to_pef[0][2] = c->xp; c->Awgs84_to_pef[1][2] = -c->yp; + // c->Awgs84_to_pef[2][2] = 1.0; /* * Define MOD <--> GSE Transformation */ // Compute the direction of the Ecliptic Pole in the MOD system - K.x = 0.0; + K.x = 0.0; K.y = -sin(epsilon); - K.z = cos(epsilon); + K.z = cos(epsilon); c->EcPole = K; // Taking X in direction of sun and Z parallel to K (ec. pole), @@ -719,47 +797,53 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { // Compute Zgse axis in MOD system Lgm_CrossProduct(&c->Sun, &Y, &Z); + // Create transformation matrix from MOD to GSE + // (c->Amod_to_gse[cols][rows]) + c->Amod_to_gse[0][0] = c->Sun.x, c->Amod_to_gse[1][0] = c->Sun.y, + c->Amod_to_gse[2][0] = c->Sun.z; + c->Amod_to_gse[0][1] = Y.x, c->Amod_to_gse[1][1] = Y.y, + c->Amod_to_gse[2][1] = Y.z; + c->Amod_to_gse[0][2] = Z.x, c->Amod_to_gse[1][2] = Z.y, + c->Amod_to_gse[2][2] = Z.z; + + c->Agse_to_mod[0][0] = c->Sun.x, c->Agse_to_mod[1][0] = Y.x, + c->Agse_to_mod[2][0] = Z.x; + c->Agse_to_mod[0][1] = c->Sun.y, c->Agse_to_mod[1][1] = Y.y, + c->Agse_to_mod[2][1] = Z.y; + c->Agse_to_mod[0][2] = c->Sun.z, c->Agse_to_mod[1][2] = Y.z, + c->Agse_to_mod[2][2] = Z.z; - // Create transformation matrix from MOD to GSE (c->Amod_to_gse[cols][rows]) - c->Amod_to_gse[0][0] = c->Sun.x, c->Amod_to_gse[1][0] = c->Sun.y, c->Amod_to_gse[2][0] = c->Sun.z; - c->Amod_to_gse[0][1] = Y.x, c->Amod_to_gse[1][1] = Y.y, c->Amod_to_gse[2][1] = Y.z; - c->Amod_to_gse[0][2] = Z.x, c->Amod_to_gse[1][2] = Z.y, c->Amod_to_gse[2][2] = Z.z; - - c->Agse_to_mod[0][0] = c->Sun.x, c->Agse_to_mod[1][0] = Y.x, c->Agse_to_mod[2][0] = Z.x; - c->Agse_to_mod[0][1] = c->Sun.y, c->Agse_to_mod[1][1] = Y.y, c->Agse_to_mod[2][1] = Z.y; - c->Agse_to_mod[0][2] = c->Sun.z, c->Agse_to_mod[1][2] = Y.z, c->Agse_to_mod[2][2] = Z.z; - - /* * Initialize IGRF to get (among other things) the dipole moment. * We really should do this more carefully. Make sure the lat/lons * are geocentric? */ N = 10; -// c->UTC.fYear = (double)c->year + ((double)c->doy + c->UTC/24.0)/(365.0 + (double)Lgm_LeapYear(c->year)); + // c->UTC.fYear = (double)c->year + ((double)c->doy + c->UTC/24.0)/(365.0 + // + (double)Lgm_LeapYear(c->year)); c->Lgm_IGRF_FirstCall = TRUE; - Lgm_InitIGRF( g, h, N, 1, c ); + Lgm_InitIGRF(g, h, N, 1, c); gclat = c->CD_gcolat; - glon = c->CD_glon; - + glon = c->CD_glon; /* * Construct Transformation Matrix from MOD to GSM * * First compute the location of the earths D axis based on IGRF - * coefficients. Note: we compute Dhat as thoughj it were sticking out of the north - * hemisphere. It really goes out the south, but its less confusing this way... + * coefficients. Note: we compute Dhat as thoughj it were sticking out of + * the north hemisphere. It really goes out the south, but its less + * confusing this way... * */ - c->CD_gcolat = gclat*DegPerRad; - c->CD_glon = glon*DegPerRad; - D.x = cos(glon)*sin(gclat); - D.y = sin(glon)*sin(gclat); - D.z = cos(gclat); + c->CD_gcolat = gclat * DegPerRad; + c->CD_glon = glon * DegPerRad; + D.x = cos(glon) * sin(gclat); + D.y = sin(glon) * sin(gclat); + D.z = cos(gclat); // Find D (i.e. dipole) axis in MOD system - Dmod.x = cos(gmst)*D.x - sin(gmst)*D.y; - Dmod.y = sin(gmst)*D.x + cos(gmst)*D.y; + Dmod.x = cos(gmst) * D.x - sin(gmst) * D.y; + Dmod.y = sin(gmst) * D.x + cos(gmst) * D.y; Dmod.z = D.z; // Compute Ygsm axis in MOD system @@ -769,41 +853,50 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { // Compute Zgsm axis in MOD system Lgm_CrossProduct(&c->Sun, &Y, &Z); - c->Amod_to_gsm[0][0] = c->Sun.x, c->Amod_to_gsm[1][0] = c->Sun.y, c->Amod_to_gsm[2][0] = c->Sun.z; - c->Amod_to_gsm[0][1] = Y.x, c->Amod_to_gsm[1][1] = Y.y, c->Amod_to_gsm[2][1] = Y.z; - c->Amod_to_gsm[0][2] = Z.x, c->Amod_to_gsm[1][2] = Z.y, c->Amod_to_gsm[2][2] = Z.z; - - c->Agsm_to_mod[0][0] = c->Sun.x, c->Agsm_to_mod[1][0] = Y.x, c->Agsm_to_mod[2][0] = Z.x; - c->Agsm_to_mod[0][1] = c->Sun.y, c->Agsm_to_mod[1][1] = Y.y, c->Agsm_to_mod[2][1] = Z.y; - c->Agsm_to_mod[0][2] = c->Sun.z, c->Agsm_to_mod[1][2] = Y.z, c->Agsm_to_mod[2][2] = Z.z; + c->Amod_to_gsm[0][0] = c->Sun.x, c->Amod_to_gsm[1][0] = c->Sun.y, + c->Amod_to_gsm[2][0] = c->Sun.z; + c->Amod_to_gsm[0][1] = Y.x, c->Amod_to_gsm[1][1] = Y.y, + c->Amod_to_gsm[2][1] = Y.z; + c->Amod_to_gsm[0][2] = Z.x, c->Amod_to_gsm[1][2] = Z.y, + c->Amod_to_gsm[2][2] = Z.z; + c->Agsm_to_mod[0][0] = c->Sun.x, c->Agsm_to_mod[1][0] = Y.x, + c->Agsm_to_mod[2][0] = Z.x; + c->Agsm_to_mod[0][1] = c->Sun.y, c->Agsm_to_mod[1][1] = Y.y, + c->Agsm_to_mod[2][1] = Z.y; + c->Agsm_to_mod[0][2] = c->Sun.z, c->Agsm_to_mod[1][2] = Y.z, + c->Agsm_to_mod[2][2] = Z.z; /* * Compute the Dipole Tilt angle. First convert Dmod into GSM. * Then psi is just the angle between Dgsm and Zgsm */ - Dgsm.x = c->Amod_to_gsm[0][0]*Dmod.x + c->Amod_to_gsm[1][0]*Dmod.y + c->Amod_to_gsm[2][0]*Dmod.z; - Dgsm.y = c->Amod_to_gsm[0][1]*Dmod.x + c->Amod_to_gsm[1][1]*Dmod.y + c->Amod_to_gsm[2][1]*Dmod.z; - Dgsm.z = c->Amod_to_gsm[0][2]*Dmod.x + c->Amod_to_gsm[1][2]*Dmod.y + c->Amod_to_gsm[2][2]*Dmod.z; - -// spsi = sqrt( Dgsm.x*Dgsm.x + Dgsm.y*Dgsm.y ); - spsi = fabs( Dgsm.x ); - psi = asin( spsi ); - psi *= ( Dgsm.x < 0.0 ) ? -1.0 : 1.0; - c->psi = psi; - c->cos_psi = cos( psi ); - c->sin_psi = sin( psi ); - c->tan_psi = c->sin_psi/c->cos_psi; - + Dgsm.x = c->Amod_to_gsm[0][0] * Dmod.x + c->Amod_to_gsm[1][0] * Dmod.y + + c->Amod_to_gsm[2][0] * Dmod.z; + Dgsm.y = c->Amod_to_gsm[0][1] * Dmod.x + c->Amod_to_gsm[1][1] * Dmod.y + + c->Amod_to_gsm[2][1] * Dmod.z; + Dgsm.z = c->Amod_to_gsm[0][2] * Dmod.x + c->Amod_to_gsm[1][2] * Dmod.y + + c->Amod_to_gsm[2][2] * Dmod.z; + + // spsi = sqrt( Dgsm.x*Dgsm.x + Dgsm.y*Dgsm.y ); + spsi = fabs(Dgsm.x); + psi = asin(spsi); + psi *= (Dgsm.x < 0.0) ? -1.0 : 1.0; + c->psi = psi; + c->cos_psi = cos(psi); + c->sin_psi = sin(psi); + c->tan_psi = c->sin_psi / c->cos_psi; /* * Construct trans. matrices for GSM <-> SM */ - c->Agsm_to_sm[0][0] = c->cos_psi, c->Agsm_to_sm[1][0] = 0.0, c->Agsm_to_sm[2][0] = -c->sin_psi; - c->Agsm_to_sm[0][1] = 0.0, c->Agsm_to_sm[1][1] = 1.0, c->Agsm_to_sm[2][1] = 0.0; - c->Agsm_to_sm[0][2] = c->sin_psi, c->Agsm_to_sm[1][2] = 0.0, c->Agsm_to_sm[2][2] = c->cos_psi; - Lgm_Transpose( c->Agsm_to_sm, c->Asm_to_gsm ); - + c->Agsm_to_sm[0][0] = c->cos_psi, c->Agsm_to_sm[1][0] = 0.0, + c->Agsm_to_sm[2][0] = -c->sin_psi; + c->Agsm_to_sm[0][1] = 0.0, c->Agsm_to_sm[1][1] = 1.0, + c->Agsm_to_sm[2][1] = 0.0; + c->Agsm_to_sm[0][2] = c->sin_psi, c->Agsm_to_sm[1][2] = 0.0, + c->Agsm_to_sm[2][2] = c->cos_psi; + Lgm_Transpose(c->Agsm_to_sm, c->Asm_to_gsm); /* * Now do WGS84 (i.e. GEO) <-> CDMAG @@ -811,69 +904,89 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { * Y: perp to both Z and Rot axis. * X: completes */ - Zgeo.x = 0.0; Zgeo.y = 0.0; Zgeo.z = 1.0; - Lgm_CrossProduct(&Zgeo, &D, &Y); // Ycdmag-hat in geo coords. + Zgeo.x = 0.0; + Zgeo.y = 0.0; + Zgeo.z = 1.0; + Lgm_CrossProduct(&Zgeo, &D, &Y); // Ycdmag-hat in geo coords. Lgm_NormalizeVector(&Y); - Lgm_CrossProduct(&Y, &D, &X); // Xcdmag-hat in geo coords. + Lgm_CrossProduct(&Y, &D, &X); // Xcdmag-hat in geo coords. Lgm_NormalizeVector(&X); - c->Awgs84_to_cdmag[0][0] = X.x, c->Awgs84_to_cdmag[1][0] = X.y, c->Awgs84_to_cdmag[2][0] = X.z; - c->Awgs84_to_cdmag[0][1] = Y.x, c->Awgs84_to_cdmag[1][1] = Y.y, c->Awgs84_to_cdmag[2][1] = Y.z; - c->Awgs84_to_cdmag[0][2] = D.x, c->Awgs84_to_cdmag[1][2] = D.y, c->Awgs84_to_cdmag[2][2] = D.z; - - c->Acdmag_to_wgs84[0][0] = X.x, c->Acdmag_to_wgs84[1][0] = Y.x, c->Acdmag_to_wgs84[2][0] = D.x; - c->Acdmag_to_wgs84[0][1] = X.y, c->Acdmag_to_wgs84[1][1] = Y.y, c->Acdmag_to_wgs84[2][1] = D.y; - c->Acdmag_to_wgs84[0][2] = X.z, c->Acdmag_to_wgs84[1][2] = Y.z, c->Acdmag_to_wgs84[2][2] = D.z; - + c->Awgs84_to_cdmag[0][0] = X.x, c->Awgs84_to_cdmag[1][0] = X.y, + c->Awgs84_to_cdmag[2][0] = X.z; + c->Awgs84_to_cdmag[0][1] = Y.x, c->Awgs84_to_cdmag[1][1] = Y.y, + c->Awgs84_to_cdmag[2][1] = Y.z; + c->Awgs84_to_cdmag[0][2] = D.x, c->Awgs84_to_cdmag[1][2] = D.y, + c->Awgs84_to_cdmag[2][2] = D.z; + + c->Acdmag_to_wgs84[0][0] = X.x, c->Acdmag_to_wgs84[1][0] = Y.x, + c->Acdmag_to_wgs84[2][0] = D.x; + c->Acdmag_to_wgs84[0][1] = X.y, c->Acdmag_to_wgs84[1][1] = Y.y, + c->Acdmag_to_wgs84[2][1] = D.y; + c->Acdmag_to_wgs84[0][2] = X.z, c->Acdmag_to_wgs84[1][2] = Y.z, + c->Acdmag_to_wgs84[2][2] = D.z; /* Construct transformation matrix from GSM to GSE and vice versa ; * Agsm_to_gse = Amod_to_gse * Agsm_to_mod */ - Lgm_MatTimesMat( c->Amod_to_gse, c->Agsm_to_mod, c->Agsm_to_gse ); - Lgm_Transpose( c->Agsm_to_gse, c->Agse_to_gsm); - + Lgm_MatTimesMat(c->Amod_to_gse, c->Agsm_to_mod, c->Agsm_to_gse); + Lgm_Transpose(c->Agsm_to_gse, c->Agse_to_gsm); /* Construct transformation matrix from GSM to WGS84 and vice versa ; * Agsm_to_wgs84 = Amod_to_wgs84 * Agsm_to_mod * Awgs84_to_gsm = Transpose( Agsm_to_wgs84 ) */ - Lgm_MatTimesMat( c->Amod_to_wgs84, c->Agsm_to_mod, c->Agsm_to_wgs84 ); - Lgm_Transpose( c->Agsm_to_wgs84, c->Awgs84_to_gsm ); - + Lgm_MatTimesMat(c->Amod_to_wgs84, c->Agsm_to_mod, c->Agsm_to_wgs84); + Lgm_Transpose(c->Agsm_to_wgs84, c->Awgs84_to_gsm); /* * Construct Transformation Matricies between WGS84 and MOD * and between WGS84 and GEI */ - Lgm_MatTimesMat( c->Apef_to_tod, c->Awgs84_to_pef, Tmp ); - Lgm_MatTimesMat( c->Atod_to_mod, Tmp, c->Awgs84_to_mod ); - Lgm_MatTimesMat( c->Amod_to_gei, c->Awgs84_to_mod, c->Awgs84_to_gei ); - Lgm_Transpose( c->Awgs84_to_mod, c->Amod_to_wgs84 ); - Lgm_Transpose( c->Awgs84_to_gei, c->Agei_to_wgs84 ); - + Lgm_MatTimesMat(c->Apef_to_tod, c->Awgs84_to_pef, Tmp); + Lgm_MatTimesMat(c->Atod_to_mod, Tmp, c->Awgs84_to_mod); + Lgm_MatTimesMat(c->Amod_to_gei, c->Awgs84_to_mod, c->Awgs84_to_gei); + Lgm_Transpose(c->Awgs84_to_mod, c->Amod_to_wgs84); + Lgm_Transpose(c->Awgs84_to_gei, c->Agei_to_wgs84); /* Compute Moon RA, Dec, distance and phase */ - Lgm_ComputeMoon( c ); - - - if ( c->Verbose ) { + Lgm_ComputeMoon(c); - printf("Time Quantitites:\n"); + if (c->Verbose) { + printf("Time Quantitites:\n"); printf(" fYear (UTC) = %lf\n", c->UTC.fYear); -// printf(" Date = %ld\n", c->Date); - printf(" UTC = %8ld %.14lf ( ", c->UTC.Date, c->UTC.Time); Lgm_Print_HMSdp( c->UTC.Time, TRUE, 8 ); printf(" )\n"); - printf(" UT1 = %8ld %.14lf ( ", c->UT1.Date, c->UT1.Time); Lgm_Print_HMSdp( c->UT1.Time, TRUE, 8 ); printf(" )\n"); - printf(" TAI = %8ld %.14lf ( ", c->TAI.Date, c->TAI.Time); Lgm_Print_HMSdp( c->TAI.Time, TRUE, 8 ); printf(" )\n"); - printf(" TT = TAI+32.184s = %8ld %.14lf ( ", c->TT.Date, c->TT.Time); Lgm_Print_HMSdp( c->TT.Time, TRUE, 8 ); printf(" )\n"); - printf(" TDB = %8ld %.14lf ( ", c->TDB.Date, c->TDB.Time); Lgm_Print_HMSdp( c->TDB.Time, TRUE, 8 ); printf(" )\n"); + // printf(" Date = %ld\n", c->Date); + printf(" UTC = %8ld %.14lf ( ", c->UTC.Date, + c->UTC.Time); + Lgm_Print_HMSdp(c->UTC.Time, TRUE, 8); + printf(" )\n"); + printf(" UT1 = %8ld %.14lf ( ", c->UT1.Date, + c->UT1.Time); + Lgm_Print_HMSdp(c->UT1.Time, TRUE, 8); + printf(" )\n"); + printf(" TAI = %8ld %.14lf ( ", c->TAI.Date, + c->TAI.Time); + Lgm_Print_HMSdp(c->TAI.Time, TRUE, 8); + printf(" )\n"); + printf(" TT = TAI+32.184s = %8ld %.14lf ( ", c->TT.Date, + c->TT.Time); + Lgm_Print_HMSdp(c->TT.Time, TRUE, 8); + printf(" )\n"); + printf(" TDB = %8ld %.14lf ( ", c->TDB.Date, + c->TDB.Time); + Lgm_Print_HMSdp(c->TDB.Time, TRUE, 8); + printf(" )\n"); printf(" DUT1 = UT1-UTC = %.7lf seconds\n", c->DUT1); printf(" DAT = TAI-UTC = %.7lf seconds\n", c->DAT); printf(" JD (UTC) = %.12lf\n", c->UTC.JD); printf(" JD (UT1) = %.12lf\n", c->UT1.JD); printf(" JD (TT) = %.12lf\n", c->TT.JD); - printf(" T (UTC) = %15.12lf Julian Centuries of UTC\n", c->UTC.T); - printf(" T (UT1) = %15.12lf Julian Centuries of UT1\n", c->UT1.T); - printf(" T (TT) = %15.12lf Julian Centuries of TT\n", c->TT.T); + printf(" T (UTC) = %15.12lf Julian Centuries of UTC\n", + c->UTC.T); + printf(" T (UT1) = %15.12lf Julian Centuries of UT1\n", + c->UT1.T); + printf(" T (TT) = %15.12lf Julian Centuries of TT\n", + c->TT.T); printf(" Year (UTC) = %d\n", c->UTC.Year); printf(" Month (UTC) = %d\n", c->UTC.Month); @@ -882,283 +995,498 @@ void Lgm_Set_Coord_Transforms( long int date, double UTC, Lgm_CTrans *c ) { printf(" Dow (UTC) = %d\n", c->UTC.Dow); printf(" Dowstr (UTC) = %s\n", c->UTC.DowStr); - printf(" gmst (hours) = %.7lf ( ", c->gmst); Lgm_Print_HMSd( c->gmst ); printf(" )\n"); - printf(" gmst (degrees) = %.7lf ( ", c->gmst*15.0); Lgm_Print_DMSd( c->gmst*15.0 ); printf(" )\n"); - printf(" gast (hours) = %.7lf ( ", c->gast/15.0); Lgm_Print_HMSd( c->gast/15.0 ); printf(" )\n"); - printf(" gast (degrees) = %.7lf ( ", c->gast); Lgm_Print_DMSd( c->gast ); printf(" )\n"); - - printf("\n"); - printf("Eccentricity and Obliquity:\n"); - printf(" eccentricity = %.8lf\n", c->eccentricity); - printf(" epsilon mean (obliq. of ecliptic) = %.8lf ( ", c->epsilon/3600.0); Lgm_Print_DMSd( c->epsilon/3600.0 ); printf(" )\n"); - printf(" epsilon true (obliq. of ecliptic) = %.8lf ( ", c->epsilon_true/3600.0); Lgm_Print_DMSd( c->epsilon_true/3600.0 ); printf(" )\n"); - - printf("\n"); - printf("Precession Quantities:\n"); - printf(" Zeta = %g ( ", c->Zeta); Lgm_Print_DMSd( c->Zeta ); printf(" )\n"); - printf(" Zee = %g ( ", c->Zee); Lgm_Print_DMSd( c->Zee ); printf(" )\n"); - printf(" Theta = %g ( ", c->Theta); Lgm_Print_DMSd( c->Theta ); printf(" )\n"); - - printf("\n"); - printf("Nutation Quantities:\n"); - printf(" dPsi (w.o. corrections) = %.8lf ( ", (c->dPsi - c->ddPsi)/3600.0); Lgm_Print_DMSd( (c->dPsi - c->ddPsi)/3600.0 ); printf(" )\n"); - printf(" dEps (w.o. corrections) = %.8lf ( ", (c->dEps - c->ddEps)/3600.0); Lgm_Print_DMSd( (c->dEps - c->ddEps)/3600.0 ); printf(" )\n"); - printf(" ddPsi (EOP correction) = %.8lf ( ", c->ddPsi/3600.0); Lgm_Print_DMSd( c->ddPsi/3600.0 ); printf(" )\n"); - printf(" ddEps (EOP correction) = %.8lf ( ", c->ddEps/3600.0); Lgm_Print_DMSd( c->ddEps/3600.0 ); printf(" )\n"); - printf(" dPsi (w. corrections) = %.8lf ( ", c->dPsi/3600.0); Lgm_Print_DMSd( c->dPsi/3600.0 ); printf(" )\n"); - printf(" dEps (w. corrections) = %.8lf ( ", c->dEps/3600.0); Lgm_Print_DMSd( c->dEps/3600.0 ); printf(" )\n"); - printf(" epsilon true (obliq. of ecliptic) = %.8lf ( ", c->epsilon_true/3600.0); Lgm_Print_DMSd( c->epsilon_true/3600.0 ); printf(" )\n"); - printf(" Equation of the Equinox = %.8lf ( ", c->EQ_Eq/3600.0); Lgm_Print_DMSd( c->EQ_Eq/3600.0 ); printf(" )\n"); - - printf("\n"); - if (c->ephModel==LGM_EPH_LOW_ACCURACY) printf("Low Accuracy Position of Sun:\n"); - if (c->ephModel==LGM_EPH_HIGH_ACCURACY) printf("High Accuracy Position of Sun:\n"); - if (c->ephModel==LGM_EPH_DE) printf("DE%d Position of Sun:\n", c->jpl->DEnum); - printf(" lambda_sun = %15lf ( ", c->lambda_sun*DegPerRad); Lgm_Print_DMSd( c->lambda_sun*DegPerRad ); printf(" )\n"); + printf(" gmst (hours) = %.7lf ( ", c->gmst); + Lgm_Print_HMSd(c->gmst); + printf(" )\n"); + printf(" gmst (degrees) = %.7lf ( ", c->gmst * 15.0); + Lgm_Print_DMSd(c->gmst * 15.0); + printf(" )\n"); + printf(" gast (hours) = %.7lf ( ", c->gast / 15.0); + Lgm_Print_HMSd(c->gast / 15.0); + printf(" )\n"); + printf(" gast (degrees) = %.7lf ( ", c->gast); + Lgm_Print_DMSd(c->gast); + printf(" )\n"); + + printf("\n"); + printf("Eccentricity and Obliquity:\n"); + printf(" eccentricity = %.8lf\n", + c->eccentricity); + printf(" epsilon mean (obliq. of ecliptic) = %.8lf ( ", + c->epsilon / 3600.0); + Lgm_Print_DMSd(c->epsilon / 3600.0); + printf(" )\n"); + printf(" epsilon true (obliq. of ecliptic) = %.8lf ( ", + c->epsilon_true / 3600.0); + Lgm_Print_DMSd(c->epsilon_true / 3600.0); + printf(" )\n"); + + printf("\n"); + printf("Precession Quantities:\n"); + printf(" Zeta = %g ( ", c->Zeta); + Lgm_Print_DMSd(c->Zeta); + printf(" )\n"); + printf(" Zee = %g ( ", c->Zee); + Lgm_Print_DMSd(c->Zee); + printf(" )\n"); + printf(" Theta = %g ( ", c->Theta); + Lgm_Print_DMSd(c->Theta); + printf(" )\n"); + + printf("\n"); + printf("Nutation Quantities:\n"); + printf(" dPsi (w.o. corrections) = %.8lf ( ", + (c->dPsi - c->ddPsi) / 3600.0); + Lgm_Print_DMSd((c->dPsi - c->ddPsi) / 3600.0); + printf(" )\n"); + printf(" dEps (w.o. corrections) = %.8lf ( ", + (c->dEps - c->ddEps) / 3600.0); + Lgm_Print_DMSd((c->dEps - c->ddEps) / 3600.0); + printf(" )\n"); + printf(" ddPsi (EOP correction) = %.8lf ( ", + c->ddPsi / 3600.0); + Lgm_Print_DMSd(c->ddPsi / 3600.0); + printf(" )\n"); + printf(" ddEps (EOP correction) = %.8lf ( ", + c->ddEps / 3600.0); + Lgm_Print_DMSd(c->ddEps / 3600.0); + printf(" )\n"); + printf(" dPsi (w. corrections) = %.8lf ( ", + c->dPsi / 3600.0); + Lgm_Print_DMSd(c->dPsi / 3600.0); + printf(" )\n"); + printf(" dEps (w. corrections) = %.8lf ( ", + c->dEps / 3600.0); + Lgm_Print_DMSd(c->dEps / 3600.0); + printf(" )\n"); + printf(" epsilon true (obliq. of ecliptic) = %.8lf ( ", + c->epsilon_true / 3600.0); + Lgm_Print_DMSd(c->epsilon_true / 3600.0); + printf(" )\n"); + printf(" Equation of the Equinox = %.8lf ( ", + c->EQ_Eq / 3600.0); + Lgm_Print_DMSd(c->EQ_Eq / 3600.0); + printf(" )\n"); + + printf("\n"); + if (c->ephModel == LGM_EPH_LOW_ACCURACY) + printf("Low Accuracy Position of Sun:\n"); + if (c->ephModel == LGM_EPH_HIGH_ACCURACY) + printf("High Accuracy Position of Sun:\n"); + if (c->ephModel == LGM_EPH_DE) + printf("DE%d Position of Sun:\n", c->jpl->DEnum); + printf(" lambda_sun = %15lf ( ", c->lambda_sun * DegPerRad); + Lgm_Print_DMSd(c->lambda_sun * DegPerRad); + printf(" )\n"); printf(" earth_sun_dist = %15lf Re\n", c->earth_sun_dist); - printf(" beta_sun = %14g ( ", c->beta_sun*DegPerRad); Lgm_Print_DMSd( c->beta_sun*DegPerRad ); printf(" )\n"); - printf(" RA_sun (MOD) = %15lf ( ", c->RA_sun); Lgm_Print_HMSd( c->RA_sun/15.0 ); printf(" )\n"); - printf(" DEC_sun (MOD) = %15lf ( ", c->DEC_sun); Lgm_Print_DMSd( c->DEC_sun ); printf(" )\n"); - Lgm_Radec_to_Cart( c->RA_sun, c->DEC_sun, &u_mod ); - Lgm_Convert_Coords( &u_mod, &u_tod, MOD_TO_TOD, c ); - RA_tod = atan2( u_tod.y, u_tod.x)*DegPerRad; if (RA_tod<0.0) RA_tod += 360.0; - DEC_tod = asin( u_tod.z )*DegPerRad; - printf(" RA_sun (TOD) = %15lf ( ", RA_tod); Lgm_Print_HMSd( RA_tod/15.0 ); printf(" )\n"); - printf(" DEC_sun (TOD) = %15lf ( ", DEC_tod); Lgm_Print_DMSd( DEC_tod ); printf(" )\n"); - Lgm_Convert_Coords( &u_mod, &u_gei, MOD_TO_GEI2000, c ); - RA_gei = atan2( u_gei.y, u_gei.x)*DegPerRad; if (RA_gei<0.0) RA_gei += 360.0; - DEC_gei = asin( u_gei.z )*DegPerRad; - printf(" RA_sun (J2000) = %15lf ( ", RA_gei); Lgm_Print_HMSd( RA_gei/15.0 ); printf(" )\n"); - printf(" DEC_sun (J2000) = %15lf ( ", DEC_gei); Lgm_Print_DMSd( DEC_gei ); printf(" )\n"); - - printf("\n"); - printf("Sun vector and Ecliptic Pole in GEI2000:\n"); - printf(" Sun = (%lf, %lf, %lf)\n", c->Sun.x, c->Sun.y, c->Sun.z); - printf(" EcPole = (%lf, %lf, %lf)\n", c->EcPole.x, c->EcPole.y, c->EcPole.z); - - printf("\n"); - printf("Geo-dipole tilt angle:\n"); - printf(" psi = %lf ( ", c->psi*DegPerRad); Lgm_Print_DMSd( c->psi*DegPerRad ); printf(" )\n"); + printf(" beta_sun = %14g ( ", c->beta_sun * DegPerRad); + Lgm_Print_DMSd(c->beta_sun * DegPerRad); + printf(" )\n"); + printf(" RA_sun (MOD) = %15lf ( ", c->RA_sun); + Lgm_Print_HMSd(c->RA_sun / 15.0); + printf(" )\n"); + printf(" DEC_sun (MOD) = %15lf ( ", c->DEC_sun); + Lgm_Print_DMSd(c->DEC_sun); + printf(" )\n"); + Lgm_Radec_to_Cart(c->RA_sun, c->DEC_sun, &u_mod); + Lgm_Convert_Coords(&u_mod, &u_tod, MOD_TO_TOD, c); + RA_tod = atan2(u_tod.y, u_tod.x) * DegPerRad; + if (RA_tod < 0.0) + RA_tod += 360.0; + DEC_tod = asin(u_tod.z) * DegPerRad; + printf(" RA_sun (TOD) = %15lf ( ", RA_tod); + Lgm_Print_HMSd(RA_tod / 15.0); + printf(" )\n"); + printf(" DEC_sun (TOD) = %15lf ( ", DEC_tod); + Lgm_Print_DMSd(DEC_tod); + printf(" )\n"); + Lgm_Convert_Coords(&u_mod, &u_gei, MOD_TO_GEI2000, c); + RA_gei = atan2(u_gei.y, u_gei.x) * DegPerRad; + if (RA_gei < 0.0) + RA_gei += 360.0; + DEC_gei = asin(u_gei.z) * DegPerRad; + printf(" RA_sun (J2000) = %15lf ( ", RA_gei); + Lgm_Print_HMSd(RA_gei / 15.0); + printf(" )\n"); + printf(" DEC_sun (J2000) = %15lf ( ", DEC_gei); + Lgm_Print_DMSd(DEC_gei); + printf(" )\n"); + + printf("\n"); + printf("Sun vector and Ecliptic Pole in GEI2000:\n"); + printf(" Sun = (%lf, %lf, %lf)\n", c->Sun.x, c->Sun.y, + c->Sun.z); + printf(" EcPole = (%lf, %lf, %lf)\n", c->EcPole.x, + c->EcPole.y, c->EcPole.z); + + printf("\n"); + printf("Geo-dipole tilt angle:\n"); + printf(" psi = %lf ( ", c->psi * DegPerRad); + Lgm_Print_DMSd(c->psi * DegPerRad); + printf(" )\n"); printf(" sin_psi = %lf\n", c->sin_psi); printf(" cos_psi = %lf\n", c->cos_psi); printf(" tan_psi = %lf\n", c->tan_psi); - printf("\n"); - printf("Position of Moon:\n"); - printf(" RA_moon = %lf ( ", c->RA_moon); Lgm_Print_HMSd( c->RA_moon/15.0 ); printf(" )\n"); - printf(" DEC_moon = %lf ( ", c->DEC_moon); Lgm_Print_DMSd( c->DEC_moon ); printf(" )\n"); + printf("\n"); + printf("Position of Moon:\n"); + printf(" RA_moon = %lf ( ", c->RA_moon); + Lgm_Print_HMSd(c->RA_moon / 15.0); + printf(" )\n"); + printf(" DEC_moon = %lf ( ", c->DEC_moon); + Lgm_Print_DMSd(c->DEC_moon); + printf(" )\n"); printf(" EarthMoonDistance = %lf\n", c->EarthMoonDistance); printf(" MoonPhase = %lf\n", c->MoonPhase); - - printf("\n"); - printf("IGRF-derived quantities:\n"); + printf("\n"); + printf("IGRF-derived quantities:\n"); printf(" M_cd = %.10lf nT\n", c->M_cd); printf(" M_cd_McIlwain = %.10lf nT\n", c->M_cd_McIlwain); printf(" M_cd_2010 = %.10lf nT\n", c->M_cd_2010); - printf(" CD_gcolat = %lf (deg.) ( ", c->CD_gcolat); Lgm_Print_DMSd( c->CD_gcolat ); printf(" )\n"); - printf(" CD_glon = %lf (deg.) ( ", c->CD_glon); Lgm_Print_DMSd( c->CD_glon ); printf(" )\n"); - printf(" ED_x0 = %lf Re (%lf km)\n", c->ED_x0, c->ED_x0*Re); - printf(" ED_y0 = %lf Re (%lf km)\n", c->ED_y0, c->ED_y0*Re); - printf(" ED_z0 = %lf Re (%lf km)\n", c->ED_z0, c->ED_z0*Re); - - - printf("\n"); - printf("Transformation Matrices:\n"); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gse[0][0], c->Amod_to_gse[1][0], c->Amod_to_gse[2][0]); - printf(" Amod_to_gse = [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gse[0][1], c->Amod_to_gse[1][1], c->Amod_to_gse[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Amod_to_gse[0][2], c->Amod_to_gse[1][2], c->Amod_to_gse[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gsm[0][0], c->Amod_to_gsm[1][0], c->Amod_to_gsm[2][0]); - printf(" Amod_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gsm[0][1], c->Amod_to_gsm[1][1], c->Amod_to_gsm[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Amod_to_gsm[0][2], c->Amod_to_gsm[1][2], c->Amod_to_gsm[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_wgs84[0][0], c->Agei_to_wgs84[1][0], c->Agei_to_wgs84[2][0]); - printf(" Agei_to_wgs84 = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_wgs84[0][1], c->Agei_to_wgs84[1][1], c->Agei_to_wgs84[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agei_to_wgs84[0][2], c->Agei_to_wgs84[1][2], c->Agei_to_wgs84[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse_to_mod[0][0], c->Agse_to_mod[1][0], c->Agse_to_mod[2][0]); - printf(" Agse_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse_to_mod[0][1], c->Agse_to_mod[1][1], c->Agse_to_mod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agse_to_mod[0][2], c->Agse_to_mod[1][2], c->Agse_to_mod[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse_to_gsm[0][0], c->Agse_to_gsm[1][0], c->Agse_to_gsm[2][0]); - printf(" Agse_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse_to_gsm[0][1], c->Agse_to_gsm[1][1], c->Agse_to_gsm[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agse_to_gsm[0][2], c->Agse_to_gsm[1][2], c->Agse_to_gsm[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Awgs84_to_gei[0][0], c->Awgs84_to_gei[1][0], c->Awgs84_to_gei[2][0]); - printf(" Awgs84_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", c->Awgs84_to_gei[0][1], c->Awgs84_to_gei[1][1], c->Awgs84_to_gei[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Awgs84_to_gei[0][2], c->Awgs84_to_gei[1][2], c->Awgs84_to_gei[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_mod[0][0], c->Agsm_to_mod[1][0], c->Agsm_to_mod[2][0]); - printf(" Agsm_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_mod[0][1], c->Agsm_to_mod[1][1], c->Agsm_to_mod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agsm_to_mod[0][2], c->Agsm_to_mod[1][2], c->Agsm_to_mod[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_sm[0][0], c->Agsm_to_sm[1][0], c->Agsm_to_sm[2][0]); - printf(" Agsm_to_sm = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_sm[0][1], c->Agsm_to_sm[1][1], c->Agsm_to_sm[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agsm_to_sm[0][2], c->Agsm_to_sm[1][2], c->Agsm_to_sm[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_gse[0][0], c->Agsm_to_gse[1][0], c->Agsm_to_gse[2][0]); - printf(" Agsm_to_gse = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agsm_to_gse[0][1], c->Agsm_to_gse[1][1], c->Agsm_to_gse[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agsm_to_gse[0][2], c->Agsm_to_gse[1][2], c->Agsm_to_gse[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Asm_to_gsm[0][0], c->Asm_to_gsm[1][0], c->Asm_to_gsm[2][0]); - printf(" Asm_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", c->Asm_to_gsm[0][1], c->Asm_to_gsm[1][1], c->Asm_to_gsm[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Asm_to_gsm[0][2], c->Asm_to_gsm[1][2], c->Asm_to_gsm[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_mod[0][0], c->Agei_to_mod[1][0], c->Agei_to_mod[2][0]); - printf(" Agei_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_mod[0][1], c->Agei_to_mod[1][1], c->Agei_to_mod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agei_to_mod[0][2], c->Agei_to_mod[1][2], c->Agei_to_mod[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gei[0][0], c->Amod_to_gei[1][0], c->Amod_to_gei[2][0]); - printf(" Amod_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_gei[0][1], c->Amod_to_gei[1][1], c->Amod_to_gei[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Amod_to_gei[0][2], c->Amod_to_gei[1][2], c->Amod_to_gei[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_tod[0][0], c->Amod_to_tod[1][0], c->Amod_to_tod[2][0]); - printf(" Amod_to_tod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Amod_to_tod[0][1], c->Amod_to_tod[1][1], c->Amod_to_tod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Amod_to_tod[0][2], c->Agei_to_mod[1][2], c->Amod_to_tod[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Atod_to_mod[0][0], c->Atod_to_mod[1][0], c->Atod_to_mod[2][0]); - printf(" Atod_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Atod_to_mod[0][1], c->Atod_to_mod[1][1], c->Atod_to_mod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Atod_to_mod[0][2], c->Atod_to_mod[1][2], c->Atod_to_mod[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Atod_to_pef[0][0], c->Atod_to_pef[1][0], c->Atod_to_pef[2][0]); - printf(" Atod_to_pef = [ %15.8lf %15.8lf %15.8lf ]\n", c->Atod_to_pef[0][1], c->Atod_to_pef[1][1], c->Atod_to_pef[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Atod_to_pef[0][2], c->Atod_to_pef[1][2], c->Atod_to_pef[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Apef_to_tod[0][0], c->Apef_to_tod[1][0], c->Apef_to_tod[2][0]); - printf(" Apef_to_tod = [ %15.8lf %15.8lf %15.8lf ]\n", c->Apef_to_tod[0][1], c->Apef_to_tod[1][1], c->Apef_to_tod[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Apef_to_tod[0][2], c->Apef_to_tod[1][2], c->Apef_to_tod[2][2]); - - printf(" [ %15.8e %15.8e %15.8e ]\n", c->Ateme_to_pef[0][0], c->Ateme_to_pef[1][0], c->Ateme_to_pef[2][0]); - printf(" Ateme_to_pef = [ %15.8e %15.8e %15.8e ]\n", c->Ateme_to_pef[0][1], c->Ateme_to_pef[1][1], c->Ateme_to_pef[2][1]); - printf(" [ %15.8e %15.8e %15.8e ]\n\n", c->Ateme_to_pef[0][2], c->Ateme_to_pef[1][2], c->Ateme_to_pef[2][2]); - - printf(" [ %15.8e %15.8e %15.8e ]\n", c->Apef_to_teme[0][0], c->Apef_to_teme[1][0], c->Apef_to_teme[2][0]); - printf(" Apef_to_teme = [ %15.8e %15.8e %15.8e ]\n", c->Apef_to_teme[0][1], c->Apef_to_teme[1][1], c->Apef_to_teme[2][1]); - printf(" [ %15.8e %15.8e %15.8e ]\n\n", c->Apef_to_teme[0][2], c->Apef_to_teme[1][2], c->Apef_to_teme[2][2]); - - printf(" [ %15.8e %15.8e %15.8e ]\n", c->Awgs84_to_pef[0][0], c->Awgs84_to_pef[1][0], c->Awgs84_to_pef[2][0]); - printf(" Awgs84_to_pef = [ %15.8e %15.8e %15.8e ]\n", c->Awgs84_to_pef[0][1], c->Awgs84_to_pef[1][1], c->Awgs84_to_pef[2][1]); - printf(" [ %15.8e %15.8e %15.8e ]\n\n", c->Awgs84_to_pef[0][2], c->Awgs84_to_pef[1][2], c->Awgs84_to_pef[2][2]); - - printf(" [ %15.8e %15.8e %15.8e ]\n", c->Apef_to_wgs84[0][0], c->Apef_to_wgs84[1][0], c->Apef_to_wgs84[2][0]); - printf(" Apef_to_wgs84 = [ %15.8e %15.8e %15.8e ]\n", c->Apef_to_wgs84[0][1], c->Apef_to_wgs84[1][1], c->Apef_to_wgs84[2][1]); - printf(" [ %15.8e %15.8e %15.8e ]\n\n", c->Apef_to_wgs84[0][2], c->Apef_to_wgs84[1][2], c->Apef_to_wgs84[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse2000_to_gei[0][0], c->Agse2000_to_gei[1][0], c->Agse2000_to_gei[2][0]); - printf(" Agse2000_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agse2000_to_gei[0][1], c->Agse2000_to_gei[1][1], c->Agse2000_to_gei[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agse2000_to_gei[0][2], c->Agse2000_to_gei[1][2], c->Agse2000_to_gei[2][2]); - - printf(" [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_gse2000[0][0], c->Agei_to_gse2000[1][0], c->Agei_to_gse2000[2][0]); - printf(" Agei_to_gse2000 = [ %15.8lf %15.8lf %15.8lf ]\n", c->Agei_to_gse2000[0][1], c->Agei_to_gse2000[1][1], c->Agei_to_gse2000[2][1]); - printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", c->Agei_to_gse2000[0][2], c->Agei_to_gse2000[1][2], c->Agei_to_gse2000[2][2]); + printf(" CD_gcolat = %lf (deg.) ( ", c->CD_gcolat); + Lgm_Print_DMSd(c->CD_gcolat); + printf(" )\n"); + printf(" CD_glon = %lf (deg.) ( ", c->CD_glon); + Lgm_Print_DMSd(c->CD_glon); + printf(" )\n"); + printf(" ED_x0 = %lf Re (%lf km)\n", c->ED_x0, + c->ED_x0 * Re); + printf(" ED_y0 = %lf Re (%lf km)\n", c->ED_y0, + c->ED_y0 * Re); + printf(" ED_z0 = %lf Re (%lf km)\n", c->ED_z0, + c->ED_z0 * Re); + + printf("\n"); + printf("Transformation Matrices:\n"); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gse[0][0], c->Amod_to_gse[1][0], + c->Amod_to_gse[2][0]); + printf(" Amod_to_gse = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gse[0][1], c->Amod_to_gse[1][1], + c->Amod_to_gse[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Amod_to_gse[0][2], c->Amod_to_gse[1][2], + c->Amod_to_gse[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gsm[0][0], c->Amod_to_gsm[1][0], + c->Amod_to_gsm[2][0]); + printf(" Amod_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gsm[0][1], c->Amod_to_gsm[1][1], + c->Amod_to_gsm[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Amod_to_gsm[0][2], c->Amod_to_gsm[1][2], + c->Amod_to_gsm[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_wgs84[0][0], c->Agei_to_wgs84[1][0], + c->Agei_to_wgs84[2][0]); + printf(" Agei_to_wgs84 = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_wgs84[0][1], c->Agei_to_wgs84[1][1], + c->Agei_to_wgs84[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agei_to_wgs84[0][2], c->Agei_to_wgs84[1][2], + c->Agei_to_wgs84[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse_to_mod[0][0], c->Agse_to_mod[1][0], + c->Agse_to_mod[2][0]); + printf(" Agse_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse_to_mod[0][1], c->Agse_to_mod[1][1], + c->Agse_to_mod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agse_to_mod[0][2], c->Agse_to_mod[1][2], + c->Agse_to_mod[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse_to_gsm[0][0], c->Agse_to_gsm[1][0], + c->Agse_to_gsm[2][0]); + printf(" Agse_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse_to_gsm[0][1], c->Agse_to_gsm[1][1], + c->Agse_to_gsm[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agse_to_gsm[0][2], c->Agse_to_gsm[1][2], + c->Agse_to_gsm[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Awgs84_to_gei[0][0], c->Awgs84_to_gei[1][0], + c->Awgs84_to_gei[2][0]); + printf(" Awgs84_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Awgs84_to_gei[0][1], c->Awgs84_to_gei[1][1], + c->Awgs84_to_gei[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Awgs84_to_gei[0][2], c->Awgs84_to_gei[1][2], + c->Awgs84_to_gei[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_mod[0][0], c->Agsm_to_mod[1][0], + c->Agsm_to_mod[2][0]); + printf(" Agsm_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_mod[0][1], c->Agsm_to_mod[1][1], + c->Agsm_to_mod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agsm_to_mod[0][2], c->Agsm_to_mod[1][2], + c->Agsm_to_mod[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_sm[0][0], c->Agsm_to_sm[1][0], c->Agsm_to_sm[2][0]); + printf(" Agsm_to_sm = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_sm[0][1], c->Agsm_to_sm[1][1], c->Agsm_to_sm[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agsm_to_sm[0][2], c->Agsm_to_sm[1][2], c->Agsm_to_sm[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_gse[0][0], c->Agsm_to_gse[1][0], + c->Agsm_to_gse[2][0]); + printf(" Agsm_to_gse = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agsm_to_gse[0][1], c->Agsm_to_gse[1][1], + c->Agsm_to_gse[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agsm_to_gse[0][2], c->Agsm_to_gse[1][2], + c->Agsm_to_gse[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Asm_to_gsm[0][0], c->Asm_to_gsm[1][0], c->Asm_to_gsm[2][0]); + printf(" Asm_to_gsm = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Asm_to_gsm[0][1], c->Asm_to_gsm[1][1], c->Asm_to_gsm[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Asm_to_gsm[0][2], c->Asm_to_gsm[1][2], c->Asm_to_gsm[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_mod[0][0], c->Agei_to_mod[1][0], + c->Agei_to_mod[2][0]); + printf(" Agei_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_mod[0][1], c->Agei_to_mod[1][1], + c->Agei_to_mod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agei_to_mod[0][2], c->Agei_to_mod[1][2], + c->Agei_to_mod[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gei[0][0], c->Amod_to_gei[1][0], + c->Amod_to_gei[2][0]); + printf(" Amod_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_gei[0][1], c->Amod_to_gei[1][1], + c->Amod_to_gei[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Amod_to_gei[0][2], c->Amod_to_gei[1][2], + c->Amod_to_gei[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_tod[0][0], c->Amod_to_tod[1][0], + c->Amod_to_tod[2][0]); + printf(" Amod_to_tod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Amod_to_tod[0][1], c->Amod_to_tod[1][1], + c->Amod_to_tod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Amod_to_tod[0][2], c->Agei_to_mod[1][2], + c->Amod_to_tod[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Atod_to_mod[0][0], c->Atod_to_mod[1][0], + c->Atod_to_mod[2][0]); + printf(" Atod_to_mod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Atod_to_mod[0][1], c->Atod_to_mod[1][1], + c->Atod_to_mod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Atod_to_mod[0][2], c->Atod_to_mod[1][2], + c->Atod_to_mod[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Atod_to_pef[0][0], c->Atod_to_pef[1][0], + c->Atod_to_pef[2][0]); + printf(" Atod_to_pef = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Atod_to_pef[0][1], c->Atod_to_pef[1][1], + c->Atod_to_pef[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Atod_to_pef[0][2], c->Atod_to_pef[1][2], + c->Atod_to_pef[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Apef_to_tod[0][0], c->Apef_to_tod[1][0], + c->Apef_to_tod[2][0]); + printf(" Apef_to_tod = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Apef_to_tod[0][1], c->Apef_to_tod[1][1], + c->Apef_to_tod[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Apef_to_tod[0][2], c->Apef_to_tod[1][2], + c->Apef_to_tod[2][2]); + + printf(" [ %15.8e %15.8e %15.8e ]\n", + c->Ateme_to_pef[0][0], c->Ateme_to_pef[1][0], + c->Ateme_to_pef[2][0]); + printf(" Ateme_to_pef = [ %15.8e %15.8e %15.8e ]\n", + c->Ateme_to_pef[0][1], c->Ateme_to_pef[1][1], + c->Ateme_to_pef[2][1]); + printf(" [ %15.8e %15.8e %15.8e ]\n\n", + c->Ateme_to_pef[0][2], c->Ateme_to_pef[1][2], + c->Ateme_to_pef[2][2]); + + printf(" [ %15.8e %15.8e %15.8e ]\n", + c->Apef_to_teme[0][0], c->Apef_to_teme[1][0], + c->Apef_to_teme[2][0]); + printf(" Apef_to_teme = [ %15.8e %15.8e %15.8e ]\n", + c->Apef_to_teme[0][1], c->Apef_to_teme[1][1], + c->Apef_to_teme[2][1]); + printf(" [ %15.8e %15.8e %15.8e ]\n\n", + c->Apef_to_teme[0][2], c->Apef_to_teme[1][2], + c->Apef_to_teme[2][2]); + + printf(" [ %15.8e %15.8e %15.8e ]\n", + c->Awgs84_to_pef[0][0], c->Awgs84_to_pef[1][0], + c->Awgs84_to_pef[2][0]); + printf(" Awgs84_to_pef = [ %15.8e %15.8e %15.8e ]\n", + c->Awgs84_to_pef[0][1], c->Awgs84_to_pef[1][1], + c->Awgs84_to_pef[2][1]); + printf(" [ %15.8e %15.8e %15.8e ]\n\n", + c->Awgs84_to_pef[0][2], c->Awgs84_to_pef[1][2], + c->Awgs84_to_pef[2][2]); + + printf(" [ %15.8e %15.8e %15.8e ]\n", + c->Apef_to_wgs84[0][0], c->Apef_to_wgs84[1][0], + c->Apef_to_wgs84[2][0]); + printf(" Apef_to_wgs84 = [ %15.8e %15.8e %15.8e ]\n", + c->Apef_to_wgs84[0][1], c->Apef_to_wgs84[1][1], + c->Apef_to_wgs84[2][1]); + printf(" [ %15.8e %15.8e %15.8e ]\n\n", + c->Apef_to_wgs84[0][2], c->Apef_to_wgs84[1][2], + c->Apef_to_wgs84[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse2000_to_gei[0][0], c->Agse2000_to_gei[1][0], + c->Agse2000_to_gei[2][0]); + printf(" Agse2000_to_gei = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agse2000_to_gei[0][1], c->Agse2000_to_gei[1][1], + c->Agse2000_to_gei[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agse2000_to_gei[0][2], c->Agse2000_to_gei[1][2], + c->Agse2000_to_gei[2][2]); + + printf(" [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_gse2000[0][0], c->Agei_to_gse2000[1][0], + c->Agei_to_gse2000[2][0]); + printf(" Agei_to_gse2000 = [ %15.8lf %15.8lf %15.8lf ]\n", + c->Agei_to_gse2000[0][1], c->Agei_to_gse2000[1][1], + c->Agei_to_gse2000[2][1]); + printf(" [ %15.8lf %15.8lf %15.8lf ]\n\n", + c->Agei_to_gse2000[0][2], c->Agei_to_gse2000[1][2], + c->Agei_to_gse2000[2][2]); } - } - -void Lgm_ComputeSun( Lgm_CTrans *c ) { - double r0, earth_sun_distance; - double epsilon, lambnew, cos_epsilon, sin_epsilon, sin_lambnew; - double sin_b, cos_b, sin_l; - double l, r, b, Dec, RA, zec; - Lgm_Vector SunICRF, Sunmod, S; +void Lgm_ComputeSun(Lgm_CTrans* c) { + double r0, earth_sun_distance; + double epsilon, lambnew, cos_epsilon, sin_epsilon, sin_lambnew; + double sin_b, cos_b, sin_l; + double l, r, b, Dec, RA, zec; + Lgm_Vector SunICRF, Sunmod, S; /* Compute distance from Earth to the Sun */ - r0 = 1.495985e8; /* in km */ - epsilon = c->epsilon*RadPerArcSec; // radians + r0 = 1.495985e8; /* in km */ + epsilon = c->epsilon * RadPerArcSec; // radians cos_epsilon = cos(epsilon); sin_epsilon = sin(epsilon); - lambnew = c->lambda_sun; + lambnew = c->lambda_sun; switch (c->ephModel) { case LGM_EPH_DE: - Lgm_JPL_getSunVector( c->TT.JD, c->jpl, &SunICRF); - c->earth_sun_dist = Lgm_Magnitude( &SunICRF )/Re; + Lgm_JPL_getSunVector(c->TT.JD, c->jpl, &SunICRF); + c->earth_sun_dist = Lgm_Magnitude(&SunICRF) / Re; Lgm_NormalizeVector(&SunICRF); c->SunJ2000 = SunICRF; Lgm_MatTimesVec(c->Agei_to_mod, &SunICRF, &Sunmod); - //Lgm_Convert_Coords( &SunICRF, &Sunmod, GEI2000_TO_MOD, c ); - Lgm_CartToSphCoords( &Sunmod, &Dec, &RA, &r); - c->RA_sun = Lgm_angle360( RA ); + // Lgm_Convert_Coords( &SunICRF, &Sunmod, GEI2000_TO_MOD, c ); + Lgm_CartToSphCoords(&Sunmod, &Dec, &RA, &r); + c->RA_sun = Lgm_angle360(RA); c->DEC_sun = Dec; // Direction of the Sun in MOD coords Lgm_NormalizeVector(&Sunmod); c->Sun = Sunmod; - zec = -1.0*sin_epsilon*Sunmod.y + cos_epsilon*Sunmod.z; + zec = -1.0 * sin_epsilon * Sunmod.y + cos_epsilon * Sunmod.z; c->beta_sun = asin(zec); - c->lambda_sun = -1.0*acos(Sunmod.x/cos(c->beta_sun)); - c->lambda_sun = (c->lambda_sun<0) ? c->lambda_sun+2*M_PI : c->lambda_sun ; + c->lambda_sun = -1.0 * acos(Sunmod.x / cos(c->beta_sun)); + c->lambda_sun = + (c->lambda_sun < 0) ? c->lambda_sun + 2 * M_PI : c->lambda_sun; break; case LGM_EPH_HIGH_ACCURACY: sin_lambnew = sin(lambnew); - Lgm_SunPosition( c->TT.T, &l, &r, &b ); - c->lambda_sun = l; // high accuracy values - c->beta_sun = b; // high accuracy values - sin_b = sin(b); cos_b = cos(b); sin_l = sin(l); - RA = Lgm_angle360( atan2( cos_epsilon*cos_b*sin_l-sin_epsilon*sin_b, cos_b*cos(l) )*DegPerRad ); - Dec = asin( sin_epsilon*cos_b*sin_l + cos_epsilon*sin_b )*DegPerRad; - c->RA_sun = RA; // high accuracy RA - c->DEC_sun = Dec; // high accuracy DEC - c->earth_sun_dist = r*AU/Re; // high accuracy values + Lgm_SunPosition(c->TT.T, &l, &r, &b); + c->lambda_sun = l; // high accuracy values + c->beta_sun = b; // high accuracy values + sin_b = sin(b); + cos_b = cos(b); + sin_l = sin(l); + RA = Lgm_angle360( + atan2(cos_epsilon * cos_b * sin_l - sin_epsilon * sin_b, + cos_b * cos(l)) * + DegPerRad); + Dec = asin(sin_epsilon * cos_b * sin_l + cos_epsilon * sin_b) * + DegPerRad; + c->RA_sun = RA; // high accuracy RA + c->DEC_sun = Dec; // high accuracy DEC + c->earth_sun_dist = r * AU / Re; // high accuracy values // Direction of the Sun in MOD coords S.x = cos(c->lambda_sun); - S.y = cos(epsilon)*sin(c->lambda_sun); - S.z = sin(epsilon)*sin(c->lambda_sun); + S.y = cos(epsilon) * sin(c->lambda_sun); + S.z = sin(epsilon) * sin(c->lambda_sun); c->Sun = S; - Lgm_Convert_Coords( &c->Sun, &SunICRF, MOD_TO_GEI2000, c ); + Lgm_Convert_Coords(&c->Sun, &SunICRF, MOD_TO_GEI2000, c); c->SunJ2000 = SunICRF; break; case LGM_EPH_LOW_ACCURACY: default: - /* Compute Right Ascension and Declination of the Sun (Low precision) */ + /* Compute Right Ascension and Declination of the Sun (Low + * precision) */ sin_lambnew = sin(lambnew); - RA = Lgm_angle360(atan2(sin_lambnew*cos_epsilon, cos(lambnew))*DegPerRad); - Dec = asin(sin_epsilon*sin_lambnew)*DegPerRad; - c->beta_sun= 0.0; // low accuracy values - c->RA_sun = RA; + RA = Lgm_angle360(atan2(sin_lambnew * cos_epsilon, cos(lambnew)) * + DegPerRad); + Dec = asin(sin_epsilon * sin_lambnew) * DegPerRad; + c->beta_sun = 0.0; // low accuracy values + c->RA_sun = RA; c->DEC_sun = Dec; - earth_sun_distance = r0*(1-c->eccentricity*c->eccentricity)/(1.0 + c->eccentricity*cos(c->true_anomaly))/Re; + earth_sun_distance = + r0 * (1 - c->eccentricity * c->eccentricity) / + (1.0 + c->eccentricity * cos(c->true_anomaly)) / Re; c->earth_sun_dist = earth_sun_distance; // Direction of the Sun in MOD coords S.x = cos(c->lambda_sun); - S.y = cos(epsilon)*sin(c->lambda_sun); - S.z = sin(epsilon)*sin(c->lambda_sun); + S.y = cos(epsilon) * sin(c->lambda_sun); + S.z = sin(epsilon) * sin(c->lambda_sun); c->Sun = S; - Lgm_Convert_Coords( &c->Sun, &SunICRF, MOD_TO_GEI2000, c ); + Lgm_Convert_Coords(&c->Sun, &SunICRF, MOD_TO_GEI2000, c); c->SunJ2000 = SunICRF; break; } } - -void Lgm_ComputeMoon( Lgm_CTrans *c ) { - - double RA_Moon, DEC_Moon; - double Lmoon_0, P0, N0, Imoon, Lmoon, Mmoon_m, Nmoon, Cmoon; - double Emoon_nu, Amoon_e, Amoon_3, Mmoon_mp, Emoon_c, amoon, emoon; - double Amoon_4, Lmoon_p, Vmoon, Lmoon_pp, Nmoon_p, LambdaMoon, BetaMoon; - double JD, RA, Dec, r; - double days, M, epsilon; - Lgm_Vector MoonGCRF, Moonmod; - int ephModel; +void Lgm_ComputeMoon(Lgm_CTrans* c) { + double RA_Moon, DEC_Moon; + double Lmoon_0, P0, N0, Imoon, Lmoon, Mmoon_m, Nmoon, Cmoon; + double Emoon_nu, Amoon_e, Amoon_3, Mmoon_mp, Emoon_c, amoon, emoon; + double Amoon_4, Lmoon_p, Vmoon, Lmoon_pp, Nmoon_p, LambdaMoon, BetaMoon; + double JD, RA, Dec, r; + double days, M, epsilon; + Lgm_Vector MoonGCRF, Moonmod; + int ephModel; /* * Compute Right Ascension and Declination of the Moon in MOD */ - JD = Lgm_JD( c->TT.Year, c->TT.Month, c->TT.Day, c->TT.Time, LGM_TIME_SYS_TT, c ); - epsilon = c->epsilon*RadPerArcSec; - M = c->mean_anomaly; - ephModel = ( c->jpl==NULL ) ? LGM_EPH_LOW_ACCURACY : c->ephModel; + JD = Lgm_JD(c->TT.Year, c->TT.Month, c->TT.Day, c->TT.Time, LGM_TIME_SYS_TT, + c); + epsilon = c->epsilon * RadPerArcSec; + M = c->mean_anomaly; + ephModel = (c->jpl == NULL) ? LGM_EPH_LOW_ACCURACY : c->ephModel; switch (ephModel) { case LGM_EPH_DE: /* Compute Right Ascension and Declination of the Moon */ - Lgm_JPLephem_position( JD, LGM_DE_MOON, c->jpl, &MoonGCRF ); - c->MoonJ2000 = MoonGCRF; // mgh - should this be GCRF or ICRF? - Lgm_NormalizeVector( &(c->MoonJ2000) ); - Lgm_Convert_Coords( &MoonGCRF, &Moonmod, GEI2000_TO_MOD, c ); - Lgm_CartToSphCoords( &Moonmod, &Dec, &RA, &r); + Lgm_JPLephem_position(JD, LGM_DE_MOON, c->jpl, &MoonGCRF); + c->MoonJ2000 = MoonGCRF; // mgh - should this be GCRF or ICRF? + Lgm_NormalizeVector(&(c->MoonJ2000)); + Lgm_Convert_Coords(&MoonGCRF, &Moonmod, GEI2000_TO_MOD, c); + Lgm_CartToSphCoords(&Moonmod, &Dec, &RA, &r); c->RA_moon = Lgm_angle360(RA); c->DEC_moon = Dec; @@ -1166,7 +1494,8 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { c->MoonPhase = LGM_FILL_VALUE; /* Earth-Moon Distance in Earth Radii */ - c->EarthMoonDistance = Lgm_Magnitude(&Moonmod)/Re; //Re comes from CTrans.h + c->EarthMoonDistance = + Lgm_Magnitude(&Moonmod) / Re; // Re comes from CTrans.h break; case LGM_EPH_HIGH_ACCURACY: case LGM_EPH_LOW_ACCURACY: @@ -1176,61 +1505,70 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { P0 = 36.340410; N0 = 318.510107; Imoon = 5.145396; - days = JD - 2447891.5; - Lmoon = 13.1763966*days + Lmoon_0; - Mmoon_m = Lmoon - 0.1114041*days - P0; - Nmoon = N0 - 0.0529539*days; - Cmoon = Lmoon*RadPerDeg - c->lambda_sun; - Emoon_nu = 1.2739*sin(2.0*Cmoon - Mmoon_m*RadPerDeg); - Amoon_e = 0.1858*sin(M); - Amoon_3 = 0.37*sin(M); + days = JD - 2447891.5; + Lmoon = 13.1763966 * days + Lmoon_0; + Mmoon_m = Lmoon - 0.1114041 * days - P0; + Nmoon = N0 - 0.0529539 * days; + Cmoon = Lmoon * RadPerDeg - c->lambda_sun; + Emoon_nu = 1.2739 * sin(2.0 * Cmoon - Mmoon_m * RadPerDeg); + Amoon_e = 0.1858 * sin(M); + Amoon_3 = 0.37 * sin(M); Mmoon_mp = Mmoon_m + Emoon_nu - Amoon_e - Amoon_3; - Emoon_c = 6.2886*sin(Mmoon_mp*RadPerDeg); - Amoon_4 = 0.214*sin(2.0*Mmoon_mp*RadPerDeg); + Emoon_c = 6.2886 * sin(Mmoon_mp * RadPerDeg); + Amoon_4 = 0.214 * sin(2.0 * Mmoon_mp * RadPerDeg); Lmoon_p = Lmoon + Emoon_nu + Emoon_c - Amoon_e + Amoon_4; - Vmoon = 0.6583*sin(2.0*(Lmoon_p*RadPerDeg - c->lambda_sun)); + Vmoon = 0.6583 * sin(2.0 * (Lmoon_p * RadPerDeg - c->lambda_sun)); Lmoon_pp = Lmoon_p + Vmoon; - Nmoon_p = Nmoon - 0.16*sin(M); - LambdaMoon = atan2( sin((Lmoon_pp - Nmoon_p)*RadPerDeg)*cos(Imoon*RadPerDeg), - cos((Lmoon_pp - Nmoon_p)*RadPerDeg) ) + Nmoon_p*RadPerDeg; - BetaMoon = asin(sin((Lmoon_pp - Nmoon_p)*RadPerDeg)*sin(Imoon*RadPerDeg)); - RA_Moon = Lgm_angle360(atan2(sin(LambdaMoon)*cos(epsilon)-tan(BetaMoon)*sin(epsilon), - cos(LambdaMoon))*DegPerRad); - DEC_Moon = asin( sin(BetaMoon)*cos(epsilon) + cos(BetaMoon)*sin(epsilon)*sin(LambdaMoon))*DegPerRad; - c->RA_moon = RA_Moon; + Nmoon_p = Nmoon - 0.16 * sin(M); + LambdaMoon = atan2(sin((Lmoon_pp - Nmoon_p) * RadPerDeg) * + cos(Imoon * RadPerDeg), + cos((Lmoon_pp - Nmoon_p) * RadPerDeg)) + + Nmoon_p * RadPerDeg; + BetaMoon = asin(sin((Lmoon_pp - Nmoon_p) * RadPerDeg) * + sin(Imoon * RadPerDeg)); + RA_Moon = Lgm_angle360(atan2(sin(LambdaMoon) * cos(epsilon) - + tan(BetaMoon) * sin(epsilon), + cos(LambdaMoon)) * + DegPerRad); + DEC_Moon = asin(sin(BetaMoon) * cos(epsilon) + + cos(BetaMoon) * sin(epsilon) * sin(LambdaMoon)) * + DegPerRad; + c->RA_moon = RA_Moon; c->DEC_moon = DEC_Moon; /* Get phase of Moon */ - c->MoonPhase = 0.5*(1.0 - cos(Lmoon_pp*RadPerDeg - c->lambda_sun)); + c->MoonPhase = + 0.5 * (1.0 - cos(Lmoon_pp * RadPerDeg - c->lambda_sun)); /* Earth-Moon Distance in Earth Radii */ amoon = 384401.0; emoon = 0.054900; - c->EarthMoonDistance = amoon*(1.0 - emoon*emoon)/(1.0 + emoon*cos((Mmoon_mp + Emoon_c)*RadPerDeg)); + c->EarthMoonDistance = + amoon * (1.0 - emoon * emoon) / + (1.0 + emoon * cos((Mmoon_mp + Emoon_c) * RadPerDeg)); c->EarthMoonDistance /= Re; - //c->MoonJ2000 = XXX; + // c->MoonJ2000 = XXX; break; - } - + } } - /* * * Lgm_Vector *u; -- input vector * Lgm_Vector *v; -- output vector * int flag; -- flag to specify the type of coord transformation - * (see LgmCtrans.h for description of whats available) - * Lgm_CTrans *c; -- structure that holds all the coord trans info + * (see LgmCtrans.h for description of whats + * available) Lgm_CTrans *c; -- structure that holds all the coord trans + * info * */ - -/** +/** * \brief - * Transforms the components of a vector from one coordinate system to another. + * Transforms the components of a vector from one coordinate system to + * another. * * \details * The defined coordinate systems are given in the Lgm_CTrans.h file. @@ -1244,22 +1582,20 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { * #include * int main( ) { * - * Lgm_CTrans *c = Lgm_init_ctrans( 1 ); // The '1' produces verbose output. - * Lgm_Vector Ugsm, Usm; - * long int Date; - * double UTC; + * Lgm_CTrans *c = Lgm_init_ctrans( 1 ); // The '1' + * produces verbose output. Lgm_Vector Ugsm, Usm; long int Date; double UTC; * * // Set Date and Time * Date = 20000101; // Jan 1, 2000 - * UTC = 3.5; // 3:30 UTC + * UTC = 3.5; // 3:30 UTC * * // Set a vector in GSM coordinates * Ugsm.x = -6.6; // Re * Ugsm.y = 3.4; // Re * Ugsm.z = -2.3; // Re * - * // Set up all the necessary transformations for this Date/UTC - * Lgm_Set_Coord_Transforms( Date, UTC, c ); + * // Set up all the necessary transformations for this + * Date/UTC Lgm_Set_Coord_Transforms( Date, UTC, c ); * * // Do the transformation from GSM->SM * Lgm_Convert_Coords( &Ugsm, &Usm, GSM_TO_SM, c ); @@ -1267,8 +1603,8 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { * // Print out the final results * printf( "Date = %8ld\n", Date ); * printf( "UTC = %lf\n", UTC ); - * printf( "Ugsm = %.8lf %.8lf %.8lf Re\n", Ugsm.x, Ugsm.y, Ugsm.z ); - * printf( "Usm = %.8lf %.8lf %.8lf Re\n", Usm.x, Usm.y, Usm.z ); + * printf( "Ugsm = %.8lf %.8lf %.8lf Re\n", Ugsm.x, Ugsm.y, + * Ugsm.z ); printf( "Usm = %.8lf %.8lf %.8lf Re\n", Usm.x, Usm.y, Usm.z ); * * // free the structure * Lgm_free_ctrans( c ); @@ -1276,7 +1612,7 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { * return(0); * * } - * + * * \endcode * * Internally, the transformation is identified by decoding the number @@ -1301,10 +1637,11 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { * * \param[in] u The input vector. * \param[in] UTC The transformed output vector. - * \param[in] flag A flag describing the desired coordinate transformation. - * \param[in,out] c Pointer to a properly configured Lgm_CTrans structure (See Lgm_Set_Coord_Transforms() ). + * \param[in] flag A flag describing the desired coordinate + * transformation. \param[in,out] c Pointer to a properly configured + * Lgm_CTrans structure (See Lgm_Set_Coord_Transforms() ). + * * - * * * \returns void * \sa Lgm_init_ctrans(), Lgm_Set_Coord_Transforms( ) @@ -1314,17 +1651,16 @@ void Lgm_ComputeMoon( Lgm_CTrans *c ) { * * */ -void Lgm_Convert_Coords( Lgm_Vector *u, Lgm_Vector *v, int flag, Lgm_CTrans *c ) { - - Lgm_Vector w, r, z, e, d; - int inflag, outflag; +void Lgm_Convert_Coords(Lgm_Vector* u, Lgm_Vector* v, int flag, Lgm_CTrans* c) { + Lgm_Vector w, r, z, e, d; + int inflag, outflag; /* * Figure out what system the input coords are in * and what system the output coords should be in... */ - inflag = (int)((float)flag/100.0); - outflag = flag - inflag*100; + inflag = (int)((float)flag / 100.0); + outflag = flag - inflag * 100; /* * Catch case where in coords are same as out coords @@ -1342,60 +1678,62 @@ void Lgm_Convert_Coords( Lgm_Vector *u, Lgm_Vector *v, int flag, Lgm_CTrans *c ) * Lets choose MOD since its pretty common */ - /* * convert coords to a common system: use MOD... */ - switch(inflag){ - case EME2000_COORDS: // in coords are in EME2000 (aka ICRF2000 or GEI2000) - // aka ICRF2000_COORDS - // aka GEI2000_COORDS + switch (inflag) { + case EME2000_COORDS: // in coords are in EME2000 (aka ICRF2000 or + // GEI2000) aka ICRF2000_COORDS aka GEI2000_COORDS Lgm_MatTimesVec(c->Agei_to_mod, u, &w); break; - case MOD_COORDS: // in coords are in MOD + case MOD_COORDS: // in coords are in MOD w.x = u->x, w.y = u->y, w.z = u->z; break; - case TOD_COORDS: // in coords are in TOD + case TOD_COORDS: // in coords are in TOD Lgm_MatTimesVec(c->Atod_to_mod, u, &w); break; - case TEME_COORDS: // in coords are in TEME + case TEME_COORDS: // in coords are in TEME Lgm_MatTimesVec(c->Ateme_to_pef, u, &r); Lgm_MatTimesVec(c->Apef_to_tod, &r, &z); Lgm_MatTimesVec(c->Atod_to_mod, &z, &w); break; - case PEF_COORDS: // in coords are in PEF + case PEF_COORDS: // in coords are in PEF Lgm_MatTimesVec(c->Apef_to_tod, u, &r); Lgm_MatTimesVec(c->Atod_to_mod, &r, &w); break; - case WGS84_COORDS: // in coords are in WGS84 + case WGS84_COORDS: // in coords are in WGS84 Lgm_MatTimesVec(c->Awgs84_to_pef, u, &r); Lgm_MatTimesVec(c->Apef_to_tod, &r, &z); Lgm_MatTimesVec(c->Atod_to_mod, &z, &w); break; - case GSE_COORDS: // in coords are in GSE + case GSE_COORDS: // in coords are in GSE Lgm_MatTimesVec(c->Agse_to_mod, u, &w); break; case GSE2000_COORDS: Lgm_MatTimesVec(c->Agse2000_to_gei, u, &r); Lgm_MatTimesVec(c->Agei_to_mod, &r, &w); break; - case GSM_COORDS: // in coords are in GSM + case GSM_COORDS: // in coords are in GSM Lgm_MatTimesVec(c->Agsm_to_mod, u, &w); break; - case SM_COORDS: // in coords are in SM - Lgm_MatTimesVec(c->Asm_to_gsm, u, &r); + case SM_COORDS: // in coords are in SM + Lgm_MatTimesVec(c->Asm_to_gsm, u, &r); Lgm_MatTimesVec(c->Agsm_to_mod, &r, &w); break; - case CDMAG_COORDS: // in coords are in CDMAG + case CDMAG_COORDS: // in coords are in CDMAG Lgm_MatTimesVec(c->Acdmag_to_wgs84, u, &r); Lgm_MatTimesVec(c->Awgs84_to_mod, &r, &w); break; - case EDMAG_COORDS: // in coords are in EDMAG - // Convert the dipole offset to CDMAG coords first - d.x = c->ED_x0; d.y = c->ED_y0; d.z = c->ED_z0; // offset vector in wgs84 (i.e. in geo) - Lgm_MatTimesVec(c->Awgs84_to_cdmag, &d, &e); + case EDMAG_COORDS: // in coords are in EDMAG + // Convert the dipole offset to CDMAG coords first + d.x = c->ED_x0; + d.y = c->ED_y0; + d.z = c->ED_z0; // offset vector in wgs84 (i.e. in geo) + Lgm_MatTimesVec(c->Awgs84_to_cdmag, &d, &e); // now Rcd = d_offset_cd + Red - z.x = u->x + e.x; z.y = u->y + e.y; z.z = u->z + e.z; // Rcd = R0 + Red (z should be in CD now) + z.x = u->x + e.x; + z.y = u->y + e.y; + z.z = u->z + e.z; // Rcd = R0 + Red (z should be in CD now) Lgm_MatTimesVec(c->Acdmag_to_wgs84, &z, &r); Lgm_MatTimesVec(c->Awgs84_to_mod, &r, &w); break; @@ -1403,63 +1741,65 @@ void Lgm_Convert_Coords( Lgm_Vector *u, Lgm_Vector *v, int flag, Lgm_CTrans *c ) // w now holds the coords in MOD -- now transform to desired system - switch(outflag){ - case EME2000_COORDS: // out coords are in EME2000 (aka ICRF2000 or GEI2000) + switch (outflag) { + case EME2000_COORDS: // out coords are in EME2000 (aka ICRF2000 or + // GEI2000) Lgm_MatTimesVec(c->Amod_to_gei, &w, v); break; - case MOD_COORDS: // out coords are in MOD + case MOD_COORDS: // out coords are in MOD v->x = w.x, v->y = w.y, v->z = w.z; break; - case TOD_COORDS: // out coords are in TOD + case TOD_COORDS: // out coords are in TOD Lgm_MatTimesVec(c->Amod_to_tod, &w, v); break; - case TEME_COORDS: // out coords are in TEME + case TEME_COORDS: // out coords are in TEME Lgm_MatTimesVec(c->Amod_to_tod, &w, &r); Lgm_MatTimesVec(c->Atod_to_pef, &r, &z); Lgm_MatTimesVec(c->Apef_to_teme, &z, v); break; - case PEF_COORDS: // out coords are in PEF + case PEF_COORDS: // out coords are in PEF Lgm_MatTimesVec(c->Amod_to_tod, &w, &r); Lgm_MatTimesVec(c->Atod_to_pef, &r, v); break; - case WGS84_COORDS: // out coords are in WGS84 + case WGS84_COORDS: // out coords are in WGS84 Lgm_MatTimesVec(c->Amod_to_tod, &w, &r); Lgm_MatTimesVec(c->Atod_to_pef, &r, &z); Lgm_MatTimesVec(c->Apef_to_wgs84, &z, v); break; - case GSE_COORDS: // out coords are in GSE + case GSE_COORDS: // out coords are in GSE Lgm_MatTimesVec(c->Amod_to_gse, &w, v); break; - case GSM_COORDS: // out coords are in GSM + case GSM_COORDS: // out coords are in GSM Lgm_MatTimesVec(c->Amod_to_gsm, &w, v); break; - case GSE2000_COORDS: // out coords are in GSE2000 + case GSE2000_COORDS: // out coords are in GSE2000 Lgm_MatTimesVec(c->Amod_to_gei, &w, &r); - Lgm_MatTimesVec(c->Agei_to_gse2000, &r, v); + Lgm_MatTimesVec(c->Agei_to_gse2000, &r, v); break; - case SM_COORDS: // out coords are in SM + case SM_COORDS: // out coords are in SM Lgm_MatTimesVec(c->Amod_to_gsm, &w, &r); - Lgm_MatTimesVec(c->Agsm_to_sm, &r, v); + Lgm_MatTimesVec(c->Agsm_to_sm, &r, v); break; - case CDMAG_COORDS: // out coords are in CDMAG + case CDMAG_COORDS: // out coords are in CDMAG Lgm_MatTimesVec(c->Amod_to_wgs84, &w, &r); Lgm_MatTimesVec(c->Awgs84_to_cdmag, &r, v); break; - case EDMAG_COORDS: // out coords are in ED + case EDMAG_COORDS: // out coords are in ED Lgm_MatTimesVec(c->Amod_to_wgs84, &w, &r); Lgm_MatTimesVec(c->Awgs84_to_cdmag, &r, &z); - // Convert the dipole offset to CDMAG coords - d.x = c->ED_x0; d.y = c->ED_y0; d.z = c->ED_z0; // offset vector in wgs84 (i.e. in geo) - Lgm_MatTimesVec(c->Awgs84_to_cdmag, &d, &e); + // Convert the dipole offset to CDMAG coords + d.x = c->ED_x0; + d.y = c->ED_y0; + d.z = c->ED_z0; // offset vector in wgs84 (i.e. in geo) + Lgm_MatTimesVec(c->Awgs84_to_cdmag, &d, &e); // now Rcd - d_offset_cd = Red - v->x = z.x - e.x; v->y = z.y - e.y; v->z = z.z - e.z; // Rcd - R0 = Red (z should be in ED now) + v->x = z.x - e.x; + v->y = z.y - e.y; + v->z = z.z - e.z; // Rcd - R0 = Red (z should be in ED now) break; - } - - + } } - /* * Input: * GeodLat: in degrees @@ -1469,287 +1809,287 @@ void Lgm_Convert_Coords( Lgm_Vector *u, Lgm_Vector *v, int flag, Lgm_CTrans *c ) * Output: * v: in Re */ -void Lgm_GEOD_to_WGS84( double GeodLat, double GeodLong, double GeodHeight, Lgm_Vector *v ) { - - double lam, phi, h, CosPhi, SinPhi, CosLam, SinLam, Chi; - - lam = GeodLat*RadPerDeg; - phi = GeodLong*RadPerDeg; - h = GeodHeight; - - CosPhi = cos(phi); SinPhi = sin(phi); SinLam = sin(lam); CosLam = cos(lam); - Chi = sqrt( 1.0 - WGS84_E2*SinLam*SinLam ); +void Lgm_GEOD_to_WGS84(double GeodLat, + double GeodLong, + double GeodHeight, + Lgm_Vector* v) { + double lam, phi, h, CosPhi, SinPhi, CosLam, SinLam, Chi; + + lam = GeodLat * RadPerDeg; + phi = GeodLong * RadPerDeg; + h = GeodHeight; + + CosPhi = cos(phi); + SinPhi = sin(phi); + SinLam = sin(lam); + CosLam = cos(lam); + Chi = sqrt(1.0 - WGS84_E2 * SinLam * SinLam); // convert to GEO (in units of Re) - v->x = (WGS84_A/Chi + h)*CosLam*CosPhi/WGS84_A; - v->y = (WGS84_A/Chi + h)*CosLam*SinPhi/WGS84_A; - v->z = (WGS84_A*(1.0-WGS84_E2)/Chi + h)*SinLam/WGS84_A; - + v->x = (WGS84_A / Chi + h) * CosLam * CosPhi / WGS84_A; + v->y = (WGS84_A / Chi + h) * CosLam * SinPhi / WGS84_A; + v->z = (WGS84_A * (1.0 - WGS84_E2) / Chi + h) * SinLam / WGS84_A; } -void Lgm_WGS84_to_GEOD( Lgm_Vector *uin, double *GeodLat, double *GeodLong, double *GeodHeight ) { - +void Lgm_WGS84_to_GEOD(Lgm_Vector* uin, + double* GeodLat, + double* GeodLong, + double* GeodHeight) { Lgm_Vector u; - double r, r2, z2, F, G, G2, G3, c, s, tt, tt2, P; - double Q, ro, U, V, zo; + double r, r2, z2, F, G, G2, G3, c, s, tt, tt2, P; + double Q, ro, U, V, zo; u = *uin; - Lgm_ScaleVector( &u, WGS84_A ); // convert to km + Lgm_ScaleVector(&u, WGS84_A); // convert to km - r2 = u.x*u.x + u.y*u.y; + r2 = u.x * u.x + u.y * u.y; r = sqrt(r2); - z2 = u.z*u.z; - F = 54.0*WGS84_B2*z2; - G = r2 + WGS84_1mE2*z2 - WGS84_E2*WGS84_A2mB2; - G2 = G*G; G3 = G2*G; - c = (WGS84_E4*F*r2)/G3; - s = pow( 1.0 + c + sqrt(c*c + 2.0*c), M_OneThird ); - tt = s + 1.0/s + 1.0; tt2 = tt*tt; - P = F/( 3.0*tt2*G2 ); - - Q = sqrt( 1.0 + 2.0*WGS84_E4*P ); - ro = -(WGS84_E2*P*r)/(1.0+Q) + sqrt( (0.5*WGS84_A2)*(1.0+1.0/Q) - (WGS84_1mE2*P*z2)/(Q*(1.0+Q)) - 0.5*P*r2 ); - - tt = (r - WGS84_E2*ro); tt2 = tt*tt; - U = sqrt( tt2 + z2 ); - V = sqrt( tt2 + WGS84_1mE2*z2 ); - zo = (WGS84_B2*u.z)/(WGS84_A*V); - - *GeodLat = DegPerRad*atan( (u.z + WGS84_EP2*zo)/r ); // geodetic latitude - *GeodLong = DegPerRad*atan2( u.y, u.x ); // geodetic longitude (same as GEO) - *GeodHeight = U*( 1.0 - WGS84_B2/(WGS84_A*V)); // geodetic height (km) + z2 = u.z * u.z; + F = 54.0 * WGS84_B2 * z2; + G = r2 + WGS84_1mE2 * z2 - WGS84_E2 * WGS84_A2mB2; + G2 = G * G; + G3 = G2 * G; + c = (WGS84_E4 * F * r2) / G3; + s = pow(1.0 + c + sqrt(c * c + 2.0 * c), M_OneThird); + tt = s + 1.0 / s + 1.0; + tt2 = tt * tt; + P = F / (3.0 * tt2 * G2); + + Q = sqrt(1.0 + 2.0 * WGS84_E4 * P); + ro = -(WGS84_E2 * P * r) / (1.0 + Q) + + sqrt((0.5 * WGS84_A2) * (1.0 + 1.0 / Q) - + (WGS84_1mE2 * P * z2) / (Q * (1.0 + Q)) - 0.5 * P * r2); + + tt = (r - WGS84_E2 * ro); + tt2 = tt * tt; + U = sqrt(tt2 + z2); + V = sqrt(tt2 + WGS84_1mE2 * z2); + zo = (WGS84_B2 * u.z) / (WGS84_A * V); + + *GeodLat = + DegPerRad * atan((u.z + WGS84_EP2 * zo) / r); // geodetic latitude + *GeodLong = + DegPerRad * atan2(u.y, u.x); // geodetic longitude (same as GEO) + *GeodHeight = U * (1.0 - WGS84_B2 / (WGS84_A * V)); // geodetic height (km) } // same as above, but just returns height (saves a few expensive atans) -void Lgm_WGS84_to_GeodHeight( Lgm_Vector *uin, double *GeodHeight ) { - +void Lgm_WGS84_to_GeodHeight(Lgm_Vector* uin, double* GeodHeight) { Lgm_Vector u; - double r, r2, z2, F, G, G2, G3, c, s, tt, tt2, P; - double Q, ro, U, V, zo; + double r, r2, z2, F, G, G2, G3, c, s, tt, tt2, P; + double Q, ro, U, V, zo; u = *uin; - Lgm_ScaleVector( &u, WGS84_A ); // convert to km + Lgm_ScaleVector(&u, WGS84_A); // convert to km - r2 = u.x*u.x + u.y*u.y; + r2 = u.x * u.x + u.y * u.y; r = sqrt(r2); - z2 = u.z*u.z; - F = 54.0*WGS84_B2*z2; - G = r2 + WGS84_1mE2*z2 - WGS84_E2*WGS84_A2mB2; - G2 = G*G; G3 = G2*G; - c = (WGS84_E4*F*r2)/G3; - s = pow( 1.0 + c + sqrt(c*c + 2.0*c), M_OneThird ); - tt = s + 1.0/s + 1.0; tt2 = tt*tt; - P = F/( 3.0*tt2*G2 ); - - Q = sqrt( 1.0 + 2.0*WGS84_E4*P ); - ro = -(WGS84_E2*P*r)/(1.0+Q) + sqrt( (0.5*WGS84_A2)*(1.0+1.0/Q) - (WGS84_1mE2*P*z2)/(Q*(1.0+Q)) - 0.5*P*r2 ); - - tt = (r - WGS84_E2*ro); tt2 = tt*tt; - U = sqrt( tt2 + z2 ); - V = sqrt( tt2 + WGS84_1mE2*z2 ); - zo = (WGS84_B2*u.z)/(WGS84_A*V); - - *GeodHeight = U*( 1.0 - WGS84_B2/(WGS84_A*V)); // geodetic height (km) + z2 = u.z * u.z; + F = 54.0 * WGS84_B2 * z2; + G = r2 + WGS84_1mE2 * z2 - WGS84_E2 * WGS84_A2mB2; + G2 = G * G; + G3 = G2 * G; + c = (WGS84_E4 * F * r2) / G3; + s = pow(1.0 + c + sqrt(c * c + 2.0 * c), M_OneThird); + tt = s + 1.0 / s + 1.0; + tt2 = tt * tt; + P = F / (3.0 * tt2 * G2); + + Q = sqrt(1.0 + 2.0 * WGS84_E4 * P); + ro = -(WGS84_E2 * P * r) / (1.0 + Q) + + sqrt((0.5 * WGS84_A2) * (1.0 + 1.0 / Q) - + (WGS84_1mE2 * P * z2) / (Q * (1.0 + Q)) - 0.5 * P * r2); + + tt = (r - WGS84_E2 * ro); + tt2 = tt * tt; + U = sqrt(tt2 + z2); + V = sqrt(tt2 + WGS84_1mE2 * z2); + zo = (WGS84_B2 * u.z) / (WGS84_A * V); + + *GeodHeight = U * (1.0 - WGS84_B2 / (WGS84_A * V)); // geodetic height (km) } - - /* * These rotuines are included here, just because its trivial * to do it here. */ -void Lgm_B_igrf_ctrans(Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c) { - - double st, ct, sp, cp; - double B_r, B_theta, B_phi; - double r, theta, phi; - Lgm_Vector w, Bgeo; - +void Lgm_B_igrf_ctrans(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double st, ct, sp, cp; + double B_r, B_theta, B_phi; + double r, theta, phi; + Lgm_Vector w, Bgeo; /* * Convert Coords to GEO */ - Lgm_Convert_Coords( v, &w, GSM_TO_WGS84, c ); - + Lgm_Convert_Coords(v, &w, GSM_TO_WGS84, c); /* - * compute GEO (WGS84) geocentric speherical coords. (r, theta, phi) theta is colat + * compute GEO (WGS84) geocentric speherical coords. (r, theta, phi) theta + * is colat */ -// w.x *= Re; w.x /= 6371.2; -// w.y *= Re; w.y /= 6371.2; -// w.z *= Re; w.z /= 6371.2; - r = sqrt(w.x*w.x + w.y*w.y + w.z*w.z ); - theta = acos( w.z / r ); - phi = atan2(w.y, w.x); - - - st = sin( theta ); ct = cos( theta ); - sp = sin( phi ); cp = cos( phi ); - + // w.x *= Re; w.x /= 6371.2; + // w.y *= Re; w.y /= 6371.2; + // w.z *= Re; w.z /= 6371.2; + r = sqrt(w.x * w.x + w.y * w.y + w.z * w.z); + theta = acos(w.z / r); + phi = atan2(w.y, w.x); + + st = sin(theta); + ct = cos(theta); + sp = sin(phi); + cp = cos(phi); /* * Compute spherical components of B in GEO (WGS84) */ - w.x = r; w.y = theta; w.z = phi; - Lgm_IGRF( &w, &Bgeo, c ); - B_r = Bgeo.x; B_theta = Bgeo.y; B_phi = Bgeo.z; - - + w.x = r; + w.y = theta; + w.z = phi; + Lgm_IGRF(&w, &Bgeo, c); + B_r = Bgeo.x; + B_theta = Bgeo.y; + B_phi = Bgeo.z; /* * Convert Bgeo to cartesian */ - Bgeo.x = B_r*st*cp + B_theta*ct*cp - B_phi*sp; - Bgeo.y = B_r*st*sp + B_theta*ct*sp + B_phi*cp; - Bgeo.z = B_r*ct - B_theta*st; + Bgeo.x = B_r * st * cp + B_theta * ct * cp - B_phi * sp; + Bgeo.y = B_r * st * sp + B_theta * ct * sp + B_phi * cp; + Bgeo.z = B_r * ct - B_theta * st; /* * Convert Coords to GSM */ - Lgm_Convert_Coords( &Bgeo, B, WGS84_TO_GSM, c ); - - + Lgm_Convert_Coords(&Bgeo, B, WGS84_TO_GSM, c); } -void Lgm_B_JensenCain1960_ctrans(Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c) { - - double st, ct, sp, cp; - double B_r, B_theta, B_phi; - double r, theta, phi; - Lgm_Vector w, Bgeo; - +void Lgm_B_JensenCain1960_ctrans(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double st, ct, sp, cp; + double B_r, B_theta, B_phi; + double r, theta, phi; + Lgm_Vector w, Bgeo; /* * Convert Coords to GEO */ - Lgm_Convert_Coords( v, &w, GSM_TO_WGS84, c ); - + Lgm_Convert_Coords(v, &w, GSM_TO_WGS84, c); /* - * compute GEO (WGS84) geocentric speherical coords. (r, theta, phi) theta is colat + * compute GEO (WGS84) geocentric speherical coords. (r, theta, phi) theta + * is colat */ - r = sqrt(w.x*w.x + w.y*w.y + w.z*w.z ); - theta = acos( w.z / r ); - phi = atan2(w.y, w.x); - - - st = sin( theta ); ct = cos( theta ); - sp = sin( phi ); cp = cos( phi ); + r = sqrt(w.x * w.x + w.y * w.y + w.z * w.z); + theta = acos(w.z / r); + phi = atan2(w.y, w.x); + st = sin(theta); + ct = cos(theta); + sp = sin(phi); + cp = cos(phi); /* * Compute spherical components of B in GEO (WGS84) */ - w.x = r; w.y = theta; w.z = phi; - Lgm_JensenCain1960( &w, &Bgeo, c ); - B_r = Bgeo.x; B_theta = Bgeo.y; B_phi = Bgeo.z; - - + w.x = r; + w.y = theta; + w.z = phi; + Lgm_JensenCain1960(&w, &Bgeo, c); + B_r = Bgeo.x; + B_theta = Bgeo.y; + B_phi = Bgeo.z; /* * Convert Bgeo to cartesian */ - Bgeo.x = B_r*st*cp + B_theta*ct*cp - B_phi*sp; - Bgeo.y = B_r*st*sp + B_theta*ct*sp + B_phi*cp; - Bgeo.z = B_r*ct - B_theta*st; + Bgeo.x = B_r * st * cp + B_theta * ct * cp - B_phi * sp; + Bgeo.y = B_r * st * sp + B_theta * ct * sp + B_phi * cp; + Bgeo.z = B_r * ct - B_theta * st; /* * Convert Coords to GSM */ - Lgm_Convert_Coords( &Bgeo, B, WGS84_TO_GSM, c ); - - + Lgm_Convert_Coords(&Bgeo, B, WGS84_TO_GSM, c); } - - -void Lgm_B_cdip_ctrans(Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c) { - - double x_sm, y_sm, z_sm; - double rho, theta, phi; - Lgm_Vector Bsm; - double B_rho, B_theta, B_phi; - double M, rho2, rho3; - double cp, sp, ct, st; +void Lgm_B_cdip_ctrans(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double x_sm, y_sm, z_sm; + double rho, theta, phi; + Lgm_Vector Bsm; + double B_rho, B_theta, B_phi; + double M, rho2, rho3; + double cp, sp, ct, st; M = c->M_cd; /* * compute SM coords from GSM coords */ - x_sm = v->x*c->cos_psi - v->z*c->sin_psi; + x_sm = v->x * c->cos_psi - v->z * c->sin_psi; y_sm = v->y; - z_sm = v->x*c->sin_psi + v->z*c->cos_psi; - + z_sm = v->x * c->sin_psi + v->z * c->cos_psi; /* * convert x_sm, y_sm, and, z_sm to spherical coords. */ - rho = sqrt(x_sm*x_sm + y_sm*y_sm + z_sm*z_sm); - phi = atan2(y_sm, x_sm); + rho = sqrt(x_sm * x_sm + y_sm * y_sm + z_sm * z_sm); + phi = atan2(y_sm, x_sm); theta = acos(z_sm / rho); - /* * compute centered dipole field in spherical coords * i.e. (B_rho, B_theta, B_phi) */ - rho2 = rho*rho; - rho3 = rho*rho2; - cp = cos( phi ); - sp = sin( phi ); - ct = cos( theta ); - st = sin( theta ); - B_rho = -2.0*M*ct/rho3; - B_phi = 0.0; - B_theta = -1.0*M*st/rho3; - + rho2 = rho * rho; + rho3 = rho * rho2; + cp = cos(phi); + sp = sin(phi); + ct = cos(theta); + st = sin(theta); + B_rho = -2.0 * M * ct / rho3; + B_phi = 0.0; + B_theta = -1.0 * M * st / rho3; /* * Transform (B_rho, B_theta, B_phi) -> (B_xsm, B_ysm, B_zsm) (still SM) */ - Bsm.x = B_rho*st*cp + B_theta*ct*cp; - Bsm.y = B_rho*st*sp + B_theta*ct*sp; - Bsm.z = B_rho*ct - B_theta*st; - + Bsm.x = B_rho * st * cp + B_theta * ct * cp; + Bsm.y = B_rho * st * sp + B_theta * ct * sp; + Bsm.z = B_rho * ct - B_theta * st; /* * Transform (B_xsm, B_ysm, B_zsm) -> (B_x, B_y, B_z) i.e. trans. to GSM */ - B->x = Bsm.x*c->cos_psi + Bsm.z*c->sin_psi; - B->y = Bsm.y; - B->z = -Bsm.x*c->sin_psi + Bsm.z*c->cos_psi; - - + B->x = Bsm.x * c->cos_psi + Bsm.z * c->sin_psi; + B->y = Bsm.y; + B->z = -Bsm.x * c->sin_psi + Bsm.z * c->cos_psi; } - -void Lgm_B_edip_ctrans(Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c) { - - double x_sm, y_sm, z_sm; - double x_ed, y_ed, z_ed; - double rho, theta, phi; - Lgm_Vector Bsm, ED_sm, ED_geo; - double B_rho, B_theta, B_phi; - double M, rho2, rho3; - double cp, sp, ct, st; +void Lgm_B_edip_ctrans(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double x_sm, y_sm, z_sm; + double x_ed, y_ed, z_ed; + double rho, theta, phi; + Lgm_Vector Bsm, ED_sm, ED_geo; + double B_rho, B_theta, B_phi; + double M, rho2, rho3; + double cp, sp, ct, st; M = c->M_cd; /* * compute SM coords from GSM coords */ - x_sm = v->x*c->cos_psi - v->z*c->sin_psi; + x_sm = v->x * c->cos_psi - v->z * c->sin_psi; y_sm = v->y; - z_sm = v->x*c->sin_psi + v->z*c->cos_psi; - + z_sm = v->x * c->sin_psi + v->z * c->cos_psi; /* * Convert (c->ED_x0, c->ED_x0, c->ED_x0) to SM */ - ED_geo.x = c->ED_x0; ED_geo.y = c->ED_y0; ED_geo.z = c->ED_z0; - Lgm_Convert_Coords( &ED_geo, &ED_sm, WGS84_TO_SM, c ); - + ED_geo.x = c->ED_x0; + ED_geo.y = c->ED_y0; + ED_geo.z = c->ED_z0; + Lgm_Convert_Coords(&ED_geo, &ED_sm, WGS84_TO_SM, c); /* * compute ED coords from SM coords (i.e. offset the dipole) @@ -1758,110 +2098,111 @@ void Lgm_B_edip_ctrans(Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c) { y_ed = y_sm - ED_sm.y; z_ed = z_sm - ED_sm.z; - /* * convert to spherical coords. */ - rho = sqrt(x_ed*x_ed + y_ed*y_ed + z_ed*z_ed); - phi = atan2(y_ed, x_ed); + rho = sqrt(x_ed * x_ed + y_ed * y_ed + z_ed * z_ed); + phi = atan2(y_ed, x_ed); theta = acos(z_ed / rho); - /* * compute centered dipole field in spherical coords * i.e. (B_rho, B_theta, B_phi) */ - rho2 = rho*rho; - rho3 = rho*rho2; - cp = cos( phi ); - sp = sin( phi ); - ct = cos( theta ); - st = sin( theta ); - B_rho = -2.0*M*ct/rho3; - B_phi = 0.0; - B_theta = -1.0*M*st/rho3; - + rho2 = rho * rho; + rho3 = rho * rho2; + cp = cos(phi); + sp = sin(phi); + ct = cos(theta); + st = sin(theta); + B_rho = -2.0 * M * ct / rho3; + B_phi = 0.0; + B_theta = -1.0 * M * st / rho3; /* * Transform (B_rho, B_theta, B_phi) -> (B_xsm, B_ysm, B_zsm) (still SM) */ - Bsm.x = B_rho*st*cp + B_theta*ct*cp; - Bsm.y = B_rho*st*sp + B_theta*ct*sp; - Bsm.z = B_rho*ct - B_theta*st; - + Bsm.x = B_rho * st * cp + B_theta * ct * cp; + Bsm.y = B_rho * st * sp + B_theta * ct * sp; + Bsm.z = B_rho * ct - B_theta * st; /* * Transform (B_xsm, B_ysm, B_zsm) -> (B_x, B_y, B_z) i.e. trans. to GSM */ - B->x = Bsm.x*c->cos_psi + Bsm.z*c->sin_psi; - B->y = Bsm.y; - B->z = -Bsm.x*c->sin_psi + Bsm.z*c->cos_psi; - - + B->x = Bsm.x * c->cos_psi + Bsm.z * c->sin_psi; + B->y = Bsm.y; + B->z = -Bsm.x * c->sin_psi + Bsm.z * c->cos_psi; } - /* * Compute the Julian Day number for the given date. * Julian Date is the number of days since noon of Jan 1 4713 B.C. */ -void Lgm_jd_to_ymdh ( double JD, long int *Date, int *year, int *month, int *day, double *UT ) { - - int I, A, B, C, D, E, y, G; - double F, m, d; - +void Lgm_jd_to_ymdh(double JD, + long int* Date, + int* year, + int* month, + int* day, + double* UT) { + int I, A, B, C, D, E, y, G; + double F, m, d; JD += 0.5; I = (int)JD; F = JD - (double)I; - if ( I > 2299160 ) { - A = (int)( ((double)I-1867216.25)/36524.25 ); - B = I + 1 + A - (int)( A/4 ); + if (I > 2299160) { + A = (int)(((double)I - 1867216.25) / 36524.25); + B = I + 1 + A - (int)(A / 4); } else { B = I; } C = B + 1524; - D = (int)( ((double)C - 122.1)/365.25 ); - E = (int)( 365.25 * D ); - G = (int)( (double)((C-E))/30.6001 ); - d = (double)(C - E) + F - (double)( (int)( 30.6001*G ) ); + D = (int)(((double)C - 122.1) / 365.25); + E = (int)(365.25 * D); + G = (int)((double)((C - E)) / 30.6001); + d = (double)(C - E) + F - (double)((int)(30.6001 * G)); - if ( (double)G < 13.5 ) { + if ((double)G < 13.5) { m = (double)G - 1.0; } else { m = (double)G - 13.0; } - if ( m > 2.5 ) { + if (m > 2.5) { y = D - 4716; } else { y = D - 4715; } *day = (int)d; - *UT = (d - *day)*24.0; + *UT = (d - *day) * 24.0; *month = (int)m; *year = y; - *Date = *year*10000 + *month*100 + *day; + *Date = *year * 10000 + *month * 100 + *day; } //? -void Lgm_mjd_to_ymdh( double MJD, long int *Date, int *year, int *month, int *day, double *UT ) { - Lgm_jd_to_ymdh( MJD+2400000.5, Date, year, month, day, UT ); +void Lgm_mjd_to_ymdh(double MJD, + long int* Date, + int* year, + int* month, + int* day, + double* UT) { + Lgm_jd_to_ymdh(MJD + 2400000.5, Date, year, month, day, UT); } - - /* * milli-seconds are rounded up to nearest whole milli-second */ -void Lgm_UT_to_hmsms( double UT, int *Hour, int *Min, int *Sec, int *MilliSec ) { - - *Hour = (int)UT; UT = (UT - *Hour)*60.0; - *Min = (int)UT; UT = (UT - *Min)*60.0; - *Sec = (int)UT; UT = (UT - *Sec)*1000.0; - *MilliSec = (int)(UT+0.5); +void Lgm_UT_to_hmsms(double UT, int* Hour, int* Min, int* Sec, int* MilliSec) { + *Hour = (int)UT; + UT = (UT - *Hour) * 60.0; + *Min = (int)UT; + UT = (UT - *Min) * 60.0; + *Sec = (int)UT; + UT = (UT - *Sec) * 1000.0; + *MilliSec = (int)(UT + 0.5); if (*MilliSec == 1000) { *MilliSec -= 1000; @@ -1869,67 +2210,63 @@ void Lgm_UT_to_hmsms( double UT, int *Hour, int *Min, int *Sec, int *MilliSec ) } if (*Sec == 60) { - *Sec = *Sec-60; + *Sec = *Sec - 60; *Min += 1; } - if ( *Min == 60 ) { + if (*Min == 60) { *Min -= 60.0; *Hour += 1; } } - /* * seconds are rounded up to nearest whole second */ -void Lgm_UT_to_HMS( double UT, int *HH, int *MM, int *SS ) { +void Lgm_UT_to_HMS(double UT, int* HH, int* MM, int* SS) { + int Days, Hours, Minutes; + double Seconds; - int Days, Hours, Minutes; - double Seconds; + Seconds = UT * 3600.0; - Seconds = UT*3600.0; + Days = (int)(Seconds / 86400.0); + Seconds -= Days * 86400.0; - Days = (int)(Seconds/86400.0); - Seconds -= Days*86400.0; + Hours = (int)(Seconds / 3600.0); + Seconds -= Hours * 3600.0; - Hours = (int)(Seconds/3600.0); - Seconds -= Hours*3600.0; - - Minutes = (int)(Seconds/60.0); - Seconds -= Minutes*60.0; + Minutes = (int)(Seconds / 60.0); + Seconds -= Minutes * 60.0; *HH = Hours; *MM = Minutes; - *SS = (int)(Seconds+0.5); - + *SS = (int)(Seconds + 0.5); } -void Lgm_UT_to_HMSd( double UT, int *sgn, int *HH, int *MM, double *SS ) { - - int Days, Hours, Minutes; - double Seconds; +void Lgm_UT_to_HMSd(double UT, int* sgn, int* HH, int* MM, double* SS) { + int Days, Hours, Minutes; + double Seconds; *sgn = (UT < 0.0) ? -1 : 1; UT = fabs(UT); - Seconds = UT*3600.0; + Seconds = UT * 3600.0; - Days = (int)(Seconds/86400.0); - Seconds -= Days*86400.0; + Days = (int)(Seconds / 86400.0); + Seconds -= Days * 86400.0; - Hours = (int)(Seconds/3600.0); - Seconds -= Hours*3600.0; + Hours = (int)(Seconds / 3600.0); + Seconds -= Hours * 3600.0; - Minutes = (int)(Seconds/60.0); - Seconds -= Minutes*60.0; -//printf("Hours, Minutes, Seconds = %d %d %lf\n", Hours, Minutes, Seconds); + Minutes = (int)(Seconds / 60.0); + Seconds -= Minutes * 60.0; + // printf("Hours, Minutes, Seconds = %d %d %lf\n", Hours, Minutes, Seconds); - if ( Seconds >= 60.0 ) { + if (Seconds >= 60.0) { Seconds = 0.0; Minutes += 1; } - if ( Minutes >= 60.0 ) { + if (Minutes >= 60.0) { Minutes = 0; Hours += 1; } @@ -1937,89 +2274,76 @@ void Lgm_UT_to_HMSd( double UT, int *sgn, int *HH, int *MM, double *SS ) { *HH = Hours; *MM = Minutes; *SS = Seconds; -//printf("Hours, Minutes, Seconds = %d %d %lf\n", Hours, Minutes, Seconds); - + // printf("Hours, Minutes, Seconds = %d %d %lf\n", Hours, Minutes, Seconds); } -void Lgm_D_to_DMS( double D, int *DD, int *MM, int *SS ) { - - int sgn; - double f; +void Lgm_D_to_DMS(double D, int* DD, int* MM, int* SS) { + int sgn; + double f; sgn = (D < 0.0) ? -1 : 1; D = fabs(D); - *DD = (int)D; // degrees + *DD = (int)D; // degrees - f = (D - (double)*DD)*60.0; // decimal minutes - *MM = (int)f; // number of whole minutes + f = (D - (double)*DD) * 60.0; // decimal minutes + *MM = (int)f; // number of whole minutes - f = (f - (double)*MM)*60.0; // decimal seconds - *SS = (int)(f+0.5); + f = (f - (double)*MM) * 60.0; // decimal seconds + *SS = (int)(f + 0.5); - if ( *SS == 60 ){ + if (*SS == 60) { *SS = 0; ++(*MM); } - if ( *MM == 60 ){ + if (*MM == 60) { *MM = 0; ++(*DD); } - - - - *DD *= sgn; // put sign back onto whole degrees part only - + *DD *= sgn; // put sign back onto whole degrees part only } - // return a decimal degree broken down int whole degrees, whole arc-minutes and // decimal arc-seconds. Also return the sign of the original number. -void Lgm_D_to_DMSd( double D, int *sgn, int *DD, int *MM, double *SS ) { - - double f; +void Lgm_D_to_DMSd(double D, int* sgn, int* DD, int* MM, double* SS) { + double f; *sgn = (D < 0.0) ? -1 : 1; D = fabs(D); - *DD = (int)D; // degrees + *DD = (int)D; // degrees - f = (D - (double)*DD)*60.0; // decimal minutes - *MM = (int)f; // number of whole minutes + f = (D - (double)*DD) * 60.0; // decimal minutes + *MM = (int)f; // number of whole minutes - f = (f - (double)*MM)*60.0; // decimal seconds + f = (f - (double)*MM) * 60.0; // decimal seconds *SS = f; - } +double Lgm_GetCurrentJD(Lgm_CTrans* c) { + time_t CurrentTime; + struct tm tp; + double UTC, JD; -double Lgm_GetCurrentJD( Lgm_CTrans *c ){ - - time_t CurrentTime; - struct tm tp; - double UTC, JD; - - - CurrentTime = time( NULL ); - gmtime_r( &CurrentTime, &tp ); - UTC = (double)(tp.tm_hour + tp.tm_min/60.0 + tp.tm_sec/3600.0); - JD = Lgm_JD( tp.tm_year+1900, tp.tm_mon+1, tp.tm_mday, UTC, LGM_TIME_SYS_UTC, c ); - - return( JD ); + CurrentTime = time(NULL); + gmtime_r(&CurrentTime, &tp); + UTC = (double)(tp.tm_hour + tp.tm_min / 60.0 + tp.tm_sec / 3600.0); + JD = Lgm_JD(tp.tm_year + 1900, tp.tm_mon + 1, tp.tm_mday, UTC, + LGM_TIME_SYS_UTC, c); + return (JD); } -double Lgm_GetCurrentMJD( Lgm_CTrans *c ){ - return( Lgm_GetCurrentJD( c ) - 2400000.5 ); +double Lgm_GetCurrentMJD(Lgm_CTrans* c) { + return (Lgm_GetCurrentJD(c) - 2400000.5); } - // types out hours/minutes/seconds with unicode characters. -void Lgm_Print_HMS( double d ){ +void Lgm_Print_HMS(double d) { int HH, MM, SS; - Lgm_UT_to_HMS( d, &HH, &MM, &SS ); + Lgm_UT_to_HMS(d, &HH, &MM, &SS); printf("%02d\u02b0 %02d\u1d50 %02d\u02e2", HH, MM, SS); } /* @@ -2033,91 +2357,127 @@ void Lgm_Print_HMS( double d ){ * Controls how many decimals to print for the seconds. * Max of 20 (-- although prob more than machine prec.) */ -void Lgm_Print_HMSdp( double d, int UnicodeHMS, int p ){ - int HH, MM, SS, sgn; - double S, SFRAC; - char SecFracStr[30]; - - - Lgm_UT_to_HMSd( d, &sgn, &HH, &MM, &S ); - -//printf("HH, MM, S = %d %d %.20lf\n", HH, MM, S); - S = fabs(S)+pow(10.0, -1.0-p ); - SS = (int)S; - SFRAC = S-(double)SS; -//printf("HH, MM, S = %d %d %.20lf\n", HH, MM, S); +void Lgm_Print_HMSdp(double d, int UnicodeHMS, int p) { + int HH, MM, SS, sgn; + double S, SFRAC; + char SecFracStr[30]; + Lgm_UT_to_HMSd(d, &sgn, &HH, &MM, &S); -//printf("S = %lf SFRAC = %lf\n", S, SFRAC); - if (( p <= 0 ) && ( SFRAC >= 0.5)) { SS += 1; } + // printf("HH, MM, S = %d %d %.20lf\n", HH, MM, S); + S = fabs(S) + pow(10.0, -1.0 - p); + SS = (int)S; + SFRAC = S - (double)SS; + // printf("HH, MM, S = %d %d %.20lf\n", HH, MM, S); -//printf("S = %lf\n", S); + // printf("S = %lf SFRAC = %lf\n", S, SFRAC); + if ((p <= 0) && (SFRAC >= 0.5)) { + SS += 1; + } - sprintf( SecFracStr, "%.*lf", (p>=20)?20:p, SFRAC ); - if (SS==60) { SS=0; ++MM; } - if (MM==60) { MM=0; ++HH; } + // printf("S = %lf\n", S); + sprintf(SecFracStr, "%.*lf", (p >= 20) ? 20 : p, SFRAC); + if (SS == 60) { + SS = 0; + ++MM; + } + if (MM == 60) { + MM = 0; + ++HH; + } // probably a cleaner way to do this(?) - if ( p <= 0 ) { - if ( UnicodeHMS ) { - if (sgn<0) printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2", HH, MM, SS ); - else printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2", HH, MM, SS ); + if (p <= 0) { + if (UnicodeHMS) { + if (sgn < 0) + printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2", HH, MM, SS); + else + printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2", HH, MM, SS); } else { - if (sgn<0) printf("-%02d:%02d:%02d", HH, MM, SS ); - else printf(" %02d:%02d:%02d", HH, MM, SS ); + if (sgn < 0) + printf("-%02d:%02d:%02d", HH, MM, SS); + else + printf(" %02d:%02d:%02d", HH, MM, SS); } } else { - if ( UnicodeHMS ) { - if (sgn<0) printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2.%s", HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2.%s", HH, MM, SS, strstr(SecFracStr, ".")+1 ); + if (UnicodeHMS) { + if (sgn < 0) + printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2.%s", HH, MM, SS, + strstr(SecFracStr, ".") + 1); + else + printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2.%s", HH, MM, SS, + strstr(SecFracStr, ".") + 1); } else { - if (sgn<0) printf("-%02d:%02d:%02d.%s", HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else printf(" %02d:%02d:%02d.%s", HH, MM, SS, strstr(SecFracStr, ".")+1 ); + if (sgn < 0) + printf("-%02d:%02d:%02d.%s", HH, MM, SS, + strstr(SecFracStr, ".") + 1); + else + printf(" %02d:%02d:%02d.%s", HH, MM, SS, + strstr(SecFracStr, ".") + 1); } } - } - // types out hours/minutes/seconds with unicode characters. // does decimals on the seconds -void Lgm_Print_HMSd( double d ){ +void Lgm_Print_HMSd(double d) { int HH, MM, SS, MS, sgn; double S; - Lgm_UT_to_HMSd( d, &sgn, &HH, &MM, &S ); + Lgm_UT_to_HMSd(d, &sgn, &HH, &MM, &S); S = fabs(S); SS = (int)S; - MS = (int)((S-(double)SS)*1000.0+0.5); - if (MS==1000){ MS=0; ++SS; } - if (SS==60) { SS=0; ++MM; } - if (MM==60) { MM=0; ++HH; } - if (sgn<0) printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2.%03d", HH, MM, SS, MS); - else printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2.%03d", HH, MM, SS, MS); - + MS = (int)((S - (double)SS) * 1000.0 + 0.5); + if (MS == 1000) { + MS = 0; + ++SS; + } + if (SS == 60) { + SS = 0; + ++MM; + } + if (MM == 60) { + MM = 0; + ++HH; + } + if (sgn < 0) + printf("-%02d\u02b0 %02d\u1d50 %02d\u02e2.%03d", HH, MM, SS, MS); + else + printf(" %02d\u02b0 %02d\u1d50 %02d\u02e2.%03d", HH, MM, SS, MS); } // types out degrees/arc-minutes/arc-seconds with unicode characters. -void Lgm_Print_DMS( double d ){ +void Lgm_Print_DMS(double d) { int HH, MM, SS; - Lgm_D_to_DMS( d, &HH, &MM, &SS ); + Lgm_D_to_DMS(d, &HH, &MM, &SS); printf("%02d\u00b0 %02d\u2032 %02d\u2033", HH, MM, SS); } // types out degrees/arc-minutes/arc-seconds with unicode characters. // does decimals on the arc-seconds -void Lgm_Print_DMSd( double d ){ +void Lgm_Print_DMSd(double d) { int DD, MM, SS, MS, sgn; double S; - Lgm_D_to_DMSd( d, &sgn, &DD, &MM, &S ); + Lgm_D_to_DMSd(d, &sgn, &DD, &MM, &S); SS = (int)S; - MS = (int)((S-(double)SS)*1000.0+0.5); - if (MS==1000){ MS=0; ++SS; } - if (SS==60) { SS=0; ++MM; } - if (MM==60) { MM=0; ++DD; } + MS = (int)((S - (double)SS) * 1000.0 + 0.5); + if (MS == 1000) { + MS = 0; + ++SS; + } + if (SS == 60) { + SS = 0; + ++MM; + } + if (MM == 60) { + MM = 0; + ++DD; + } - if ( sgn < 0 ) printf("-%02d\u00b0 %02d\u2032 %02d\u2033.%03d", DD, MM, SS, MS); - else printf(" %02d\u00b0 %02d\u2032 %02d\u2033.%03d", DD, MM, SS, MS); + if (sgn < 0) + printf("-%02d\u00b0 %02d\u2032 %02d\u2033.%03d", DD, MM, SS, MS); + else + printf(" %02d\u00b0 %02d\u2032 %02d\u2033.%03d", DD, MM, SS, MS); } /* @@ -2126,32 +2486,36 @@ void Lgm_Print_DMSd( double d ){ * longitude of the point in question and the magnetic longitude of the * anti-solar point. Its coord system dependent. */ -void Lgm_CDMAG_to_R_MLAT_MLON_MLT( Lgm_Vector *u, double *R, double *MLAT, double *MLON, double *MLT, Lgm_CTrans *c ) { - - double SunMlon; - Lgm_Vector v, w; +void Lgm_CDMAG_to_R_MLAT_MLON_MLT(Lgm_Vector* u, + double* R, + double* MLAT, + double* MLON, + double* MLT, + Lgm_CTrans* c) { + double SunMlon; + Lgm_Vector v, w; // Get R and MLAT - w = *u; // copy vector -- so we dont normalize original - *R = Lgm_NormalizeVector( &w ); - *MLAT = asin( u->z/(*R) )*DegPerRad; + w = *u; // copy vector -- so we dont normalize original + *R = Lgm_NormalizeVector(&w); + *MLAT = asin(u->z / (*R)) * DegPerRad; // Find Longitude of Sun vector in CDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_CDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_CDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 // Find Longitude of input vector in CDMAG coords. - *MLON = atan2( u->y, u->x )*DegPerRad; // in range -180 to 180 - if (*MLON < 0.0) *MLON += 360.0; // puts into range 0 to 360 + *MLON = atan2(u->y, u->x) * DegPerRad; // in range -180 to 180 + if (*MLON < 0.0) + *MLON += 360.0; // puts into range 0 to 360 // Compute MLT (add 24 before the fmod so we dont get negative). - *MLT = fmod( (*MLON-SunMlon)/15.0+24.0, 24.0 ); - + *MLT = fmod((*MLON - SunMlon) / 15.0 + 24.0, 24.0); } - /* * returns cartesian vector in CDMAG coords. * MLT in decimal hours. @@ -2160,57 +2524,62 @@ void Lgm_CDMAG_to_R_MLAT_MLON_MLT( Lgm_Vector *u, double *R, double *MLAT, doubl * R in Re * */ -void Lgm_R_MLAT_MLT_to_CDMAG( double R, double MLAT, double MLT, Lgm_Vector *u, Lgm_CTrans *c ) { - - Lgm_Vector v; - double Mlon, SunMlon, phi, the, ct; +void Lgm_R_MLAT_MLT_to_CDMAG(double R, + double MLAT, + double MLT, + Lgm_Vector* u, + Lgm_CTrans* c) { + Lgm_Vector v; + double Mlon, SunMlon, phi, the, ct; // Find Longitude of Sun vector in CDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_CDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_CDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 - Mlon = (MLT*15.0 + SunMlon); + Mlon = (MLT * 15.0 + SunMlon); phi = Mlon * RadPerDeg; - the = MLAT*RadPerDeg; - ct = cos( the ); - - - u->x = R*cos( phi )*ct; - u->y = R*sin( phi )*ct; - u->z = R*sin( the ); + the = MLAT * RadPerDeg; + ct = cos(the); + u->x = R * cos(phi) * ct; + u->y = R * sin(phi) * ct; + u->z = R * sin(the); } - - /* * Given Cartesian EDMAG vector, convert to R, MLAT, MLON, MLT */ -void Lgm_EDMAG_to_R_MLAT_MLON_MLT( Lgm_Vector *u, double *R, double *MLAT, double *MLON, double *MLT, Lgm_CTrans *c ) { - - double SunMlon; - Lgm_Vector v, w; +void Lgm_EDMAG_to_R_MLAT_MLON_MLT(Lgm_Vector* u, + double* R, + double* MLAT, + double* MLON, + double* MLT, + Lgm_CTrans* c) { + double SunMlon; + Lgm_Vector v, w; // Get R and MLAT - w = *u; // copy vector -- so we dont normalize original - *R = Lgm_NormalizeVector( &w ); - *MLAT = asin( u->z/(*R) )*DegPerRad; + w = *u; // copy vector -- so we dont normalize original + *R = Lgm_NormalizeVector(&w); + *MLAT = asin(u->z / (*R)) * DegPerRad; // Find Longitude of Sun vector in EDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_EDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_EDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 // Find Longitude of input vector in EDMAG coords. - *MLON = atan2( u->y, u->x )*DegPerRad; // in range -180 to 180 - if (*MLON < 0.0) *MLON += 360.0; // puts into range 0 to 360 + *MLON = atan2(u->y, u->x) * DegPerRad; // in range -180 to 180 + if (*MLON < 0.0) + *MLON += 360.0; // puts into range 0 to 360 // Compute MLT (add 24 before the fmod so we dont get negative). - *MLT = fmod( (*MLON-SunMlon)/15.0+24.0, 24.0 ); - + *MLT = fmod((*MLON - SunMlon) / 15.0 + 24.0, 24.0); } /* @@ -2219,154 +2588,175 @@ void Lgm_EDMAG_to_R_MLAT_MLON_MLT( Lgm_Vector *u, double *R, double *MLAT, doubl * MLAT in degrees. * MLT in decimal hours. */ -void Lgm_R_MLAT_MLT_to_EDMAG( double R, double MLAT, double MLT, Lgm_Vector *u, Lgm_CTrans *c ) { - - Lgm_Vector v; - double Mlon, SunMlon, phi, the, ct; +void Lgm_R_MLAT_MLT_to_EDMAG(double R, + double MLAT, + double MLT, + Lgm_Vector* u, + Lgm_CTrans* c) { + Lgm_Vector v; + double Mlon, SunMlon, phi, the, ct; // Find Longitude of Sun vector in EDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_EDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_EDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 - Mlon = (MLT*15.0 + SunMlon); + Mlon = (MLT * 15.0 + SunMlon); phi = Mlon * RadPerDeg; - the = MLAT*RadPerDeg; - ct = cos( the ); - - - u->x = R*cos( phi )*ct; - u->y = R*sin( phi )*ct; - u->z = R*sin( the ); + the = MLAT * RadPerDeg; + ct = cos(the); + u->x = R * cos(phi) * ct; + u->y = R * sin(phi) * ct; + u->z = R * sin(the); } - - /* * Convert GLAT/GLON to CDMAG MLAT/MLON/MLT */ -void Lgm_GLATLON_TO_CDMLATLONMLT( double GLAT, double GLON, double *MLAT, double *MLON, double *MLT, Lgm_CTrans *c ) { - - Lgm_Vector v, w, z; - double Mlon, SunMlon, phi, the, ct; +void Lgm_GLATLON_TO_CDMLATLONMLT(double GLAT, + double GLON, + double* MLAT, + double* MLON, + double* MLT, + Lgm_CTrans* c) { + Lgm_Vector v, w, z; + double Mlon, SunMlon, phi, the, ct; // Find Longitude of Sun vector in CDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_CDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_CDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 // Convert GLAT/GLON to cartesian (assume r==1) - phi = GLON*RadPerDeg; - the = GLAT*RadPerDeg; - ct = cos(the); - w.x = cos( phi )*ct; - w.y = sin( phi )*ct; - w.z = sin( the ); + phi = GLON * RadPerDeg; + the = GLAT * RadPerDeg; + ct = cos(the); + w.x = cos(phi) * ct; + w.y = sin(phi) * ct; + w.z = sin(the); // Convert to CDMAG - Lgm_Convert_Coords( &w, &z, WGS84_TO_CDMAG, c ); - *MLAT = asin( z.z )*DegPerRad; - *MLON = atan2( z.y, z.x )*DegPerRad; - if (*MLON < 0.0) *MLON += 360.0; // puts into range 0 to 360 + Lgm_Convert_Coords(&w, &z, WGS84_TO_CDMAG, c); + *MLAT = asin(z.z) * DegPerRad; + *MLON = atan2(z.y, z.x) * DegPerRad; + if (*MLON < 0.0) + *MLON += 360.0; // puts into range 0 to 360 // Compute MLT (add 24 before the fmod so we dont get negative). - *MLT = fmod( (*MLON-SunMlon)/15.0+24.0, 24.0 ); - + *MLT = fmod((*MLON - SunMlon) / 15.0 + 24.0, 24.0); } /* * Convert GLAT/GLON to EDMAG MLAT/MLON/MLT */ -void Lgm_GLATLON_TO_EDMLATLONMLT( double GLAT, double GLON, double *MLAT, double *MLON, double *MLT, Lgm_CTrans *c ) { - - Lgm_Vector v, w, z; - double Mlon, SunMlon, phi, the, ct; +void Lgm_GLATLON_TO_EDMLATLONMLT(double GLAT, + double GLON, + double* MLAT, + double* MLON, + double* MLT, + Lgm_CTrans* c) { + Lgm_Vector v, w, z; + double Mlon, SunMlon, phi, the, ct; // Find Longitude of Sun vector in CDMAG coords. - // And the Long thats 180deg. from it. (Because thats what MLT is reckoned from). - Lgm_Convert_Coords( &(c->Sun), &v, MOD_TO_EDMAG, c ); - SunMlon = atan2( v.y, v.x )*DegPerRad; // in range -180 to 180 - SunMlon += 180.0; // in range 0 to 360 + // And the Long thats 180deg. from it. (Because thats what MLT is reckoned + // from). + Lgm_Convert_Coords(&(c->Sun), &v, MOD_TO_EDMAG, c); + SunMlon = atan2(v.y, v.x) * DegPerRad; // in range -180 to 180 + SunMlon += 180.0; // in range 0 to 360 // Convert GLAT/GLON to cartesian (assume r==1) - phi = GLON*RadPerDeg; - the = GLAT*RadPerDeg; - ct = cos(the); - w.x = cos( phi )*ct; - w.y = sin( phi )*ct; - w.z = sin( the ); + phi = GLON * RadPerDeg; + the = GLAT * RadPerDeg; + ct = cos(the); + w.x = cos(phi) * ct; + w.y = sin(phi) * ct; + w.z = sin(the); // Convert to CDMAG - Lgm_Convert_Coords( &w, &z, WGS84_TO_EDMAG, c ); - *MLAT = asin( z.z )*DegPerRad; - *MLON = atan2( z.y, z.x )*DegPerRad; - if (*MLON < 0.0) *MLON += 360.0; // puts into range 0 to 360 + Lgm_Convert_Coords(&w, &z, WGS84_TO_EDMAG, c); + *MLAT = asin(z.z) * DegPerRad; + *MLON = atan2(z.y, z.x) * DegPerRad; + if (*MLON < 0.0) + *MLON += 360.0; // puts into range 0 to 360 // Compute MLT (add 24 before the fmod so we dont get negative). - *MLT = fmod( (*MLON-SunMlon)/15.0+24.0, 24.0 ); - + *MLT = fmod((*MLON - SunMlon) / 15.0 + 24.0, 24.0); } - -int MonthStrToNum( char *str ) { - char *p = Lgm_StrToLower( str, strlen(str) ); // force to lower case - if ( !strncmp( p, "jan", 3 ) ) { return( 1 ); } - else if ( !strncmp( p, "feb", 3 ) ) { return( 2 ); } - else if ( !strncmp( p, "mar", 3 ) ) { return( 3 ); } - else if ( !strncmp( p, "apr", 3 ) ) { return( 4 ); } - else if ( !strncmp( p, "may", 3 ) ) { return( 5 ); } - else if ( !strncmp( p, "jun", 3 ) ) { return( 6 ); } - else if ( !strncmp( p, "jul", 3 ) ) { return( 7 ); } - else if ( !strncmp( p, "aug", 3 ) ) { return( 8 ); } - else if ( !strncmp( p, "sep", 3 ) ) { return( 9 ); } - else if ( !strncmp( p, "oct", 3 ) ) { return( 10 ); } - else if ( !strncmp( p, "nov", 3 ) ) { return( 11 ); } - else if ( !strncmp( p, "dec", 3 ) ) { return( 12 ); } - else { return( LGM_ERROR ); } +int MonthStrToNum(char* str) { + char* p = Lgm_StrToLower(str, strlen(str)); // force to lower case + if (!strncmp(p, "jan", 3)) { + return (1); + } else if (!strncmp(p, "feb", 3)) { + return (2); + } else if (!strncmp(p, "mar", 3)) { + return (3); + } else if (!strncmp(p, "apr", 3)) { + return (4); + } else if (!strncmp(p, "may", 3)) { + return (5); + } else if (!strncmp(p, "jun", 3)) { + return (6); + } else if (!strncmp(p, "jul", 3)) { + return (7); + } else if (!strncmp(p, "aug", 3)) { + return (8); + } else if (!strncmp(p, "sep", 3)) { + return (9); + } else if (!strncmp(p, "oct", 3)) { + return (10); + } else if (!strncmp(p, "nov", 3)) { + return (11); + } else if (!strncmp(p, "dec", 3)) { + return (12); + } else { + return (LGM_ERROR); + } } - -char *Lgm_StrToLower( char *str, int nmax ) { - int n = 0; - char *p = str; - while ( (*p != '\0' ) && (nRA_sun + c->gmst * 15.0) * RadPerDeg; + delta = c->DEC_sun * RadPerDeg; + + sd = sin(delta); + cd = cos(delta); + sa = sin(alpha * RadPerDeg); + co = cos(omega); - double sd, cd, sa, co, sd2, A, B, C, A2; - double disc, s, u1, u2, phi1, phi2, phi3, phi4; - double delta, omega, L, GST, RA; + sd2 = sd * sd; - omega = (GLON - c->RA_sun + c->gmst*15.0)*RadPerDeg; - delta = c->DEC_sun*RadPerDeg; - + A = sd2 + cd * cd * co * co; + A2 = 2.0 * A; + B = -2.0 * sa * cd * co; + C = sa * sa - sd2; - sd = sin(delta); cd = cos(delta); - sa = sin(alpha*RadPerDeg); - co = cos(omega); - - sd2 = sd*sd; - - A = sd2 + cd*cd * co*co; A2 = 2.0*A; - B = -2.0*sa*cd*co; - C = sa*sa - sd2; - - disc = B*B - 4.0*A*C; - if ( disc >= 0.0 ){ - s = sqrt( disc ); - u1 = (-B + s)/A2; - u2 = (-B - s)/A2; + disc = B * B - 4.0 * A * C; + if (disc >= 0.0) { + s = sqrt(disc); + u1 = (-B + s) / A2; + u2 = (-B - s) / A2; } /* - * We cannot get the right value of phi from just cos(phi) alone. We also need sin(phi). - * sin(alpha) = sin(delta) sin(phi) + cos(delta)cos(phi)cos(omega) + * We cannot get the right value of phi from just cos(phi) alone. We also + * need sin(phi). sin(alpha) = sin(delta) sin(phi) + + * cos(delta)cos(phi)cos(omega) */ double SinPhi; - SinPhi = (sa - cd*u1*co)/sd; - phi1 = (fabs(SinPhi) <= 1.0) ? DegPerRad*atan2( SinPhi, u1 ) : LGM_FILL_VALUE; - SinPhi = (sa - cd*u2*co)/sd; - phi2 = (fabs(SinPhi) <= 1.0) ? DegPerRad*atan2( SinPhi, u2 ) : LGM_FILL_VALUE; - - if ( (phi1 > 90.0) || (phi1 < -90.0) ) { phi1 = LGM_FILL_VALUE; } - if ( (phi2 > 90.0) || (phi2 < -90.0) ) { phi2 = LGM_FILL_VALUE; } - - //printf("A. SinPhi = %g CosPhi = %g B, disc, A2, s = %g %g %g %g u1, u2 = %g %g phi1, phi2 = %lf %lf\n", SinPhi, u1, B, disc, A2, s, u1, u2, phi1, phi2); - + SinPhi = (sa - cd * u1 * co) / sd; + phi1 = + (fabs(SinPhi) <= 1.0) ? DegPerRad * atan2(SinPhi, u1) : LGM_FILL_VALUE; + SinPhi = (sa - cd * u2 * co) / sd; + phi2 = + (fabs(SinPhi) <= 1.0) ? DegPerRad * atan2(SinPhi, u2) : LGM_FILL_VALUE; + + if ((phi1 > 90.0) || (phi1 < -90.0)) { + phi1 = LGM_FILL_VALUE; + } + if ((phi2 > 90.0) || (phi2 < -90.0)) { + phi2 = LGM_FILL_VALUE; + } + // printf("A. SinPhi = %g CosPhi = %g B, disc, A2, s = %g %g %g %g u1, + // u2 = %g %g phi1, phi2 = %lf %lf\n", SinPhi, u1, B, disc, A2, s, u1, u2, + // phi1, phi2); /* * return min sort order */ - if ( (phi1 > -1e20) && (phi2 > -1e20) ) { - // Two valid roots. + if ((phi1 > -1e20) && (phi2 > -1e20)) { + // Two valid roots. *nRoots = 2; - if ( phi1 < phi2 ) { + if (phi1 < phi2) { GLAT[0] = phi1; GLAT[1] = phi2; } else { GLAT[0] = phi2; GLAT[1] = phi1; } - } else if ( (phi1 > -1e20) ) { + } else if ((phi1 > -1e20)) { // only phi1 is a valid root *nRoots = 1; GLAT[0] = phi1; GLAT[1] = LGM_FILL_VALUE; - } else if ( (phi2 > -1e20) ) { + } else if ((phi2 > -1e20)) { // only phi2 is a valid root *nRoots = 1; GLAT[0] = phi2; @@ -2465,7 +2869,5 @@ void Lgm_Terminator( double GLON, double *GLAT, int *nRoots, double alpha, Lgm_C GLAT[1] = LGM_FILL_VALUE; } - return; - } diff --git a/libLanlGeoMag/Lgm_Cgm.c b/libLanlGeoMag/Lgm_Cgm.c index 3880eb08d..e5958f2dd 100644 --- a/libLanlGeoMag/Lgm_Cgm.c +++ b/libLanlGeoMag/Lgm_Cgm.c @@ -3,13 +3,13 @@ * \brief Routines to convert to/from Corrected Geomagnetic Coordinates (CGM and CBM). * */ -#include -#include -#include "Lgm/Lgm_QuadPack.h" -#include "Lgm/Lgm_MagModelInfo.h" #include #include +#include +#include #include +#include "Lgm/Lgm_MagModelInfo.h" +#include "Lgm/Lgm_QuadPack.h" #define TRACE_TOL 1e-8 diff --git a/libLanlGeoMag/Lgm_ComputeLstarVersusPA.c b/libLanlGeoMag/Lgm_ComputeLstarVersusPA.c index 9e321f0e8..14127269b 100644 --- a/libLanlGeoMag/Lgm_ComputeLstarVersusPA.c +++ b/libLanlGeoMag/Lgm_ComputeLstarVersusPA.c @@ -4,21 +4,21 @@ * * */ -#include "Lgm/Lgm_MagModelInfo.h" -#include "Lgm/Lgm_LstarInfo.h" -#include "Lgm/Lgm_MagEphemInfo.h" #ifdef HAVE_CONFIG_H #include #endif #if USE_OPENMP #include #endif +#include #include #include -#include -#include #include -#include +#include +#include +#include "Lgm/Lgm_LstarInfo.h" +#include "Lgm/Lgm_MagEphemInfo.h" +#include "Lgm/Lgm_MagModelInfo.h" #define TRACE_TOL 1e-7 #define TRACE_TOL2 1e-10 diff --git a/libLanlGeoMag/Lgm_Coulomb.c b/libLanlGeoMag/Lgm_Coulomb.c index 560b98e92..d26cf85ad 100644 --- a/libLanlGeoMag/Lgm_Coulomb.c +++ b/libLanlGeoMag/Lgm_Coulomb.c @@ -1,14 +1,14 @@ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include #if USE_OPENMP #include #endif -#include "Lgm/Lgm_Coulomb.h" +#include +#include #include "Lgm/Lgm_Constants.h" +#include "Lgm/Lgm_Coulomb.h" diff --git a/libLanlGeoMag/Lgm_DateAndTime.c b/libLanlGeoMag/Lgm_DateAndTime.c index bcff2151d..ea411b15d 100644 --- a/libLanlGeoMag/Lgm_DateAndTime.c +++ b/libLanlGeoMag/Lgm_DateAndTime.c @@ -1,32 +1,29 @@ /*! \file Lgm_DateAndTime.c - * - * \brief Collection of routines for data and time calculations. (Also see rotuines in Lgm_CTrans.c). + * + * \brief Collection of routines for data and time calculations. (Also see + * routines in Lgm_CTrans.c). * */ -#ifdef HAVE_CONFIG_H -#include "config.h" +#ifdef HAVE_CONFIG_H +#include "config.h" #endif +#include #include #include -#include #include "Lgm/Lgm_CTrans.h" - - - - /* * returns 1 if the year is a leap year, 0 otherwise. */ int Lgm_LeapYear(int year) { - - if ((year%100 == 0)&&(year%400 != 0)) return(0); - else if (year%4 == 0) return(1); - else return(0); - + if ((year % 100 == 0) && (year % 400 != 0)) + return (0); + else if (year % 4 == 0) + return (1); + else + return (0); } - /*! * Routines for dealing with leap seconds. Also time conversions that require * knowledge about leap seconds. @@ -60,7 +57,7 @@ int Lgm_LeapYear(int year) { * dT -- different between TT and UT1 (i.e. dT = TT-UT1) * (this was 32.184s when TAI was introduced in 1958 -- hence the * definitions below). - * + * * * Related by: * @@ -72,11 +69,10 @@ int Lgm_LeapYear(int year) { * non-integral (leap seconds (werent invented yet?) * */ -double Lgm_GetLeapSeconds( double JD, Lgm_CTrans *c ) { - - Lgm_LeapSeconds *l; - int i; - double MJD, TAI_Minus_UTC = 0.0; +double Lgm_GetLeapSeconds(double JD, Lgm_CTrans* c) { + Lgm_LeapSeconds* l; + int i; + double MJD, TAI_Minus_UTC = 0.0; l = &(c->l); @@ -85,11 +81,12 @@ double Lgm_GetLeapSeconds( double JD, Lgm_CTrans *c ) { * Lgm_LeapSeconds structure. * Parse list in reverse order. */ - for (i=l->nLeapSecondDates-1; i>=0; i--) { - // do > and not >= here because the 86400th second is still before the leap second - if ( JD >= l->LeapSecondJDs[i] ) { + for (i = l->nLeapSecondDates - 1; i >= 0; i--) { + // do > and not >= here because the 86400th second is still before the + // leap second + if (JD >= l->LeapSecondJDs[i]) { TAI_Minus_UTC = l->LeapSeconds[i]; - return( TAI_Minus_UTC ); + return (TAI_Minus_UTC); } } @@ -98,35 +95,95 @@ double Lgm_GetLeapSeconds( double JD, Lgm_CTrans *c ) { */ // Different system (leap seconds introduced in 1972). Calculate MJD first. MJD = JD - 2400000.5; - if ( JD >= 2439887.5 ) TAI_Minus_UTC = 4.2131700 + (MJD-39126.0)*0.002592; // 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S - else if ( JD >= 2439126.5 ) TAI_Minus_UTC = 4.3131700 + (MJD-39126.0)*0.002592; // 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S - else if ( JD >= 2439004.5 ) TAI_Minus_UTC = 3.8401300 + (MJD-38761.0)*0.002592; // 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438820.5 ) TAI_Minus_UTC = 3.6401300 + (MJD-38761.0)*0.001296; // 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438942.5 ) TAI_Minus_UTC = 3.7401300 + (MJD-38761.0)*0.001296; // 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438761.5 ) TAI_Minus_UTC = 3.5401300 + (MJD-38761.0)*0.001296; // 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438639.5 ) TAI_Minus_UTC = 3.4401300 + (MJD-38761.0)*0.001296; // 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438395.5 ) TAI_Minus_UTC = 3.2401300 + (MJD-38761.0)*0.001296; // 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438486.5 ) TAI_Minus_UTC = 3.3401300 + (MJD-38761.0)*0.001296; // 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S - else if ( JD >= 2438334.5 ) TAI_Minus_UTC = 1.9458580 + (MJD-37665.0)*0.0011232; // 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232 S - else if ( JD >= 2437665.5 ) TAI_Minus_UTC = 1.8458580 + (MJD-37665.0)*0.0011232; // 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232 S - else if ( JD >= 2437300.5 ) TAI_Minus_UTC = 1.4228180 + (MJD-37300.0)*0.001296; // 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S - else if ( JD >= 2437512.5 ) TAI_Minus_UTC = 1.3728180 + (MJD-37300.0)*0.001296; // 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S - - return( TAI_Minus_UTC ); - + if (JD >= 2439887.5) + TAI_Minus_UTC = + 4.2131700 + + (MJD - 39126.0) * + 0.002592; // 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + + // (MJD - 39126.) X 0.002592 S + else if (JD >= 2439126.5) + TAI_Minus_UTC = + 4.3131700 + + (MJD - 39126.0) * + 0.002592; // 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + + // (MJD - 39126.) X 0.002592 S + else if (JD >= 2439004.5) + TAI_Minus_UTC = + 3.8401300 + + (MJD - 38761.0) * + 0.002592; // 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438820.5) + TAI_Minus_UTC = + 3.6401300 + + (MJD - 38761.0) * + 0.001296; // 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438942.5) + TAI_Minus_UTC = + 3.7401300 + + (MJD - 38761.0) * + 0.001296; // 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438761.5) + TAI_Minus_UTC = + 3.5401300 + + (MJD - 38761.0) * + 0.001296; // 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438639.5) + TAI_Minus_UTC = + 3.4401300 + + (MJD - 38761.0) * + 0.001296; // 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438395.5) + TAI_Minus_UTC = + 3.2401300 + + (MJD - 38761.0) * + 0.001296; // 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438486.5) + TAI_Minus_UTC = + 3.3401300 + + (MJD - 38761.0) * + 0.001296; // 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + + // (MJD - 38761.) X 0.001296 S + else if (JD >= 2438334.5) + TAI_Minus_UTC = + 1.9458580 + + (MJD - 37665.0) * + 0.0011232; // 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + + // (MJD - 37665.) X 0.0011232 S + else if (JD >= 2437665.5) + TAI_Minus_UTC = + 1.8458580 + + (MJD - 37665.0) * + 0.0011232; // 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + + // (MJD - 37665.) X 0.0011232 S + else if (JD >= 2437300.5) + TAI_Minus_UTC = + 1.4228180 + + (MJD - 37300.0) * + 0.001296; // 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + + // (MJD - 37300.) X 0.001296 S + else if (JD >= 2437512.5) + TAI_Minus_UTC = + 1.3728180 + + (MJD - 37300.0) * + 0.001296; // 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + + // (MJD - 37300.) X 0.001296 S + + return (TAI_Minus_UTC); } - - - /* * Returns a 1 if the given date is a LeapSecond date, 0 otherwise. I.e. -- a * date on which a leap second was added. */ -int Lgm_IsLeapSecondDay( long int Date, double *SecondsInDay, Lgm_CTrans *c ) { - - Lgm_LeapSeconds *l; - int i; +int Lgm_IsLeapSecondDay(long int Date, double* SecondsInDay, Lgm_CTrans* c) { + Lgm_LeapSeconds* l; + int i; l = &(c->l); @@ -134,76 +191,93 @@ int Lgm_IsLeapSecondDay( long int Date, double *SecondsInDay, Lgm_CTrans *c ) { * Parse list in reverse order. */ *SecondsInDay = 86400.0; - for (i=l->nLeapSecondDates-1; i>=0; i--) { - if ( Date == l->LeapSecondDates[i] ) { + for (i = l->nLeapSecondDates - 1; i >= 0; i--) { + if (Date == l->LeapSecondDates[i]) { if (i > 0) { - if ( (l->LeapSeconds[i] - l->LeapSeconds[i-1]) > 0.0) { + if ((l->LeapSeconds[i] - l->LeapSeconds[i - 1]) > 0.0) { *SecondsInDay = 86401.0; } else { - *SecondsInDay = 86399.0; // implies leap second deleted (this has never happened yet). + *SecondsInDay = 86399.0; // implies leap second deleted + // (this has never happened yet). } } - return(1); + return (1); } } - return(0); - + return (0); } - - - /* * Reads in the file containing leap second info and packs the results into a * Lgm_LeapSeconds Structure contained in the Lgm_CTrans structure. */ -int Lgm_LoadLeapSeconds( Lgm_CTrans *c ) { - - Lgm_LeapSeconds *l; - int i, n=0, N=50, Year, Month, Day; - char Line[513], LeapSecondFile[512]; - double JD, Time; - FILE *fp; +int Lgm_LoadLeapSeconds(Lgm_CTrans* c) { + Lgm_LeapSeconds* l; + int i, n = 0, N = 50, Year, Month, Day; + char Line[513], LeapSecondFile[512]; + double JD, Time; + FILE* fp; l = &(c->l); - sprintf( LeapSecondFile, "%s/%s", LGM_EOP_DATA_DIR, "/Lgm_LeapSecondDates.dat"); - //printf("File = %s\n", LeapSecondFile ); - - if ( (fp = fopen( LeapSecondFile, "r" )) != NULL ){ + sprintf(LeapSecondFile, "%s/%s", LGM_EOP_DATA_DIR, + "/Lgm_LeapSecondDates.dat"); + // printf("File = %s\n", LeapSecondFile ); + if ((fp = fopen(LeapSecondFile, "r")) != NULL) { l->nLeapSecondDates = 0; - l->LeapSecondDates = (long int *) malloc( N*sizeof(long int) ); - l->LeapSecondJDs = (double *) malloc( N*sizeof(double) ); - l->LeapSeconds = (double *) malloc( N*sizeof(double) ); - + l->LeapSecondDates = (long int*)malloc(N * sizeof(long int)); + l->LeapSecondJDs = (double*)malloc(N * sizeof(double)); + l->LeapSeconds = (double*)malloc(N * sizeof(double)); + // read off header - for (i=0;i<17; i++) fgets( Line, 512, fp ); + for (i = 0; i < 17; i++) + if (fgets(Line, 512, fp) == NULL) { + // We have reached EOF and failed to read... + printf( + "Lgm_LoadLeapSeconds: Reached EOF before header was " + "complete\n"); + fclose(fp); + return (LGM_ERROR); + } // read off data - while ( fscanf( fp, "%ld %lf %lf", &l->LeapSecondDates[n], &l->LeapSecondJDs[n], &l->LeapSeconds[n] ) != EOF) { - - //printf("l->LeapSecondDates[%d] = %ld, l->LeapSecondJDs[%d] = %lf, l->LeapSeconds[%d] = %g\n", - // n, l->LeapSecondDates[n], n, l->LeapSecondJDs[n], n, l->LeapSeconds[n] ); - ++n; + while (fscanf(fp, "%ld %lf %lf", &l->LeapSecondDates[n], + &l->LeapSecondJDs[n], &l->LeapSeconds[n]) != EOF) { + // printf("l->LeapSecondDates[%d] = %ld, l->LeapSecondJDs[%d] = %lf, + // l->LeapSeconds[%d] = %g\n", + // n, l->LeapSecondDates[n], n, l->LeapSecondJDs[n], n, + // l->LeapSeconds[n] ); + ++n; // increase number of elements if needed - if ( n>(N-1) ){ - N = (int)(N*1.2); - if ( (l->LeapSecondDates = (long int *)realloc( (void *)l->LeapSecondDates, N*sizeof(long int) )) == NULL ) { - printf("Lgm_LoadLeapSeconds: Memory allocation problem (in realloc)\n"); + if (n > (N - 1)) { + N = (int)(N * 1.2); + if ((l->LeapSecondDates = (long int*)realloc( + (void*)l->LeapSecondDates, N * sizeof(long int))) == + NULL) { + printf( + "Lgm_LoadLeapSeconds: Memory allocation problem (in " + "realloc)\n"); fclose(fp); - return(LGM_ERROR); + return (LGM_ERROR); } - if ( (l->LeapSecondJDs = (double *)realloc( (void *)l->LeapSecondJDs, N*sizeof(double) )) == NULL ) { - printf("Lgm_LoadLeapSeconds: Memory allocation problem (in realloc)\n"); + if ((l->LeapSecondJDs = (double*)realloc( + (void*)l->LeapSecondJDs, N * sizeof(double))) == + NULL) { + printf( + "Lgm_LoadLeapSeconds: Memory allocation problem (in " + "realloc)\n"); fclose(fp); - return(LGM_ERROR); + return (LGM_ERROR); } - if ( (l->LeapSeconds = (double *)realloc( (void *)l->LeapSeconds, N*sizeof(double) )) == NULL ) { - printf("Lgm_LoadLeapSeconds: Memory allocation problem (in realloc)\n"); + if ((l->LeapSeconds = (double*)realloc( + (void*)l->LeapSeconds, N * sizeof(double))) == NULL) { + printf( + "Lgm_LoadLeapSeconds: Memory allocation problem (in " + "realloc)\n"); fclose(fp); - return(LGM_ERROR); + return (LGM_ERROR); } } } @@ -211,138 +285,163 @@ int Lgm_LoadLeapSeconds( Lgm_CTrans *c ) { } else { /* - * Provides a fallback in case the Lgm_LeapSecondDates.dat was not present. + * Provides a fallback in case the Lgm_LeapSecondDates.dat was not + * present. */ N = 28; l->nLeapSecondDates = N; - l->LeapSecondDates = (long int *) malloc( N*sizeof(long int) ); - l->LeapSecondJDs = (double *) malloc( N*sizeof(double) ); - l->LeapSeconds = (double *) malloc( N*sizeof(double) ); - l->LeapSecondDates[0] = 19720101, l->LeapSecondJDs[0] = 2441317.5, l->LeapSeconds[0] = 10.0; - l->LeapSecondDates[1] = 19720701, l->LeapSecondJDs[1] = 2441499.5, l->LeapSeconds[1] = 11.0; - l->LeapSecondDates[2] = 19730101, l->LeapSecondJDs[2] = 2441683.5, l->LeapSeconds[2] = 12.0; - l->LeapSecondDates[3] = 19740101, l->LeapSecondJDs[3] = 2442048.5, l->LeapSeconds[3] = 13.0; - l->LeapSecondDates[4] = 19750101, l->LeapSecondJDs[4] = 2442413.5, l->LeapSeconds[4] = 14.0; - l->LeapSecondDates[5] = 19760101, l->LeapSecondJDs[5] = 2442778.5, l->LeapSeconds[5] = 15.0; - l->LeapSecondDates[6] = 19770101, l->LeapSecondJDs[6] = 2443144.5, l->LeapSeconds[6] = 16.0; - l->LeapSecondDates[7] = 19780101, l->LeapSecondJDs[7] = 2443509.5, l->LeapSeconds[7] = 17.0; - l->LeapSecondDates[8] = 19790101, l->LeapSecondJDs[8] = 2443874.5, l->LeapSeconds[8] = 18.0; - l->LeapSecondDates[9] = 19800101, l->LeapSecondJDs[9] = 2444239.5, l->LeapSeconds[9] = 19.0; - l->LeapSecondDates[10] = 19810701, l->LeapSecondJDs[10] = 2444786.5, l->LeapSeconds[10] = 20.0; - l->LeapSecondDates[11] = 19820701, l->LeapSecondJDs[11] = 2445151.5, l->LeapSeconds[11] = 21.0; - l->LeapSecondDates[12] = 19830701, l->LeapSecondJDs[12] = 2445516.5, l->LeapSeconds[12] = 22.0; - l->LeapSecondDates[13] = 19850701, l->LeapSecondJDs[13] = 2446247.5, l->LeapSeconds[13] = 23.0; - l->LeapSecondDates[14] = 19880101, l->LeapSecondJDs[14] = 2447161.5, l->LeapSeconds[14] = 24.0; - l->LeapSecondDates[15] = 19900101, l->LeapSecondJDs[15] = 2447892.5, l->LeapSeconds[15] = 25.0; - l->LeapSecondDates[16] = 19910101, l->LeapSecondJDs[16] = 2448257.5, l->LeapSeconds[16] = 26.0; - l->LeapSecondDates[17] = 19920701, l->LeapSecondJDs[17] = 2448804.5, l->LeapSeconds[17] = 27.0; - l->LeapSecondDates[18] = 19930701, l->LeapSecondJDs[18] = 2449169.5, l->LeapSeconds[18] = 28.0; - l->LeapSecondDates[19] = 19940701, l->LeapSecondJDs[19] = 2449534.5, l->LeapSeconds[19] = 29.0; - l->LeapSecondDates[20] = 19960101, l->LeapSecondJDs[20] = 2450083.5, l->LeapSeconds[20] = 30.0; - l->LeapSecondDates[21] = 19970701, l->LeapSecondJDs[21] = 2450630.5, l->LeapSeconds[21] = 31.0; - l->LeapSecondDates[22] = 19990101, l->LeapSecondJDs[22] = 2451179.5, l->LeapSeconds[22] = 32.0; - l->LeapSecondDates[23] = 20060101, l->LeapSecondJDs[23] = 2453736.5, l->LeapSeconds[23] = 33.0; - l->LeapSecondDates[24] = 20090101, l->LeapSecondJDs[24] = 2454832.5, l->LeapSeconds[24] = 34.0; - l->LeapSecondDates[25] = 20120701, l->LeapSecondJDs[25] = 2456109.5, l->LeapSeconds[25] = 35.0; - l->LeapSecondDates[26] = 20150701, l->LeapSecondJDs[26] = 2457204.5, l->LeapSeconds[26] = 36.0; - l->LeapSecondDates[27] = 20170101, l->LeapSecondJDs[27] = 2457754.5, l->LeapSeconds[27] = 37.0; - printf("Lgm_LoadLeapSeconds: Could not open Lgm_LeapSecondDates.dat file!\n"); - printf(" Setting the leap second values that I know about\n"); - printf(" (latest leap second I know about was introduced on\n"); - printf(" %8ld (total leap seconds is %g))\n", l->LeapSecondDates[N-1], l->LeapSeconds[N-1]); - //return(LGM_ERROR); + l->LeapSecondDates = (long int*)malloc(N * sizeof(long int)); + l->LeapSecondJDs = (double*)malloc(N * sizeof(double)); + l->LeapSeconds = (double*)malloc(N * sizeof(double)); + l->LeapSecondDates[0] = 19720101, l->LeapSecondJDs[0] = 2441317.5, + l->LeapSeconds[0] = 10.0; + l->LeapSecondDates[1] = 19720701, l->LeapSecondJDs[1] = 2441499.5, + l->LeapSeconds[1] = 11.0; + l->LeapSecondDates[2] = 19730101, l->LeapSecondJDs[2] = 2441683.5, + l->LeapSeconds[2] = 12.0; + l->LeapSecondDates[3] = 19740101, l->LeapSecondJDs[3] = 2442048.5, + l->LeapSeconds[3] = 13.0; + l->LeapSecondDates[4] = 19750101, l->LeapSecondJDs[4] = 2442413.5, + l->LeapSeconds[4] = 14.0; + l->LeapSecondDates[5] = 19760101, l->LeapSecondJDs[5] = 2442778.5, + l->LeapSeconds[5] = 15.0; + l->LeapSecondDates[6] = 19770101, l->LeapSecondJDs[6] = 2443144.5, + l->LeapSeconds[6] = 16.0; + l->LeapSecondDates[7] = 19780101, l->LeapSecondJDs[7] = 2443509.5, + l->LeapSeconds[7] = 17.0; + l->LeapSecondDates[8] = 19790101, l->LeapSecondJDs[8] = 2443874.5, + l->LeapSeconds[8] = 18.0; + l->LeapSecondDates[9] = 19800101, l->LeapSecondJDs[9] = 2444239.5, + l->LeapSeconds[9] = 19.0; + l->LeapSecondDates[10] = 19810701, l->LeapSecondJDs[10] = 2444786.5, + l->LeapSeconds[10] = 20.0; + l->LeapSecondDates[11] = 19820701, l->LeapSecondJDs[11] = 2445151.5, + l->LeapSeconds[11] = 21.0; + l->LeapSecondDates[12] = 19830701, l->LeapSecondJDs[12] = 2445516.5, + l->LeapSeconds[12] = 22.0; + l->LeapSecondDates[13] = 19850701, l->LeapSecondJDs[13] = 2446247.5, + l->LeapSeconds[13] = 23.0; + l->LeapSecondDates[14] = 19880101, l->LeapSecondJDs[14] = 2447161.5, + l->LeapSeconds[14] = 24.0; + l->LeapSecondDates[15] = 19900101, l->LeapSecondJDs[15] = 2447892.5, + l->LeapSeconds[15] = 25.0; + l->LeapSecondDates[16] = 19910101, l->LeapSecondJDs[16] = 2448257.5, + l->LeapSeconds[16] = 26.0; + l->LeapSecondDates[17] = 19920701, l->LeapSecondJDs[17] = 2448804.5, + l->LeapSeconds[17] = 27.0; + l->LeapSecondDates[18] = 19930701, l->LeapSecondJDs[18] = 2449169.5, + l->LeapSeconds[18] = 28.0; + l->LeapSecondDates[19] = 19940701, l->LeapSecondJDs[19] = 2449534.5, + l->LeapSeconds[19] = 29.0; + l->LeapSecondDates[20] = 19960101, l->LeapSecondJDs[20] = 2450083.5, + l->LeapSeconds[20] = 30.0; + l->LeapSecondDates[21] = 19970701, l->LeapSecondJDs[21] = 2450630.5, + l->LeapSeconds[21] = 31.0; + l->LeapSecondDates[22] = 19990101, l->LeapSecondJDs[22] = 2451179.5, + l->LeapSeconds[22] = 32.0; + l->LeapSecondDates[23] = 20060101, l->LeapSecondJDs[23] = 2453736.5, + l->LeapSeconds[23] = 33.0; + l->LeapSecondDates[24] = 20090101, l->LeapSecondJDs[24] = 2454832.5, + l->LeapSeconds[24] = 34.0; + l->LeapSecondDates[25] = 20120701, l->LeapSecondJDs[25] = 2456109.5, + l->LeapSeconds[25] = 35.0; + l->LeapSecondDates[26] = 20150701, l->LeapSecondJDs[26] = 2457204.5, + l->LeapSeconds[26] = 36.0; + l->LeapSecondDates[27] = 20170101, l->LeapSecondJDs[27] = 2457754.5, + l->LeapSeconds[27] = 37.0; + printf( + "Lgm_LoadLeapSeconds: Could not open Lgm_LeapSecondDates.dat " + "file!\n"); + printf( + " Setting the leap second values that I know " + "about\n"); + printf( + " (latest leap second I know about was " + "introduced on\n"); + printf(" %8ld (total leap seconds is %g))\n", + l->LeapSecondDates[N - 1], l->LeapSeconds[N - 1]); + // return(LGM_ERROR); } l->nLeapSecondDates = n; /* - * The LeapSecondDates values are the dates that the given corrections came into effect. But the actual leap second - * date is the day before -- thats when the extra second was tacked on. So subtract a day from each of the dates. + * The LeapSecondDates values are the dates that the given corrections came + * into effect. But the actual leap second date is the day before -- thats + * when the extra second was tacked on. So subtract a day from each of the + * dates. */ - for (i=0; inLeapSecondDates; i++){ - JD = l->LeapSecondJDs[i]+0.5; // Noon on the given date - Lgm_JD_to_Date( JD-1.0, &Year, &Month, &Day, &Time ); - l->LeapSecondDates[i] = Year*10000 + Month*100 + Day; + for (i = 0; i < l->nLeapSecondDates; i++) { + JD = l->LeapSecondJDs[i] + 0.5; // Noon on the given date + Lgm_JD_to_Date(JD - 1.0, &Year, &Month, &Day, &Time); + l->LeapSecondDates[i] = Year * 10000 + Month * 100 + Day; } - return(TRUE); - + return (TRUE); } - - - /* * GPS <-> TAI Conversions */ -void Lgm_TAI_to_GPS( Lgm_DateTime *TAI, Lgm_DateTime *GPS, Lgm_CTrans *c ) { - - double Time; +void Lgm_TAI_to_GPS(Lgm_DateTime* TAI, Lgm_DateTime* GPS, Lgm_CTrans* c) { + double Time; *GPS = *TAI; - GPS->Time -= 19.0/3600.0; - GPS->JD = Lgm_JD( GPS->Year, GPS->Month, GPS->Day, GPS->Time, LGM_TIME_SYS_GPS, c ); - GPS->Date = Lgm_JD_to_Date( GPS->JD, &GPS->Year, &GPS->Month, &GPS->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - GPS->Time = Lgm_hour24( GPS->Time ); - GPS->T = (GPS->JD - 2451545.0)/36525.0; + GPS->Time -= 19.0 / 3600.0; + GPS->JD = + Lgm_JD(GPS->Year, GPS->Month, GPS->Day, GPS->Time, LGM_TIME_SYS_GPS, c); + GPS->Date = + Lgm_JD_to_Date(GPS->JD, &GPS->Year, &GPS->Month, &GPS->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + GPS->Time = Lgm_hour24(GPS->Time); + GPS->T = (GPS->JD - 2451545.0) / 36525.0; GPS->TimeSystem = LGM_TIME_SYS_GPS; - } -void Lgm_GPS_to_TAI( Lgm_DateTime *GPS, Lgm_DateTime *TAI, Lgm_CTrans *c ) { - - double Time; +void Lgm_GPS_to_TAI(Lgm_DateTime* GPS, Lgm_DateTime* TAI, Lgm_CTrans* c) { + double Time; *TAI = *GPS; - TAI->Time += 19.0/3600.0; - TAI->JD = Lgm_JD( TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c ); - TAI->Date = Lgm_JD_to_Date( TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TAI->Time = Lgm_hour24( TAI->Time ); - TAI->T = (TAI->JD - 2451545.0)/36525.0; + TAI->Time += 19.0 / 3600.0; + TAI->JD = + Lgm_JD(TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c); + TAI->Date = + Lgm_JD_to_Date(TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TAI->Time = Lgm_hour24(TAI->Time); + TAI->T = (TAI->JD - 2451545.0) / 36525.0; TAI->TimeSystem = LGM_TIME_SYS_TAI; - } - - - /* * UTC <-> GPS conversions */ -void Lgm_UTC_to_GPS( Lgm_DateTime *UTC, Lgm_DateTime *GPS, Lgm_CTrans *c ) { - - Lgm_DateTime TAI; +void Lgm_UTC_to_GPS(Lgm_DateTime* UTC, Lgm_DateTime* GPS, Lgm_CTrans* c) { + Lgm_DateTime TAI; // First go UTC -> TAI - Lgm_UTC_to_TAI( UTC, &TAI, c ); + Lgm_UTC_to_TAI(UTC, &TAI, c); // Then go TAI->GPS - Lgm_TAI_to_GPS( &TAI, GPS, c ); + Lgm_TAI_to_GPS(&TAI, GPS, c); GPS->TimeSystem = LGM_TIME_SYS_GPS; - } -void Lgm_GPS_to_UTC( Lgm_DateTime *GPS, Lgm_DateTime *UTC, Lgm_CTrans *c ) { - - Lgm_DateTime TAI; +void Lgm_GPS_to_UTC(Lgm_DateTime* GPS, Lgm_DateTime* UTC, Lgm_CTrans* c) { + Lgm_DateTime TAI; // First go GPS -> TAI - Lgm_GPS_to_TAI( GPS, &TAI, c ); + Lgm_GPS_to_TAI(GPS, &TAI, c); // Then go TAI->UTC - Lgm_TAI_to_UTC( &TAI, UTC, c ); + Lgm_TAI_to_UTC(&TAI, UTC, c); UTC->TimeSystem = LGM_TIME_SYS_UTC; - } - - - - /* * GpsSeconds Routines * ------------------- @@ -352,42 +451,41 @@ void Lgm_GPS_to_UTC( Lgm_DateTime *GPS, Lgm_DateTime *UTC, Lgm_CTrans *c ) { * current week. But the week number will eventually roll over sometime soon? * The Weeks/Seconds thing is kind of useless for our purposes...) */ -double Lgm_GPS_to_GpsSeconds( Lgm_DateTime *GPS ) { - double JDN, Seconds; - JDN = Lgm_JDN( GPS->Year, GPS->Month, GPS->Day ); - Seconds = (JDN - LGM_JD_GPS0)*86400.0 + GPS->Time*3600.0; - return( Seconds ); +double Lgm_GPS_to_GpsSeconds(Lgm_DateTime* GPS) { + double JDN, Seconds; + JDN = Lgm_JDN(GPS->Year, GPS->Month, GPS->Day); + Seconds = (JDN - LGM_JD_GPS0) * 86400.0 + GPS->Time * 3600.0; + return (Seconds); } -void Lgm_GpsSeconds_to_GPS( double GpsSeconds, Lgm_DateTime *GPS ) { - +void Lgm_GpsSeconds_to_GPS(double GpsSeconds, Lgm_DateTime* GPS) { long int dJDN; - double tmp, JDN; - dJDN = (long int)(GpsSeconds/86400.0); - GPS->Time = (GpsSeconds - dJDN*86400.0)/3600.0; + double tmp, JDN; + dJDN = (long int)(GpsSeconds / 86400.0); + GPS->Time = (GpsSeconds - dJDN * 86400.0) / 3600.0; JDN = LGM_JD_GPS0 + dJDN; - Lgm_jd_to_ymdh( JDN, &GPS->Date, &GPS->Year, &GPS->Month, &GPS->Day, &tmp); - - GPS->JD = JDN + GPS->Time/24.0; - GPS->T = (GPS->JD - 2451545.0)/36525.0; - GPS->TimeSystem = LGM_TIME_SYS_GPS; + Lgm_jd_to_ymdh(JDN, &GPS->Date, &GPS->Year, &GPS->Month, &GPS->Day, &tmp); + GPS->JD = JDN + GPS->Time / 24.0; + GPS->T = (GPS->JD - 2451545.0) / 36525.0; + GPS->TimeSystem = LGM_TIME_SYS_GPS; } -void Lgm_GpsSeconds_to_UTC( double GpsSeconds, Lgm_DateTime *UTC, Lgm_CTrans *c ) { +void Lgm_GpsSeconds_to_UTC(double GpsSeconds, + Lgm_DateTime* UTC, + Lgm_CTrans* c) { Lgm_DateTime GPS; - Lgm_GpsSeconds_to_GPS( GpsSeconds, &GPS ); - Lgm_GPS_to_UTC( &GPS, UTC, c ); + Lgm_GpsSeconds_to_GPS(GpsSeconds, &GPS); + Lgm_GPS_to_UTC(&GPS, UTC, c); UTC->TimeSystem = LGM_TIME_SYS_UTC; } -double Lgm_UTC_to_GpsSeconds( Lgm_DateTime *UTC, Lgm_CTrans *c ) { +double Lgm_UTC_to_GpsSeconds(Lgm_DateTime* UTC, Lgm_CTrans* c) { Lgm_DateTime GPS; - Lgm_UTC_to_GPS( UTC, &GPS, c ); - return( Lgm_GPS_to_GpsSeconds( &GPS) ); + Lgm_UTC_to_GPS(UTC, &GPS, c); + return (Lgm_GPS_to_GpsSeconds(&GPS)); } - /* * TaiSeconds Routines * ------------------- @@ -400,56 +498,52 @@ double Lgm_UTC_to_GpsSeconds( Lgm_DateTime *UTC, Lgm_CTrans *c ) { * * Here, I call the "number of SI seconds since 0h Jan 1, 1958" TaiSeconds. */ -double Lgm_TAI_to_TaiSeconds( Lgm_DateTime *TAI ) { - double JDN, Seconds; - JDN = Lgm_JDN( TAI->Year, TAI->Month, TAI->Day ); - Seconds = (JDN - LGM_JD_TAI0)*86400.0 + TAI->Time*3600.0; - return( Seconds ); +double Lgm_TAI_to_TaiSeconds(Lgm_DateTime* TAI) { + double JDN, Seconds; + JDN = Lgm_JDN(TAI->Year, TAI->Month, TAI->Day); + Seconds = (JDN - LGM_JD_TAI0) * 86400.0 + TAI->Time * 3600.0; + return (Seconds); } -void Lgm_TaiSeconds_to_TAI( double TaiSeconds, Lgm_DateTime *TAI ) { - +void Lgm_TaiSeconds_to_TAI(double TaiSeconds, Lgm_DateTime* TAI) { long int dJDN; - double tmp, JDN; - dJDN = (long int)(TaiSeconds/86400.0); - TAI->Time = (TaiSeconds - dJDN*86400.0)/3600.0; + double tmp, JDN; + dJDN = (long int)(TaiSeconds / 86400.0); + TAI->Time = (TaiSeconds - dJDN * 86400.0) / 3600.0; JDN = LGM_JD_TAI0 + dJDN; - Lgm_jd_to_ymdh( JDN, &TAI->Date, &TAI->Year, &TAI->Month, &TAI->Day, &tmp); - - TAI->JD = JDN + TAI->Time/24.0; - TAI->T = (TAI->JD - 2451545.0)/36525.0; - TAI->TimeSystem = LGM_TIME_SYS_TAI; + Lgm_jd_to_ymdh(JDN, &TAI->Date, &TAI->Year, &TAI->Month, &TAI->Day, &tmp); + TAI->JD = JDN + TAI->Time / 24.0; + TAI->T = (TAI->JD - 2451545.0) / 36525.0; + TAI->TimeSystem = LGM_TIME_SYS_TAI; } -void Lgm_TaiSeconds_to_UTC( double TaiSeconds, Lgm_DateTime *UTC, Lgm_CTrans *c ) { +void Lgm_TaiSeconds_to_UTC(double TaiSeconds, + Lgm_DateTime* UTC, + Lgm_CTrans* c) { Lgm_DateTime TAI; - Lgm_TaiSeconds_to_TAI( TaiSeconds, &TAI ); - Lgm_TAI_to_UTC( &TAI, UTC, c ); + Lgm_TaiSeconds_to_TAI(TaiSeconds, &TAI); + Lgm_TAI_to_UTC(&TAI, UTC, c); UTC->TimeSystem = LGM_TIME_SYS_UTC; } -double Lgm_UTC_to_TaiSeconds( Lgm_DateTime *UTC, Lgm_CTrans *c ) { +double Lgm_UTC_to_TaiSeconds(Lgm_DateTime* UTC, Lgm_CTrans* c) { Lgm_DateTime TAI; - Lgm_UTC_to_TAI( UTC, &TAI, c ); - return( Lgm_TAI_to_TaiSeconds( &TAI) ); + Lgm_UTC_to_TAI(UTC, &TAI, c); + return (Lgm_TAI_to_TaiSeconds(&TAI)); } - - - - /* * UTC <-> TAI conversion rotuines * - * Lgm_UTC_to_TAI() - converts UTC to TAI using appropriaste number of leapseconds - * Lgm_TAI_to_UTC() - converts TAI to UTC using appropriaste number of leapseconds + * Lgm_UTC_to_TAI() - converts UTC to TAI using appropriaste number of + * leapseconds Lgm_TAI_to_UTC() - converts TAI to UTC using appropriaste number + * of leapseconds * */ -void Lgm_UTC_to_TAI( Lgm_DateTime *UTC, Lgm_DateTime *TAI, Lgm_CTrans *c ) { - - double Time, DAT, JD; - int Year, Month, Day, sgn; +void Lgm_UTC_to_TAI(Lgm_DateTime* UTC, Lgm_DateTime* TAI, Lgm_CTrans* c) { + double Time, DAT, JD; + int Year, Month, Day, sgn; // Set relavent fields in TAI structure. *TAI = *UTC; @@ -457,35 +551,39 @@ void Lgm_UTC_to_TAI( Lgm_DateTime *UTC, Lgm_DateTime *TAI, Lgm_CTrans *c ) { TAI->DaySeconds = 86400.0; // Get leap seconds - JD = Lgm_JD( UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c ); - DAT = Lgm_GetLeapSeconds( JD, c ); + JD = + Lgm_JD(UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c); + DAT = Lgm_GetLeapSeconds(JD, c); // Add leap seconds to UTC time to get TAI time - TAI->Time = UTC->Time + DAT/3600.0; + TAI->Time = UTC->Time + DAT / 3600.0; // Convert Year,Month,Day,Time TAI into a Julian Date.(Note that the Time // argument to Lgm_JD() doesnt have to be between 0 and 24. This allows for // date roll-overs one way or the other.) - TAI->JD = Lgm_JD( TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c ); + TAI->JD = + Lgm_JD(TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c); - // From the new JD, compute the Gregorian Date that the TAI Time occurred on. - // This routin returns Time back out, but we will ignore it. - TAI->Date = Lgm_JD_to_Date( TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time ); + // From the new JD, compute the Gregorian Date that the TAI Time occurred + // on. This routin returns Time back out, but we will ignore it. + TAI->Date = + Lgm_JD_to_Date(TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time); - // Instead, just remap the time we have to be between 0 and 24 (limits roundoff error) - TAI->Time = Lgm_hour24( TAI->Time ); + // Instead, just remap the time we have to be between 0 and 24 (limits + // roundoff error) + TAI->Time = Lgm_hour24(TAI->Time); // Compute Julian Centuries since J2000. - TAI->T = (TAI->JD - 2451545.0)/36525.0; + TAI->T = (TAI->JD - 2451545.0) / 36525.0; // Set Day Of Week and Day Of Week String - TAI->Dow = Lgm_DayOfWeek( TAI->Year, TAI->Month, TAI->Day, TAI->DowStr ); + TAI->Dow = Lgm_DayOfWeek(TAI->Year, TAI->Month, TAI->Day, TAI->DowStr); // Set Hour, Minute, Seconds - Lgm_UT_to_HMSd( TAI->Time, &sgn, &TAI->Hour, &TAI->Minute, &TAI->Second ); + Lgm_UT_to_HMSd(TAI->Time, &sgn, &TAI->Hour, &TAI->Minute, &TAI->Second); // Set Day Of Year - Lgm_Doy( TAI->Date, &Year, &Month, &Day, &TAI->Doy); + Lgm_Doy(TAI->Date, &Year, &Month, &Day, &TAI->Doy); TAI->TimeSystem = LGM_TIME_SYS_TAI; @@ -493,7 +591,7 @@ void Lgm_UTC_to_TAI( Lgm_DateTime *UTC, Lgm_DateTime *TAI, Lgm_CTrans *c ) { } /* - * TAI -> UTC + * TAI -> UTC * This rotuine is not too complicated, but its not trivial. Here is an * outline of the problem: * @@ -521,10 +619,9 @@ void Lgm_UTC_to_TAI( Lgm_DateTime *UTC, Lgm_DateTime *TAI, Lgm_CTrans *c ) { * * */ -void Lgm_TAI_to_UTC( Lgm_DateTime *TAI, Lgm_DateTime *UTC, Lgm_CTrans *c ) { - - double t_target, f, d, tim; - Lgm_DateTime t; +void Lgm_TAI_to_UTC(Lgm_DateTime* TAI, Lgm_DateTime* UTC, Lgm_CTrans* c) { + double t_target, f, d, tim; + Lgm_DateTime t; /* * Keep track of the TAI time we want to convert. @@ -535,37 +632,40 @@ void Lgm_TAI_to_UTC( Lgm_DateTime *TAI, Lgm_DateTime *UTC, Lgm_CTrans *c ) { * estimate of JD for UTC */ d = TAI->JD; -//printf("d = %lf\n", d); -//printf("%d %d %d\n", TAI->Year, TAI->Month, TAI->Day); -//printf("JD = %lf\n", Lgm_JD( TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c )); + // printf("d = %lf\n", d); + // printf("%d %d %d\n", TAI->Year, TAI->Month, TAI->Day); + // printf("JD = %lf\n", Lgm_JD( TAI->Year, TAI->Month, TAI->Day, TAI->Time, + // LGM_TIME_SYS_TAI, c )); - /* + /* * Estimate UTC using the JD of the TAI time. This is a naive first guess * at the answer. */ - f = Lgm_GetLeapSeconds( d, c ); - UTC->Time = TAI->Time - f/3600.0; - UTC->Year = TAI->Year; UTC->Month = TAI->Month; UTC->Day = TAI->Day; + f = Lgm_GetLeapSeconds(d, c); + UTC->Time = TAI->Time - f / 3600.0; + UTC->Year = TAI->Year; + UTC->Month = TAI->Month; + UTC->Day = TAI->Day; /* - * convert UTC back to TAI in order verify that we have the right answer. If we - * dont, we'll have to do some more work. + * convert UTC back to TAI in order verify that we have the right answer. If + * we dont, we'll have to do some more work. */ - UTC->JD = Lgm_JD( UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c ); - UTC->Date = Lgm_JD_to_Date( UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &tim ); - Lgm_IsLeapSecondDay( UTC->Date, &UTC->DaySeconds, c ); - UTC->Time = Lgm_RemapTime( UTC->Time, UTC->DaySeconds ); - Lgm_UTC_to_TAI( UTC, &t, c ); - + UTC->JD = + Lgm_JD(UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c); + UTC->Date = + Lgm_JD_to_Date(UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &tim); + Lgm_IsLeapSecondDay(UTC->Date, &UTC->DaySeconds, c); + UTC->Time = Lgm_RemapTime(UTC->Time, UTC->DaySeconds); + Lgm_UTC_to_TAI(UTC, &t, c); - /* + /* * If subtracting the leap seconds took us back over a leapsecond * (positive or minus), then the time will be off. We need to adjust d so * that the calculation uses the correct number of leap seconds. */ - if ( fabs( t_target - t.Time ) > 0.1 ) { - - if ( (t_target - t.Time) > 0.1 ) { + if (fabs(t_target - t.Time) > 0.1) { + if ((t_target - t.Time) > 0.1) { // occurs because the date we used to get leapseconds has more leap // seconds in it that we should have used. --d; @@ -577,169 +677,172 @@ void Lgm_TAI_to_UTC( Lgm_DateTime *TAI, Lgm_DateTime *UTC, Lgm_CTrans *c ) { ++d; } - f = Lgm_GetLeapSeconds( d, c ); - UTC->Time = TAI->Time - f/3600.0; - UTC->Year = TAI->Year; UTC->Month = TAI->Month; UTC->Day = TAI->Day; - UTC->JD = Lgm_JD( UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c ); - UTC->Date = Lgm_JD_to_Date( UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &tim ); - Lgm_IsLeapSecondDay( UTC->Date, &UTC->DaySeconds, c ); - UTC->Time = Lgm_RemapTime( UTC->Time, UTC->DaySeconds ); + f = Lgm_GetLeapSeconds(d, c); + UTC->Time = TAI->Time - f / 3600.0; + UTC->Year = TAI->Year; + UTC->Month = TAI->Month; + UTC->Day = TAI->Day; + UTC->JD = Lgm_JD(UTC->Year, UTC->Month, UTC->Day, UTC->Time, + LGM_TIME_SYS_UTC, c); + UTC->Date = + Lgm_JD_to_Date(UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &tim); + Lgm_IsLeapSecondDay(UTC->Date, &UTC->DaySeconds, c); + UTC->Time = Lgm_RemapTime(UTC->Time, UTC->DaySeconds); } - // Set relavent fields in UTC structure. UTC->TimeSystem = LGM_TIME_SYS_UTC; - UTC->T = (UTC->JD - 2451545.0)/36525.0; + UTC->T = (UTC->JD - 2451545.0) / 36525.0; UTC->TimeSystem = LGM_TIME_SYS_UTC; return; } - - /* * TT -> TAI - * (Dont really need leap seconds here, but pass CTrans structure so all the args are the same.) + * (Dont really need leap seconds here, but pass CTrans structure so all the + * args are the same.) */ -void Lgm_TT_to_TAI( Lgm_DateTime *TT, Lgm_DateTime *TAI, Lgm_CTrans *c ) { - - double Time; - - *TAI = *TT; // initially make DateTime structures the same - TAI->Time = TT->Time - 32.184/3600.0; - TAI->JD = Lgm_JD( TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c ); - TAI->Date = Lgm_JD_to_Date( TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TAI->Time = Lgm_hour24( TAI->Time ); - TAI->T = (TAI->JD - 2451545.0)/36525.0; +void Lgm_TT_to_TAI(Lgm_DateTime* TT, Lgm_DateTime* TAI, Lgm_CTrans* c) { + double Time; + + *TAI = *TT; // initially make DateTime structures the same + TAI->Time = TT->Time - 32.184 / 3600.0; + TAI->JD = + Lgm_JD(TAI->Year, TAI->Month, TAI->Day, TAI->Time, LGM_TIME_SYS_TAI, c); + TAI->Date = + Lgm_JD_to_Date(TAI->JD, &TAI->Year, &TAI->Month, &TAI->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TAI->Time = Lgm_hour24(TAI->Time); + TAI->T = (TAI->JD - 2451545.0) / 36525.0; TAI->TimeSystem = LGM_TIME_SYS_TAI; return; - } // Does Lgm_JD need leapseconds for TAI ??? check that its working ok /* * TAI -> TT - * (Dont really need leap seconds here, but pass CTrans structure so all the args are the same.) + * (Dont really need leap seconds here, but pass CTrans structure so all the + * args are the same.) */ -void Lgm_TAI_to_TT( Lgm_DateTime *TAI, Lgm_DateTime *TT, Lgm_CTrans *c ) { - - double Time; - - *TT = *TAI; // initially make DateTime structures the same - TT->Time = TAI->Time + 32.184/3600.0; - TT->JD = Lgm_JD( TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c ); - TT->Date = Lgm_JD_to_Date( TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TT->Time = Lgm_hour24( TT->Time ); - TT->T = (TT->JD - 2451545.0)/36525.0; +void Lgm_TAI_to_TT(Lgm_DateTime* TAI, Lgm_DateTime* TT, Lgm_CTrans* c) { + double Time; + + *TT = *TAI; // initially make DateTime structures the same + TT->Time = TAI->Time + 32.184 / 3600.0; + TT->JD = Lgm_JD(TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c); + TT->Date = Lgm_JD_to_Date(TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TT->Time = Lgm_hour24(TT->Time); + TT->T = (TT->JD - 2451545.0) / 36525.0; TT->TimeSystem = LGM_TIME_SYS_TT; return; - } - - - - - - - - - /* * TT -> TDB ( IAU 1976 Resolution Version ) */ -void Lgm_TT_to_TDB( Lgm_DateTime *TT, Lgm_DateTime *TDB, Lgm_CTrans *c ) { - - double Mearth, Time; - - *TDB = *TT; // initially make DateTime structures the same - - Mearth = (357.53 + 35999.050*TT->T)*RadPerDeg; - TDB->Time = TT->Time + ( 0.001658*sin(Mearth) + 0.000014*sin(2.0*Mearth) )/3600.0; - TDB->JD = Lgm_JD( TDB->Year, TDB->Month, TDB->Day, TDB->Time, LGM_TIME_SYS_TDB, c ); - TDB->Date = Lgm_JD_to_Date( TDB->JD, &TDB->Year, &TDB->Month, &TDB->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TDB->Time = Lgm_hour24( TDB->Time ); - TDB->T = (TDB->JD - 2451545.0)/36525.0; +void Lgm_TT_to_TDB(Lgm_DateTime* TT, Lgm_DateTime* TDB, Lgm_CTrans* c) { + double Mearth, Time; + + *TDB = *TT; // initially make DateTime structures the same + + Mearth = (357.53 + 35999.050 * TT->T) * RadPerDeg; + TDB->Time = + TT->Time + + (0.001658 * sin(Mearth) + 0.000014 * sin(2.0 * Mearth)) / 3600.0; + TDB->JD = + Lgm_JD(TDB->Year, TDB->Month, TDB->Day, TDB->Time, LGM_TIME_SYS_TDB, c); + TDB->Date = + Lgm_JD_to_Date(TDB->JD, &TDB->Year, &TDB->Month, &TDB->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TDB->Time = Lgm_hour24(TDB->Time); + TDB->T = (TDB->JD - 2451545.0) / 36525.0; TDB->TimeSystem = LGM_TIME_SYS_TDB; return; } - - /* * TT -> TDB ( IAU 2006 Resolution Version ) */ -void Lgm_TT_to_TDB_IAU2006( Lgm_DateTime *TT, Lgm_DateTime *TDB, Lgm_CTrans *c ) { - - double Time; - - *TDB = *TT; // initially make DateTime structures the same - TDB->Time = TT->Time + (0.001658*sin( 628.3076*TT->T + 6.2401 ) - + 0.000022*sin( 575.3385*TT->T + 4.2970 ) + 0.000014*sin( 1256.6152*TT->T + 6.1969 ) - + 0.000005*sin( 606.9777*TT->T + 4.0212 ) + 0.000005*sin( 52.9691*TT->T + 0.4444 ) - + 0.000002*sin( 21.3299*TT->T + 5.5431 ) + 0.000010*sin( 628.3076*TT->T + 4.2490 ))/3600.0; - - TDB->JD = Lgm_JD( TDB->Year, TDB->Month, TDB->Day, TDB->Time, LGM_TIME_SYS_TDB, c ); - TDB->Date = Lgm_JD_to_Date( TDB->JD, &TDB->Year, &TDB->Month, &TDB->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TDB->Time = Lgm_hour24( TDB->Time ); - TDB->T = (TDB->JD - 2451545.0)/36525.0; +void Lgm_TT_to_TDB_IAU2006(Lgm_DateTime* TT, Lgm_DateTime* TDB, Lgm_CTrans* c) { + double Time; + + *TDB = *TT; // initially make DateTime structures the same + TDB->Time = TT->Time + (0.001658 * sin(628.3076 * TT->T + 6.2401) + + 0.000022 * sin(575.3385 * TT->T + 4.2970) + + 0.000014 * sin(1256.6152 * TT->T + 6.1969) + + 0.000005 * sin(606.9777 * TT->T + 4.0212) + + 0.000005 * sin(52.9691 * TT->T + 0.4444) + + 0.000002 * sin(21.3299 * TT->T + 5.5431) + + 0.000010 * sin(628.3076 * TT->T + 4.2490)) / + 3600.0; + + TDB->JD = + Lgm_JD(TDB->Year, TDB->Month, TDB->Day, TDB->Time, LGM_TIME_SYS_TDB, c); + TDB->Date = + Lgm_JD_to_Date(TDB->JD, &TDB->Year, &TDB->Month, &TDB->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TDB->Time = Lgm_hour24(TDB->Time); + TDB->T = (TDB->JD - 2451545.0) / 36525.0; TDB->TimeSystem = LGM_TIME_SYS_TDB; return; } - - /* - * TDB -> TT + * TDB -> TT * Unfortunately, this is a transendental equation, have to solve numerically. * The two times should be very close -- to within a few ms of each other... */ -void Lgm_TDB_to_TT( Lgm_DateTime *TDB, Lgm_DateTime *TT, Lgm_CTrans *c ) { - - int done; - double max, tdb_target, Ta, Tb, Tc, Ba, Bb, Bc, Fa, Fb, Fc, Time; - Lgm_DateTime *T, *B; +void Lgm_TDB_to_TT(Lgm_DateTime* TDB, Lgm_DateTime* TT, Lgm_CTrans* c) { + int done; + double max, tdb_target, Ta, Tb, Tc, Ba, Bb, Bc, Fa, Fb, Fc, Time; + Lgm_DateTime *T, *B; // start out with approximation that TT ~= TDB. This is our "initial guess". *TT = *TDB; - - tdb_target = TDB->Time; - - T = (Lgm_DateTime *) calloc( 1, sizeof(Lgm_DateTime) ); - B = (Lgm_DateTime *) calloc( 1, sizeof(Lgm_DateTime) ); + T = (Lgm_DateTime*)calloc(1, sizeof(Lgm_DateTime)); + B = (Lgm_DateTime*)calloc(1, sizeof(Lgm_DateTime)); // set T to our initial guess - *T = *TDB; - + *T = *TDB; /* * set up bracket */ - max = (0.001658 + 0.000014)/3600.0; // maximum possible diff... + max = (0.001658 + 0.000014) / 3600.0; // maximum possible diff... - //(Ta, Ba) + // (Ta, Ba) Ta = tdb_target - max; - T->Time = Ta; Lgm_TT_to_TDB( T, B, c ); Ba = B->Time; - // Lgm_TT_to_TDB() will recast the times if they cross date boundaries.(undo this.) - if ( (Ba - Ta) > 12.0 ) Ba -= 24.0; - if ( (Ta - Ba) > 12.0 ) Ba += 24.0; - - //(Tc, Bc) + T->Time = Ta; + Lgm_TT_to_TDB(T, B, c); + Ba = B->Time; + // Lgm_TT_to_TDB() will recast the times if they cross date boundaries.(undo + // this.) + if ((Ba - Ta) > 12.0) + Ba -= 24.0; + if ((Ta - Ba) > 12.0) + Ba += 24.0; + + // (Tc, Bc) Tc = tdb_target + max; - T->Time = Tc; Lgm_TT_to_TDB( T, B, c ); Bc = B->Time; - // Lgm_TT_to_TDB() will recast the times if they cross date boundaries.(undo this.) - if ( (Bc - Tc) > 12.0 ) Bc -= 24.0; - if ( (Tc - Bc) > 12.0 ) Bc += 24.0; - - + T->Time = Tc; + Lgm_TT_to_TDB(T, B, c); + Bc = B->Time; + // Lgm_TT_to_TDB() will recast the times if they cross date boundaries.(undo + // this.) + if ((Bc - Tc) > 12.0) + Bc -= 24.0; + if ((Tc - Bc) > 12.0) + Bc += 24.0; /* F is what we want to make zero @@ -749,19 +852,20 @@ void Lgm_TDB_to_TT( Lgm_DateTime *TDB, Lgm_DateTime *TT, Lgm_CTrans *c ) { Fa = tdb_target - Ba; Fc = tdb_target - Bc; - done = FALSE; - while ( !done ) { - - + while (!done) { // bisect and evaluate result at new point - Tb = 0.5*(Ta+Tc); - T->Time = Tb; Lgm_TT_to_TDB( T, B, c ); Bb = B->Time; - if ( (Bb - Tb) > 12.0 ) Bb -= 24.0; - if ( (Tb - Bb) > 12.0 ) Bb += 24.0; + Tb = 0.5 * (Ta + Tc); + T->Time = Tb; + Lgm_TT_to_TDB(T, B, c); + Bb = B->Time; + if ((Bb - Tb) > 12.0) + Bb -= 24.0; + if ((Tb - Bb) > 12.0) + Bb += 24.0; Fb = tdb_target - Bb; - - if ( Fb*Fa > 0.0 ) { + + if (Fb * Fa > 0.0) { // we are on the `a' side Ta = Tb; Fa = Fb; @@ -769,208 +873,227 @@ void Lgm_TDB_to_TT( Lgm_DateTime *TDB, Lgm_DateTime *TT, Lgm_CTrans *c ) { // we are on the `c' side Tc = Tb; Fc = Fb; - } + } - if ( fabs(Ta-Tc)*86400.0 < 1e-8 ){ + if (fabs(Ta - Tc) * 86400.0 < 1e-8) { done = TRUE; } - - } - free( T ); - free( B ); - + free(T); + free(B); // Fill in some of the other fields correctly. - TT->Time = 0.5*(Ta+Tc); - TT->JD = Lgm_JD( TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c ); - TT->Date = Lgm_JD_to_Date( TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TT->Time = Lgm_hour24( TT->Time ); - TT->T = (TT->JD - 2451545.0)/36525.0; + TT->Time = 0.5 * (Ta + Tc); + TT->JD = Lgm_JD(TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c); + TT->Date = Lgm_JD_to_Date(TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TT->Time = Lgm_hour24(TT->Time); + TT->T = (TT->JD - 2451545.0) / 36525.0; TT->TimeSystem = LGM_TIME_SYS_TT; return; } - -void Lgm_UTC_to_TT( Lgm_DateTime *UTC, Lgm_DateTime *TT, Lgm_CTrans *c ) { - +void Lgm_UTC_to_TT(Lgm_DateTime* UTC, Lgm_DateTime* TT, Lgm_CTrans* c) { Lgm_DateTime TAI; - double Time; - -//printf("\tLgm_UTC_to_TT: UTC = "); Lgm_Print_DateTime( *UTC, 4, 8 ); printf("\n"); + double Time; + // printf("\tLgm_UTC_to_TT: UTC = "); Lgm_Print_DateTime( *UTC, 4, 8 ); + // printf("\n"); TAI = *UTC; - Lgm_UTC_to_TAI( UTC, &TAI, c ); -//printf("\tLgm_UTC_to_TT: TAI = "); Lgm_Print_DateTime( TAI, 4, 8 ); printf("\n"); + Lgm_UTC_to_TAI(UTC, &TAI, c); + // printf("\tLgm_UTC_to_TT: TAI = "); Lgm_Print_DateTime( TAI, 4, 8 ); + // printf("\n"); *TT = TAI; - TT->Time = TAI.Time + 32.184/3600.0; - TT->JD = Lgm_JD( TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c ); - TT->Date = Lgm_JD_to_Date( TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - TT->Time = Lgm_hour24( TT->Time ); - TT->T = (TT->JD - 2451545.0)/36525.0; -//printf("\tLgm_UTC_to_TT: TT = "); Lgm_Print_DateTime( *TT, 4, 8 ); printf("\n"); + TT->Time = TAI.Time + 32.184 / 3600.0; + TT->JD = Lgm_JD(TT->Year, TT->Month, TT->Day, TT->Time, LGM_TIME_SYS_TT, c); + TT->Date = Lgm_JD_to_Date(TT->JD, &TT->Year, &TT->Month, &TT->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + TT->Time = Lgm_hour24(TT->Time); + TT->T = (TT->JD - 2451545.0) / 36525.0; + // printf("\tLgm_UTC_to_TT: TT = "); Lgm_Print_DateTime( *TT, 4, 8 ); + // printf("\n"); TT->TimeSystem = LGM_TIME_SYS_TT; return; } - - - -void Lgm_TT_to_UTC( Lgm_DateTime *TT, Lgm_DateTime *UTC, Lgm_CTrans *c ) { - +void Lgm_TT_to_UTC(Lgm_DateTime* TT, Lgm_DateTime* UTC, Lgm_CTrans* c) { Lgm_DateTime TAI; - double Time; + double Time; -//printf("\tLgm_TT_to_UTC: TT = "); Lgm_Print_DateTime( *TT, 4, 8 ); printf("\n"); + // printf("\tLgm_TT_to_UTC: TT = "); Lgm_Print_DateTime( *TT, 4, 8 ); + // printf("\n"); // Go TT -> TAI TAI = *TT; - Lgm_TT_to_TAI( TT, &TAI, c ); -//printf("\tLgm_TT_to_UTC: TAI = "); Lgm_Print_DateTime( TAI, 4, 8 ); printf("\n"); + Lgm_TT_to_TAI(TT, &TAI, c); + // printf("\tLgm_TT_to_UTC: TAI = "); Lgm_Print_DateTime( TAI, 4, 8 ); + // printf("\n"); // Go TAI -> UTC - Lgm_TAI_to_UTC( &TAI, UTC, c ); + Lgm_TAI_to_UTC(&TAI, UTC, c); // Fill in some of the other fields correctly - UTC->JD = Lgm_JD( UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c ); - UTC->Date = Lgm_JD_to_Date( UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &Time ); - // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). This limits roundoff error - UTC->Time = Lgm_hour24( UTC->Time ); - UTC->T = (UTC->JD - 2451545.0)/36525.0; -//printf("\tLgm_TT_to_UTC: UTC = "); Lgm_Print_DateTime( *UTC, 4, 8 ); printf("\n"); + UTC->JD = + Lgm_JD(UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c); + UTC->Date = + Lgm_JD_to_Date(UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &Time); + // Keep the time we had rather than getting it back from Lgm_JD_to_Date(). + // This limits roundoff error + UTC->Time = Lgm_hour24(UTC->Time); + UTC->T = (UTC->JD - 2451545.0) / 36525.0; + // printf("\tLgm_TT_to_UTC: UTC = "); Lgm_Print_DateTime( *UTC, 4, 8 ); + // printf("\n"); UTC->TimeSystem = LGM_TIME_SYS_UTC; return; } -void Lgm_UTC_to_TDB( Lgm_DateTime *UTC, Lgm_DateTime *TDB, Lgm_CTrans *c ) { +void Lgm_UTC_to_TDB(Lgm_DateTime* UTC, Lgm_DateTime* TDB, Lgm_CTrans* c) { Lgm_DateTime TT; -//printf("\tLgm_UTC_to_TDB: UTC: "); Lgm_Print_DateTime( *UTC, 4, 8 ); printf("\n"); - Lgm_UTC_to_TT( UTC, &TT, c ); -//printf("\tLgm_UTC_to_TDB: TT: "); Lgm_Print_DateTime( TT, 4, 8 ); printf("\n"); - Lgm_TT_to_TDB( &TT, TDB, c ); -//printf("\tLgm_UTC_to_TDB: TDB: "); Lgm_Print_DateTime( *TDB, 4, 8 ); printf("\n"); + // printf("\tLgm_UTC_to_TDB: UTC: "); Lgm_Print_DateTime( *UTC, 4, 8 ); + // printf("\n"); + Lgm_UTC_to_TT(UTC, &TT, c); + // printf("\tLgm_UTC_to_TDB: TT: "); Lgm_Print_DateTime( TT, 4, 8 ); + // printf("\n"); + Lgm_TT_to_TDB(&TT, TDB, c); + // printf("\tLgm_UTC_to_TDB: TDB: "); Lgm_Print_DateTime( *TDB, 4, 8 ); + // printf("\n"); TDB->TimeSystem = LGM_TIME_SYS_TDB; return; } -void Lgm_TDB_to_UTC( Lgm_DateTime *TDB, Lgm_DateTime *UTC, Lgm_CTrans *c ) { +void Lgm_TDB_to_UTC(Lgm_DateTime* TDB, Lgm_DateTime* UTC, Lgm_CTrans* c) { Lgm_DateTime TT; -//printf("\tLgm_TDB_to_UTC: TDB: "); Lgm_Print_DateTime( *TDB, 4, 8 ); printf("\n"); - Lgm_TDB_to_TT( TDB, &TT, c ); -//printf("\tLgm_TDB_to_UTC: TT: "); Lgm_Print_DateTime( TT, 4, 8 ); printf("\n"); - Lgm_TT_to_UTC( &TT, UTC, c ); -//printf("\tLgm_TDB_to_UTC: UTC: "); Lgm_Print_DateTime( *UTC, 4, 8 ); printf("\n"); + // printf("\tLgm_TDB_to_UTC: TDB: "); Lgm_Print_DateTime( *TDB, 4, 8 ); + // printf("\n"); + Lgm_TDB_to_TT(TDB, &TT, c); + // printf("\tLgm_TDB_to_UTC: TT: "); Lgm_Print_DateTime( TT, 4, 8 ); + // printf("\n"); + Lgm_TT_to_UTC(&TT, UTC, c); + // printf("\tLgm_TDB_to_UTC: UTC: "); Lgm_Print_DateTime( *UTC, 4, 8 ); + // printf("\n"); UTC->TimeSystem = LGM_TIME_SYS_UTC; return; } +Lgm_DateTime* Lgm_DateTime_Create(int Year, + int Month, + int Day, + double Time, + int TimeSystem, + Lgm_CTrans* c) { + double t; + Lgm_DateTime* d; + + d = calloc(1, sizeof(Lgm_DateTime)); + + d->Date = Year * 10000 + Month * 100 + Day; + d->Time = Time; + Lgm_Doy(d->Date, &d->Year, &d->Month, &d->Day, &d->Doy); + d->JD = Lgm_JD(d->Year, d->Month, d->Day, d->Time, TimeSystem, c); + d->Date = Lgm_JD_to_Date(d->JD, &d->Year, &d->Month, &d->Day, &t); + // we could just set UTC->Time to the t from the previous call, but t will + // have suffered round off errors. The following reduces roundoff errors. + if ((d->Time - t) > 12.0) { + d->Time -= 24.0; + } else if ((t - d->Time) > 12.0) { + d->Time += 24.0; + } - - - - - - - - -Lgm_DateTime *Lgm_DateTime_Create( int Year, int Month, int Day, double Time, int TimeSystem, Lgm_CTrans *c ) { - - double t; - Lgm_DateTime *d; - - d = calloc( 1, sizeof(Lgm_DateTime) ); - - d->Date = Year*10000 + Month*100 + Day; - d->Time = Time; - Lgm_Doy( d->Date, &d->Year, &d->Month, &d->Day, &d->Doy ); - d->JD = Lgm_JD( d->Year, d->Month, d->Day, d->Time, TimeSystem, c ); - d->Date = Lgm_JD_to_Date( d->JD, &d->Year, &d->Month, &d->Day, &t ); - // we could just set UTC->Time to the t from the previous call, but t will have - // suffered round off errors. The following reduces roundoff errors. - if ( (d->Time - t) > 12.0 ) { d->Time -= 24.0; } - else if ( (t - d->Time) > 12.0 ) { d->Time += 24.0; } - - if ( TimeSystem == LGM_TIME_SYS_UTC ) { - Lgm_IsLeapSecondDay( d->Date, &d->DaySeconds, c ); + if (TimeSystem == LGM_TIME_SYS_UTC) { + Lgm_IsLeapSecondDay(d->Date, &d->DaySeconds, c); } else { d->DaySeconds = 86400.0; } - d->Dow = Lgm_DayOfWeek( d->Year, d->Month, d->Day, d->DowStr ); - d->Time = Lgm_RemapTime( d->Time, d->DaySeconds ); - d->T = (d->JD - 2451545.0)/36525.0; - d->fYear = (double)d->Year + ((double)d->Doy + d->Time/24.0)/(365.0 + (double)Lgm_LeapYear(d->Year)); + d->Dow = Lgm_DayOfWeek(d->Year, d->Month, d->Day, d->DowStr); + d->Time = Lgm_RemapTime(d->Time, d->DaySeconds); + d->T = (d->JD - 2451545.0) / 36525.0; + d->fYear = (double)d->Year + ((double)d->Doy + d->Time / 24.0) / + (365.0 + (double)Lgm_LeapYear(d->Year)); d->TimeSystem = TimeSystem; - return(d); - + return (d); } -void Lgm_DateTime_Destroy( Lgm_DateTime *d ) { - free( d ); +void Lgm_DateTime_Destroy(Lgm_DateTime* d) { + free(d); } - - /* * Fills up a UTC DateTime Structure. */ -int Lgm_Make_UTC( long int Date, double Time, Lgm_DateTime *UTC, Lgm_CTrans *c ) { - - double t; - int year, month, day, doy; +int Lgm_Make_UTC(long int Date, double Time, Lgm_DateTime* UTC, Lgm_CTrans* c) { + double t; + int year, month, day, doy; - Lgm_Doy( Date, &year, &month, &day, &doy ); - UTC->Date = year*10000 + month*100 + day; - UTC->Year = year; - UTC->Month = month; - UTC->Day = day; - UTC->Doy = doy; - UTC->Time = Time; -//printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, UTC->Time); + Lgm_Doy(Date, &year, &month, &day, &doy); + UTC->Date = year * 10000 + month * 100 + day; + UTC->Year = year; + UTC->Month = month; + UTC->Day = day; + UTC->Doy = doy; + UTC->Time = Time; + // printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d + // %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, + // UTC->Time); // convert to JD. - UTC->JD = Lgm_JD( UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c ); -//printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, UTC->Time); - - UTC->Date = Lgm_JD_to_Date( UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &t ); - - // redo the Doy calcs in case we got a new date (e.g. due to Time beingm > 24.0) - Lgm_Doy( UTC->Date, &UTC->Year, &UTC->Month, &UTC->Day, &UTC->Doy ); -//printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time, t = %ld, %d %d %d %d %lf %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, UTC->Time, t); - - // we could just set UTC->Time to the t from the previous call, but t will have - // suffered round off errors. The following reduces roundoff errors. - if ( (UTC->Time - t) > 12.0 ) { UTC->Time -= 24.0; } - else if ( (t - UTC->Time) > 12.0 ) { UTC->Time += 24.0; } -//printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, UTC->Time); - Lgm_IsLeapSecondDay( UTC->Date, &UTC->DaySeconds, c ); - UTC->Time = Lgm_RemapTime( UTC->Time, UTC->DaySeconds ); -//printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, UTC->Time); - UTC->T = (UTC->JD - 2451545.0)/36525.0; - UTC->fYear = (double)UTC->Year + ((double)UTC->Doy + UTC->Time/24.0)/(365.0 + (double)Lgm_LeapYear(UTC->Year)); + UTC->JD = + Lgm_JD(UTC->Year, UTC->Month, UTC->Day, UTC->Time, LGM_TIME_SYS_UTC, c); + // printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d + // %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, + // UTC->Time); + + UTC->Date = Lgm_JD_to_Date(UTC->JD, &UTC->Year, &UTC->Month, &UTC->Day, &t); + + // redo the Doy calcs in case we got a new date (e.g. due to Time beingm + // > 24.0) + Lgm_Doy(UTC->Date, &UTC->Year, &UTC->Month, &UTC->Day, &UTC->Doy); + // printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time, t = %ld, %d %d + // %d %d %lf %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, + // UTC->Time, t); + + // we could just set UTC->Time to the t from the previous call, but t will + // have suffered round off errors. The following reduces roundoff errors. + if ((UTC->Time - t) > 12.0) { + UTC->Time -= 24.0; + } else if ((t - UTC->Time) > 12.0) { + UTC->Time += 24.0; + } + // printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d + // %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, + // UTC->Time); + Lgm_IsLeapSecondDay(UTC->Date, &UTC->DaySeconds, c); + UTC->Time = Lgm_RemapTime(UTC->Time, UTC->DaySeconds); + // printf("Lgm_Make_UTC: Date, Year, Month, Day, Doy, Time = %ld, %d %d %d + // %d %lf\n", UTC->Date, UTC->Year, UTC->Month, UTC->Day, UTC->Doy, + // UTC->Time); + UTC->T = (UTC->JD - 2451545.0) / 36525.0; + UTC->fYear = + (double)UTC->Year + ((double)UTC->Doy + UTC->Time / 24.0) / + (365.0 + (double)Lgm_LeapYear(UTC->Year)); UTC->TimeSystem = LGM_TIME_SYS_UTC; t = UTC->Time; - UTC->Hour = (int)t; t = (t - UTC->Hour)*60.0; - UTC->Minute = (int)t; t = (t - UTC->Minute)*60.0; + UTC->Hour = (int)t; + t = (t - UTC->Hour) * 60.0; + UTC->Minute = (int)t; + t = (t - UTC->Minute) * 60.0; UTC->Second = t; - UTC->Dow = Lgm_DayOfWeek( UTC->Year, UTC->Month, UTC->Day, UTC->DowStr ); - UTC->Week = Lgm_ISO_WeekNumber( UTC->Year, UTC->Month, UTC->Day, &UTC->wYear ); - - return( 1 ); // eventually return FALSE if invalid date. + UTC->Dow = Lgm_DayOfWeek(UTC->Year, UTC->Month, UTC->Day, UTC->DowStr); + UTC->Week = + Lgm_ISO_WeekNumber(UTC->Year, UTC->Month, UTC->Day, &UTC->wYear); + return (1); // eventually return FALSE if invalid date. } - - /* * This routine prints out time in different ways. * @@ -982,177 +1105,214 @@ int Lgm_Make_UTC( long int Date, double Time, Lgm_DateTime *UTC, Lgm_CTrans *c ) * Controls how many decimals to print for the seconds. * Max of 20 (-- although prob more than machine prec.) */ -void Lgm_Print_DateTime( Lgm_DateTime *DT, int Style, int p ){ - char *Str= calloc( 128, sizeof(char) ); - Lgm_DateTimeToString( Str, DT, Style, p ); +void Lgm_Print_DateTime(Lgm_DateTime* DT, int Style, int p) { + char* Str = calloc(128, sizeof(char)); + Lgm_DateTimeToString(Str, DT, Style, p); printf("%s", Str); free(Str); } -void Lgm_DateTimeToString( char *Str, Lgm_DateTime *DT, int Style, int p ){ - int HH, MM, SS, sgn, leapsec; - int Year, Month, d; - double S, SFRAC, Seconds, TotalSeconds; - char SecFracStr[30]; +void Lgm_DateTimeToString(char* Str, Lgm_DateTime* DT, int Style, int p) { + int HH, MM, SS, sgn, leapsec; + int Year, Month, d; + double S, SFRAC, Seconds, TotalSeconds; + char SecFracStr[30]; leapsec = (int)(DT->DaySeconds - 86400.0); // Total Number of Seconds - leapsecs - Seconds = DT->Time*3600.0; + Seconds = DT->Time * 3600.0; TotalSeconds = Seconds; - + // Hours - HH = (int)(Seconds/3600.0); - Seconds -= HH*3600.0; + HH = (int)(Seconds / 3600.0); + Seconds -= HH * 3600.0; // Minutes - MM = (int)(Seconds/60.0); - Seconds -= MM*60.0; + MM = (int)(Seconds / 60.0); + Seconds -= MM * 60.0; -// Lgm_UT_to_HMSd( DT->Time, &sgn, &HH, &MM, &S ); + // Lgm_UT_to_HMSd( DT->Time, &sgn, &HH, &MM, &S ); sgn = 1; + S = fabs(Seconds) + pow(10.0, -1.0 - p); + SS = (int)S; + SFRAC = S - (double)SS; - S = fabs(Seconds)+pow(10.0, -1.0-p ); - SS = (int)S; - SFRAC = S-(double)SS; - - - if (( p <= 0 ) && ( SFRAC >= 0.5)) { SS += 1; } - + if ((p <= 0) && (SFRAC >= 0.5)) { + SS += 1; + } - sprintf( SecFracStr, "%.*lf", (p>=20)?20:p, SFRAC ); - if ( leapsec && (TotalSeconds>=86400.0) && (TotalSeconds<86401.0) ){ - HH = 23; MM = 59; SS = 60; + sprintf(SecFracStr, "%.*lf", (p >= 20) ? 20 : p, SFRAC); + if (leapsec && (TotalSeconds >= 86400.0) && (TotalSeconds < 86401.0)) { + HH = 23; + MM = 59; + SS = 60; } else { - if (SS==(60)) { SS=0; ++MM; } - if (MM==60) { MM=0; ++HH; } + if (SS == (60)) { + SS = 0; + ++MM; + } + if (MM == 60) { + MM = 0; + ++HH; + } } - d = DT->Date; Year = d/10000; - d = d - Year*10000; Month = d/100; - d = d - Month*100; + d = DT->Date; + Year = d / 10000; + d = d - Year * 10000; + Month = d / 100; + d = d - Month * 100; // probably a cleaner way to do this(?) // Styles 0, 1, and 2 are ISO compliant...(check?) - if ( p <= 0 ) { - if ( Style == 0 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%02d-%02d-%02dT%02d:%02d:%02dZ", Year, Month, d, HH, MM, SS ); - else - sprintf( Str, "%02d-%02d-%02dT%02d:%02d:%02d", Year, Month, d, HH, MM, SS ); - } else if ( Style == 1 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%8ldT%02d%02d%02dZ", DT->Date, HH, MM, SS ); - else - sprintf( Str, "%8ldT%02d%02d%02d", DT->Date, HH, MM, SS ); - } else if ( Style == 2 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%8ld %02d:%02d:%02dZ", DT->Date, HH, MM, SS ); - else - sprintf( Str, "%8ld %02d:%02d:%02d", DT->Date, HH, MM, SS ); - } else if ( Style == 3 ) { - if (sgn<0) sprintf( Str, "%8ld -%02d:%02d:%02d", DT->Date, HH, MM, SS ); - else sprintf( Str, "%8ld %02d:%02d:%02d", DT->Date, HH, MM, SS ); + if (p <= 0) { + if (Style == 0) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%02d-%02d-%02dT%02d:%02d:%02dZ", Year, Month, d, + HH, MM, SS); + else + sprintf(Str, "%02d-%02d-%02dT%02d:%02d:%02d", Year, Month, d, + HH, MM, SS); + } else if (Style == 1) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%8ldT%02d%02d%02dZ", DT->Date, HH, MM, SS); + else + sprintf(Str, "%8ldT%02d%02d%02d", DT->Date, HH, MM, SS); + } else if (Style == 2) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%8ld %02d:%02d:%02dZ", DT->Date, HH, MM, SS); + else + sprintf(Str, "%8ld %02d:%02d:%02d", DT->Date, HH, MM, SS); + } else if (Style == 3) { + if (sgn < 0) + sprintf(Str, "%8ld -%02d:%02d:%02d", DT->Date, HH, MM, SS); + else + sprintf(Str, "%8ld %02d:%02d:%02d", DT->Date, HH, MM, SS); } else { - if (sgn<0) sprintf( Str, "%8ld -%02d\u02b0 %02d\u1d50 %02d\u02e2", DT->Date, HH, MM, SS ); - else sprintf( Str, "%8ld %02d\u02b0 %02d\u1d50 %02d\u02e2", DT->Date, HH, MM, SS ); + if (sgn < 0) + sprintf(Str, "%8ld -%02d\u02b0 %02d\u1d50 %02d\u02e2", DT->Date, + HH, MM, SS); + else + sprintf(Str, "%8ld %02d\u02b0 %02d\u1d50 %02d\u02e2", DT->Date, + HH, MM, SS); } } else { - if ( Style == 0 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%02d-%02d-%02dT%02d:%02d:%02d.%sZ", Year, Month, d, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else - sprintf( Str, "%02d-%02d-%02dT%02d:%02d:%02d.%s", Year, Month, d, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - } else if ( Style == 1 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%8ldT%02d%02d%02d.%sZ", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else - sprintf( Str, "%8ldT%02d%02d%02d.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - } else if ( Style == 2 ) { - if ( DT->TimeSystem == LGM_TIME_SYS_UTC ) - sprintf( Str, "%8ld %02d:%02d:%02d.%sZ", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else - sprintf( Str, "%8ld %02d:%02d:%02d.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - } else if ( Style == 3 ) { - if (sgn<0) sprintf( Str, "%8ld -%02d:%02d:%02d.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else sprintf( Str, "%8ld %02d:%02d:%02d.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); + if (Style == 0) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%02d-%02d-%02dT%02d:%02d:%02d.%sZ", Year, Month, + d, HH, MM, SS, strstr(SecFracStr, ".") + 1); + else + sprintf(Str, "%02d-%02d-%02dT%02d:%02d:%02d.%s", Year, Month, d, + HH, MM, SS, strstr(SecFracStr, ".") + 1); + } else if (Style == 1) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%8ldT%02d%02d%02d.%sZ", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); + else + sprintf(Str, "%8ldT%02d%02d%02d.%s", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); + } else if (Style == 2) { + if (DT->TimeSystem == LGM_TIME_SYS_UTC) + sprintf(Str, "%8ld %02d:%02d:%02d.%sZ", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); + else + sprintf(Str, "%8ld %02d:%02d:%02d.%s", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); + } else if (Style == 3) { + if (sgn < 0) + sprintf(Str, "%8ld -%02d:%02d:%02d.%s", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); + else + sprintf(Str, "%8ld %02d:%02d:%02d.%s", DT->Date, HH, MM, SS, + strstr(SecFracStr, ".") + 1); } else { - if (sgn<0) sprintf( Str, "%8ld -%02d\u02b0 %02d\u1d50 %02d\u02e2.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); - else sprintf( Str, "%8ld %02d\u02b0 %02d\u1d50 %02d\u02e2.%s", DT->Date, HH, MM, SS, strstr(SecFracStr, ".")+1 ); + if (sgn < 0) + sprintf(Str, "%8ld -%02d\u02b0 %02d\u1d50 %02d\u02e2.%s", + DT->Date, HH, MM, SS, strstr(SecFracStr, ".") + 1); + else + sprintf(Str, "%8ld %02d\u02b0 %02d\u1d50 %02d\u02e2.%s", + DT->Date, HH, MM, SS, strstr(SecFracStr, ".") + 1); } } - } - -void Lgm_Print_SimpleTime( Lgm_DateTime *DT, int p, char *Str ){ - int HH, MM, SS, sgn, leapsec; - int Year, Month, d; - double S, SFRAC, Seconds, TotalSeconds; - char SecFracStr[30]; +void Lgm_Print_SimpleTime(Lgm_DateTime* DT, int p, char* Str) { + int HH, MM, SS, sgn, leapsec; + int Year, Month, d; + double S, SFRAC, Seconds, TotalSeconds; + char SecFracStr[30]; leapsec = (int)(DT->DaySeconds - 86400.0); // Total Number of Seconds - leapsecs - Seconds = DT->Time*3600.0; + Seconds = DT->Time * 3600.0; TotalSeconds = Seconds; - + // Hours - HH = (int)(Seconds/3600.0); - Seconds -= HH*3600.0; + HH = (int)(Seconds / 3600.0); + Seconds -= HH * 3600.0; // Minutes - MM = (int)(Seconds/60.0); - Seconds -= MM*60.0; + MM = (int)(Seconds / 60.0); + Seconds -= MM * 60.0; -// Lgm_UT_to_HMSd( DT.Time, &sgn, &HH, &MM, &S ); + // Lgm_UT_to_HMSd( DT.Time, &sgn, &HH, &MM, &S ); sgn = 1; + S = fabs(Seconds) + pow(10.0, -1.0 - p); + SS = (int)S; + SFRAC = S - (double)SS; - S = fabs(Seconds)+pow(10.0, -1.0-p ); - SS = (int)S; - SFRAC = S-(double)SS; - - - if (( p <= 0 ) && ( SFRAC >= 0.5)) { SS += 1; } - + if ((p <= 0) && (SFRAC >= 0.5)) { + SS += 1; + } - sprintf( SecFracStr, "%.*lf", (p>=20)?20:p, SFRAC ); - if ( leapsec && (TotalSeconds>=86400.0) && (TotalSeconds<86401.0) ){ - HH = 23; MM = 59; SS = 60; - } else { - if (SS==(60)) { SS=0; ++MM; } - if (MM==60) { MM=0; ++HH; } + sprintf(SecFracStr, "%.*lf", (p >= 20) ? 20 : p, SFRAC); + if (leapsec && (TotalSeconds >= 86400.0) && (TotalSeconds < 86401.0)) { + HH = 23; + MM = 59; + SS = 60; + } else { + if (SS == (60)) { + SS = 0; + ++MM; + } + if (MM == 60) { + MM = 0; + ++HH; + } } - d = DT->Date; Year = d/10000; - d = d - Year*10000; Month = d/100; - d = d - Month*100; + d = DT->Date; + Year = d / 10000; + d = d - Year * 10000; + Month = d / 100; + d = d - Month * 100; // probably a cleaner way to do this(?) - if ( p <= 0 ) { - sprintf(Str, "%02d:%02d:%02d", HH, MM, SS ); + if (p <= 0) { + sprintf(Str, "%02d:%02d:%02d", HH, MM, SS); } else { - sprintf(Str, "%02d:%02d:%02d.%s", HH, MM, SS, strstr(SecFracStr, ".")+1 ); + sprintf(Str, "%02d:%02d:%02d.%s", HH, MM, SS, + strstr(SecFracStr, ".") + 1); } - } - /* * Compute the Julian Date for the given Gregorian Date and Time. * Julian Date is the number of days since noon of Jan 1 4713 B.C. * Only need to worry about leap seconds if TimeSystem is UTC. - * + * * Computes the Julian Date for a given time. Recall that JDN is an integer - * corresponding to noon on the given Gregorian date. Thus, + * corresponding to noon on the given Gregorian date. Thus, * - * JDN - 0.5 + * JDN - 0.5 * * is the Julian Date at the beginning of the day. And, * - * JDN - 0.5 + FractionOfDay + * JDN - 0.5 + FractionOfDay * * is the Julian date corresponding to the given Time. Note that the Julian * Date can be constructed from times in different time systems (e.g. UTC, @@ -1163,43 +1323,43 @@ void Lgm_Print_SimpleTime( Lgm_DateTime *DT, int p, char *Str ){ * routine first computes the number of secons in a day, then computes the * fraction of a day. This fraction is then added on to the Julian Date at the * beginning of the day (i.e. JDN-0.5). - * + * */ -double Lgm_JD( int Year, int Month, int Day, double Time, int TimeSystem, Lgm_CTrans *c ) { - - long int Date, JDN; - double ns, FracDay, JD; +double Lgm_JD(int Year, + int Month, + int Day, + double Time, + int TimeSystem, + Lgm_CTrans* c) { + long int Date, JDN; + double ns, FracDay, JD; // Get JDN - JDN = Lgm_JDN( Year, Month, Day ); -//printf("JDN, Year, Month, Day = %ld %d %d %d\n", JDN, Year, Month, Day); + JDN = Lgm_JDN(Year, Month, Day); + // printf("JDN, Year, Month, Day = %ld %d %d %d\n", JDN, Year, Month, Day); // Form Date - Date = Year*10000 + Month*100 + Day; + Date = Year * 10000 + Month * 100 + Day; // Set number of seconds in this day -- only applies to UTC system - if ( TimeSystem == LGM_TIME_SYS_UTC ) { - Lgm_IsLeapSecondDay( Date, &ns, c ); + if (TimeSystem == LGM_TIME_SYS_UTC) { + Lgm_IsLeapSecondDay(Date, &ns, c); // Compute fractional part of current day - FracDay = Time*3600.0/ns; + FracDay = Time * 3600.0 / ns; } else { ns = 86400.0; // Compute fractional part of current day - FracDay = Time/24.0; + FracDay = Time / 24.0; } -//printf("ns = %lf\n", ns); - + // printf("ns = %lf\n", ns); // Shift back to midnight and then add in the Fractional part JD = JDN - 0.5 + FracDay; -//printf("FracDay = %lf\n", FracDay); - - return( JD ); + // printf("FracDay = %lf\n", FracDay); + return (JD); } - - /* * Compute the Julian Day Number for the given Gregorian Date. * Julian Date is the number of days since noon of Jan 1 4713 B.C. @@ -1207,434 +1367,403 @@ double Lgm_JD( int Year, int Month, int Day, double Time, int TimeSystem, Lgm_CT * The long integer number returned here is the Julian Day Number * for Noon on the given calendar date. */ -long int Lgm_JDN( int Year, int Month, int Day ) { - int q = (Month < 3 ) ? -1 : 0; +long int Lgm_JDN(int Year, int Month, int Day) { + int q = (Month < 3) ? -1 : 0; // Compute integer part of julian date - return( (1461*(Year + 4800 + q))/4 + (367*(Month - 2 - 12*q))/12 - - (3*((Year + 4900 + q)/100))/4 + Day - 32075 ); + return ((1461 * (Year + 4800 + q)) / 4 + (367 * (Month - 2 - 12 * q)) / 12 - + (3 * ((Year + 4900 + q) / 100)) / 4 + Day - 32075); } - - -double Lgm_MJD(int ny, int nm, int nd, double UT, int TimeSystem, Lgm_CTrans *c ) { - return( Lgm_JD( ny, nm, nd, UT, TimeSystem, c ) - 2400000.5 ); +double Lgm_MJD(int ny, + int nm, + int nd, + double UT, + int TimeSystem, + Lgm_CTrans* c) { + return (Lgm_JD(ny, nm, nd, UT, TimeSystem, c) - 2400000.5); } - -double Lgm_Date_to_JD( long int Date, double UT, Lgm_CTrans *c) { - +double Lgm_Date_to_JD(long int Date, double UT, Lgm_CTrans* c) { int year, month, day, doy; - Lgm_Doy( Date, &year, &month, &day, &doy); - return( Lgm_JD( year, month, day, UT, LGM_TIME_SYS_UTC, c) ); - + Lgm_Doy(Date, &year, &month, &day, &doy); + return (Lgm_JD(year, month, day, UT, LGM_TIME_SYS_UTC, c)); } -int Lgm_DayOfYear(int year, int month, int day, Lgm_CTrans *c) { - return((int)(Lgm_JD(year, month, day, 0.0, LGM_TIME_SYS_UTC, c) - Lgm_JD(year, 1, 0, 0.0, LGM_TIME_SYS_UTC, c))); +int Lgm_DayOfYear(int year, int month, int day, Lgm_CTrans* c) { + return ((int)(Lgm_JD(year, month, day, 0.0, LGM_TIME_SYS_UTC, c) - + Lgm_JD(year, 1, 0, 0.0, LGM_TIME_SYS_UTC, c))); } - - - /* * Here the number goes from 0-6 Sun-Sat. * But ISO 8601 goes from: 1 is Monday to 7 is Sunday - * In the Lgm_DateTime struct we will use ISO defs thats why the last bit that changes 0 to 7 if we get a zero.... + * In the Lgm_DateTime struct we will use ISO defs thats why the last bit that + * changes 0 to 7 if we get a zero.... */ -int Lgm_DayOfWeek( int Year, int Month, int Day, char *dowstr ) { - +int Lgm_DayOfWeek(int Year, int Month, int Day, char* dowstr) { int q, m, K, J, Y, h, d; - q = Day; - m = Month; + q = Day; + m = Month; Y = Year; - if (m<3){ - --Y; - m+=12; + if (m < 3) { + --Y; + m += 12; + } + K = Y % 100; + J = Year / 100; + + h = (q + (((m + 1) * 26) / 10) + Y + (Y / 4) + 6 * (Y / 100) + (Y / 400)) % + 7; + d = ((h + 5) % 7) + 1; + + if (d == 1) { + strcpy(dowstr, "Mon"); + } else if (d == 2) { + strcpy(dowstr, "Tue"); + } else if (d == 3) { + strcpy(dowstr, "Wed"); + } else if (d == 4) { + strcpy(dowstr, "Thu"); + } else if (d == 5) { + strcpy(dowstr, "Fri"); + } else if (d == 6) { + strcpy(dowstr, "Sat"); + } else if (d == 7) { + strcpy(dowstr, "Sun"); } - K = Y%100; - J = Year/100; - - h = ( q + (((m+1)*26)/10) + Y + (Y/4) + 6*(Y/100) + (Y/400))%7; - d = ((h+5)%7)+1; - - if ( d == 1 ) { strcpy(dowstr, "Mon"); } - else if ( d == 2 ) { strcpy(dowstr, "Tue"); } - else if ( d == 3 ) { strcpy(dowstr, "Wed"); } - else if ( d == 4 ) { strcpy(dowstr, "Thu"); } - else if ( d == 5 ) { strcpy(dowstr, "Fri"); } - else if ( d == 6 ) { strcpy(dowstr, "Sat"); } - else if ( d == 7 ) { strcpy(dowstr, "Sun"); } - - - return(d); + return (d); } /* * Compute the JDN of the start of week 1 for the given year * This relies on the fact that Jan 4 is always in the first week of its year. */ -long int Lgm_JDNofWeek1( int Year ) { - char str[10]; - int Dow_JAN4 = Lgm_DayOfWeek( Year, 1, 4, str ); - long int JDN_JAN4 = Lgm_JDN( Year, 1, 4 ); - return( JDN_JAN4 + 1 - Dow_JAN4 ); +long int Lgm_JDNofWeek1(int Year) { + char str[10]; + int Dow_JAN4 = Lgm_DayOfWeek(Year, 1, 4, str); + long int JDN_JAN4 = Lgm_JDN(Year, 1, 4); + return (JDN_JAN4 + 1 - Dow_JAN4); } /* * Compute ISO week number */ -int Lgm_ISO_WeekNumber( int Year, int Month, int Day, int *ISO_WeekYear ) { - - int ISO_Year = Year; - long int JDN_DEC29 = Lgm_JDN( Year, 12, 29 ); - long int JDN = Lgm_JDN( Year, Month, Day ); +int Lgm_ISO_WeekNumber(int Year, int Month, int Day, int* ISO_WeekYear) { + int ISO_Year = Year; + long int JDN_DEC29 = Lgm_JDN(Year, 12, 29); + long int JDN = Lgm_JDN(Year, Month, Day); long int JDN_Week1; - if ( JDN >= JDN_DEC29 ) { - JDN_Week1 = Lgm_JDNofWeek1( ISO_Year+1 ); - if ( JDN < JDN_Week1 ){ - JDN_Week1 = Lgm_JDNofWeek1( ISO_Year ); + if (JDN >= JDN_DEC29) { + JDN_Week1 = Lgm_JDNofWeek1(ISO_Year + 1); + if (JDN < JDN_Week1) { + JDN_Week1 = Lgm_JDNofWeek1(ISO_Year); } else { ++ISO_Year; } } else { - JDN_Week1 = Lgm_JDNofWeek1( ISO_Year ); - if ( JDN < JDN_Week1 ) JDN_Week1 = Lgm_JDNofWeek1( --ISO_Year ); + JDN_Week1 = Lgm_JDNofWeek1(ISO_Year); + if (JDN < JDN_Week1) + JDN_Week1 = Lgm_JDNofWeek1(--ISO_Year); } *ISO_WeekYear = ISO_Year; - return( (JDN-JDN_Week1)/7 + 1 ); - + return ((JDN - JDN_Week1) / 7 + 1); } - /* * Compute the last week of the year. It can be 52 or 53. * This relies on the fact that Dec 28 is always in the last week of its year. */ -int Lgm_MaxWeekNumber( int Year ) { +int Lgm_MaxWeekNumber(int Year) { int tmp; - return( Lgm_ISO_WeekNumber( Year, 12, 28, &tmp ) ); + return (Lgm_ISO_WeekNumber(Year, 12, 28, &tmp)); } /* * Convert ISO_WeekYear/Week/Dow back to Date */ -void Lgm_ISO_YearWeekDow_to_Date( int ISO_WeekYear, int Week, int Dow, long int *Date, int *Year, int *Month, int *Day ) { - long int JDN_Week1 = Lgm_JDNofWeek1( ISO_WeekYear ); - long int JDN = JDN_Week1 + 7*(Week-1) + Dow - 1; - double tmp; - Lgm_jd_to_ymdh( JDN, Date, Year, Month, Day, &tmp); +void Lgm_ISO_YearWeekDow_to_Date(int ISO_WeekYear, + int Week, + int Dow, + long int* Date, + int* Year, + int* Month, + int* Day) { + long int JDN_Week1 = Lgm_JDNofWeek1(ISO_WeekYear); + long int JDN = JDN_Week1 + 7 * (Week - 1) + Dow - 1; + double tmp; + Lgm_jd_to_ymdh(JDN, Date, Year, Month, Day, &tmp); } - - /* - * Routine converts between day number and mmdd formats. Input date can be in any of the following - * formats; - * yyddd (where yy is assumed to be a year in the 20th century) - * yymmdd (where yy is assumed to be a year in the 20th century) - * yyyyddd (where yyyy is assumed to be between 1000 A.D. and 9999 A.D.) - * yyyymmdd (where yyyy is assumed to be between 1000 A.D. and 9999 A.D.) + * Routine converts between day number and mmdd formats. Input date can be in + * any of the following formats; yyddd (where yy is assumed to be a year in + * the 20th century) yymmdd (where yy is assumed to be a year in the 20th + * century) yyyyddd (where yyyy is assumed to be between 1000 A.D. and 9999 + * A.D.) yyyymmdd (where yyyy is assumed to be between 1000 A.D. and 9999 A.D.) * - * Should be good enough for space physics! Need separate routines or add a flag or something - * if you want it to be completely general.... Its not completely general now but it is - * convenient. + * Should be good enough for space physics! Need separate routines or add a + * flag or something if you want it to be completely general.... Its not + * completely general now but it is convenient. * */ -int Lgm_Doy( long int date, int *YY, int *MM, int *DD, int *DOY) { - +int Lgm_Doy(long int date, int* YY, int* MM, int* DD, int* DOY) { int ddd, n, i, m; double f; static double days1[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static double days2[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - if ((date < 1e5)||((date < 1e7)&&(date > 1e6))){ /* then the date is in yyddd or yyyyddd format */ - *YY = (int)(date/1000.0); - *DOY = date - *YY * 1000; - if (date < 1e5) *YY += 1900; - - ddd = 0, n = 0; - if (Lgm_LeapYear(*YY)){ - while ( (ddd+days2[n]) < *DOY) { - ddd += days2[n]; - ++n; + if ((date < 1e5) || + ((date < 1e7) && + (date > 1e6))) { /* then the date is in yyddd or yyyyddd format */ + *YY = (int)(date / 1000.0); + *DOY = date - *YY * 1000; + if (date < 1e5) + *YY += 1900; + + ddd = 0, n = 0; + if (Lgm_LeapYear(*YY)) { + while ((ddd + days2[n]) < *DOY) { + ddd += days2[n]; + ++n; + } + } else { + while ((ddd + days1[n]) < *DOY) { + ddd += days1[n]; + ++n; + } } - } - else{ - while ( (ddd+days1[n]) < *DOY) { - ddd += days1[n]; - ++n; + *MM = n + 1; + *DD = *DOY - ddd; + } else { /* then the date is in yymmdd or yyyymmdd format */ + f = date / 10000.0; + *YY = (int)f; + + f = date - *YY * 10000; + *MM = (int)(f / 100.0); + m = *MM - 1; + + f = f - *MM * 100; + *DD = (int)f; + + if (Lgm_LeapYear((date < 1e7) ? 1900 + *YY : *YY)) { + for (i = 0, ddd = 0; i < m; ++i) + ddd += days2[i]; + } else { + for (i = 0, ddd = 0; i < m; ++i) + ddd += days1[i]; } - } - *MM = n+1; - *DD = *DOY - ddd; - } - else{ /* then the date is in yymmdd or yyyymmdd format */ - f = date/10000.0; - *YY = (int)f; - - f = date - *YY * 10000; - *MM = (int)(f/100.0); - m = *MM - 1; - - f = f - *MM * 100; - *DD = (int)f; - - if (Lgm_LeapYear( (date < 1e7) ? 1900 + *YY : *YY )){ - for (i=0, ddd=0; i 12)) return(0); + if ((mm < 1) || (mm > 12)) + return (0); - if (dd < 1) return(0); + if (dd < 1) + return (0); - if (Lgm_LeapYear(yy)){ - if (dd > mdays2[mm-1]) return(0); + if (Lgm_LeapYear(yy)) { + if (dd > mdays2[mm - 1]) + return (0); } else { - if (dd > mdays[mm-1]) return(0); + if (dd > mdays[mm - 1]) + return (0); } /* * Must be a valid date (at least in terms of month and day) */ - return(1); - + return (1); } -double Lgm_RemapTime( double Time, double SecondsInADay ) { +double Lgm_RemapTime(double Time, double SecondsInADay) { + double Seconds; - double Seconds; + Seconds = Time * 3600.0; - Seconds = Time*3600.0; + if (Seconds < 0.0) + Seconds += SecondsInADay; + if (Seconds >= SecondsInADay) + Seconds -= SecondsInADay; - if ( Seconds < 0.0 ) Seconds += SecondsInADay; - if ( Seconds >= SecondsInADay ) Seconds -= SecondsInADay; - - Time = Seconds/3600.0; - - return(Time); + Time = Seconds / 3600.0; + return (Time); } - - - - - - /* * We really should examine the TimeSystem field in the Lgm_DateTime structure * and convert appropriately . But for now lets just assume input is in UTc. */ -double Lgm_UTC_to_TDBSeconds( Lgm_DateTime *UTC, Lgm_CTrans *c ){ - return( Lgm_TDBSecSinceJ2000( UTC, c ) ); +double Lgm_UTC_to_TDBSeconds(Lgm_DateTime* UTC, Lgm_CTrans* c) { + return (Lgm_TDBSecSinceJ2000(UTC, c)); } - /* * TDBSecSinceJ2000 is like SPICE's 'ephemeris time'. Probably differs in 7th * decimal place or so. Convenience rotuine to get TdbSecSinceJ2000 driectly * from UTC rather than from TDB */ -double Lgm_TDBSecSinceJ2000( Lgm_DateTime *UTC, Lgm_CTrans *c ){ - - long int JDN; - double DaySeconds, Seconds; - Lgm_DateTime TDB; +double Lgm_TDBSecSinceJ2000(Lgm_DateTime* UTC, Lgm_CTrans* c) { + long int JDN; + double DaySeconds, Seconds; + Lgm_DateTime TDB; // Convet to TDB - Lgm_UTC_to_TDB( UTC, &TDB, c ); + Lgm_UTC_to_TDB(UTC, &TDB, c); // Get JDN - JDN = Lgm_JDN( TDB.Year, TDB.Month, TDB.Day ); + JDN = Lgm_JDN(TDB.Year, TDB.Month, TDB.Day); // Get seconds past start of day (i.e. midnight) - DaySeconds = TDB.Time*3600.0; + DaySeconds = TDB.Time * 3600.0; // Compute Seconds since J2000 - Seconds = ((JDN-LGM_JD_J2000)*86400 - 43200) + DaySeconds; - - return( Seconds ); + Seconds = ((JDN - LGM_JD_J2000) * 86400 - 43200) + DaySeconds; + return (Seconds); } - - -double Lgm_TDB_to_TdbSecSinceJ2000( Lgm_DateTime *TDB ) { - double JDN, Seconds; - JDN = Lgm_JDN( TDB->Year, TDB->Month, TDB->Day ); - Seconds = ((JDN - LGM_JD_J2000)*86400.0 - 43200.0) + TDB->Time*3600.0; - return( Seconds ); +double Lgm_TDB_to_TdbSecSinceJ2000(Lgm_DateTime* TDB) { + double JDN, Seconds; + JDN = Lgm_JDN(TDB->Year, TDB->Month, TDB->Day); + Seconds = ((JDN - LGM_JD_J2000) * 86400.0 - 43200.0) + TDB->Time * 3600.0; + return (Seconds); } -void Lgm_TdbSecSinceJ2000_to_TDB( double TdbSeconds, Lgm_DateTime *TDB ) { - +void Lgm_TdbSecSinceJ2000_to_TDB(double TdbSeconds, Lgm_DateTime* TDB) { long int dJDN; - double tmp, JDN; - dJDN = (long int)((TdbSeconds + 43200.0)/86400.0); - TDB->Time = (TdbSeconds - dJDN*86400.0 + 43200.0)/3600.0; + double tmp, JDN; + dJDN = (long int)((TdbSeconds + 43200.0) / 86400.0); + TDB->Time = (TdbSeconds - dJDN * 86400.0 + 43200.0) / 3600.0; JDN = LGM_JD_J2000 + dJDN; - Lgm_jd_to_ymdh( JDN, &TDB->Date, &TDB->Year, &TDB->Month, &TDB->Day, &tmp); - - TDB->JD = JDN + TDB->Time/24.0; - TDB->T = (TDB->JD - 2451545.0)/36525.0; - TDB->TimeSystem = LGM_TIME_SYS_TDB; + Lgm_jd_to_ymdh(JDN, &TDB->Date, &TDB->Year, &TDB->Month, &TDB->Day, &tmp); + TDB->JD = JDN + TDB->Time / 24.0; + TDB->T = (TDB->JD - 2451545.0) / 36525.0; + TDB->TimeSystem = LGM_TIME_SYS_TDB; } -void Lgm_TdbSecSinceJ2000_to_UTC( double TdbSeconds, Lgm_DateTime *UTC, Lgm_CTrans *c ) { +void Lgm_TdbSecSinceJ2000_to_UTC(double TdbSeconds, + Lgm_DateTime* UTC, + Lgm_CTrans* c) { Lgm_DateTime TDB; - Lgm_TdbSecSinceJ2000_to_TDB( TdbSeconds, &TDB ); - Lgm_TDB_to_UTC( &TDB, UTC, c ); + Lgm_TdbSecSinceJ2000_to_TDB(TdbSeconds, &TDB); + Lgm_TDB_to_UTC(&TDB, UTC, c); UTC->TimeSystem = LGM_TIME_SYS_UTC; } -double Lgm_UTC_to_TdbSecSinceJ2000( Lgm_DateTime *UTC, Lgm_CTrans *c ) { +double Lgm_UTC_to_TdbSecSinceJ2000(Lgm_DateTime* UTC, Lgm_CTrans* c) { Lgm_DateTime TDB; - Lgm_UTC_to_TDB( UTC, &TDB, c ); - return( Lgm_TDB_to_TdbSecSinceJ2000( &TDB) ); + Lgm_UTC_to_TDB(UTC, &TDB, c); + return (Lgm_TDB_to_TdbSecSinceJ2000(&TDB)); } - - - - - - - /* * To TT */ -double Lgm_UTC_to_TTSeconds( Lgm_DateTime *UTC, Lgm_CTrans *c ){ - return( Lgm_TTSecSinceJ2000( UTC, c ) ); +double Lgm_UTC_to_TTSeconds(Lgm_DateTime* UTC, Lgm_CTrans* c) { + return (Lgm_TTSecSinceJ2000(UTC, c)); } - /* */ -double Lgm_TTSecSinceJ2000( Lgm_DateTime *UTC, Lgm_CTrans *c ){ - - long int JDN; - double DaySeconds, Seconds; - Lgm_DateTime TT; +double Lgm_TTSecSinceJ2000(Lgm_DateTime* UTC, Lgm_CTrans* c) { + long int JDN; + double DaySeconds, Seconds; + Lgm_DateTime TT; // Convet to TT - Lgm_UTC_to_TT( UTC, &TT, c ); + Lgm_UTC_to_TT(UTC, &TT, c); // Get JDN - JDN = Lgm_JDN( TT.Year, TT.Month, TT.Day ); + JDN = Lgm_JDN(TT.Year, TT.Month, TT.Day); // Get seconds past start of day (i.e. midnight) - DaySeconds = TT.Time*3600.0; + DaySeconds = TT.Time * 3600.0; // Compute Seconds since J2000 - Seconds = ((JDN-LGM_JD_J2000)*86400 - 43200) + DaySeconds; - - return( Seconds ); + Seconds = ((JDN - LGM_JD_J2000) * 86400 - 43200) + DaySeconds; + return (Seconds); } - - -double Lgm_TT_to_TTSecSinceJ2000( Lgm_DateTime *TT ) { - double JDN, Seconds; - JDN = Lgm_JDN( TT->Year, TT->Month, TT->Day ); - Seconds = ((JDN - LGM_JD_J2000)*86400.0 - 43200.0) + TT->Time*3600.0; - return( Seconds ); +double Lgm_TT_to_TTSecSinceJ2000(Lgm_DateTime* TT) { + double JDN, Seconds; + JDN = Lgm_JDN(TT->Year, TT->Month, TT->Day); + Seconds = ((JDN - LGM_JD_J2000) * 86400.0 - 43200.0) + TT->Time * 3600.0; + return (Seconds); } -void Lgm_TTSecSinceJ2000_to_TT( double TTSeconds, Lgm_DateTime *TT ) { - +void Lgm_TTSecSinceJ2000_to_TT(double TTSeconds, Lgm_DateTime* TT) { long int dJDN; - double tmp, JDN; - dJDN = (long int)((TTSeconds + 43200.0)/86400.0); - TT->Time = (TTSeconds - dJDN*86400.0 + 43200.0)/3600.0; + double tmp, JDN; + dJDN = (long int)((TTSeconds + 43200.0) / 86400.0); + TT->Time = (TTSeconds - dJDN * 86400.0 + 43200.0) / 3600.0; JDN = LGM_JD_J2000 + dJDN; - Lgm_jd_to_ymdh( JDN, &TT->Date, &TT->Year, &TT->Month, &TT->Day, &tmp); - - TT->JD = JDN + TT->Time/24.0; - TT->T = (TT->JD - 2451545.0)/36525.0; - TT->TimeSystem = LGM_TIME_SYS_TT; + Lgm_jd_to_ymdh(JDN, &TT->Date, &TT->Year, &TT->Month, &TT->Day, &tmp); + TT->JD = JDN + TT->Time / 24.0; + TT->T = (TT->JD - 2451545.0) / 36525.0; + TT->TimeSystem = LGM_TIME_SYS_TT; } -void Lgm_TTSecSinceJ2000_to_UTC( double TTSeconds, Lgm_DateTime *UTC, Lgm_CTrans *c ) { +void Lgm_TTSecSinceJ2000_to_UTC(double TTSeconds, + Lgm_DateTime* UTC, + Lgm_CTrans* c) { Lgm_DateTime TT; - Lgm_TTSecSinceJ2000_to_TT( TTSeconds, &TT ); - Lgm_TT_to_UTC( &TT, UTC, c ); + Lgm_TTSecSinceJ2000_to_TT(TTSeconds, &TT); + Lgm_TT_to_UTC(&TT, UTC, c); UTC->TimeSystem = LGM_TIME_SYS_UTC; } - Lgm_DateTime TT; -double Lgm_UTC_to_TTSecSinceJ2000( Lgm_DateTime *UTC, Lgm_CTrans *c ) { - Lgm_UTC_to_TT( UTC, &TT, c ); - return( Lgm_TT_to_TTSecSinceJ2000( &TT) ); +Lgm_DateTime TT; +double Lgm_UTC_to_TTSecSinceJ2000(Lgm_DateTime* UTC, Lgm_CTrans* c) { + Lgm_UTC_to_TT(UTC, &TT, c); + return (Lgm_TT_to_TTSecSinceJ2000(&TT)); } - - - - - - - - - - - - - - - /* * Convert JD directly to a UTC DateTime structure. */ -void Lgm_JD_to_DateTime( double JD, Lgm_DateTime *UTC, Lgm_CTrans *c ){ - +void Lgm_JD_to_DateTime(double JD, Lgm_DateTime* UTC, Lgm_CTrans* c) { long int Date; - int Year, Month, Day; - double Time; - - Date = Lgm_JD_to_Date( JD, &Year, &Month, &Day, &Time ); - Lgm_Make_UTC( Date, Time, UTC, c ); + int Year, Month, Day; + double Time; + Date = Lgm_JD_to_Date(JD, &Year, &Month, &Day, &Time); + Lgm_Make_UTC(Date, Time, UTC, c); } /* * Convert MJD directly to a UTC DateTime structure */ -void Lgm_MJD_to_DateTime( double MJD, Lgm_DateTime *UTC, Lgm_CTrans *c ) { - double JD; +void Lgm_MJD_to_DateTime(double MJD, Lgm_DateTime* UTC, Lgm_CTrans* c) { + double JD; JD = MJD + 2400000.5; - Lgm_JD_to_DateTime( JD, UTC, c ); + Lgm_JD_to_DateTime(JD, UTC, c); } diff --git a/libLanlGeoMag/Lgm_Eclipse.c b/libLanlGeoMag/Lgm_Eclipse.c index dc5f1dcd2..ed488f303 100644 --- a/libLanlGeoMag/Lgm_Eclipse.c +++ b/libLanlGeoMag/Lgm_Eclipse.c @@ -14,8 +14,8 @@ * */ -#include #include +#include #include "Lgm/Lgm_CTrans.h" #include "Lgm/Lgm_Vec.h" diff --git a/libLanlGeoMag/Lgm_FluxToPsd.c b/libLanlGeoMag/Lgm_FluxToPsd.c index df8574b0a..de6ffd885 100644 --- a/libLanlGeoMag/Lgm_FluxToPsd.c +++ b/libLanlGeoMag/Lgm_FluxToPsd.c @@ -1,18 +1,18 @@ #ifdef HAVE_CONFIG_H #include #endif -#include -#include -#include #include #include +#include #if USE_OPENMP #include #endif -#include "Lgm/Lgm_FluxToPsd.h" +#include +#include #include "Lgm/Lgm_CTrans.h" -#include "Lgm/Lgm_MagModelInfo.h" #include "Lgm/Lgm_DynamicMemory.h" +#include "Lgm/Lgm_FluxToPsd.h" +#include "Lgm/Lgm_MagModelInfo.h" void praxis( int n, double *x, int *data, double (*funct)(double *, void *data), double *in, double *out); diff --git a/libLanlGeoMag/Lgm_GradB.c b/libLanlGeoMag/Lgm_GradB.c index 4be9b0e16..4cf5e3cad 100644 --- a/libLanlGeoMag/Lgm_GradB.c +++ b/libLanlGeoMag/Lgm_GradB.c @@ -1,5 +1,5 @@ -#include #include +#include #include "Lgm/Lgm_MagModelInfo.h" diff --git a/libLanlGeoMag/Lgm_GradBvec.c b/libLanlGeoMag/Lgm_GradBvec.c index c98c7b459..46416eb77 100644 --- a/libLanlGeoMag/Lgm_GradBvec.c +++ b/libLanlGeoMag/Lgm_GradBvec.c @@ -1,5 +1,5 @@ -#include #include +#include #include "Lgm/Lgm_MagModelInfo.h" /** diff --git a/libLanlGeoMag/Lgm_GradBvec2.c b/libLanlGeoMag/Lgm_GradBvec2.c index b9428ce33..d174a365e 100644 --- a/libLanlGeoMag/Lgm_GradBvec2.c +++ b/libLanlGeoMag/Lgm_GradBvec2.c @@ -1,5 +1,5 @@ -#include #include +#include #include "Lgm/Lgm_MagModelInfo.h" /** diff --git a/libLanlGeoMag/Lgm_IGRF.c b/libLanlGeoMag/Lgm_IGRF.c index e221ffcef..bc0e9c2db 100644 --- a/libLanlGeoMag/Lgm_IGRF.c +++ b/libLanlGeoMag/Lgm_IGRF.c @@ -1,9 +1,10 @@ /* - * IGFC.c - Copyright (c) 1999-2006 Michael G. Henderson + * IGFC.c - Copyright (c) 1999-2006 Michael G. Henderson + * * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or @@ -13,28 +14,28 @@ * * * This is my own implementation. It isnt *radically* optimized yet. - * But it does use recurrence relations for lots of stuff. + * But it does use recurrence relations for lots of stuff. * (Could probably be made faster by fine tuning and could also use * Clenshaw's recurrence formula to do some of the sums...?) * * * Be careful when testing this code against other IGRF codes. Many of the - * available versions assume that you are inputing "geodetic coordinates", not - * geocentric coordinates. So in some other codes, your Theta and Phi are assummed - * to be geodetic and then they are converted to geocentric, then B is calculated - * and then the B is converted back to geodetic. This is NOT what we want here. - * Here, I assume the input coords are in geocentric and the output field is also. + * available versions assume that you are inputing "geodetic coordinates", + * not geocentric coordinates. So in some other codes, your Theta and Phi are + * assummed to be geodetic and then they are converted to geocentric, then B is + * calculated and then the B is converted back to geodetic. This is NOT what we + * want here. Here, I assume the input coords are in geocentric and the output + * field is also. * * The Earth model is the WGS84 spheroid. (Equatorial radius a=6378.137 km, - * Polar Radius b=6356.752 km. These are also defined in LgmCtrans.h as WGS84_A - * and WGS84_B) + * Polar Radius b=6356.752 km. These are also defined in LgmCtrans.h as + * WGS84_A and WGS84_B) * * I think this is now reentrant and thread-safe. But we should do some more * checking.... * */ -#include "Lgm/Lgm_CTrans.h" #include "Lgm/Lgm_IGRF.h" #define TINY 1.0e-25 #ifdef HAVE_CONFIG_H @@ -43,16 +44,12 @@ #if USE_OPENMP #include #endif +#include "Lgm/Lgm_CTrans.h" - - - -void Lgm_IGRF( Lgm_Vector *vin, Lgm_Vector *B, Lgm_CTrans *c ) { - - double x[7], y[7], z[7], t[7], e; - int i, n; - Lgm_Vector v, w; - +void Lgm_IGRF(Lgm_Vector* vin, Lgm_Vector* B, Lgm_CTrans* c) { + double x[7], y[7], z[7], t[7], e; + int i, n; + Lgm_Vector v, w; /* * For various reasons, LGM adopted a definition of an Earth radius as the @@ -62,19 +59,11 @@ void Lgm_IGRF( Lgm_Vector *vin, Lgm_Vector *B, Lgm_CTrans *c ) { * km. Therefore, to get the proper r value into the IGRF equations, we * need to rescale the input r value. See Finlay et al., International * Geomagnetic Reference Field: the eleventh generation, Geophys. J. Int. - * (2010) 183, 1216–1230, doi: 10.1111/j.1365-246X.2010.04804.x + * (2010) 183, 1216–1230, doi: 10.1111/j.1365-246X.2010.04804.x */ v = *vin; - v.x *= Re; // convert r back to km - v.x /= IGRF_Re; // convert r to have units of IGRF_Re - - - - - - - - + v.x *= Re; // convert r back to km + v.x /= IGRF_Re; // convert r to have units of IGRF_Re /* * Since there is a singularity at the pole, we should @@ -83,42 +72,37 @@ void Lgm_IGRF( Lgm_Vector *vin, Lgm_Vector *B, Lgm_CTrans *c ) { * away from the pole. * */ - if ( fabs( v.y*RadPerDeg ) < 1e-4 ) { - for (n=0, i=-3; i<=3; ++i){ + if (fabs(v.y * RadPerDeg) < 1e-4) { + for (n = 0, i = -3; i <= 3; ++i) { if (i != 0) { - t[n] = 1e-4*(double)i; - //t[n] = 5.0*RadPerDeg*(double)i; - w.x = v.x; w.y = t[n]; w.z = v.z; - _Lgm_IGRF4( &w, B, c ); - x[n] = B->x; y[n] = B->y; z[n] = B->z; + t[n] = 1e-4 * (double)i; + // t[n] = 5.0*RadPerDeg*(double)i; + w.x = v.x; + w.y = t[n]; + w.z = v.z; + _Lgm_IGRF4(&w, B, c); + x[n] = B->x; + y[n] = B->y; + z[n] = B->z; ++n; } } - Lgm_PolFunInt( t, x, 6, v.y, &(B->x), &e); - Lgm_PolFunInt( t, y, 6, v.y, &(B->y), &e); - Lgm_PolFunInt( t, z, 6, v.y, &(B->z), &e); + Lgm_PolFunInt(t, x, 6, v.y, &(B->x), &e); + Lgm_PolFunInt(t, y, 6, v.y, &(B->y), &e); + Lgm_PolFunInt(t, z, 6, v.y, &(B->z), &e); } else { - - _Lgm_IGRF4( &v, B, c ); - + _Lgm_IGRF4(&v, B, c); } - } - - -void _Lgm_IGRF( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { - - double r, Theta, Phi, B_r, B_theta, B_phi; - double st, ct, sp, cp, t; - double P[14][14], dP[14][14], Cmp[14], Smp[14], f1[14][14], f2[14], rinv; - int N; +void _Lgm_IGRF(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double r, Theta, Phi, B_r, B_theta, B_phi; + double st, ct, sp, cp, t; + double P[14][14], dP[14][14], Cmp[14], Smp[14], f1[14][14], f2[14], rinv; + int N; register double nsum, msum; - register int n, m; - - - + register int n, m; /* * (r, theta, phi) are the spherical input coords. @@ -132,42 +116,39 @@ void _Lgm_IGRF( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * * r in units of Re */ - r = v->x; + r = v->x; Theta = v->y; - Phi = v->z; - st = sin( Theta ); ct = cos( Theta ); - sp = sin( Phi ); cp = cos( Phi ); - - - + Phi = v->z; + st = sin(Theta); + ct = cos(Theta); + sp = sin(Phi); + cp = cos(Phi); /* - * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our purposes? + * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our + * purposes? */ N = 13; Lgm_InitIGRF(c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); - - /* * Compute all of the Legendre-related values. */ - Lgm_InitPnm( ct, st, c->Lgm_IGRF_R, P, dP, N, c ); - Lgm_InitTrigmp( cp, sp, Cmp, Smp, N ); - - - + Lgm_InitPnm(ct, st, c->Lgm_IGRF_R, P, dP, N, c); + Lgm_InitTrigmp(cp, sp, Cmp, Smp, N); /* * precompute some quantities */ { #if USE_OPENMP - //#pragma omp parallel private(m) - //#pragma omp for + // #pragma omp parallel private(m) + // #pragma omp for #endif - for (n=1; n<=N; ++n){ - for (m=0; m<=n; ++m) f1[n][m] = c->Lgm_IGRF_g[n][m]*Cmp[m] + c->Lgm_IGRF_h[n][m]*Smp[m]; + for (n = 1; n <= N; ++n) { + for (m = 0; m <= n; ++m) + f1[n][m] = + c->Lgm_IGRF_g[n][m] * Cmp[m] + c->Lgm_IGRF_h[n][m] * Smp[m]; } } @@ -175,85 +156,75 @@ void _Lgm_IGRF( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * Precompute f2_n = (1/r)^(n+2) */ { - rinv = 1.0/r; - t = rinv*rinv; + rinv = 1.0 / r; + t = rinv * rinv; f2[0] = t; // f2[0] is never used, could comment out? - for (n=1; n<=N; ++n){ + for (n = 1; n <= N; ++n) { t *= rinv; f2[n] = t; } } - - /* * Compute B_r */ { - for (nsum=0.0, n=1; n<=N; ++n){ - for (msum=0.0, m=0; m<=n; ++m) msum += f1[n][m]*P[n][m]; - nsum += (n+1)*f2[n]*msum; + for (nsum = 0.0, n = 1; n <= N; ++n) { + for (msum = 0.0, m = 0; m <= n; ++m) + msum += f1[n][m] * P[n][m]; + nsum += (n + 1) * f2[n] * msum; } } B_r = nsum; - - - /* * Compute B_theta */ - for (nsum=0.0, n=1; n<=N; ++n){ - for (msum=0.0, m=0; m<=n; ++m) msum += f1[n][m]*dP[n][m]; - nsum += f2[n]*msum; + for (nsum = 0.0, n = 1; n <= N; ++n) { + for (msum = 0.0, m = 0; m <= n; ++m) + msum += f1[n][m] * dP[n][m]; + nsum += f2[n] * msum; } B_theta = -nsum; - - /* * Compute B_phi */ - for (nsum=0.0, n=1; n<=N; ++n){ - for (msum=0.0, m=0; m<=n; ++m) msum += (c->Lgm_IGRF_g[n][m]*Smp[m] - c->Lgm_IGRF_h[n][m]*Cmp[m])*m*P[n][m]; - nsum += f2[n]*msum; + for (nsum = 0.0, n = 1; n <= N; ++n) { + for (msum = 0.0, m = 0; m <= n; ++m) + msum += + (c->Lgm_IGRF_g[n][m] * Smp[m] - c->Lgm_IGRF_h[n][m] * Cmp[m]) * + m * P[n][m]; + nsum += f2[n] * msum; } - B_phi = nsum/st; - - - + B_phi = nsum / st; B->x = B_r; B->y = B_theta; B->z = B_phi; c->Lgm_IGRF_FirstCall = FALSE; - } - - /* * Using a different recurrence relation */ -void _Lgm_IGRF2( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { - - double r, Theta, Phi, B_r, B_theta, B_phi; - double st, ct, sp, cp, t; - double val, val2, Cmp[14], Smp[14], f2[14], rinv; - int N; +void _Lgm_IGRF2(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double r, Theta, Phi, B_r, B_theta, B_phi; + double st, ct, sp, cp, t; + double val, val2, Cmp[14], Smp[14], f2[14], rinv; + int N; register double P_n_m, P_nm1_m, P_nm1_mm1, P_nm2_m; register double dP_n_m, dP_nm1_m, dP_nm1_mm1, dP_nm2_m; - register int n, m; - + register int n, m; + /* - * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our purposes? + * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our + * purposes? */ N = 13; - Lgm_InitIGRF( c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); - - + Lgm_InitIGRF(c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); /* * (r, theta, phi) are the spherical input coords. @@ -267,41 +238,38 @@ void _Lgm_IGRF2( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * * r in units of Re */ - r = v->x; + r = v->x; Theta = v->y; - Phi = v->z; - st = sin( Theta ); ct = cos( Theta ); - sp = sin( Phi ); cp = cos( Phi ); - - - if ( c->Lgm_IGRF_FirstCall ) { - Lgm_InitK( c->Lgm_IGRF_K, N ); - Lgm_InitS( c->Lgm_IGRF_S, N ); + Phi = v->z; + st = sin(Theta); + ct = cos(Theta); + sp = sin(Phi); + cp = cos(Phi); + + if (c->Lgm_IGRF_FirstCall) { + Lgm_InitK(c->Lgm_IGRF_K, N); + Lgm_InitS(c->Lgm_IGRF_S, N); } - - /* * Precompute the Cos(m*phi) and Sin(m*phi) using recurance relations */ - Lgm_InitTrigmp( cp, sp, Cmp, Smp, N ); - + Lgm_InitTrigmp(cp, sp, Cmp, Smp, N); /* * Precompute f2_n = (1/r)^(n+2) efficiently */ { - rinv = 1.0/r; - t = rinv*rinv; + rinv = 1.0 / r; + t = rinv * rinv; f2[0] = t; // f2[0] is never used, could comment out? - for (n=1; n<=N; ++n){ + for (n = 1; n <= N; ++n) { t *= rinv; f2[n] = t; } } - /* * Use the recursions: * @@ -319,7 +287,7 @@ void _Lgm_IGRF2( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * So for each m, we start with a Pnn and work up. * * n=0 n=1 n=2 n=3 n=N - * + * * m=0 P00 P10 P20 P30 ... PN0 * m=1 P11 P21 P31 ... PN1 * m=2 P22 P32 ... PN2 @@ -328,78 +296,85 @@ void _Lgm_IGRF2( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * . * . * m=N PNN - * + * */ - B_r = B_theta = B_phi = 0.0; - P_nm1_mm1 = 1.0; P_nm1_m = 1.0; // Initially these are P_0,0 - dP_nm1_mm1 = 0.0; dP_nm1_m = 0.0; // Initially these are dP_0,0 - - for ( m=0; m<= N; ++m ) { - for ( n=1; n<= N; ++n ) { - if ( n >= m ) { - - if ( n == m ) { - P_n_m = st*P_nm1_mm1; - dP_n_m = st*dP_nm1_mm1 + ct*P_nm1_mm1; - P_nm1_mm1 = P_n_m; P_nm1_m = P_n_m; P_nm2_m = 0.0; - dP_nm1_mm1 = dP_n_m; dP_nm1_m = dP_n_m; dP_nm2_m = 0.0; - } else if ( n == 1 ) { - P_n_m = ct*P_nm1_m; - dP_n_m = ct*dP_nm1_m - st*P_nm1_m; - P_nm2_m = P_nm1_m; P_nm1_m = P_n_m; - dP_nm2_m = dP_nm1_m; dP_nm1_m = dP_n_m; + P_nm1_mm1 = 1.0; + P_nm1_m = 1.0; // Initially these are P_0,0 + dP_nm1_mm1 = 0.0; + dP_nm1_m = 0.0; // Initially these are dP_0,0 + + for (m = 0; m <= N; ++m) { + for (n = 1; n <= N; ++n) { + if (n >= m) { + if (n == m) { + P_n_m = st * P_nm1_mm1; + dP_n_m = st * dP_nm1_mm1 + ct * P_nm1_mm1; + P_nm1_mm1 = P_n_m; + P_nm1_m = P_n_m; + P_nm2_m = 0.0; + dP_nm1_mm1 = dP_n_m; + dP_nm1_m = dP_n_m; + dP_nm2_m = 0.0; + } else if (n == 1) { + P_n_m = ct * P_nm1_m; + dP_n_m = ct * dP_nm1_m - st * P_nm1_m; + P_nm2_m = P_nm1_m; + P_nm1_m = P_n_m; + dP_nm2_m = dP_nm1_m; + dP_nm1_m = dP_n_m; } else { - P_n_m = ct*P_nm1_m - c->Lgm_IGRF_K[n][m]*P_nm2_m; - dP_n_m = ct*dP_nm1_m - st*P_nm1_m - c->Lgm_IGRF_K[n][m]*dP_nm2_m; - P_nm2_m = P_nm1_m; P_nm1_m = P_n_m; - dP_nm2_m = dP_nm1_m; dP_nm1_m = dP_n_m; + P_n_m = ct * P_nm1_m - c->Lgm_IGRF_K[n][m] * P_nm2_m; + dP_n_m = ct * dP_nm1_m - st * P_nm1_m - + c->Lgm_IGRF_K[n][m] * dP_nm2_m; + P_nm2_m = P_nm1_m; + P_nm1_m = P_n_m; + dP_nm2_m = dP_nm1_m; + dP_nm1_m = dP_n_m; } - - val = c->Lgm_IGRF_g[n][m]*Cmp[m] + c->Lgm_IGRF_h[n][m]*Smp[m]; - val2 = c->Lgm_IGRF_S[n][m]*f2[n]; - B_r += val2 * (double)(n+1)*val*P_n_m; - B_theta += val2 * val*dP_n_m; - B_phi += val2 * (double)m*(-c->Lgm_IGRF_g[n][m]*Smp[m] + c->Lgm_IGRF_h[n][m]*Cmp[m])*P_n_m; - + + val = + c->Lgm_IGRF_g[n][m] * Cmp[m] + c->Lgm_IGRF_h[n][m] * Smp[m]; + val2 = c->Lgm_IGRF_S[n][m] * f2[n]; + B_r += val2 * (double)(n + 1) * val * P_n_m; + B_theta += val2 * val * dP_n_m; + B_phi += val2 * (double)m * + (-c->Lgm_IGRF_g[n][m] * Smp[m] + + c->Lgm_IGRF_h[n][m] * Cmp[m]) * + P_n_m; } } } B->x = B_r; B->y = -B_theta; - B->z = -B_phi/st; + B->z = -B_phi / st; c->Lgm_IGRF_FirstCall = FALSE; - } - - /* * Same recurrence relation as _Lgm_IGRF2, but paralellized */ -void _Lgm_IGRF3( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { - - double r, Theta, Phi, B_r, B_theta, B_phi; - double st, ct, sp, cp, t; - double val, val2, Cmp[14], Smp[14], f2[14], rinv, Pnn[14], dPnn[14], g, h; - int N, nmin; - //register double P_n_m, P_nm1_m, P_nm1_mm1, P_nm2_m; - //register double dP_n_m, dP_nm1_m, dP_nm1_mm1, dP_nm2_m; - //register int n, m; +void _Lgm_IGRF3(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double r, Theta, Phi, B_r, B_theta, B_phi; + double st, ct, sp, cp, t; + double val, val2, Cmp[14], Smp[14], f2[14], rinv, Pnn[14], dPnn[14], g, h; + int N, nmin; + // register double P_n_m, P_nm1_m, P_nm1_mm1, P_nm2_m; + // register double dP_n_m, dP_nm1_m, dP_nm1_mm1, dP_nm2_m; + // register int n, m; double P_n_m, P_nm1_m, P_nm1_mm1, P_nm2_m; double dP_n_m, dP_nm1_m, dP_nm1_mm1, dP_nm2_m; - int n, m; - + int n, m; + /* - * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our purposes? + * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our + * purposes? */ N = 13; - Lgm_InitIGRF( c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); - - + Lgm_InitIGRF(c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); /* * (r, theta, phi) are the spherical input coords. @@ -418,33 +393,29 @@ void _Lgm_IGRF3( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * Compute cos(theta), sin(theta), cos(phi), sin(phi) * Precompute the Cos(m*phi) and Sin(m*phi) using recurance relations */ - st = sin( v->y ); ct = cos( v->y); - sp = sin( v->z ); cp = cos( v->z ); - Lgm_InitTrigmp( cp, sp, Cmp, Smp, N ); - - + st = sin(v->y); + ct = cos(v->y); + sp = sin(v->z); + cp = cos(v->z); + Lgm_InitTrigmp(cp, sp, Cmp, Smp, N); /* * Precompute f2_n = (1/r)^(n+2) efficiently */ - rinv = 1.0/v->x; - t = rinv*rinv; + rinv = 1.0 / v->x; + t = rinv * rinv; f2[0] = t; // f2[0] is never used, could comment out? - for (n=1; n<=N; ++n){ + for (n = 1; n <= N; ++n) { t *= rinv; f2[n] = t; } - - - if ( c->Lgm_IGRF_FirstCall ) { - Lgm_InitK( c->Lgm_IGRF_K, N ); - Lgm_InitS( c->Lgm_IGRF_S, N ); + if (c->Lgm_IGRF_FirstCall) { + Lgm_InitK(c->Lgm_IGRF_K, N); + Lgm_InitS(c->Lgm_IGRF_S, N); } - - /* * Use the recursions: * @@ -462,7 +433,7 @@ void _Lgm_IGRF3( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * So for each m, we start with a Pnn and work up. * * n=0 n=1 n=2 n=3 n=N - * + * * m=0 P00 P10 P20 P30 ... PN0 * m=1 P11 P21 P31 ... PN1 * m=2 P22 P32 ... PN2 @@ -471,7 +442,7 @@ void _Lgm_IGRF3( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * . * . * m=N PNN - * + * * * This can be parallelized if we precompute all of the P_n,n's first. * Then all of the m's can be done independantly. @@ -482,96 +453,102 @@ void _Lgm_IGRF3( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { // precompute P_n_n's and dP_n_n's Pnn[0] = P_nm1_mm1 = 1.0; dPnn[0] = dP_nm1_mm1 = 0.0; - for ( m=1; m<= N; ++m ) { - Pnn[m] = st*P_nm1_mm1; - dPnn[m] = st*dP_nm1_mm1 + ct*P_nm1_mm1; - P_nm1_mm1 = Pnn[m]; dP_nm1_mm1 = dPnn[m]; + for (m = 1; m <= N; ++m) { + Pnn[m] = st * P_nm1_mm1; + dPnn[m] = st * dP_nm1_mm1 + ct * P_nm1_mm1; + P_nm1_mm1 = Pnn[m]; + dP_nm1_mm1 = dPnn[m]; } - // initialize sums B_r = B_theta = B_phi = 0.0; - - // { // BEGIN PARALLEL - // this granularity here is too small. Parallel version actually runs slower. But serially, its faster than - // previous versions. +// this granularity here is too small. Parallel version actually runs slower. +// But serially, its faster than previous versions. #if USE_OPENMP - //#pragma omp parallel firstprivate(m,n,P_nm1_m,P_nm2_m,dP_nm1_m,dP_nm2_m,P_n_m,dP_n_m,val,val2) - //#pragma omp for schedule(static,1) reduction(+:B_r,B_theta,B_phi) + // #pragma omp parallel + // firstprivate(m,n,P_nm1_m,P_nm2_m,dP_nm1_m,dP_nm2_m,P_n_m,dP_n_m,val,val2) + // #pragma omp for schedule(static,1) reduction(+:B_r,B_theta,B_phi) #endif - for ( m=0; m<= N; ++m ) { - - P_n_m = Pnn[m]; - dP_n_m = dPnn[m]; - P_nm1_m = P_n_m; P_nm2_m = 0.0; - dP_nm1_m = dP_n_m; dP_nm2_m = 0.0; - - for ( n=m; n<= N; ++n ) { - - if ( n != m ) { - if ( n == 1 ) { - P_n_m = ct*P_nm1_m; - dP_n_m = ct*dP_nm1_m - st*P_nm1_m; - P_nm2_m = P_nm1_m; P_nm1_m = P_n_m; - dP_nm2_m = dP_nm1_m; dP_nm1_m = dP_n_m; - } else { - P_n_m = ct*P_nm1_m - c->Lgm_IGRF_K[n][m]*P_nm2_m; - dP_n_m = ct*dP_nm1_m - st*P_nm1_m - c->Lgm_IGRF_K[n][m]*dP_nm2_m; - P_nm2_m = P_nm1_m; P_nm1_m = P_n_m; - dP_nm2_m = dP_nm1_m; dP_nm1_m = dP_n_m; - } - } - - if ( n > 0 ){ - val = c->Lgm_IGRF_g[n][m]*Cmp[m] + c->Lgm_IGRF_h[n][m]*Smp[m]; - val2 = c->Lgm_IGRF_S[n][m]*f2[n]; - - //B_r = B_r + (val2 * (double)(n+1)*val*P_n_m); - //B_theta = B_theta + (val2 * val*dP_n_m); - //B_phi = B_phi + (val2 * (double)m*(-c->Lgm_IGRF_g[n][m]*Smp[m] + c->Lgm_IGRF_h[n][m]*Cmp[m])*P_n_m); - - B_r += (val2 * (double)(n+1)*val*P_n_m); - B_theta += (val2 * val*dP_n_m); - B_phi += (val2 * (double)m*(-c->Lgm_IGRF_g[n][m]*Smp[m] + c->Lgm_IGRF_h[n][m]*Cmp[m])*P_n_m); + for (m = 0; m <= N; ++m) { + P_n_m = Pnn[m]; + dP_n_m = dPnn[m]; + P_nm1_m = P_n_m; + P_nm2_m = 0.0; + dP_nm1_m = dP_n_m; + dP_nm2_m = 0.0; + + for (n = m; n <= N; ++n) { + if (n != m) { + if (n == 1) { + P_n_m = ct * P_nm1_m; + dP_n_m = ct * dP_nm1_m - st * P_nm1_m; + P_nm2_m = P_nm1_m; + P_nm1_m = P_n_m; + dP_nm2_m = dP_nm1_m; + dP_nm1_m = dP_n_m; + } else { + P_n_m = ct * P_nm1_m - c->Lgm_IGRF_K[n][m] * P_nm2_m; + dP_n_m = ct * dP_nm1_m - st * P_nm1_m - + c->Lgm_IGRF_K[n][m] * dP_nm2_m; + P_nm2_m = P_nm1_m; + P_nm1_m = P_n_m; + dP_nm2_m = dP_nm1_m; + dP_nm1_m = dP_n_m; } - + } + + if (n > 0) { + val = + c->Lgm_IGRF_g[n][m] * Cmp[m] + c->Lgm_IGRF_h[n][m] * Smp[m]; + val2 = c->Lgm_IGRF_S[n][m] * f2[n]; + + // B_r = B_r + (val2 * (double)(n+1)*val*P_n_m); + // B_theta = B_theta + (val2 * val*dP_n_m); + // B_phi = B_phi + (val2 * + // (double)m*(-c->Lgm_IGRF_g[n][m]*Smp[m] + + // c->Lgm_IGRF_h[n][m]*Cmp[m])*P_n_m); + + B_r += (val2 * (double)(n + 1) * val * P_n_m); + B_theta += (val2 * val * dP_n_m); + B_phi += (val2 * (double)m * + (-c->Lgm_IGRF_g[n][m] * Smp[m] + + c->Lgm_IGRF_h[n][m] * Cmp[m]) * + P_n_m); } } + } -// } // END PARALLEL + // } // END PARALLEL B->x = B_r; B->y = -B_theta; - B->z = -B_phi/st; + B->z = -B_phi / st; c->Lgm_IGRF_FirstCall = FALSE; - } - - /* - * Same recurrence relation as _Lgm_IGRF3, but attempt at making it more efficient + * Same recurrence relation as _Lgm_IGRF3, but attempt at making it more + * efficient */ -void _Lgm_IGRF4( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { - - double r, Theta, Phi, B_r, B_theta, B_phi; - double st, ct, sp, cp, t, gnm, hnm, Knm; - double val, val2, val3, Cmp_m, Smp_m, Cmp[14], Smp[14], f2[14], rinv, Pnn[14], dPnn[14]; - int N; +void _Lgm_IGRF4(Lgm_Vector* v, Lgm_Vector* B, Lgm_CTrans* c) { + double r, Theta, Phi, B_r, B_theta, B_phi; + double st, ct, sp, cp, t, gnm, hnm, Knm; + double val, val2, val3, Cmp_m, Smp_m, Cmp[14], Smp[14], f2[14], rinv, + Pnn[14], dPnn[14]; + int N; register double P_n_m, P_nm1_m, P_nm1_mm1, P_nm2_m; register double dP_n_m, dP_nm1_m, dP_nm1_mm1, dP_nm2_m; - register int n, m; - + register int n, m; + /* - * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our purposes? + * IGRF 2005 goes up to N=13, but 10 ought to be good enough for our + * purposes? */ N = 13; - Lgm_InitIGRF( c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); - - + Lgm_InitIGRF(c->Lgm_IGRF_g, c->Lgm_IGRF_h, N, c->Lgm_IGRF_FirstCall, c); /* * (r, theta, phi) are the spherical input coords. @@ -590,32 +567,28 @@ void _Lgm_IGRF4( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * Compute cos(theta), sin(theta), cos(phi), sin(phi) * Precompute the Cos(m*phi) and Sin(m*phi) using recurance relations */ - st = sin( v->y ); ct = cos( v->y); - sp = sin( v->z ); cp = cos( v->z ); - Lgm_InitTrigmp( cp, sp, Cmp, Smp, N ); - - + st = sin(v->y); + ct = cos(v->y); + sp = sin(v->z); + cp = cos(v->z); + Lgm_InitTrigmp(cp, sp, Cmp, Smp, N); /* * Precompute f2_n = (1/r)^(n+2) efficiently */ - rinv = 1.0/v->x; - f2[0] = t = rinv*rinv; // f2[0] is never used(?) + rinv = 1.0 / v->x; + f2[0] = t = rinv * rinv; // f2[0] is never used(?) - for (n=1; n<=N; ++n){ + for (n = 1; n <= N; ++n) { t *= rinv; f2[n] = t; } - - - if ( c->Lgm_IGRF_FirstCall ) { - Lgm_InitK( c->Lgm_IGRF_K, N ); - Lgm_InitS( c->Lgm_IGRF_S, N ); + if (c->Lgm_IGRF_FirstCall) { + Lgm_InitK(c->Lgm_IGRF_K, N); + Lgm_InitS(c->Lgm_IGRF_S, N); } - - /* * Use the recursions: * @@ -633,7 +606,7 @@ void _Lgm_IGRF4( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * So for each m, we start with a Pnn and work up. * * n=0 n=1 n=2 n=3 n=N - * + * * m=0 P00 P10 P20 P30 ... PN0 * m=1 P11 P21 P31 ... PN1 * m=2 P22 P32 ... PN2 @@ -642,7 +615,7 @@ void _Lgm_IGRF4( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { * . * . * m=N PNN - * + * * * This can be parallelized if we precompute all of the P_n,n's first. * Then all of the m's can be done independantly. @@ -653,83 +626,83 @@ void _Lgm_IGRF4( Lgm_Vector *v, Lgm_Vector *B, Lgm_CTrans *c ) { // precompute P_n_n's and dP_n_n's Pnn[0] = P_nm1_mm1 = 1.0; dPnn[0] = dP_nm1_mm1 = 0.0; - for ( m=1; m<= N; ++m ) { - Pnn[m] = st*P_nm1_mm1; - dPnn[m] = st*dP_nm1_mm1 + ct*P_nm1_mm1; - P_nm1_mm1 = Pnn[m]; dP_nm1_mm1 = dPnn[m]; + for (m = 1; m <= N; ++m) { + Pnn[m] = st * P_nm1_mm1; + dPnn[m] = st * dP_nm1_mm1 + ct * P_nm1_mm1; + P_nm1_mm1 = Pnn[m]; + dP_nm1_mm1 = dPnn[m]; } - // initialize sums B_r = B_theta = B_phi = 0.0; - for ( m=0; m<= N; ++m ) { - - P_n_m = Pnn[m]; - dP_n_m = dPnn[m]; - P_nm1_m = P_n_m; P_nm2_m = 0.0; - dP_nm1_m = dP_n_m; dP_nm2_m = 0.0; - - for ( n=m; n<= N; ++n ) { + for (m = 0; m <= N; ++m) { + P_n_m = Pnn[m]; + dP_n_m = dPnn[m]; + P_nm1_m = P_n_m; + P_nm2_m = 0.0; + dP_nm1_m = dP_n_m; + dP_nm2_m = 0.0; + for (n = m; n <= N; ++n) { gnm = c->Lgm_IGRF_g[n][m]; hnm = c->Lgm_IGRF_h[n][m]; - if ( n != m ) { + if (n != m) { Knm = c->Lgm_IGRF_K[n][m]; - P_n_m = ct*P_nm1_m - Knm*P_nm2_m; - dP_n_m = ct*dP_nm1_m - st*P_nm1_m - Knm*dP_nm2_m; - P_nm2_m = P_nm1_m; P_nm1_m = P_n_m; - dP_nm2_m = dP_nm1_m; dP_nm1_m = dP_n_m; + P_n_m = ct * P_nm1_m - Knm * P_nm2_m; + dP_n_m = ct * dP_nm1_m - st * P_nm1_m - Knm * dP_nm2_m; + P_nm2_m = P_nm1_m; + P_nm1_m = P_n_m; + dP_nm2_m = dP_nm1_m; + dP_nm1_m = dP_n_m; } - - if ( n > 0 ){ - Cmp_m = Cmp[m]; Smp_m = Smp[m]; - val = gnm*Cmp_m + hnm*Smp_m; - val2 = c->Lgm_IGRF_S[n][m]*f2[n]; + + if (n > 0) { + Cmp_m = Cmp[m]; + Smp_m = Smp[m]; + val = gnm * Cmp_m + hnm * Smp_m; + val2 = c->Lgm_IGRF_S[n][m] * f2[n]; val3 = val2 * val; - B_r += (val3*(n+1)*P_n_m); - B_theta += (val3*dP_n_m); - B_phi += (val2 * m*(-gnm*Smp_m + hnm*Cmp_m)*P_n_m); + B_r += (val3 * (n + 1) * P_n_m); + B_theta += (val3 * dP_n_m); + B_phi += (val2 * m * (-gnm * Smp_m + hnm * Cmp_m) * P_n_m); } - } } - - B->x = B_r; B->y = -B_theta; - B->z = -B_phi/st; + B->z = -B_phi / st; c->Lgm_IGRF_FirstCall = FALSE; - } - - - - -void Lgm_InitPnm( double ct, double st, double R[14][14], double P[14][14], double dP[14][14], int N, Lgm_CTrans *c ) { - - double Pmm, Pmp1m, Pnm, Pnm1m, Pnm2m, a, b, f, x, x2; - int NmM, Nm1, Mp1; -// static double TwoNm1_Over_NmM[13][13], NpMm1_Over_NmM[13][13]; -// static int FirstTimeThrough=TRUE; - register int n, m, i; +void Lgm_InitPnm(double ct, + double st, + double R[14][14], + double P[14][14], + double dP[14][14], + int N, + Lgm_CTrans* c) { + double Pmm, Pmp1m, Pnm, Pnm1m, Pnm2m, a, b, f, x, x2; + int NmM, Nm1, Mp1; + // static double TwoNm1_Over_NmM[13][13], NpMm1_Over_NmM[13][13]; + // static int FirstTimeThrough=TRUE; + register int n, m, i; x = ct; /* * Initialize */ -/* -we dont really need this if we set everything below -*/ - if ( c->Lgm_IGRF_FirstCall ) { - for (n=0; n<=N; ++n){ - for (m=0; m<=N; ++m){ + /* + we dont really need this if we set everything below + */ + if (c->Lgm_IGRF_FirstCall) { + for (n = 0; n <= N; ++n) { + for (m = 0; m <= N; ++m) { P[n][m] = 0.0; dP[n][m] = 0.0; R[n][m] = 0.0; @@ -742,362 +715,323 @@ we dont really need this if we set everything below * There's almost certainly a better way to do this, but * we really only ever need to do this once (they are constants). * - * One solution would be to precompute them an stuff them into + * One solution would be to precompute them an stuff them into * a static variable. */ - if ( c->Lgm_IGRF_FirstCall ) { - for (n=0; n<=N; ++n){ - for (m=0; m<=n; ++m){ + if (c->Lgm_IGRF_FirstCall) { + for (n = 0; n <= N; ++n) { + for (m = 0; m <= n; ++m) { + NmM = n - m; + Nm1 = n - 1; - NmM = n-m; - Nm1 = n-1; - - if (m==0) { + if (m == 0) { R[n][m] = 1.0; } else { - R[n][m] = sqrt( 2.0*Lgm_Factorial(NmM)/Lgm_Factorial(n+m) ); + R[n][m] = + sqrt(2.0 * Lgm_Factorial(NmM) / Lgm_Factorial(n + m)); } - if (n>m+1){ - c->Lgm_IGRF_TwoNm1_Over_NmM[n][m] = (double)(Nm1+n)/(double)NmM; - c->Lgm_IGRF_NpMm1_Over_NmM[n][m] = (double)(Nm1+m)/(double)NmM; + if (n > m + 1) { + c->Lgm_IGRF_TwoNm1_Over_NmM[n][m] = + (double)(Nm1 + n) / (double)NmM; + c->Lgm_IGRF_NpMm1_Over_NmM[n][m] = + (double)(Nm1 + m) / (double)NmM; } - } } - } - + } - x2 = x*x; + x2 = x * x; b = 1.0 - x2; - a = sqrt( b ); - + a = sqrt(b); /* * Compute all of the Pnm */ - for (m=0; m<=N; ++m){ - + for (m = 0; m <= N; ++m) { /* * For a given m, we need to first compute Pm,m * Set it to 1 first. If m == 0, then leave it at * 1. If m>0, then compute Pmm */ Pmm = 1.0; - if (m>0) { + if (m > 0) { f = 1.0; - // are we computing the following too many times? I.e., could we be more efficient? - for (i=1; i<=m; ++i){ - Pmm *= f*a; f += 2.0; + // are we computing the following too many times? I.e., could we be + // more efficient? + for (i = 1; i <= m; ++i) { + Pmm *= f * a; + f += 2.0; } } - P[m][m] = Pmm*R[m][m]; - + P[m][m] = Pmm * R[m][m]; if (m == N) { - /* In this case Pnmp1 should be zero -- we are done with * this value of m. Move one to next value of m... */ - } else { - - Mp1 = m+1; - Pmp1m = x*(m+Mp1)*Pmm; - P[Mp1][m] = Pmp1m*R[Mp1][m]; + Mp1 = m + 1; + Pmp1m = x * (m + Mp1) * Pmm; + P[Mp1][m] = Pmp1m * R[Mp1][m]; if (N == (Mp1)) { - - /* There arent any more values to compute for + /* There arent any more values to compute for * this value of m. Move one to next value of m... */ - } else { - Pnm1m = Pmp1m; Pnm2m = Pmm; - for (n=m+2; n<=N; ++n){ - + for (n = m + 2; n <= N; ++n) { // Pnm = ( x*(2*n-1)*Pnm1m - (n+m-1)*Pnm2m )/ (n-m); - Pnm = x*c->Lgm_IGRF_TwoNm1_Over_NmM[n][m]*Pnm1m - c->Lgm_IGRF_NpMm1_Over_NmM[n][m]*Pnm2m; - P[n][m] = Pnm*R[n][m]; + Pnm = x * c->Lgm_IGRF_TwoNm1_Over_NmM[n][m] * Pnm1m - + c->Lgm_IGRF_NpMm1_Over_NmM[n][m] * Pnm2m; + P[n][m] = Pnm * R[n][m]; Pnm2m = Pnm1m; Pnm1m = Pnm; - } - } - } - } - - Lgm_InitdPnm( P, dP, N, c ); - - + Lgm_InitdPnm(P, dP, N, c); } +void Lgm_InitdPnm(double P[14][14], double dP[14][14], int N, Lgm_CTrans* c) { + int n, m; + // static double SqrtNM1[13][13], SqrtNM2[13][13]; + // static int FirstTimeThrough=TRUE; + // c->Lgm_IGRF_FirstCall = TRUE; + if (c->Lgm_IGRF_FirstCall) + Lgm_InitSqrtFuncs(c->Lgm_IGRF_SqrtNM1, c->Lgm_IGRF_SqrtNM2, N); -void Lgm_InitdPnm( double P[14][14], double dP[14][14], int N, Lgm_CTrans *c ) { - - int n, m; -// static double SqrtNM1[13][13], SqrtNM2[13][13]; -// static int FirstTimeThrough=TRUE; - - -//c->Lgm_IGRF_FirstCall = TRUE; - if ( c->Lgm_IGRF_FirstCall ) Lgm_InitSqrtFuncs( c->Lgm_IGRF_SqrtNM1, c->Lgm_IGRF_SqrtNM2, N ); - - for (n=0; n<=N; ++n){ - for (m=n; m>=0; --m){ - - if (m==0) { - - //dP[n][0] = -sqrt(0.5*n*(n+1)) * P[n][1]; + for (n = 0; n <= N; ++n) { + for (m = n; m >= 0; --m) { + if (m == 0) { + // dP[n][0] = -sqrt(0.5*n*(n+1)) * P[n][1]; dP[n][0] = c->Lgm_IGRF_SqrtNM1[n][m] * P[n][1]; } else { + // q = ( (m-1) == 0 ) ? 2 : 1; - //q = ( (m-1) == 0 ) ? 2 : 1; - - if (m==n){ - //dP[n][m] = 0.5* sqrt((double)(q*(n+m)*(n-m+1))) * P[n][m-1]; - dP[n][m] = c->Lgm_IGRF_SqrtNM1[n][m] * P[n][m-1]; + if (m == n) { + // dP[n][m] = 0.5* sqrt((double)(q*(n+m)*(n-m+1))) * + // P[n][m-1]; + dP[n][m] = c->Lgm_IGRF_SqrtNM1[n][m] * P[n][m - 1]; } else { - //dP[n][m] = 0.5*( sqrt((double)(q*(n+m)*(n-m+1))) * P[n][m-1] - sqrt((double)((n+m+1)*(n-m))) * P[n][m+1] ); - dP[n][m] = c->Lgm_IGRF_SqrtNM1[n][m] * P[n][m-1] - c->Lgm_IGRF_SqrtNM2[n][m]* P[n][m+1]; + // dP[n][m] = 0.5*( sqrt((double)(q*(n+m)*(n-m+1))) * + // P[n][m-1] - sqrt((double)((n+m+1)*(n-m))) * P[n][m+1] ); + dP[n][m] = c->Lgm_IGRF_SqrtNM1[n][m] * P[n][m - 1] - + c->Lgm_IGRF_SqrtNM2[n][m] * P[n][m + 1]; } - } - } } - - } +void Lgm_InitSqrtFuncs(double SqrtNM1[14][14], double SqrtNM2[14][14], int N) { + int n, m, q, NmM, NpM; - -void Lgm_InitSqrtFuncs( double SqrtNM1[14][14], double SqrtNM2[14][14], int N ) { - - int n, m, q, NmM, NpM; - - for (n=0; n<=N; ++n){ - for (m=n; m>=0; --m){ - - if (m==0) { - - SqrtNM1[n][m] = -sqrt(0.5*n*(n+1)); + for (n = 0; n <= N; ++n) { + for (m = n; m >= 0; --m) { + if (m == 0) { + SqrtNM1[n][m] = -sqrt(0.5 * n * (n + 1)); } else { + q = ((m - 1) == 0) ? 2 : 1; - q = ( (m-1) == 0 ) ? 2 : 1; - - NpM = n+m; - NmM = n-m; - SqrtNM1[n][m] = 0.5*sqrt((double)(q*NpM*(NmM+1))); - SqrtNM2[n][m] = 0.5*sqrt((double)((NpM+1)*NmM)); - + NpM = n + m; + NmM = n - m; + SqrtNM1[n][m] = 0.5 * sqrt((double)(q * NpM * (NmM + 1))); + SqrtNM2[n][m] = 0.5 * sqrt((double)((NpM + 1) * NmM)); } - } } - } +double Lgm_Factorial(int k) { + double f; + int i; + if (k == 0) + return (1.0); + for (f = 1.0, i = 2; i <= k; ++i) + f *= (double)i; - -double Lgm_Factorial( int k ) { - - double f; - int i; - - if ( k == 0 ) return( 1.0 ); - - for (f=1.0, i=2; i<=k; ++i) f *= (double)i; - - return( f ); - + return (f); } - - - /* * Compute all of the sin(m phi) and cos(m phi) values * efficiently using recurrences. Doesnt require any costly * trig functions. */ -void Lgm_InitTrigmp( double cp, double sp, double *Cmp, double *Smp, int N ) { - - double b; - double Cm, Cmm1, Cmm2, Sm, Smm1, Smm2; - int m; - - b = 2.0*cp; - Cmp[0] = 1.0; Cmp[1] = cp; - Cmm2 = Cmp[0]; Cmm1 = Cmp[1]; - Smp[0] = 0.0; Smp[1] = sp; - Smm2 = Smp[0]; Smm1 = Smp[1]; - for (m=2; m<=N; ++m){ - Cm = b*Cmm1 - Cmm2; +void Lgm_InitTrigmp(double cp, double sp, double* Cmp, double* Smp, int N) { + double b; + double Cm, Cmm1, Cmm2, Sm, Smm1, Smm2; + int m; + + b = 2.0 * cp; + Cmp[0] = 1.0; + Cmp[1] = cp; + Cmm2 = Cmp[0]; + Cmm1 = Cmp[1]; + Smp[0] = 0.0; + Smp[1] = sp; + Smm2 = Smp[0]; + Smm1 = Smp[1]; + for (m = 2; m <= N; ++m) { + Cm = b * Cmm1 - Cmm2; Cmp[m] = Cm; Cmm2 = Cmm1; Cmm1 = Cm; - Sm = b*Smm1 - Smm2; + Sm = b * Smm1 - Smm2; Smp[m] = Sm; Smm2 = Smm1; Smm1 = Sm; } - - } -void Lgm_InitS( double S[14][14], int N ) { - +void Lgm_InitS(double S[14][14], int N) { register int n, m; - int nm1, nm1_2; + int nm1, nm1_2; - for ( n=0; n<=N; n++ ) { - for ( m=0; m<=N; m++ ) { + for (n = 0; n <= N; n++) { + for (m = 0; m <= N; m++) { S[n][m] = 0.0; } } - S[0][0] = 1.0; - for ( m=0; m<=N; m++ ) { - for ( n=1; n<=N; n++ ) { - - if ( m<=n){ - if ( m==0 ) { - S[n][0] = S[n-1][0]*(double)(2*n-1)/(double)n; - } else if ( m==1) { - S[n][m] = S[n][m-1]*sqrt( (double)(2*(n-m+1))/((double)(n+m)) ); + for (m = 0; m <= N; m++) { + for (n = 1; n <= N; n++) { + if (m <= n) { + if (m == 0) { + S[n][0] = S[n - 1][0] * (double)(2 * n - 1) / (double)n; + } else if (m == 1) { + S[n][m] = S[n][m - 1] * sqrt((double)(2 * (n - m + 1)) / + ((double)(n + m))); } else { - S[n][m] = S[n][m-1]*sqrt( (double)(n-m+1)/((double)(n+m)) ); + S[n][m] = S[n][m - 1] * + sqrt((double)(n - m + 1) / ((double)(n + m))); } } -//printf("S[%d][%d] = %g\n", n, m, S[n][m] ); + // printf("S[%d][%d] = %g\n", n, m, S[n][m] ); } } - - - } -void Lgm_InitK( double K[14][14], int N ) { - +void Lgm_InitK(double K[14][14], int N) { register int n, m; - int nm1, nm1_2; - + int nm1, nm1_2; - for ( n=1; n<=N; n++ ) { - for ( m=0; m<=N; m++ ) { - if ( n == 1 ) { + for (n = 1; n <= N; n++) { + for (m = 0; m <= N; m++) { + if (n == 1) { K[n][m] = 0.0; } else { - nm1 = n-1; nm1_2 = nm1*nm1; - K[n][m] = (double)((nm1_2 - m*m))/((double)((2*n-1)*(2*n-3))); + nm1 = n - 1; + nm1_2 = nm1 * nm1; + K[n][m] = (double)((nm1_2 - m * m)) / + ((double)((2 * n - 1) * (2 * n - 3))); } -//printf("K[%d][%d] = %g\n", n, m, K[n][m] ); + // printf("K[%d][%d] = %g\n", n, m, K[n][m] ); } } - - } - -void Lgm_InitIGRF( double g[14][14], double h[14][14], int N, int Flag, Lgm_CTrans *c ){ - - double Year; - double g0, g1, h0, h1, gs, hs, y0, y1; - double H0, H02, Lx, Ly, Lz, E; - int j, j0, j1, n, m; - +void Lgm_InitIGRF(double g[14][14], + double h[14][14], + int N, + int Flag, + Lgm_CTrans* c) { + double Year; + double g0, g1, h0, h1, gs, hs, y0, y1; + double H0, H02, Lx, Ly, Lz, E; + int j, j0, j1, n, m; /* Get Year from Lgm_CTrans structure */ Year = c->UTC.fYear; - if ( Year < 1.0 ) { + if (Year < 1.0) { printf("Year not set?! ( Year = %g )\n", Year); exit(-1); } - /* * Set IGRF Model based on the current epoch. */ - if ( (fabs(Year - c->Lgm_IGRF_OldYear) > 0.0) || Flag ) { - + if ((fabs(Year - c->Lgm_IGRF_OldYear) > 0.0) || Flag) { + if (Year < IGRF_epoch[IGRF_nModels - 1]) { + /* + * Interpolation/Extrapolation the past. + * Use linear for now. + * Rational or Polynomial function extrapolation would be better. + * + */ + if (Year >= IGRF_epoch[0]) { + j = IGRF_nModels - 1; + while (Year < IGRF_epoch[j]) { + --j; + } + j0 = j; + j1 = j + 1; + } else { /* extrapolate to the past */ + j0 = 0; + j1 = 1; + } - if (Year < IGRF_epoch[IGRF_nModels-1]) { + y0 = IGRF_epoch[j0]; + y1 = IGRF_epoch[j1]; + for (n = 0; n <= N; ++n) { + for (m = 0; m <= n; ++m) { + g0 = IGRF_g[j0][n][m]; + g1 = IGRF_g[j1][n][m]; + h0 = IGRF_h[j0][n][m]; + h1 = IGRF_h[j1][n][m]; - /* - * Interpolation/Extrapolation the past. - * Use linear for now. - * Rational or Polynomial function extrapolation would be better. - * - */ - if(Year >= IGRF_epoch[0]) { - j = IGRF_nModels-1; - while ( Year < IGRF_epoch[j] ){ --j; } - j0 = j; - j1 = j+1; - } else { /* extrapolate to the past */ - j0 = 0; j1 = 1; - } + gs = (g1 - g0) / (y1 - y0); + hs = (h1 - h0) / (y1 - y0); - y0 = IGRF_epoch[j0]; y1 = IGRF_epoch[j1]; - for (n=0; n<=N; ++n){ - for (m=0; m<=n; ++m){ - g0 = IGRF_g[j0][n][m]; g1 = IGRF_g[j1][n][m]; - h0 = IGRF_h[j0][n][m]; h1 = IGRF_h[j1][n][m]; - - gs = (g1-g0)/(y1-y0); hs = (h1-h0)/(y1-y0); - - g[n][m] = gs*(Year - y0) + g0; - h[n][m] = hs*(Year - y0) + h0; - } - } + g[n][m] = gs * (Year - y0) + g0; + h[n][m] = hs * (Year - y0) + h0; + } + } - } else { - /* - * extrapolation using IGRF SV - */ - j0 = IGRF_nModels-1; - y0 = IGRF_epoch[j0]; - for (n=0; n<=N; ++n){ - for (m=0; m<=n; ++m){ - g[n][m] = IGRF_g_SV[n][m]*(Year - y0) + IGRF_g[j0][n][m]; - h[n][m] = IGRF_h_SV[n][m]*(Year - y0) + IGRF_h[j0][n][m]; - } + } else { + /* + * extrapolation using IGRF SV + */ + j0 = IGRF_nModels - 1; + y0 = IGRF_epoch[j0]; + for (n = 0; n <= N; ++n) { + for (m = 0; m <= n; ++m) { + g[n][m] = IGRF_g_SV[n][m] * (Year - y0) + IGRF_g[j0][n][m]; + h[n][m] = IGRF_h_SV[n][m] * (Year - y0) + IGRF_h[j0][n][m]; + } + } } - } /* - * Compute the various IGRF dependent things like position of CD + * Compute the various IGRF dependent things like position of CD */ - H02 = g[1][0]*g[1][0] + g[1][1]*g[1][1] + h[1][1]*h[1][1]; - H0 = sqrt(H02); + H02 = g[1][0] * g[1][0] + g[1][1] * g[1][1] + h[1][1] * h[1][1]; + H0 = sqrt(H02); /* * Compute dipole moments. */ c->M_cd = H0; c->M_cd_McIlwain = 31165.3; - c->M_cd_2010 = 29950.1686985232; - - c->CD_gcolat = M_PI - acos(g[1][0]/H0); - c->CD_glon = atan(h[1][1]/g[1][1]); + c->M_cd_2010 = 29950.1686985232; + c->CD_gcolat = M_PI - acos(g[1][0] / H0); + c->CD_glon = atan(h[1][1] / g[1][1]); /* * Compute the Eccentric dipole offset vector Chapman and Bartels, @@ -1107,38 +1041,41 @@ void Lgm_InitIGRF( double g[14][14], double h[14][14], int N, int Flag, Lgm_CTra * mixed up.) A better reference is Akasofu and Chapman [1972]. * Plus, I'm sure Jacobs' books are good on this too. */ - Lx = -g[1][1]*g[2][0] + (g[1][1]*g[2][2] + h[1][1]*h[2][2] + g[1][0]*g[2][1])*M_SQRT_3; - Ly = -h[1][1]*g[2][0] + (g[1][1]*h[2][2] - h[1][1]*g[2][2] + g[1][0]*h[2][1])*M_SQRT_3; - Lz = 2.0*g[1][0]*g[2][0] + (g[1][1]*g[2][1] + h[1][1]*h[2][1])*M_SQRT_3; - E = (Lx*g[1][1] + Ly*h[1][1] + Lz*g[1][0])/(4.0*H02); - - c->ED_x0 = (Lx-g[1][1]*E)/(3.0*H02); // in units of Re - c->ED_y0 = (Ly-h[1][1]*E)/(3.0*H02); // in units of Re - c->ED_z0 = (Lz-g[1][0]*E)/(3.0*H02); // in units of Re - - } + Lx = -g[1][1] * g[2][0] + + (g[1][1] * g[2][2] + h[1][1] * h[2][2] + g[1][0] * g[2][1]) * + M_SQRT_3; + Ly = -h[1][1] * g[2][0] + + (g[1][1] * h[2][2] - h[1][1] * g[2][2] + g[1][0] * h[2][1]) * + M_SQRT_3; + Lz = 2.0 * g[1][0] * g[2][0] + + (g[1][1] * g[2][1] + h[1][1] * h[2][1]) * M_SQRT_3; + E = (Lx * g[1][1] + Ly * h[1][1] + Lz * g[1][0]) / (4.0 * H02); + + c->ED_x0 = (Lx - g[1][1] * E) / (3.0 * H02); // in units of Re + c->ED_y0 = (Ly - h[1][1] * E) / (3.0 * H02); // in units of Re + c->ED_z0 = (Lz - g[1][0] * E) / (3.0 * H02); // in units of Re + } c->Lgm_IGRF_OldYear = Year; - - } +void Lgm_PolFunInt(double* xa, + double* ya, + int n, + double x, + double* y, + double* dy) { + int i, m, ns = 0; + double den, dif, dift, ho, hp, w; + double *c, *d; - - -void Lgm_PolFunInt( double *xa, double *ya, int n, double x, double *y, double *dy ) { - - int i, m, ns=0; - double den, dif, dift, ho, hp, w; - double *c, *d; - - c = (double *)calloc(n, sizeof(double)); - d = (double *)calloc(n, sizeof(double)); + c = (double*)calloc(n, sizeof(double)); + d = (double*)calloc(n, sizeof(double)); dif = fabs(x - xa[0]); - for (i=0; i #endif +#include #include #include #include -#include -#include "Lgm/Lgm_Vec.h" #include "Lgm/Lgm_HDF5.h" #include "Lgm/Lgm_JPLeph.h" +#include "Lgm/Lgm_Vec.h" #ifndef LGM_INDEX_DATA_DIR #warning "hard-coding LGM_INDEX_DATA_DIR because it was not in config.h" diff --git a/libLanlGeoMag/Lgm_KdTree.c b/libLanlGeoMag/Lgm_KdTree.c index 4b91dae87..78b4db54e 100644 --- a/libLanlGeoMag/Lgm_KdTree.c +++ b/libLanlGeoMag/Lgm_KdTree.c @@ -8,14 +8,14 @@ #pragma GCC optimize ("O3") #include "Lgm/Lgm_KdTree.h" -#include "Lgm/quicksort.h" +#include +#include #include #include -#include +#include #include #include -#include -#include +#include "Lgm/quicksort.h" // We are missing the Lgm_KdTree_Free() routine??? diff --git a/libLanlGeoMag/Lgm_MagEphemWrite.c b/libLanlGeoMag/Lgm_MagEphemWrite.c index d98320102..30efe282c 100644 --- a/libLanlGeoMag/Lgm_MagEphemWrite.c +++ b/libLanlGeoMag/Lgm_MagEphemWrite.c @@ -2,8 +2,8 @@ #include #endif #include "Lgm/Lgm_CTrans.h" -#include "Lgm/Lgm_MagEphemInfo.h" #include "Lgm/Lgm_IGRF.h" +#include "Lgm/Lgm_MagEphemInfo.h" #ifndef LGM_INDEX_DATA_DIR #warning "hard-coding LGM_INDEX_DATA_DIR because it was not in config.h" diff --git a/libLanlGeoMag/Lgm_MagEphemWriteHdf.c b/libLanlGeoMag/Lgm_MagEphemWriteHdf.c index 3eee73b15..f89663a6b 100644 --- a/libLanlGeoMag/Lgm_MagEphemWriteHdf.c +++ b/libLanlGeoMag/Lgm_MagEphemWriteHdf.c @@ -1,6 +1,6 @@ #include "Lgm/Lgm_CTrans.h" -#include "Lgm/Lgm_MagEphemInfo.h" #include "Lgm/Lgm_HDF5.h" +#include "Lgm/Lgm_MagEphemInfo.h" //const char *sMonth[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; diff --git a/libLanlGeoMag/Lgm_MaxwellJuttner.c b/libLanlGeoMag/Lgm_MaxwellJuttner.c index 14b371698..49047dda8 100644 --- a/libLanlGeoMag/Lgm_MaxwellJuttner.c +++ b/libLanlGeoMag/Lgm_MaxwellJuttner.c @@ -1,11 +1,11 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include +#include #include #include -#include #include "Lgm/Lgm_FluxToPsd.h" -#include #define kb = 8.61734315e-11 // MeV/K diff --git a/libLanlGeoMag/Lgm_McIlwain_L.c b/libLanlGeoMag/Lgm_McIlwain_L.c index 869db732d..be08b2582 100644 --- a/libLanlGeoMag/Lgm_McIlwain_L.c +++ b/libLanlGeoMag/Lgm_McIlwain_L.c @@ -1,6 +1,7 @@ /*! \file Lgm_McIlwain_L.c * - * \brief Routine for computing the pitch-angle-dependent McIlwain L-shell parameter. + * \brief Routine for computing the pitch-angle-dependent McIlwain L-shell + * parameter. * * * @@ -11,219 +12,288 @@ * */ -#include "Lgm/Lgm_MagModelInfo.h" +#include #include #include -#include -#include #include -#include - +#include +#include +#include "Lgm/Lgm_MagModelInfo.h" /* * Lgm_McIlwain_L * ------------- */ - -//! Compute McIlwain L-shell parameter for a given date, time, location and pitch angle. +//! Compute McIlwain L-shell parameter for a given date, time, location and +//! pitch angle. /** - * \param[in] Date Date in format (e.g. 20101231). - * \param[in] UTC Universal Time (Coordinated) in decimal hours (e.g. 23.5). - * \param[in] u Position (in GSM) to compute L-shell. - * \param[in] Alpha Pitch angle to compute L for. In degrees. - * \param[in] Type Flag to indicate which alogorithm to use (0=original McIlwain; else use Hilton's formula). - * \param[out] I The integral invariant, I that was computed along the way. - * \param[out] Bm The mirror magnetic field value, Bm that was computed along the way. - * \param[out] M The dipole magnetic moment used to compute L = f(I, Bm, M) - * \param[in,out] mInfo Properly initialized Lgm_MagModelInfo structure. (A number of otherm usefull things will have been set in mInfo). + * \param[in] Date Date in format (e.g. 20101231). + * \param[in] UTC Universal Time (Coordinated) in + * decimal hours (e.g. 23.5). \param[in] u Position (in GSM) to + * compute L-shell. \param[in] Alpha Pitch angle to compute L for. + * In degrees. \param[in] Type Flag to indicate which alogorithm + * to use (0=original McIlwain; else use Hilton's formula). \param[out] I + * The integral invariant, I that was computed along the way. \param[out] Bm The + * mirror magnetic field value, Bm that was computed along the way. \param[out] + * M The dipole magnetic moment used to compute L = f(I, Bm, M) + * \param[in,out] mInfo Properly initialized + * Lgm_MagModelInfo structure. (A number of otherm usefull things will have been + * set in mInfo). * - * \return L McIlwain L-shell parameter (a dimensioless number). + * \return L McIlwain L-shell parameter (a + * dimensioless number). * */ -double Lgm_McIlwain_L( long int Date, double UTC, Lgm_Vector *u, double Alpha, int Type, double *I, double *Bm, double *M, Lgm_MagModelInfo *mInfo ) { - - int reset; - Lgm_Vector v1, v2, v3, Bvec, Bvectmp, Ptmp, u_scale; - double rat, B, sa, sa2, Blocal, dSa, dSb, r, SS, L, stmp, Hdid, Hnext, Btmp; - - if (mInfo->VerbosityLevel > 0) printf("Lgm_McIlwain_L: VerbosityLevel = %d\n", mInfo->VerbosityLevel); +double Lgm_McIlwain_L(long int Date, + double UTC, + Lgm_Vector* u, + double Alpha, + int Type, + double* I, + double* Bm, + double* M, + Lgm_MagModelInfo* mInfo) { + int reset; + Lgm_Vector v1, v2, v3, Bvec, Bvectmp, Ptmp, u_scale; + double rat, B, sa, sa2, Blocal, dSa, dSb, r, SS, L, stmp, Hdid, Hnext, Btmp; + + if (mInfo->VerbosityLevel > 0) + printf("Lgm_McIlwain_L: VerbosityLevel = %d\n", mInfo->VerbosityLevel); u_scale.x = u_scale.y = u_scale.z = 1.0; - *I = LGM_FILL_VALUE; + *I = LGM_FILL_VALUE; *Bm = LGM_FILL_VALUE; - *M = LGM_FILL_VALUE; - L = LGM_FILL_VALUE; - + *M = LGM_FILL_VALUE; + L = LGM_FILL_VALUE; /* * set coord transformations */ - Lgm_Set_Coord_Transforms( Date, UTC, mInfo->c ); - + Lgm_Set_Coord_Transforms(Date, UTC, mInfo->c); /* * Save S/C position to Lgm_MagModelInfo structure and compute Blocal. */ mInfo->P_gsm = *u; - mInfo->Bfield( u, &Bvec, mInfo ); - Blocal = Lgm_Magnitude( &Bvec ); + mInfo->Bfield(u, &Bvec, mInfo); + Blocal = Lgm_Magnitude(&Bvec); mInfo->Blocal = Blocal; /* * Set Pitch Angle, sin(Alpha), sin^2(Alpha), and Bmirror */ - sa = sin( Alpha*RadPerDeg ); sa2 = sa*sa; - mInfo->Bm = Blocal/sa2; - - + sa = sin(Alpha * RadPerDeg); + sa2 = sa * sa; + mInfo->Bm = Blocal / sa2; /* - * First do a trace to identify the FL type and some of its critical points. + * First do a trace to identify the FL type and some of its critical + * points. */ - if ( Lgm_Trace( u, &v1, &v2, &v3, mInfo->Lgm_LossConeHeight, mInfo->Lgm_TraceToEarth_Tol, mInfo->Lgm_TraceToBmin_Tol, mInfo ) == LGM_CLOSED ) { - - + if (Lgm_Trace(u, &v1, &v2, &v3, mInfo->Lgm_LossConeHeight, + mInfo->Lgm_TraceToEarth_Tol, mInfo->Lgm_TraceToBmin_Tol, + mInfo) == LGM_CLOSED) { /* * Test to see if the S/C is already close to the Bmin point or the * B's are almost the same; And the Pitch angle is close to 90. If * so, use an approximation to I. */ - if ( ( ((SS=Lgm_VecDiffMag( u, &v3 )) < 1e-4) || (fabs( mInfo->Blocal - mInfo->Bmin) < 1e-2) ) && (fabs(90.0-Alpha) < 1e-2) ) { - + if ((((SS = Lgm_VecDiffMag(u, &v3)) < 1e-4) || + (fabs(mInfo->Blocal - mInfo->Bmin) < 1e-2)) && + (fabs(90.0 - Alpha) < 1e-2)) { // if FL length is small, use an approx expression for I - rat = mInfo->Bmin/mInfo->Bm; - if ((1.0-rat) < 0.0) { + rat = mInfo->Bmin / mInfo->Bm; + if ((1.0 - rat) < 0.0) { *I = 0.0; } else { // Eqn 2.66b in Roederer - *I = SS*sqrt(1.0 - rat); + *I = SS * sqrt(1.0 - rat); } } else { - - /* * Trace from Bmin point up to northern mirror point and down to * southern mirror point. dSa and dSb are the distances along the * FL from the starting points point. So dSa is from the Bmin value. * And dSb is from the Psouth value. */ - if ( Lgm_TraceToMirrorPoint( &(mInfo->Pmin), &(mInfo->Pm_South), &dSa, mInfo->Bm, -1.0, mInfo->Lgm_TraceToMirrorPoint_Tol, mInfo ) >= 0 ) { - + if (Lgm_TraceToMirrorPoint( + &(mInfo->Pmin), &(mInfo->Pm_South), &dSa, mInfo->Bm, -1.0, + mInfo->Lgm_TraceToMirrorPoint_Tol, mInfo) >= 0) { if (mInfo->VerbosityLevel > 0) { - printf("\n\tMin-B Point Location, Pmin (Re): < %g, %g, %g >\n", mInfo->Pmin.x, mInfo->Pmin.y, mInfo->Pmin.z ); - printf("\tMirror Point Location, Pm_South (Re): < %g, %g, %g > |Pm_South| = %g\n", mInfo->Pm_South.x, mInfo->Pm_South.y, mInfo->Pm_South.z, Lgm_Magnitude(&mInfo->Pm_South) ); - mInfo->Bfield( &mInfo->Pm_South, &Bvec, mInfo ); - B = Lgm_Magnitude( &Bvec ); - printf("\tMag. Field Strength, Bm at Pm_South (nT): %g (mInfo->Bm = %g)\n", B, mInfo->Bm ); + printf( + "\n\tMin-B Point Location, Pmin (Re): < %g, %g, " + "%g >\n", + mInfo->Pmin.x, mInfo->Pmin.y, mInfo->Pmin.z); + printf( + "\tMirror Point Location, Pm_South (Re): < %g, " + "%g, %g > |Pm_South| = %g\n", + mInfo->Pm_South.x, mInfo->Pm_South.y, mInfo->Pm_South.z, + Lgm_Magnitude(&mInfo->Pm_South)); + mInfo->Bfield(&mInfo->Pm_South, &Bvec, mInfo); + B = Lgm_Magnitude(&Bvec); + printf( + "\tMag. Field Strength, Bm at Pm_South (nT): %g " + "(mInfo->Bm = %g)\n", + B, mInfo->Bm); } - - - if ( Lgm_TraceToMirrorPoint( &(mInfo->Pmin), &(mInfo->Pm_North), &dSb, mInfo->Bm, 1.0, mInfo->Lgm_TraceToMirrorPoint_Tol, mInfo ) >= 0 ) { - + if (Lgm_TraceToMirrorPoint( + &(mInfo->Pmin), &(mInfo->Pm_North), &dSb, mInfo->Bm, + 1.0, mInfo->Lgm_TraceToMirrorPoint_Tol, mInfo) >= 0) { if (mInfo->VerbosityLevel > 0) { - printf("\n\tMin-B Point Location, Pmin (Re): < %g, %g, %g >\n", mInfo->Pmin.x, mInfo->Pmin.y, mInfo->Pmin.z ); - printf("\tMirror Point Location, Pm_North (Re): < %g, %g, %g > |Pm_North| = %g\n", mInfo->Pm_North.x, mInfo->Pm_North.y, mInfo->Pm_North.z, Lgm_Magnitude(&mInfo->Pm_North) ); - mInfo->Bfield( &mInfo->Pm_North, &Bvec, mInfo ); - B = Lgm_Magnitude( &Bvec ); - printf("\tMag. Field Strength, Bm at Pm_North (nT): %g (mInfo->Bm = %g)\n", B, mInfo->Bm ); + printf( + "\n\tMin-B Point Location, Pmin (Re): < %g, " + "%g, %g >\n", + mInfo->Pmin.x, mInfo->Pmin.y, mInfo->Pmin.z); + printf( + "\tMirror Point Location, Pm_North (Re): < " + "%g, %g, %g > |Pm_North| = %g\n", + mInfo->Pm_North.x, mInfo->Pm_North.y, + mInfo->Pm_North.z, Lgm_Magnitude(&mInfo->Pm_North)); + mInfo->Bfield(&mInfo->Pm_North, &Bvec, mInfo); + B = Lgm_Magnitude(&Bvec); + printf( + "\tMag. Field Strength, Bm at Pm_North (nT): %g " + " (mInfo->Bm = %g)\n", + B, mInfo->Bm); } /* - * Set the limits of integration. Define s=0 at the sourthern mirror point. Then, sm_North will just be dSb + * Set the limits of integration. Define s=0 at the + * sourthern mirror point. Then, sm_North will just be dSb */ - //SS = dSb; - SS = dSa+dSb; - mInfo->Hmax = SS/(double)mInfo->nDivs; - if ( mInfo->Hmax > mInfo->MaxDiv ) mInfo->Hmax = mInfo->MaxDiv; - r = Lgm_Magnitude( &mInfo->Pm_North ); + // SS = dSb; + SS = dSa + dSb; + mInfo->Hmax = SS / (double)mInfo->nDivs; + if (mInfo->Hmax > mInfo->MaxDiv) + mInfo->Hmax = mInfo->MaxDiv; + r = Lgm_Magnitude(&mInfo->Pm_North); mInfo->Sm_South = 0.0; mInfo->Sm_North = SS; - if ( SS <= 1e-5 ) { - + if (SS <= 1e-5) { // if FL length is small, use an approx expression for I - rat = mInfo->Bmin/mInfo->Bm; - if ((1.0-rat) < 0.0) { + rat = mInfo->Bmin / mInfo->Bm; + if ((1.0 - rat) < 0.0) { *I = 0.0; } else { // Eqn 2.66b in Roederer - *I = SS*sqrt(1.0 - rat); + *I = SS * sqrt(1.0 - rat); } - } else if ( mInfo->UseInterpRoutines ) { - if ( Lgm_TraceLine2( &(mInfo->Pm_South), &mInfo->Pm_North, (r-1.0)*Re, 0.5*SS-mInfo->Hmax, 1.0, mInfo->Lgm_TraceToEarth_Tol, FALSE, mInfo ) <= 0 ) return(LGM_FILL_VALUE); -//printf("BEFORE mInfo->nPnts = %d mInfo->s[0] = %g mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", mInfo->nPnts, mInfo->s[0], mInfo->s[1], mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS ); - ReplaceFirstPoint( 0.0, mInfo->Bm, &mInfo->Pm_South, mInfo ); - ReplaceLastPoint( SS, mInfo->Bm, &mInfo->Pm_North, mInfo ); -//printf("AFTER1 mInfo->nPnts = %d mInfo->s[0] = %g mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", mInfo->nPnts, mInfo->s[0], mInfo->s[1], mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS ); + } else if (mInfo->UseInterpRoutines) { + if (Lgm_TraceLine2( + &(mInfo->Pm_South), &mInfo->Pm_North, + (r - 1.0) * Re, 0.5 * SS - mInfo->Hmax, 1.0, + mInfo->Lgm_TraceToEarth_Tol, FALSE, mInfo) <= 0) + return (LGM_FILL_VALUE); + // printf("BEFORE mInfo->nPnts = %d mInfo->s[0] = %g + // mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g + // mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", + // mInfo->nPnts, mInfo->s[0], mInfo->s[1], + // mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS + // ); + ReplaceFirstPoint(0.0, mInfo->Bm, &mInfo->Pm_South, + mInfo); + ReplaceLastPoint(SS, mInfo->Bm, &mInfo->Pm_North, + mInfo); + // printf("AFTER1 mInfo->nPnts = %d mInfo->s[0] = %g + // mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g + // mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", + // mInfo->nPnts, mInfo->s[0], mInfo->s[1], + // mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS + // ); /* * Make sure we have a small margin before and after so * we dont end up trying to extrapolate if s ever gets * slightly out of bounds. */ - Ptmp = mInfo->Pm_South; stmp = 0.0; reset = FALSE; - if ( Lgm_MagStep( &Ptmp, &u_scale, 0.01, &Hdid, &Hnext, -1.0, &stmp, &reset, mInfo->Bfield, mInfo ) < 0 ) { return(-1); } - mInfo->Bfield( &Ptmp, &Bvectmp, mInfo ); Btmp = Lgm_Magnitude( &Bvectmp ); - //printf("-stmp, Btmp = %g %g\n", -stmp, Btmp ); - AddNewPoint( -stmp, Btmp, &Ptmp, mInfo ); -//printf("AFTER2 mInfo->nPnts = %d mInfo->s[0] = %g mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", mInfo->nPnts, mInfo->s[0], mInfo->s[1], mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS ); - - Ptmp = mInfo->Pm_North; stmp = 0.0; reset = FALSE; - if ( Lgm_MagStep( &Ptmp, &u_scale, 0.01, &Hdid, &Hnext, 1.0, &stmp, &reset, mInfo->Bfield, mInfo ) < 0 ) { return(-1); } - mInfo->Bfield( &Ptmp, &Bvectmp, mInfo ); Btmp = Lgm_Magnitude( &Bvectmp ); - //printf("stmp, Btmp = %g %g\n", SS+stmp, Btmp ); - AddNewPoint( SS+stmp, Btmp, &Ptmp, mInfo ); - - - - - -//printf("AFTER2 mInfo->nPnts = %d mInfo->s[0] = %g mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", mInfo->nPnts, mInfo->s[0], mInfo->s[1], mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS ); - //AddNewPoint( SS, mInfo->Bm, &mInfo->Pm_North, mInfo ); - if ( InitSpline( mInfo ) ) { - + Ptmp = mInfo->Pm_South; + stmp = 0.0; + reset = FALSE; + if (Lgm_MagStep(&Ptmp, &u_scale, 0.01, &Hdid, &Hnext, + -1.0, &stmp, &reset, mInfo->Bfield, + mInfo) < 0) { + return (-1); + } + mInfo->Bfield(&Ptmp, &Bvectmp, mInfo); + Btmp = Lgm_Magnitude(&Bvectmp); + // printf("-stmp, Btmp = %g %g\n", -stmp, Btmp ); + AddNewPoint(-stmp, Btmp, &Ptmp, mInfo); + // printf("AFTER2 mInfo->nPnts = %d mInfo->s[0] = %g + // mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g + // mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", + // mInfo->nPnts, mInfo->s[0], mInfo->s[1], + // mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS + // ); + + Ptmp = mInfo->Pm_North; + stmp = 0.0; + reset = FALSE; + if (Lgm_MagStep(&Ptmp, &u_scale, 0.01, &Hdid, &Hnext, + 1.0, &stmp, &reset, mInfo->Bfield, + mInfo) < 0) { + return (-1); + } + mInfo->Bfield(&Ptmp, &Bvectmp, mInfo); + Btmp = Lgm_Magnitude(&Bvectmp); + // printf("stmp, Btmp = %g %g\n", SS+stmp, Btmp ); + AddNewPoint(SS + stmp, Btmp, &Ptmp, mInfo); + + // printf("AFTER2 mInfo->nPnts = %d mInfo->s[0] = %g + // mInfo->s[1] = %g mInfo->s[mInfo->nPnts-2] = %g + // mInfo->s[mInfo->nPnts-1] = %g SS = %g\n", + // mInfo->nPnts, mInfo->s[0], mInfo->s[1], + // mInfo->s[mInfo->nPnts-2], mInfo->s[mInfo->nPnts-1], SS + // ); AddNewPoint( SS, mInfo->Bm, &mInfo->Pm_North, + // mInfo ); + if (InitSpline(mInfo)) { /* * Do interped I integral. */ - *I = Iinv_interped( mInfo ); - if (mInfo->VerbosityLevel > 0) printf("Lgm_McIlwain_L: Integral Invariant, I (interped): %g\n", *I ); - FreeSpline( mInfo ); + *I = Iinv_interped(mInfo); + if (mInfo->VerbosityLevel > 0) + printf( + "Lgm_McIlwain_L: Integral Invariant, I " + "(interped): %g\n", + *I); + FreeSpline(mInfo); } else { - *I = LGM_FILL_VALUE; - } } else { - /* - * Do full blown I integral. (Integrand is evaluated by tracing to required s-values.) + * Do full blown I integral. (Integrand is evaluated by + * tracing to required s-values.) */ - *I = Iinv( mInfo ); - if (mInfo->VerbosityLevel > 0) printf("Lgm_McIlwain_L: Integral Invariant, I (full integral): %g\n", *I ); - + *I = Iinv(mInfo); + if (mInfo->VerbosityLevel > 0) + printf( + "Lgm_McIlwain_L: Integral Invariant, I (full " + "integral): %g\n", + *I); } } else { - if (mInfo->VerbosityLevel > 0) printf("Could not find northern mirror point.\n"); + if (mInfo->VerbosityLevel > 0) + printf("Could not find northern mirror point.\n"); } } else { - if (mInfo->VerbosityLevel > 0) printf("Could not find southern mirror point.\n"); + if (mInfo->VerbosityLevel > 0) + printf("Could not find southern mirror point.\n"); } - - } - - + } /* - * Current time-dependant value of dipole moement (derived from first 3 vals of IGRF model) + * Current time-dependant value of dipole moement (derived from first 3 + * vals of IGRF model) */ *M = mInfo->c->M_cd; @@ -232,24 +302,17 @@ double Lgm_McIlwain_L( long int Date, double UTC, Lgm_Vector *u, double Alpha, i */ *Bm = mInfo->Bm; - /* * McIlwain L, via McIlwain's original tables or via Hilton approx. */ - if ( *I < 0.0 ){ + if (*I < 0.0) { L = LGM_FILL_VALUE; - } else if ( Type == 0 ) { - L = LFromIBmM_McIlwain( *I, *Bm, *M ); + } else if (Type == 0) { + L = LFromIBmM_McIlwain(*I, *Bm, *M); } else { - L = LFromIBmM_Hilton( *I, *Bm, *M ); + L = LFromIBmM_Hilton(*I, *Bm, *M); } - - } - - return( L ); - + return (L); } - - diff --git a/libLanlGeoMag/Lgm_Metadata.c b/libLanlGeoMag/Lgm_Metadata.c index b2b260754..02621d699 100644 --- a/libLanlGeoMag/Lgm_Metadata.c +++ b/libLanlGeoMag/Lgm_Metadata.c @@ -1,11 +1,11 @@ #include +#include #include #include -#include -#include "Lgm/Lgm_Metadata.h" #include "Lgm/Lgm_DynamicMemory.h" +#include "Lgm/Lgm_Metadata.h" #define Lgm_metadata_MAXHEADERLEN 100000 #define Lgm_metadata_MAXSINGLEVARHEADER 10000 @@ -13,299 +13,320 @@ /******************************************************************************/ -void Lgm_metadata_initvar( Lgm_metadata_variable *var, int dimension, int data, char* name ) { - - int dm[] = {dimension}; - var->dimension = dimension; - var->name = name; - var->n_attrs = 0; - var->attributes = NULL; - var->data = data; - //Lgm_metadata_addIntAttr(var, "DIMENSION", 1, &dimension); // the & since it wants a pointer - Lgm_metadata_addStringAttr( var, "DIMENSION", Lgm_metadata_intArrayToString(1, dm), 1 ); - +void Lgm_metadata_initvar(Lgm_metadata_variable* var, + int dimension, + int data, + char* name) { + int dm[] = {dimension}; + var->dimension = dimension; + var->name = name; + var->n_attrs = 0; + var->attributes = NULL; + var->data = data; + // Lgm_metadata_addIntAttr(var, "DIMENSION", 1, &dimension); // the & since + // it wants a pointer + Lgm_metadata_addStringAttr(var, "DIMENSION", + Lgm_metadata_intArrayToString(1, dm), 1); } /******************************************************************************/ -char *Lgm_metadata_JSONheader(int n_vars, ...) { - va_list hv; - char Buffer[Lgm_metadata_MAXHEADERLEN]; - char *outstr; - size_t L; - - va_start(hv, n_vars); - - // loop over n_vars vars making them all into JSON headers - { - int i; - char *p; - char *tmp_str; - Lgm_metadata_variable* var_tmp; - int current_col=0; - char int_str[80]; - - // start the block - p = Buffer; - p += sprintf(p, "%c {\n", '#'); - - for (i=0; idata) { - Lgm_metadata_addIntAttr(var_tmp, "START_COLUMN", 1, ¤t_col); // the & since it wants a pointer - current_col += var_tmp->dimension; - } - - tmp_str = Lgm_metadata_toJSON(var_tmp, i == (n_vars-1), '#'); - p += sprintf(p, "%s", tmp_str); - if (i < n_vars-1) - p += sprintf(p, ",\n"); - else - p += sprintf(p, "\n"); - +char* Lgm_metadata_JSONheader(int n_vars, ...) { + va_list hv; + char Buffer[Lgm_metadata_MAXHEADERLEN]; + char* outstr; + size_t L; + + va_start(hv, n_vars); + + // loop over n_vars vars making them all into JSON headers + { + int i; + char* p; + char* tmp_str; + Lgm_metadata_variable* var_tmp; + int current_col = 0; + char int_str[80]; + + // start the block + p = Buffer; + p += sprintf(p, "%c {\n", '#'); + + for (i = 0; i < n_vars; i++) { + var_tmp = va_arg(hv, Lgm_metadata_variable*); + if (var_tmp->data) { + Lgm_metadata_addIntAttr( + var_tmp, "START_COLUMN", 1, + ¤t_col); // the & since it wants a pointer + current_col += var_tmp->dimension; + } + + tmp_str = Lgm_metadata_toJSON(var_tmp, i == (n_vars - 1), '#'); + p += sprintf(p, "%s", tmp_str); + if (i < n_vars - 1) + p += sprintf(p, ",\n"); + else + p += sprintf(p, "\n"); + } + p += sprintf(p, "%c } # ENDJSON\n", '#'); } - p += sprintf(p, "%c } # ENDJSON\n", '#'); - } - va_end(hv); - L = strlen(Buffer); - outstr = malloc( (L + 1)*sizeof(char)); - strncpy(outstr, Buffer, L); - outstr[L] = '\0'; - return (outstr); + va_end(hv); + L = strlen(Buffer); + outstr = malloc((L + 1) * sizeof(char)); + strncpy(outstr, Buffer, strlen(outstr) - 1); + outstr[L] = '\0'; + return (outstr); } /******************************************************************************/ -char* Lgm_metadata_toJSON(Lgm_metadata_variable *var, short last, char comment) { - char Buffer[Lgm_metadata_MAXSINGLEVARHEADER]; - char *outstr; - size_t L; - char *p; +char* Lgm_metadata_toJSON(Lgm_metadata_variable* var, + short last, + char comment) { + char Buffer[Lgm_metadata_MAXSINGLEVARHEADER]; + char* outstr; + size_t L; + char* p; - p = Buffer; + p = Buffer; - // add the name and start attrs - p += sprintf(p, "%c \"%s\":%s{ ", comment, var->name, Lgm_metadata_TABCHAR); - // go through each attribute and add it to the string - { - int i; - double tmp; - for (i=0;in_attrs;i++) { - // add the name - p += sprintf(p, " \"%s\": ", (var->attributes)[i].name); - // if an array need a [ - if ((var->attributes)[i].array) - p += sprintf(p, "[ "); - // add the value - if (sscanf((var->attributes)[i].value, "%lf", &tmp)) // returns 1 if the string can be a double - p += sprintf(p, "%s ", (var->attributes)[i].value); - else - p += sprintf(p, "\"%s\" ", (var->attributes)[i].value); - // if an array need a ] - if ((var->attributes)[i].array) - p += sprintf(p, "]"); - - // what ending do I need? - if (i+1 < var->n_attrs) - p += sprintf(p, ",\n%c %s%s", comment, Lgm_metadata_TABCHAR, Lgm_metadata_TABCHAR ); - else - p += sprintf(p, "}"); + // add the name and start attrs + p += + sprintf(p, "%c \"%s\":%s{ ", comment, var->name, Lgm_metadata_TABCHAR); + // go through each attribute and add it to the string + { + int i; + double tmp; + for (i = 0; i < var->n_attrs; i++) { + // add the name + p += sprintf(p, " \"%s\": ", (var->attributes)[i].name); + // if an array need a [ + if ((var->attributes)[i].array) + p += sprintf(p, "[ "); + // add the value + if (sscanf((var->attributes)[i].value, "%lf", + &tmp)) // returns 1 if the string can be a double + p += sprintf(p, "%s ", (var->attributes)[i].value); + else + p += sprintf(p, "\"%s\" ", (var->attributes)[i].value); + // if an array need a ] + if ((var->attributes)[i].array) + p += sprintf(p, "]"); + + // what ending do I need? + if (i + 1 < var->n_attrs) + p += sprintf(p, ",\n%c %s%s", comment, Lgm_metadata_TABCHAR, + Lgm_metadata_TABCHAR); + else + p += sprintf(p, "}"); + } } - } - - L = strlen(Buffer); - outstr = malloc( (L + 1)*sizeof(char)); - strncpy(outstr, Buffer, L); - outstr[L] = '\0'; - return (outstr); -} - -/******************************************************************************/ -char *Lgm_metadata_stringArrayToString(int len, char** instring) { - char Buffer[Lgm_metadata_MAXHEADERLEN]; - char *outstr; - char *p; - size_t L; - int i; - - // TODO in here there is no " at the start or stop of an array, feels odd - - p = Buffer; - for (i=0; i1) ); + L = strlen(Buffer); + outstr = malloc((L + 1) * sizeof(char)); + strncpy(outstr, Buffer, strlen(outstr) - 1); + outstr[L] = '\0'; + return (outstr); } /******************************************************************************/ -int Lgm_metadata_addDoubleAttr(Lgm_metadata_variable *var, char *name, int len, double *invals) { - char *outstr; - // make sure the name is not already there, if it is ignore it - if (Lgm_metadata_AttrInVar(var, name)) - return (Lgm_metadata_FAILURE); // it is there we are done +int Lgm_metadata_addIntAttr(Lgm_metadata_variable* var, + char* name, + int len, + int* invals) { + char* outstr; + // make sure the name is not already there, if it is ignore it + if (Lgm_metadata_AttrInVar(var, name)) + return (Lgm_metadata_FAILURE); // it is there we are done - outstr = Lgm_metadata_doubleArrayToString(len,invals); + outstr = Lgm_metadata_intArrayToString(len, invals); - return (Lgm_metadata_addStringAttr(var, name, outstr, len>1) ); + return (Lgm_metadata_addStringAttr(var, name, outstr, len > 1)); } - /******************************************************************************/ -int Lgm_metadata_addStringAttrArray(Lgm_metadata_variable *var, char *name, int len, char **invals ) { - char *outstr; +int Lgm_metadata_addDoubleAttr(Lgm_metadata_variable* var, + char* name, + int len, + double* invals) { + char* outstr; + // make sure the name is not already there, if it is ignore it + if (Lgm_metadata_AttrInVar(var, name)) + return (Lgm_metadata_FAILURE); // it is there we are done - // make sure the name is not already there, if it is ignore it - if (Lgm_metadata_AttrInVar(var, name)) - return (Lgm_metadata_FAILURE); // it is there we are done + outstr = Lgm_metadata_doubleArrayToString(len, invals); - outstr = Lgm_metadata_stringArrayToString(len, invals); - return (Lgm_metadata_addStringAttr(var, name, outstr, len>1) ); + return (Lgm_metadata_addStringAttr(var, name, outstr, len > 1)); } /******************************************************************************/ -int Lgm_metadata_addStringAttrArray2(Lgm_metadata_variable *var, char *name, int len, ... ) { - char **outstrarr; - va_list hv; - int i; - - // make sure the name is not already there, if it is ignore it - if (Lgm_metadata_AttrInVar(var, name)) - return (Lgm_metadata_FAILURE); // it is there we are done +int Lgm_metadata_addStringAttrArray(Lgm_metadata_variable* var, + char* name, + int len, + char** invals) { + char* outstr; - va_start(hv, len); + // make sure the name is not already there, if it is ignore it + if (Lgm_metadata_AttrInVar(var, name)) + return (Lgm_metadata_FAILURE); // it is there we are done - LGM_ARRAY_2D( outstrarr,len, 80, char ); // this 80 is a limitiation here!!! - for (i=0;i 1)); } /******************************************************************************/ -int Lgm_metadata_addStringAttr( Lgm_metadata_variable *var, char *name, char * value, int array ) { - - Lgm_metadata_attr atr; - Lgm_metadata_variable newvar; - Lgm_metadata_attr* old_attr; +int Lgm_metadata_addStringAttrArray2(Lgm_metadata_variable* var, + char* name, + int len, + ...) { + char** outstrarr; + va_list hv; + int i; - // make sure the name is not already there, if it is ignore this call - if (Lgm_metadata_AttrInVar(var, name)) - return (Lgm_metadata_FAILURE); // it is there we are done + // make sure the name is not already there, if it is ignore it + if (Lgm_metadata_AttrInVar(var, name)) + return (Lgm_metadata_FAILURE); // it is there we are done - atr.name = name; - atr.value = value; - atr.array = array; - - old_attr = var->attributes; + va_start(hv, len); - var->n_attrs++; - var->attributes = (Lgm_metadata_attr*) calloc(var->n_attrs, sizeof(Lgm_metadata_attr)); - // put the ones back that were there - { - int i; - for (i=0; in_attrs-1;i++) { // the -1 is since we have a ++ above - var->attributes[i].name = old_attr[i].name; - var->attributes[i].value = old_attr[i].value; - var->attributes[i].array = old_attr[i].array; + LGM_ARRAY_2D(outstrarr, len, 80, char); // this 80 is a limitiation here!!! + for (i = 0; i < len; i++) { + outstrarr[i] = va_arg(hv, char*); } - } - var->attributes[var->n_attrs - 1].name = malloc((1+strlen(name))*sizeof(char)); - strcpy(var->attributes[var->n_attrs - 1].name, name); - var->attributes[var->n_attrs - 1].value = malloc((1+strlen(value))*sizeof(char)); - strcpy(var->attributes[var->n_attrs - 1].value, value); - var->attributes[var->n_attrs - 1].array = array; - - /* Lgm_metadata_initvar(var->start_column, var->dimension, var->name, newvar); */ - free(old_attr); - return (Lgm_metadata_SUCCESS); -} + va_end(hv); + return (Lgm_metadata_addStringAttrArray(var, name, len, outstrarr)); +} /******************************************************************************/ -int Lgm_metadata_AttrInVar(Lgm_metadata_variable *var, char *name) { - - // make sure the name is not already there, if it is ignore it - int i; - for (i=0; in_attrs; i++) { - if (strcmp(var->attributes[i].name, name) == 0) { // there are equal - return (1); // name is in the variable +int Lgm_metadata_addStringAttr(Lgm_metadata_variable* var, + char* name, + char* value, + int array) { + Lgm_metadata_attr atr; + Lgm_metadata_variable newvar; + Lgm_metadata_attr* old_attr; + + // make sure the name is not already there, if it is ignore this call + if (Lgm_metadata_AttrInVar(var, name)) + return (Lgm_metadata_FAILURE); // it is there we are done + + atr.name = name; + atr.value = value; + atr.array = array; + + old_attr = var->attributes; + + var->n_attrs++; + var->attributes = + (Lgm_metadata_attr*)calloc(var->n_attrs, sizeof(Lgm_metadata_attr)); + // put the ones back that were there + { + int i; + for (i = 0; i < var->n_attrs - 1; + i++) { // the -1 is since we have a ++ above + var->attributes[i].name = old_attr[i].name; + var->attributes[i].value = old_attr[i].value; + var->attributes[i].array = old_attr[i].array; + } } - } - return (0); // name is not in the variable + var->attributes[var->n_attrs - 1].name = + malloc((1 + strlen(name)) * sizeof(char)); + strcpy(var->attributes[var->n_attrs - 1].name, name); + var->attributes[var->n_attrs - 1].value = + malloc((1 + strlen(value)) * sizeof(char)); + strcpy(var->attributes[var->n_attrs - 1].value, value); + var->attributes[var->n_attrs - 1].array = array; + + /* Lgm_metadata_initvar(var->start_column, var->dimension, var->name, + * newvar); */ + free(old_attr); + return (Lgm_metadata_SUCCESS); } +/******************************************************************************/ - +int Lgm_metadata_AttrInVar(Lgm_metadata_variable* var, char* name) { + // make sure the name is not already there, if it is ignore it + int i; + for (i = 0; i < var->n_attrs; i++) { + if (strcmp(var->attributes[i].name, name) == 0) { // there are equal + return (1); // name is in the variable + } + } + return (0); // name is not in the variable +} diff --git a/libLanlGeoMag/Lgm_Nutation.c b/libLanlGeoMag/Lgm_Nutation.c index 043535be8..c55ac5016 100644 --- a/libLanlGeoMag/Lgm_Nutation.c +++ b/libLanlGeoMag/Lgm_Nutation.c @@ -1,6 +1,6 @@ #include "Lgm/Lgm_CTrans.h" -#include #include +#include static int a[106][5] = { { 0, 0, 0, 0, 1}, // 1 diff --git a/libLanlGeoMag/Lgm_Octree.c b/libLanlGeoMag/Lgm_Octree.c index 9ccb06604..9e1d3fa5d 100644 --- a/libLanlGeoMag/Lgm_Octree.c +++ b/libLanlGeoMag/Lgm_Octree.c @@ -12,13 +12,13 @@ */ #include "Lgm/Lgm_Octree.h" +#include +#include #include #include -#include +#include #include #include -#include -#include struct timeb StartTime; double ElapsedTime2( struct timeb StartTime ); diff --git a/libLanlGeoMag/Lgm_PolyRoots.c b/libLanlGeoMag/Lgm_PolyRoots.c index d5d688d7b..db20ff92d 100644 --- a/libLanlGeoMag/Lgm_PolyRoots.c +++ b/libLanlGeoMag/Lgm_PolyRoots.c @@ -1,11 +1,10 @@ #include "Lgm/Lgm_PolyRoots.h" /* - * Routines to compute roots of quadtratic, cubic and quartic equations exactly. - * See CRC standard math tables (Beyer) for details. + * Routines to compute roots of quadtratic, cubic and quartic equations + * exactly. See CRC standard math tables (Beyer) for details. */ - /** * \brief * Returns the two roots of the quadratic equation. @@ -29,38 +28,39 @@ * \date 2011 * */ -int Lgm_QuadraticRoots( double a, double b, double c, double complex *z1, double complex *z2 ){ - - int nReal; - double x, D2 = b*b - 4.0*a*c; - double complex D; - - if ( fabs(D2) < 1e-10 ) { +int Lgm_QuadraticRoots(double a, + double b, + double c, + double complex* z1, + double complex* z2) { + int nReal; + double x, D2 = b * b - 4.0 * a * c; + double complex D; + + if (fabs(D2) < 1e-10) { // roots are real and equal nReal = 2; - x = -0.5*b/a; + x = -0.5 * b / a; *z1 = *z2 = x; - } else if ( D2 > 0.0 ) { + } else if (D2 > 0.0) { // roots are real and unequal nReal = 2; D = sqrt(D2); - x = (-b + D)/(2.0*a); *z1 = x; - x = (-b - D)/(2.0*a); *z2 = x; + x = (-b + D) / (2.0 * a); + *z1 = x; + x = (-b - D) / (2.0 * a); + *z2 = x; } else { // roots are imaginary and unequal nReal = 0; D = csqrt(D2); - *z1 = (-b + D)/(2.0*a); - *z2 = (-b - D)/(2.0*a); + *z1 = (-b + D) / (2.0 * a); + *z2 = (-b - D) / (2.0 * a); } - return(nReal); - + return (nReal); } - - - /** * \brief * Returns the three roots of the cubic equation with real coefficients. @@ -86,56 +86,63 @@ int Lgm_QuadraticRoots( double a, double b, double c, double complex *z1, doubl * \date 2011 * */ -int Lgm_CubicRoots( double b, double c, double d, double *z1, double complex *z2, double complex *z3 ){ - - int nReal; - double b2, Q, R, D2, D, RpD, RmD, S, T, Theta, SqrtNQ, f, g, h; - - b2 = b*b; - - Q = (3.0*c - b2)/9.0; - R = (9.0*b*c - 27.0*d - 2.0*b2*b)/54.0; - D2 = Q*Q*Q + R*R; - - if (D2 == 0){ +int Lgm_CubicRoots(double b, + double c, + double d, + double* z1, + double complex* z2, + double complex* z3) { + int nReal; + double b2, Q, R, D2, D, RpD, RmD, S, T, Theta, SqrtNQ, f, g, h; + + b2 = b * b; + + Q = (3.0 * c - b2) / 9.0; + R = (9.0 * b * c - 27.0 * d - 2.0 * b2 * b) / 54.0; + D2 = Q * Q * Q + R * R; + + if (D2 == 0) { // All 3 roots are real and at least two are equal. - if ( R > 0.0) { - f = cbrt( R ); - *z1 = 2.0*f - b/3.0; - *z2 = *z3 = -f - b/3.0; + if (R > 0.0) { + f = cbrt(R); + *z1 = 2.0 * f - b / 3.0; + *z2 = *z3 = -f - b / 3.0; } else { - f = -cbrt( -R ); - *z1 = 2.0*f - b/3.0; - *z2 = *z3 = -f - b/3.0; + f = -cbrt(-R); + *z1 = 2.0 * f - b / 3.0; + *z2 = *z3 = -f - b / 3.0; } nReal = 3; - } else if ( D2 > 0 ) { + } else if (D2 > 0) { // only one real root exists. The other two are complex conjugates. - D = sqrt(D2); RpD = R+D; RmD = R-D; - S = (RpD > 0.0) ? cbrt( RpD ) : -cbrt( -RpD ); - T = (RmD > 0.0) ? cbrt( RmD ) : -cbrt( -RmD); - f = S+T; - g = sqrt(3.0)/2.0*(S-T); - h = b/3.0; + D = sqrt(D2); + RpD = R + D; + RmD = R - D; + S = (RpD > 0.0) ? cbrt(RpD) : -cbrt(-RpD); + T = (RmD > 0.0) ? cbrt(RmD) : -cbrt(-RmD); + f = S + T; + g = sqrt(3.0) / 2.0 * (S - T); + h = b / 3.0; *z1 = f - h; - *z2 = -0.5*f - h + g*I; - *z3 = -0.5*f - h - g*I; + *z2 = -0.5 * f - h + g * I; + *z3 = -0.5 * f - h - g * I; nReal = 1; - } else if ( D2 < 0 ) { + } else if (D2 < 0) { // All three roots are real and unequal. // This uses the simplest of the alternative trig forms. SqrtNQ = sqrt(-Q); - Theta = acos( R/(SqrtNQ*fabs(Q)) ); - *z1 = 2.0*SqrtNQ*cos(Theta/3.0) - b/3.0; // real (returned as real double z1) - *z2 = 2.0*SqrtNQ*cos( (Theta + 2.0*M_PI)/3.0 ) - b/3.0; // real (but returned as double complex z2) - *z3 = 2.0*SqrtNQ*cos( (Theta + 4.0*M_PI)/3.0 ) - b/3.0; // real (but returned as double complex z3) + Theta = acos(R / (SqrtNQ * fabs(Q))); + *z1 = 2.0 * SqrtNQ * cos(Theta / 3.0) - + b / 3.0; // real (returned as real double z1) + *z2 = 2.0 * SqrtNQ * cos((Theta + 2.0 * M_PI) / 3.0) - + b / 3.0; // real (but returned as double complex z2) + *z3 = 2.0 * SqrtNQ * cos((Theta + 4.0 * M_PI) / 3.0) - + b / 3.0; // real (but returned as double complex z3) nReal = 3; - } - return( nReal ); - + return (nReal); } /** @@ -166,47 +173,41 @@ int Lgm_CubicRoots( double b, double c, double d, double *z1, double complex *z * \date 2011 * */ -double Lgm_CubicRealRoot( double b, double c, double d ){ - - double b2, Q, R, D2, D, RpD, RmD, S, T, x1, Theta, SqrtNQ; +double Lgm_CubicRealRoot(double b, double c, double d) { + double b2, Q, R, D2, D, RpD, RmD, S, T, x1, Theta, SqrtNQ; - b2 = b*b; + b2 = b * b; - Q = (3.0*c - b2)/9.0; - R = (9.0*b*c - 27.0*d - 2.0*b2*b)/54.0; - D2 = Q*Q*Q + R*R; + Q = (3.0 * c - b2) / 9.0; + R = (9.0 * b * c - 27.0 * d - 2.0 * b2 * b) / 54.0; + D2 = Q * Q * Q + R * R; - if (D2 == 0){ + if (D2 == 0) { // All 3 roots are real and at least two are equal. - if ( R > 0.0) { - x1 = 2.0*cbrt( R ) - b/3.0; + if (R > 0.0) { + x1 = 2.0 * cbrt(R) - b / 3.0; } else { - x1 = -2.0*cbrt( -R ) - b/3.0; + x1 = -2.0 * cbrt(-R) - b / 3.0; } - } else if ( D2 > 0 ) { + } else if (D2 > 0) { // only one real root exists. The other two are complex conjugates. - D = sqrt(D2); RpD = R+D; RmD = R-D; - S = (RpD > 0.0) ? cbrt( RpD ) : -cbrt( -RpD ); - T = (RmD > 0.0) ? cbrt( RmD ) : -cbrt( -RmD); - x1 = S + T - b/3.0; - } else if ( D2 < 0 ) { + D = sqrt(D2); + RpD = R + D; + RmD = R - D; + S = (RpD > 0.0) ? cbrt(RpD) : -cbrt(-RpD); + T = (RmD > 0.0) ? cbrt(RmD) : -cbrt(-RmD); + x1 = S + T - b / 3.0; + } else if (D2 < 0) { // All three roots are real and unequal. // This uses the simplest of the alternative trig forms. SqrtNQ = sqrt(-Q); - Theta = acos( R/(SqrtNQ*fabs(Q)) ); - x1 = 2.0*SqrtNQ*cos(Theta/3.0) - b/3.0; + Theta = acos(R / (SqrtNQ * fabs(Q))); + x1 = 2.0 * SqrtNQ * cos(Theta / 3.0) - b / 3.0; } - return( x1 ); - + return (x1); } - - - - - - /** * \brief * Returns the four roots of the quartic equation with real coefficients. @@ -239,68 +240,76 @@ double Lgm_CubicRealRoot( double b, double c, double d ){ * \date 2011 * */ -int Lgm_QuarticRoots( double b, double c, double d, double e, double complex *z1, double complex *z2, double complex *z3, double complex *z4 ){ - - int nReal; - double p, q, r, y1, v, R2, b2, b3, f; - double complex D, E, g, R, s, t; - +int Lgm_QuarticRoots(double b, + double c, + double d, + double e, + double complex* z1, + double complex* z2, + double complex* z3, + double complex* z4) { + int nReal; + double p, q, r, y1, v, R2, b2, b3, f; + double complex D, E, g, R, s, t; /* * Obtain a real root from the "resolvent cubic". * y^3 + p y^2 + q y + r = 0 */ - p = -c; - q = (b*d - 4.0*e); - r = 4.0*c*e - b*b*e - d*d; - y1 = Lgm_CubicRealRoot( p, q, r ); - + p = -c; + q = (b * d - 4.0 * e); + r = 4.0 * c * e - b * b * e - d * d; + y1 = Lgm_CubicRealRoot(p, q, r); /* * Construct the quadratic and solve. (Must use complex math of course.) */ - b2 = b*b; - b3 = b*b2; - R2 = b2/4.0 - c + y1; - R = csqrt( R2 ); // R will in general be complex + b2 = b * b; + b3 = b * b2; + R2 = b2 / 4.0 - c + y1; + R = csqrt(R2); // R will in general be complex /* * If R is small do the first one. Its fairly sensitive here... */ - if ( fabs(R2) < 1e-7 ) { - v = y1*y1 - 4.0*e; - f = 0.75*b2 - 2.0*c; - g = 2.0*csqrt( v ); - D = csqrt( f + g ); - E = csqrt( f - g ); - s = t = -0.5*b; + if (fabs(R2) < 1e-7) { + v = y1 * y1 - 4.0 * e; + f = 0.75 * b2 - 2.0 * c; + g = 2.0 * csqrt(v); + D = csqrt(f + g); + E = csqrt(f - g); + s = t = -0.5 * b; } else { - f = 0.75*b2 - R2 - 2.0*c; - g = 0.25*(4.0*b*c - 8.0*d - b3)/R; - D = csqrt( f + g ); - E = csqrt( f - g ); - s = -0.5*b + R; - t = -0.5*b - R; + f = 0.75 * b2 - R2 - 2.0 * c; + g = 0.25 * (4.0 * b * c - 8.0 * d - b3) / R; + D = csqrt(f + g); + E = csqrt(f - g); + s = -0.5 * b + R; + t = -0.5 * b - R; } - *z1 = 0.5*( s + D); - *z2 = 0.5*( s - D); - *z3 = 0.5*( t + E); - *z4 = 0.5*( t - E); + *z1 = 0.5 * (s + D); + *z2 = 0.5 * (s - D); + *z3 = 0.5 * (t + E); + *z4 = 0.5 * (t - E); nReal = 0; - if ( fabs(cimag(*z1)) < 1e-10 ) ++nReal; - if ( fabs(cimag(*z2)) < 1e-10 ) ++nReal; - if ( fabs(cimag(*z3)) < 1e-10 ) ++nReal; - if ( fabs(cimag(*z4)) < 1e-10 ) ++nReal; - - return( nReal ); - + if (fabs(cimag(*z1)) < 1e-10) + ++nReal; + if (fabs(cimag(*z2)) < 1e-10) + ++nReal; + if (fabs(cimag(*z3)) < 1e-10) + ++nReal; + if (fabs(cimag(*z4)) < 1e-10) + ++nReal; + + return (nReal); } /** * \brief - * Returns the four roots of the quartic equation with real coefficients. Results are sorted. + * Returns the four roots of the quartic equation with real coefficients. + * Results are sorted. * * \details * Returns the four roots of the quartic equation; @@ -310,7 +319,8 @@ int Lgm_QuarticRoots( double b, double c, double d, double e, double complex *z1 * where \f$b, c, d, e\f$ are real coefficients, and the coefficient on the * \f$z^4\f$ term is assumed to be 1. * - * This routine calls Lgm_QuarticRoots() and splits the results into Real and Complex roots. + * This routine calls Lgm_QuarticRoots() and splits the results into Real + * and Complex roots. * * \param[in] b Real coefficient of the \f$z^3\f$ term. * \param[in] c Real coefficient of the \f$z^2\f$ term. @@ -330,27 +340,46 @@ int Lgm_QuarticRoots( double b, double c, double d, double e, double complex *z1 * \date 2011 * */ -int Lgm_QuarticRootsSorted( double b, double c, double d, double e, int *nReal, double *RealRoots, int *nComplex, double complex *ComplexRoots ){ - - int nr=0, nc = 0; - double complex z1, z2, z3, z4; - - Lgm_QuarticRoots( b, c, d, e, &z1, &z2, &z3, &z4 ); - - if ( cimag( z1 ) < 1e-16 ) { RealRoots[nr++] = creal(z1); } else { ComplexRoots[nc++] = z1; } - if ( cimag( z2 ) < 1e-16 ) { RealRoots[nr++] = creal(z2); } else { ComplexRoots[nc++] = z2; } - if ( cimag( z3 ) < 1e-16 ) { RealRoots[nr++] = creal(z3); } else { ComplexRoots[nc++] = z3; } - if ( cimag( z4 ) < 1e-16 ) { RealRoots[nr++] = creal(z4); } else { ComplexRoots[nc++] = z4; } +int Lgm_QuarticRootsSorted(double b, + double c, + double d, + double e, + int* nReal, + double* RealRoots, + int* nComplex, + double complex* ComplexRoots) { + int nr = 0, nc = 0; + double complex z1, z2, z3, z4; + + Lgm_QuarticRoots(b, c, d, e, &z1, &z2, &z3, &z4); + + if (cimag(z1) < 1e-16) { + RealRoots[nr++] = creal(z1); + } else { + ComplexRoots[nc++] = z1; + } + if (cimag(z2) < 1e-16) { + RealRoots[nr++] = creal(z2); + } else { + ComplexRoots[nc++] = z2; + } + if (cimag(z3) < 1e-16) { + RealRoots[nr++] = creal(z3); + } else { + ComplexRoots[nc++] = z3; + } + if (cimag(z4) < 1e-16) { + RealRoots[nr++] = creal(z4); + } else { + ComplexRoots[nc++] = z4; + } - *nReal = nr; + *nReal = nr; *nComplex = nc; - return( nr ); - + return (nr); } - - /* * An arbitrary polynomial root solver written by C. Bond (see * http://www.crbond.com ). @@ -367,68 +396,66 @@ int Lgm_QuarticRootsSorted( double b, double c, double d, double e, int *nReal, /* * Extract individual real or complex roots from list of quadratic factors. */ -int Lgm_PolyRoots_Roots( double *a, int n, double *wr, double *wi ) { - - double sq, b2, c, disc; - int i, m, numroots; +int Lgm_PolyRoots_Roots(double* a, int n, double* wr, double* wi) { + double sq, b2, c, disc; + int i, m, numroots; m = n; numroots = 0; while (m > 1) { - - b2 = -0.5*a[m-2]; - c = a[m-1]; - disc = b2*b2-c; - if (fabs(disc)/(fabs(b2*b2)+fabs(c)) <= DBL_EPSILON) disc = 0.0; + b2 = -0.5 * a[m - 2]; + c = a[m - 1]; + disc = b2 * b2 - c; + if (fabs(disc) / (fabs(b2 * b2) + fabs(c)) <= DBL_EPSILON) + disc = 0.0; if (disc < 0.0) { sq = sqrt(-disc); - wr[m-2] = b2; - wi[m-2] = sq; - wr[m-1] = b2; - wi[m-1] = -sq; - numroots+=2; + wr[m - 2] = b2; + wi[m - 2] = sq; + wr[m - 1] = b2; + wi[m - 1] = -sq; + numroots += 2; } else { sq = sqrt(disc); - wr[m-2] = fabs(b2)+sq; - if (b2 < 0.0) wr[m-2] = -wr[m-2]; - if (wr[m-2] == 0) { - wr[m-1] == 0; + wr[m - 2] = fabs(b2) + sq; + if (b2 < 0.0) + wr[m - 2] = -wr[m - 2]; + if (wr[m - 2] == 0) { + wr[m - 1] == 0; } else { - wr[m-1] = c/wr[m-2]; - numroots+=2; + wr[m - 1] = c / wr[m - 2]; + numroots += 2; } - wi[m-2] = 0.0; - wi[m-1] = 0.0; + wi[m - 2] = 0.0; + wi[m - 1] = 0.0; } m -= 2; - } if (m == 1) { - wr[0] = -a[0]; - wi[0] = 0.0; - numroots++; + wr[0] = -a[0]; + wi[0] = 0.0; + numroots++; } - return( numroots ); - + return (numroots); } - - - /* * Deflate polynomial 'a' by division of 'quad'. Return quotient * polynomial in 'b' and error (metric based on remainder) in 'err'. */ -void Lgm_PolyRootsDeflate( double *a, int n, double *b, double *quad, double *err ) { - - int i; - double r, s; - double *c = (double *)calloc( n+1, sizeof(double) ); +void Lgm_PolyRootsDeflate(double* a, + int n, + double* b, + double* quad, + double* err) { + int i; + double r, s; + double* c = (double*)calloc(n + 1, sizeof(double)); r = quad[1]; s = quad[0]; @@ -436,97 +463,94 @@ void Lgm_PolyRootsDeflate( double *a, int n, double *b, double *quad, double *er b[1] = a[1] - r; c[1] = b[1] - r; - for (i=2;i<=n;i++){ - b[i] = a[i] - r*b[i-1] - s*b[i-2]; - c[i] = b[i] - r*c[i-1] - s*c[i-2]; + for (i = 2; i <= n; i++) { + b[i] = a[i] - r * b[i - 1] - s * b[i - 2]; + c[i] = b[i] - r * c[i - 1] - s * c[i - 2]; } - *err = fabs(b[n]) + fabs(b[n-1]); - free( c ); - + *err = fabs(b[n]) + fabs(b[n - 1]); + free(c); } - - /* * Find quadratic factor using Bairstow's method (quadratic Newton method). * A number of ad hoc safeguards are incorporated to prevent stalls due * to common difficulties, such as zero slope at iteration point, and * convergence problems. */ -void Lgm_PolyRoots_FindQuad( double *a, int n, double *b, double *quad, double *err, int *iter ) { - - int i; - double dn, dr, ds, drn, dsn, eps, r, s; - double *c = (double *)calloc( n+1, sizeof(double) ); - - c[0] = 1.0; - r = quad[1]; - s = quad[0]; - dr = 1.0; - ds = 0; - eps = 1e-15; +void Lgm_PolyRoots_FindQuad(double* a, + int n, + double* b, + double* quad, + double* err, + int* iter) { + int i; + double dn, dr, ds, drn, dsn, eps, r, s; + double* c = (double*)calloc(n + 1, sizeof(double)); + + c[0] = 1.0; + r = quad[1]; + s = quad[0]; + dr = 1.0; + ds = 0; + eps = 1e-15; *iter = 1; - while ((fabs(dr)+fabs(ds)) > eps) { - - if (*iter > LGM_POLYROOTS_MAXITER) break; + while ((fabs(dr) + fabs(ds)) > eps) { + if (*iter > LGM_POLYROOTS_MAXITER) + break; - if ( ((*iter) % 200) == 0 ) eps*=10.0; + if (((*iter) % 200) == 0) + eps *= 10.0; - b[1] = a[1] - r; - c[1] = b[1] - r; + b[1] = a[1] - r; + c[1] = b[1] - r; - for ( i=2; i<=n; i++ ){ - b[i] = a[i] - r*b[i-1] - s*b[i-2]; - c[i] = b[i] - r*c[i-1] - s*c[i-2]; - } + for (i = 2; i <= n; i++) { + b[i] = a[i] - r * b[i - 1] - s * b[i - 2]; + c[i] = b[i] - r * c[i - 1] - s * c[i - 2]; + } - dn =c[n-1] * c[n-3] - c[n-2] * c[n-2]; - drn =b[n] * c[n-3] - b[n-1] * c[n-2]; - dsn =b[n-1] * c[n-1] - b[n] * c[n-2]; + dn = c[n - 1] * c[n - 3] - c[n - 2] * c[n - 2]; + drn = b[n] * c[n - 3] - b[n - 1] * c[n - 2]; + dsn = b[n - 1] * c[n - 1] - b[n] * c[n - 2]; if (fabs(dn) < 1e-10) { - if (dn < 0.0) dn = -1e-8; - else dn = 1e-8; + if (dn < 0.0) + dn = -1e-8; + else + dn = 1e-8; } dr = drn / dn; ds = dsn / dn; - r += dr; - s += ds; + r += dr; + s += ds; (*iter)++; - - } + } quad[0] = s; quad[1] = r; - *err = fabs(ds)+fabs(dr); + *err = fabs(ds) + fabs(dr); free(c); - } - - /* * Differentiate polynomial 'a' returning result in 'b'. */ -void Lgm_PolyRoots_DiffPoly( double *a, int n, double *b) { - - int i; - double coef; +void Lgm_PolyRoots_DiffPoly(double* a, int n, double* b) { + int i; + double coef; coef = (double)n; b[0] = 1.0; - for ( i=1; i 5) && (tst < 1e-4)) || ((*iter > 20) && (tst < 1e-1)) ) { - Lgm_PolyRoots_DiffPoly( b, m, c ); - Lgm_PolyRoots_Recurse( a, n, c, m-1, rs, err, iter ); + if (((*iter > 5) && (tst < 1e-4)) || ((*iter > 20) && (tst < 1e-1))) { + Lgm_PolyRoots_DiffPoly(b, m, c); + Lgm_PolyRoots_Recurse(a, n, c, m - 1, rs, err, iter); quad[0] = rs[0]; quad[1] = rs[1]; } free(c); free(x); - } - - - - /* * Top level routine to manage the determination of all roots of the given * polynomial 'a', returning the quadratic factors (and possibly one linear * factor) in 'x'. */ -void Lgm_PolyRoots_GetQuads( double *a, int n, double *quad, double *x ) { - - int iter, i, m; - double *b, *z, err, tmp; - double xr, xs; +void Lgm_PolyRoots_GetQuads(double* a, int n, double* quad, double* x) { + int iter, i, m; + double *b, *z, err, tmp; + double xr, xs; - if ( (tmp = a[0]) != 1.0 ) { + if ((tmp = a[0]) != 1.0) { a[0] = 1.0; - for ( i=1; i<=n; i++ ) a[i] /= tmp; + for (i = 1; i <= n; i++) + a[i] /= tmp; } if (n == 2) { - x[0] = a[1]; x[1] = a[2]; return; } else if (n == 1) { - x[0] = a[1]; return; - } - m = n; - b = (double *)calloc( n+1, sizeof(double) ); - z = (double *)calloc( n+1, sizeof(double) ); + b = (double*)calloc(n + 1, sizeof(double)); + z = (double*)calloc(n + 1, sizeof(double)); b[0] = 1.0; - for ( i=0; i<=n; i++ ) { + for (i = 0; i <= n; i++) { z[i] = a[i]; x[i] = 0.0; } - do { - if (n > m) { quad[0] = 3.14159e-1; quad[1] = 2.78127e-1; } do { - - Lgm_PolyRoots_FindQuad( z, m, b, quad, &err, &iter ); -// if ( (err > 1e-7) || (iter > LGM_POLYROOTS_MAXITER) ) { - if ( (err > 1e-10) || (iter > LGM_POLYROOTS_MAXITER) ) { - Lgm_PolyRoots_DiffPoly( z, m, b ); + Lgm_PolyRoots_FindQuad(z, m, b, quad, &err, &iter); + // if ( (err > 1e-7) || (iter > LGM_POLYROOTS_MAXITER) ) + // { + if ((err > 1e-10) || (iter > LGM_POLYROOTS_MAXITER)) { + Lgm_PolyRoots_DiffPoly(z, m, b); iter = 0; - Lgm_PolyRoots_Recurse( z, m, b, m-1, quad, &err, &iter ); + Lgm_PolyRoots_Recurse(z, m, b, m - 1, quad, &err, &iter); } - Lgm_PolyRootsDeflate( z, m, b, quad, &err ); - - } while ( err > 1 ); + Lgm_PolyRootsDeflate(z, m, b, quad, &err); + } while (err > 1); - x[m-2] = quad[1]; - x[m-1] = quad[0]; + x[m - 2] = quad[1]; + x[m - 1] = quad[0]; m -= 2; - for (i=0;i<=m;i++) { + for (i = 0; i <= m; i++) { z[i] = b[i]; } - } while (m > 2); - if (m == 2) { x[0] = b[1]; x[1] = b[2]; @@ -673,65 +689,63 @@ void Lgm_PolyRoots_GetQuads( double *a, int n, double *quad, double *x ) { free(z); free(b); - } - /** * \brief * Find roots of arbitrary polynomials (with real coefficients). * * Solves for the roots of the polynomial; * - * \f[ a_0 x^n + a_1 x^{n-1} + a_2 x^{n-2} + \cdots + a_{n-1} x + a_n = 0 \f] + * \f[ a_0 x^n + a_1 x^{n-1} + a_2 x^{n-2} + \cdots + a_{n-1} x + a_n = + * 0 \f] * * * \details * * - * \param[in] a The polynomial coefficients. There should be n+1 of these. - * \param[in] n The order of the polynomial. - * \param[in] z The complex roots found. + * \param[in] a The polynomial coefficients. There should be n+1 of + * these. \param[in] n The order of the polynomial. \param[in] z The + * complex roots found. * * \return The number of roots found. * * */ -int Lgm_PolyRoots( double *a, int n, double complex *z ){ - - int numr, i; - double *wr, *wi, *x, quad[2]; +int Lgm_PolyRoots(double* a, int n, double complex* z) { + int numr, i; + double *wr, *wi, *x, quad[2]; if (a[0] == 0) { printf("Lgm_PolyRoots(): Error! Highest coefficient cannot be 0.\n"); - return( 0 ); + return (0); } if (a[n] == 0) { - printf("Lgm_PolyRoots(): Error! Lowest coefficient (constant term) cannot be 0.\n"); - return( 0 ); + printf( + "Lgm_PolyRoots(): Error! Lowest coefficient (constant term) cannot " + "be 0.\n"); + return (0); } // initialize estimate for 1st root pair quad[0] = 2.71828e-1; quad[1] = 3.14159e-1; - x = (double *)calloc( n+1, sizeof(double) ); - wr = (double *)calloc( n+1, sizeof(double) ); - wi = (double *)calloc( n+1, sizeof(double) ); + x = (double*)calloc(n + 1, sizeof(double)); + wr = (double*)calloc(n + 1, sizeof(double)); + wi = (double*)calloc(n + 1, sizeof(double)); // get roots - Lgm_PolyRoots_GetQuads( a, n, quad, x ); - numr = Lgm_PolyRoots_Roots( x, n, wr, wi ); + Lgm_PolyRoots_GetQuads(a, n, quad, x); + numr = Lgm_PolyRoots_Roots(x, n, wr, wi); - for (i=0; i #endif +#include #include -#include #include #include -#include +#include #include "Lgm/Lgm_CTrans.h" -#include "Lgm/Lgm_MagModelInfo.h" #include "Lgm/Lgm_DynamicMemory.h" +#include "Lgm/Lgm_MagModelInfo.h" #include "Lgm/Lgm_QinDenton.h" @@ -225,7 +225,7 @@ void Lgm_read_QinDenton( long int Date, Lgm_QinDenton *q ) { Lgm_mjd_to_ymdh( Next_MJD, &Next_Date, &Next_Year, &Next_Month, &Next_Day, &Next_UT ); - Filename = (char *)calloc( 512, sizeof(char) ); + Filename = (char *)calloc(2575, sizeof(char) ); Line = (char *)calloc( 2050, sizeof(char) ); n = 0; diff --git a/libLanlGeoMag/Lgm_Quat.c b/libLanlGeoMag/Lgm_Quat.c index 6521a59ce..e8549ed27 100644 --- a/libLanlGeoMag/Lgm_Quat.c +++ b/libLanlGeoMag/Lgm_Quat.c @@ -11,7 +11,8 @@ * Kbh 0, Denmark (July 17, 1998). * * 2. Eberly, D., Quaternion Algebra and Calculus, Geometric Tools, - * LLC, http://www.geometrictools.com/Documentation/Quaternions.pdf (August 18, 2010). + * LLC, http://www.geometrictools.com/Documentation/Quaternions.pdf + * (August 18, 2010). * * * \author M.G. Henderson @@ -21,44 +22,41 @@ * */ -#include -#include #include "Lgm/Lgm_Quat.h" +#include +#include /* * Print a quaternian */ void Lgm_PrintQuat(double Q[4]) { - printf("x:%lf y:%lf z:%lf w:%lf mag:%lf\n", Q[0], Q[1], Q[2], Q[3], Lgm_QuatMagnitude(Q)); - return; + printf("x:%lf y:%lf z:%lf w:%lf mag:%lf\n", Q[0], Q[1], Q[2], Q[3], + Lgm_QuatMagnitude(Q)); + return; } -double Lgm_QuatNorm( double Q[4] ) { - return( Q[0]*Q[0] + Q[1]*Q[1] + Q[2]*Q[2] + Q[3]*Q[3] ); +double Lgm_QuatNorm(double Q[4]) { + return (Q[0] * Q[0] + Q[1] * Q[1] + Q[2] * Q[2] + Q[3] * Q[3]); } -void Lgm_QuatConjugate( double Qin[4], double Qout[4] ) { +void Lgm_QuatConjugate(double Qin[4], double Qout[4]) { Qout[0] = -Qin[0]; Qout[1] = -Qin[1]; Qout[2] = -Qin[2]; - Qout[3] = Qin[3]; + Qout[3] = Qin[3]; } -void Lgm_QuatInverse( double Qin[4], double Qout[4] ) { - - Lgm_QuatConjugate( Qin, Qout ); - Lgm_QuatScale( Qout, 1.0/Lgm_QuatNorm( Qin ) ); - +void Lgm_QuatInverse(double Qin[4], double Qout[4]) { + Lgm_QuatConjugate(Qin, Qout); + Lgm_QuatScale(Qout, 1.0 / Lgm_QuatNorm(Qin)); } -double Lgm_NormalizeQuat( double Q[4] ) { - - double mag, mag_inv; - - mag = sqrt(Q[0]*Q[0] + Q[1]*Q[1] + Q[2]*Q[2] + Q[3]*Q[3]); - if ( mag > 1e-12 ) { +double Lgm_NormalizeQuat(double Q[4]) { + double mag, mag_inv; - mag_inv = 1.0/mag; + mag = sqrt(Q[0] * Q[0] + Q[1] * Q[1] + Q[2] * Q[2] + Q[3] * Q[3]); + if (mag > 1e-12) { + mag_inv = 1.0 / mag; Q[0] *= mag_inv; Q[1] *= mag_inv; Q[2] *= mag_inv; @@ -72,16 +70,13 @@ double Lgm_NormalizeQuat( double Q[4] ) { Q[3] = 1.0; } - return( mag ); - + return (mag); } -double Lgm_MatrixTrace( double A[3][3] ) { - return( A[0][0] + A[1][1] + A[2][2] ); +double Lgm_MatrixTrace(double A[3][3]) { + return (A[0][0] + A[1][1] + A[2][2]); } - - /* * \brief * Routine to compute a quaternion rotation from a 3x3 rotation matrix. @@ -90,61 +85,56 @@ double Lgm_MatrixTrace( double A[3][3] ) { * double Q[4] -- Quaternion (qx, qy, qz, qw) * * \param[in] A: transformation matrix. - * \param[out] Q: + * \param[out] Q: * */ -void Lgm_MatrixToQuat( double A[3][3], double *Q ) { +void Lgm_MatrixToQuat(double A[3][3], double* Q) { + double T, SqrtT, f, finv; - double T, SqrtT, f, finv;; + T = 1.0 + Lgm_MatrixTrace(A); - T = 1.0 + Lgm_MatrixTrace( A ); + if (T >= 0.0) { + SqrtT = sqrt(T); + Q[3] = 0.5 * SqrtT; - if ( T >= 0.0 ) { - SqrtT = sqrt( T ); - Q[3] = 0.5*SqrtT; - - f = 0.25/Q[3]; - Q[0] = (A[1][2]-A[2][1]) * f; - Q[1] = (A[2][0]-A[0][2]) * f; - Q[2] = (A[0][1]-A[1][0]) * f; + f = 0.25 / Q[3]; + Q[0] = (A[1][2] - A[2][1]) * f; + Q[1] = (A[2][0] - A[0][2]) * f; + Q[2] = (A[0][1] - A[1][0]) * f; } else { - - if ( (A[0][0] > A[1][1]) && (A[0][0] > A[2][2]) ) { - f = sqrt( 1.0 + A[0][0] - A[1][1] - A[2][2] ) * 2.0; // f=4*qx - finv = 1.0/f; - Q[0] = 0.25 * f; - Q[1] = (A[1][0] + A[0][1]) * finv; - Q[2] = (A[2][0] + A[0][2]) * finv; - Q[3] = (A[2][1] - A[1][2]) * finv; - } else if (A[1][1] > A[2][2]) { - f = sqrt( 1.0 + A[1][1] - A[0][0] - A[2][2] ) * 2.0; // f=4*qy - finv = 1.0/f; - Q[0] = (A[1][0] + A[0][1]) * finv; - Q[1] = 0.25 * f; - Q[2] = (A[2][1] + A[1][2]) * finv; - Q[3] = (A[2][0] - A[0][2]) * finv; - } else { - f = sqrt( 1.0 + A[2][2] - A[0][0] - A[1][1] ) * 2.0; // f=4*qz - finv = 1.0/f; - Q[0] = (A[2][0] + A[0][2]) * finv; - Q[1] = (A[2][1] + A[1][2]) * finv; - Q[2] = 0.25 * f; - Q[3] = (A[1][0] - A[0][1]) * finv; + if ((A[0][0] > A[1][1]) && (A[0][0] > A[2][2])) { + f = sqrt(1.0 + A[0][0] - A[1][1] - A[2][2]) * 2.0; // f=4*qx + finv = 1.0 / f; + Q[0] = 0.25 * f; + Q[1] = (A[1][0] + A[0][1]) * finv; + Q[2] = (A[2][0] + A[0][2]) * finv; + Q[3] = (A[2][1] - A[1][2]) * finv; + } else if (A[1][1] > A[2][2]) { + f = sqrt(1.0 + A[1][1] - A[0][0] - A[2][2]) * 2.0; // f=4*qy + finv = 1.0 / f; + Q[0] = (A[1][0] + A[0][1]) * finv; + Q[1] = 0.25 * f; + Q[2] = (A[2][1] + A[1][2]) * finv; + Q[3] = (A[2][0] - A[0][2]) * finv; + } else { + f = sqrt(1.0 + A[2][2] - A[0][0] - A[1][1]) * 2.0; // f=4*qz + finv = 1.0 / f; + Q[0] = (A[2][0] + A[0][2]) * finv; + Q[1] = (A[2][1] + A[1][2]) * finv; + Q[2] = 0.25 * f; + Q[3] = (A[1][0] - A[0][1]) * finv; } - } - - } -void Lgm_Quat_To_Matrix( double Q[4], double A[3][3] ) { +void Lgm_Quat_To_Matrix(double Q[4], double A[3][3]) { A[0][0] = 1.0 - 2.0 * (Q[1] * Q[1] + Q[2] * Q[2]); A[1][0] = 2.0 * (Q[0] * Q[1] - Q[2] * Q[3]); A[2][0] = 2.0 * (Q[2] * Q[0] + Q[1] * Q[3]); A[0][1] = 2.0 * (Q[0] * Q[1] + Q[2] * Q[3]); - A[1][1]= 1.0 - 2.0 * (Q[2] * Q[2] + Q[0] * Q[0]); + A[1][1] = 1.0 - 2.0 * (Q[2] * Q[2] + Q[0] * Q[0]); A[2][1] = 2.0 * (Q[1] * Q[2] - Q[0] * Q[3]); A[0][2] = 2.0 * (Q[2] * Q[0] - Q[1] * Q[3]); @@ -152,35 +142,34 @@ void Lgm_Quat_To_Matrix( double Q[4], double A[3][3] ) { A[2][2] = 1.0 - 2.0 * (Q[1] * Q[1] + Q[0] * Q[0]); } - /* /* * \brief - * Routine determines the quaternion implied by the rotation angle and axis. + * Routine determines the quaternion implied by the rotation angle and +axis. * \details * The Quaternion is of the form; - * \f[ Q = ( \sin(\theta/2) \hat{u}, \cos(\theta/2) ) = ( \sin(\theta/2) u_x, \sin(\theta/2) u_y, \sin(\theta/2) u_z, \cos(\theta/2) ) \f]. + * \f[ Q = ( \sin(\theta/2) \hat{u}, \cos(\theta/2) ) = ( +\sin(\theta/2) u_x, \sin(\theta/2) u_y, \sin(\theta/2) u_z, \cos(\theta/2) ) +\f]. * * \param[in] u: pointer to unit vector rotation axis. * \param[in] Angle: angle to rotate about rotation axis. * \param[out] Q[4]: resulting quatoernion * */ -void Lgm_AxisAngleToQuat( Lgm_Vector *u, double Angle, double *Q ) { - +void Lgm_AxisAngleToQuat(Lgm_Vector* u, double Angle, double* Q) { double a, sa; // rotate by Angle deg. around u axis - a = 0.5*Angle*RadPerDeg; sa = sin( a ); - Q[0] = sa*u->x; - Q[1] = sa*u->y; - Q[2] = sa*u->z; - Q[3] = cos( a ); - + a = 0.5 * Angle * RadPerDeg; + sa = sin(a); + Q[0] = sa * u->x; + Q[1] = sa * u->y; + Q[2] = sa * u->z; + Q[3] = cos(a); } - - /* * This routinem determines the angle and axis of rotation implied * by a (normalized) quaternion. @@ -195,18 +184,15 @@ void Lgm_AxisAngleToQuat( Lgm_Vector *u, double Angle, double *Q ) { * * */ -void Lgm_QuatToAxisAngle( double *Q, double *Angle, Lgm_Vector *u ) { - - double Aover2, SinAover2, SinAover2_inv; - +void Lgm_QuatToAxisAngle(double* Q, double* Angle, Lgm_Vector* u) { + double Aover2, SinAover2, SinAover2_inv; /* * Force normalization of Q */ - Lgm_NormalizeQuat( Q ); - - if ( (1.0-fabs(Q[3])) < 1e-8 ) { + Lgm_NormalizeQuat(Q); + if ((1.0 - fabs(Q[3])) < 1e-8) { /* * Rotation angle is close to zero * (Its either A/2 = 0 (i.e. A = 0) or @@ -219,131 +205,153 @@ void Lgm_QuatToAxisAngle( double *Q, double *Angle, Lgm_Vector *u ) { u->z = 1.0; } else { - /* * Determine Angle/2 */ - Aover2 = acos( Q[3] ); - *Angle = 2.0*Aover2*DegPerRad; + Aover2 = acos(Q[3]); + *Angle = 2.0 * Aover2 * DegPerRad; - /* + /* * Compute 1.0/sin(Angle/2) */ - SinAover2 = sqrt( 1.0 - Q[3]*Q[3] ); - SinAover2_inv = 1.0/SinAover2; + SinAover2 = sqrt(1.0 - Q[3] * Q[3]); + SinAover2_inv = 1.0 / SinAover2; /* * Compute components of rotation axis */ - u->x = Q[0]*SinAover2; - u->y = Q[1]*SinAover2; - u->z = Q[2]*SinAover2; - Lgm_NormalizeVector( u ); - - + u->x = Q[0] * SinAover2; + u->y = Q[1] * SinAover2; + u->z = Q[2] * SinAover2; + Lgm_NormalizeVector(u); } - - - } - - /* * Given a Quaternion, and a vector, computes the rotated vector. */ -void Lgm_QuatRotateVector( double *Q, Lgm_Vector *v, Lgm_Vector *vp ) { - - double xx = Q[0]*Q[0]; - double yy = Q[1]*Q[1]; - double zz = Q[2]*Q[2]; - double ww = Q[3]*Q[3]; - - double xw = Q[0]*Q[3]; - double yw = Q[1]*Q[3]; - double zw = Q[2]*Q[3]; - - double xy = Q[0]*Q[1]; - double xz = Q[0]*Q[2]; - double yz = Q[1]*Q[2]; - - vp->x = ww*v->x + 2.0*yw*v->z - 2.0*zw*v->y + xx*v->x + 2*xy*v->y + 2.0*xz*v->z - zz*v->x - yy*v->x; - vp->y = 2.0*xy*v->x + yy*v->y + 2.0*yz*v->z + 2.0*zw*v->x - zz*v->y + ww*v->y - 2.0*xw*v->z - xx*v->y; - vp->z = 2.0*xz*v->x + 2.0*yz*v->y + zz*v->z - 2.0*yw*v->x - yy*v->z + 2.0*xw*v->y - xx*v->z + ww*v->z; +void Lgm_QuatRotateVector(double* Q, Lgm_Vector* v, Lgm_Vector* vp) { + double xx = Q[0] * Q[0]; + double yy = Q[1] * Q[1]; + double zz = Q[2] * Q[2]; + double ww = Q[3] * Q[3]; + + double xw = Q[0] * Q[3]; + double yw = Q[1] * Q[3]; + double zw = Q[2] * Q[3]; + + double xy = Q[0] * Q[1]; + double xz = Q[0] * Q[2]; + double yz = Q[1] * Q[2]; + + vp->x = ww * v->x + 2.0 * yw * v->z - 2.0 * zw * v->y + xx * v->x + + 2 * xy * v->y + 2.0 * xz * v->z - zz * v->x - yy * v->x; + vp->y = 2.0 * xy * v->x + yy * v->y + 2.0 * yz * v->z + 2.0 * zw * v->x - + zz * v->y + ww * v->y - 2.0 * xw * v->z - xx * v->y; + vp->z = 2.0 * xz * v->x + 2.0 * yz * v->y + zz * v->z - 2.0 * yw * v->x - + yy * v->z + 2.0 * xw * v->y - xx * v->z + ww * v->z; return; - - } - - -/* +/* * return the magnitude of a vector */ -double Lgm_QuatMagnitude( double *Q ) { - return( sqrt( Q[0]*Q[0] + Q[1]*Q[1] + Q[2]*Q[2] + Q[3]*Q[3]) ); +double Lgm_QuatMagnitude(double* Q) { + return (sqrt(Q[0] * Q[0] + Q[1] * Q[1] + Q[2] * Q[2] + Q[3] * Q[3])); } -void Lgm_QuatScale( double *Q, double t ) { Q[0] *= t; Q[1] *= t; Q[2] *= t; Q[3] *= t; } -void Lgm_QuatAdd( double *Q1, double *Q2, double *Q3 ) { Q3[0] = Q1[0]+Q2[0]; Q3[1] = Q1[1]+Q2[1]; Q3[2] = Q1[2]+Q2[2]; Q3[3] = Q1[3]+Q2[3]; } - -double Lgm_QuatVecLength( double *v ) { return ( sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]) ); } -double Lgm_QuatVecDot( double *v1, double *v2 ) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } -void Lgm_QuatVecZero( double *v ) { v[0] = 0.0; v[1] = 0.0; v[2] = 0.0; } -void Lgm_QuatVecSet( double *v, double x, double y, double z ) { v[0] = x; v[1] = y; v[2] = z; } -void Lgm_QuatVecAdd( double *a, double *b, double *c ) { c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; } -void Lgm_QuatVecSub( double *a, double *b, double *c) { c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; c[2] = a[2] - b[2]; } -void Lgm_QuatVecCopy( double *v1, double *v2 ) { int i; for (i = 0 ; i < 3 ; i++) v2[i] = v1[i]; } -void Lgm_QuatVecScale( double *v, double f ) { v[0] *= f; v[1] *= f; v[2] *= f; } -void Lgm_QuatVecNormalize( double *v ) { Lgm_QuatVecScale( v, 1.0/Lgm_QuatVecLength(v) ); } - -void Lgm_QuatVecCross( double *a, double *b, double *c ) { - c[0] = (a[1]*b[2]) - (a[2]*b[1]); - c[1] = (a[2]*b[0]) - (a[0]*b[2]); - c[2] = (a[0]*b[1]) - (a[1]*b[0]); +void Lgm_QuatScale(double* Q, double t) { + Q[0] *= t; + Q[1] *= t; + Q[2] *= t; + Q[3] *= t; +} +void Lgm_QuatAdd(double* Q1, double* Q2, double* Q3) { + Q3[0] = Q1[0] + Q2[0]; + Q3[1] = Q1[1] + Q2[1]; + Q3[2] = Q1[2] + Q2[2]; + Q3[3] = Q1[3] + Q2[3]; } -void Lgm_QuatCombineQuats( double Q1[4], double Q2[4], double Q[4] ) { +double Lgm_QuatVecLength(double* v) { + return (sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])); +} +double Lgm_QuatVecDot(double* v1, double* v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} +void Lgm_QuatVecZero(double* v) { + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; +} +void Lgm_QuatVecSet(double* v, double x, double y, double z) { + v[0] = x; + v[1] = y; + v[2] = z; +} +void Lgm_QuatVecAdd(double* a, double* b, double* c) { + c[0] = a[0] + b[0]; + c[1] = a[1] + b[1]; + c[2] = a[2] + b[2]; +} +void Lgm_QuatVecSub(double* a, double* b, double* c) { + c[0] = a[0] - b[0]; + c[1] = a[1] - b[1]; + c[2] = a[2] - b[2]; +} +void Lgm_QuatVecCopy(double* v1, double* v2) { + int i; + for (i = 0; i < 3; i++) + v2[i] = v1[i]; +} +void Lgm_QuatVecScale(double* v, double f) { + v[0] *= f; + v[1] *= f; + v[2] *= f; +} +void Lgm_QuatVecNormalize(double* v) { + Lgm_QuatVecScale(v, 1.0 / Lgm_QuatVecLength(v)); +} - double t1[4], t2[4], t3[4]; - double tf[4]; +void Lgm_QuatVecCross(double* a, double* b, double* c) { + c[0] = (a[1] * b[2]) - (a[2] * b[1]); + c[1] = (a[2] * b[0]) - (a[0] * b[2]); + c[2] = (a[0] * b[1]) - (a[1] * b[0]); +} - Lgm_QuatVecCopy( Q1,t1 ); - Lgm_QuatVecScale( t1,Q2[3] ); +void Lgm_QuatCombineQuats(double Q1[4], double Q2[4], double Q[4]) { + double t1[4], t2[4], t3[4]; + double tf[4]; - Lgm_QuatVecCopy( Q2,t2 ); - Lgm_QuatVecScale( t2,Q1[3] ); + Lgm_QuatVecCopy(Q1, t1); + Lgm_QuatVecScale(t1, Q2[3]); - Lgm_QuatVecCross( Q2, Q1, t3 ); - Lgm_QuatVecAdd( t1, t2, tf ); - Lgm_QuatVecAdd( t3, tf, tf ); - tf[3] = Q1[3]*Q2[3] - Lgm_QuatVecDot( Q1, Q2 ); + Lgm_QuatVecCopy(Q2, t2); + Lgm_QuatVecScale(t2, Q1[3]); - Q[0] = tf[0]; Q[1] = tf[1]; Q[2] = tf[2]; Q[3] = tf[3]; + Lgm_QuatVecCross(Q2, Q1, t3); + Lgm_QuatVecAdd(t1, t2, tf); + Lgm_QuatVecAdd(t3, tf, tf); + tf[3] = Q1[3] * Q2[3] - Lgm_QuatVecDot(Q1, Q2); + Q[0] = tf[0]; + Q[1] = tf[1]; + Q[2] = tf[2]; + Q[3] = tf[3]; } - - - // Q = Q1*Q2 -void Lgm_QuatMultiply( double Q1[4], double Q2[4], double Q[4] ) { - +void Lgm_QuatMultiply(double Q1[4], double Q2[4], double Q[4]) { // vector part - Q[0] = Q1[3]*Q2[0] + Q1[0]*Q2[3] + Q1[1]*Q2[2] - Q1[2]*Q2[1]; - Q[1] = Q1[3]*Q2[1] - Q1[0]*Q2[2] + Q1[1]*Q2[3] + Q1[2]*Q2[0]; - Q[2] = Q1[3]*Q2[2] + Q1[0]*Q2[1] - Q1[1]*Q2[0] + Q1[2]*Q2[3]; + Q[0] = Q1[3] * Q2[0] + Q1[0] * Q2[3] + Q1[1] * Q2[2] - Q1[2] * Q2[1]; + Q[1] = Q1[3] * Q2[1] - Q1[0] * Q2[2] + Q1[1] * Q2[3] + Q1[2] * Q2[0]; + Q[2] = Q1[3] * Q2[2] + Q1[0] * Q2[1] - Q1[1] * Q2[0] + Q1[2] * Q2[3]; // real part - Q[3] = Q1[3]*Q2[3] - Q1[0]*Q2[0] - Q1[1]*Q2[1] - Q1[2]*Q2[2]; - + Q[3] = Q1[3] * Q2[3] - Q1[0] * Q2[0] - Q1[1] * Q2[1] - Q1[2] * Q2[2]; } - - - - /** * \brief * Computes q^t . @@ -355,37 +363,32 @@ void Lgm_QuatMultiply( double Q1[4], double Q2[4], double Q[4] ) { * \f[ q^t = ( \sin(t \theta) \hat{u}, \cos(t \theta) ) \f]. * */ -void Lgm_QuatPow( double Qin[4], double t, double Qout[4] ) { - - double Angle, Theta, tTheta, s, c; - Lgm_Vector u; +void Lgm_QuatPow(double Qin[4], double t, double Qout[4]) { + double Angle, Theta, tTheta, s, c; + Lgm_Vector u; - Lgm_QuatToAxisAngle( Qin, &Angle, &u ); - Theta = Angle/2.0*RadPerDeg; + Lgm_QuatToAxisAngle(Qin, &Angle, &u); + Theta = Angle / 2.0 * RadPerDeg; - tTheta = t*Theta; - s = sin( tTheta ); - c = cos( tTheta ); - Qout[0] = s*u.x; - Qout[1] = s*u.y; - Qout[2] = s*u.z; + tTheta = t * Theta; + s = sin(tTheta); + c = cos(tTheta); + Qout[0] = s * u.x; + Qout[1] = s * u.y; + Qout[2] = s * u.z; Qout[3] = c; - } - - /** * \brief * Computes Spherical Linear Quaternion Interpolation (SLERP). * \details * Spherical linear interpolation (or slerping) is a method for smoothly * interpolating points on a sphere (its a spherical geometry version of - * linear interpolation). + * linear interpolation). */ -void Lgm_QuatSlerp( double p[4], double q[4], double h, double Qout[4] ){ - - double A[4], B[4], pconj[4]; +void Lgm_QuatSlerp(double p[4], double q[4], double h, double Qout[4]) { + double A[4], B[4], pconj[4]; /* Lgm_QuatPow( p, 1.0-h, A ); @@ -394,15 +397,12 @@ void Lgm_QuatSlerp( double p[4], double q[4], double h, double Qout[4] ){ */ // probably more efficient - Lgm_QuatConjugate( p, pconj ); - Lgm_QuatMultiply( pconj, q, A ); - Lgm_QuatPow( A, h, B ); - Lgm_QuatMultiply( p, B, Qout ); - + Lgm_QuatConjugate(p, pconj); + Lgm_QuatMultiply(pconj, q, A); + Lgm_QuatPow(A, h, B); + Lgm_QuatMultiply(p, B, Qout); } - - /** * \brief * Computes Spherical Spline Quaternion Interpolation (SQUAD). @@ -410,114 +410,103 @@ void Lgm_QuatSlerp( double p[4], double q[4], double h, double Qout[4] ){ * Spherical spline interpolation is a method for smoothly * interpolating points on a sphere. */ -void Lgm_QuatSquad( double Q0[4], double Q1[4], double S0[4], double S1[4], double h, double Qout[4] ){ - - double A[4], B[4], hh; - - //Lgm_QuatSlerp( Q0, Q1, h, Qout ); - //return; - - Lgm_QuatSlerp( Q0, Q1, h, A ); - Lgm_QuatSlerp( S0, S1, h, B ); - hh = 2.0*h*(1.0-h); - - Lgm_QuatSlerp( A, B, hh, Qout ); - +void Lgm_QuatSquad(double Q0[4], + double Q1[4], + double S0[4], + double S1[4], + double h, + double Qout[4]) { + double A[4], B[4], hh; + + // Lgm_QuatSlerp( Q0, Q1, h, Qout ); + // return; + + Lgm_QuatSlerp(Q0, Q1, h, A); + Lgm_QuatSlerp(S0, S1, h, B); + hh = 2.0 * h * (1.0 - h); + + Lgm_QuatSlerp(A, B, hh, Qout); } - - - /* * Take log() of a unit quaternion. It will be purely 'imaginary' -- real part * is zero. Result is not necessarily a unit quaternion. */ -void Lgm_QuatLog( double Q[4], double logQ[4] ) { - - double Angle, Theta; +void Lgm_QuatLog(double Q[4], double logQ[4]) { + double Angle, Theta; Lgm_Vector u; - Lgm_QuatToAxisAngle( Q, &Angle, &u ); + Lgm_QuatToAxisAngle(Q, &Angle, &u); // the Angle is actually 2*Theta - Theta = 0.5*Angle*RadPerDeg; + Theta = 0.5 * Angle * RadPerDeg; - logQ[0] = Theta*u.x; - logQ[1] = Theta*u.y; - logQ[2] = Theta*u.z; + logQ[0] = Theta * u.x; + logQ[1] = Theta * u.y; + logQ[2] = Theta * u.z; logQ[3] = 0.0; - } - - /* * Take exp() of a purely imaginary quaternion. */ -void Lgm_QuatExp( double Q[4], double expQ[4] ) { - - double Theta, SinTheta, CosTheta; +void Lgm_QuatExp(double Q[4], double expQ[4]) { + double Theta, SinTheta, CosTheta; Lgm_Vector u; u.x = Q[0]; u.y = Q[1]; u.z = Q[2]; - Theta = Lgm_NormalizeVector( &u ); - SinTheta = sin( Theta ); - CosTheta = cos( Theta ); + Theta = Lgm_NormalizeVector(&u); + SinTheta = sin(Theta); + CosTheta = cos(Theta); - expQ[0] = SinTheta*u.x; - expQ[1] = SinTheta*u.y; - expQ[2] = SinTheta*u.z; + expQ[0] = SinTheta * u.x; + expQ[1] = SinTheta * u.y; + expQ[2] = SinTheta * u.z; expQ[3] = CosTheta; - } - - // Eqn 6.15 of Dam et al. -void Lgm_QuatSquadComputeAuxPoint( double Qim1[4], double Qi[4], double Qip1[4], double si[4] ) { - +void Lgm_QuatSquadComputeAuxPoint(double Qim1[4], + double Qi[4], + double Qip1[4], + double si[4]) { double Qi_inv[4], A[4], B[4], logA[4], logB[4], C[4], D[4]; - Lgm_QuatInverse( Qi, Qi_inv ); - Lgm_QuatMultiply( Qi_inv, Qip1, A ); Lgm_QuatLog( A, logA ); - Lgm_QuatMultiply( Qi_inv, Qim1, B ); Lgm_QuatLog( B, logB ); - - Lgm_QuatAdd( logA, logB, C ); - Lgm_QuatScale( C, -0.25 ); - Lgm_QuatExp( C, D ); - Lgm_QuatMultiply( Qi, D, si ); + Lgm_QuatInverse(Qi, Qi_inv); + Lgm_QuatMultiply(Qi_inv, Qip1, A); + Lgm_QuatLog(A, logA); + Lgm_QuatMultiply(Qi_inv, Qim1, B); + Lgm_QuatLog(B, logB); + Lgm_QuatAdd(logA, logB, C); + Lgm_QuatScale(C, -0.25); + Lgm_QuatExp(C, D); + Lgm_QuatMultiply(Qi, D, si); } - -long int Lgm_QuatFindTimeIndex( double *T, long int N, double t ){ - +long int Lgm_QuatFindTimeIndex(double* T, long int N, double t) { long int jl, jh, jm; jl = -1; - jh = N; - while ( jh-jl > 1 ) { - - jm = (jh+jl)/2; - if ( t > T[jm] ) { + jh = N; + while (jh - jl > 1) { + jm = (jh + jl) / 2; + if (t > T[jm]) { jl = jm; } else { jh = jm; } } - return( jl ); - + return (jl); } - /** * \brief - * Computes Spherical Spline Quaternion Interpolation (SQUAD) on arrays of quaternions. - * \details - * Spherical spline interpolation is a method for smoothly + * Computes Spherical Spline Quaternion Interpolation (SQUAD) on arrays of + * quaternions. \details Spherical spline interpolation is a method for smoothly * interpolating points on a sphere. * * Input arrays to interpolate from: @@ -531,43 +520,42 @@ long int Lgm_QuatFindTimeIndex( double *T, long int N, double t ){ * \param[in] n: number of quaternions in (t, q) arrays * */ -int Lgm_QuatSquadInterp( double *T, double *Q[4], long int N, double *t, double *q[4], long int n ) { - - long int i, j, im1, ip1, ip2; - double si[4], sip1[4], h; - - - - for (i=0; i=N-1 ) { - - printf( "Lgm_QuatSquadInterp: Warning. Extrapolation required on the high side. t[%ld] = %g. i = %ld\n", j, t[j], i ); - return(-1); - - } else if ( i == 0 ) { - - printf( "Lgm_QuatSquadInterp: Warning. i == 0, can only do SLERP on [0,1] interval.\n"); - ip1 = i+1; - h = (t[j] - T[i])/(T[ip1] - T[i]); // fraction of the way through the interval -- is there abtter way to do this than linear? -if ((h <0.0)||(h>1.0)) { -printf("h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] = %g T[i+1] = %g\n", h, j, i, t[j], T[i], T[i+1]); -//exit(0); -} - Lgm_QuatSlerp( Q[0], Q[1], h, q[j] ); - - } else if ( i == N-2 ) { - - printf( "Lgm_QuatSquadInterp: Warning. i == %ld, can only do SLERP on [%ld,%ld] interval.\n", i, N-2, N-1 ); - ip1 = i+1; - h = (t[j] - T[i])/(T[ip1] - T[i]); // fraction of the way through the interval -- is there abtter way to do this than linear? -if ((h <0.0)||(h>1.0)) { -printf("h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] = %g T[i+1] = %g\n", h, j, i, t[j], T[i], T[i+1]); -//exit(0); -} - Lgm_QuatSlerp( Q[N-2], Q[N-1], h, q[j] ); + i = Lgm_QuatFindTimeIndex(T, N, t[j]); + + if (i < 0) { + printf( + "Lgm_QuatSquadInterp: Warning. Extrapolation required on the " + "low side. t[%ld] = %g. i = %ld\n", + j, t[j], i); + return (-1); + + } else if (i >= N - 1) { + printf( + "Lgm_QuatSquadInterp: Warning. Extrapolation required on the " + "high side. t[%ld] = %g. i = %ld\n", + j, t[j], i); + return (-1); + + } else if (i == 0) { + printf( + "Lgm_QuatSquadInterp: Warning. i == 0, can only do SLERP on " + "[0,1] interval.\n"); + ip1 = i + 1; + h = (t[j] - T[i]) / + (T[ip1] - T[i]); // fraction of the way through the interval -- + // is there abtter way to do this than linear? + if ((h < 0.0) || (h > 1.0)) { + printf( + "h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] " + "= %g T[i+1] = %g\n", + h, j, i, t[j], T[i], T[i + 1]); + // exit(0); + } + Lgm_QuatSlerp(Q[0], Q[1], h, q[j]); + + } else if (i == N - 2) { + printf( + "Lgm_QuatSquadInterp: Warning. i == %ld, can only do SLERP on " + "[%ld,%ld] interval.\n", + i, N - 2, N - 1); + ip1 = i + 1; + h = (t[j] - T[i]) / + (T[ip1] - T[i]); // fraction of the way through the interval -- + // is there abtter way to do this than linear? + if ((h < 0.0) || (h > 1.0)) { + printf( + "h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] " + "= %g T[i+1] = %g\n", + h, j, i, t[j], T[i], T[i + 1]); + // exit(0); + } + Lgm_QuatSlerp(Q[N - 2], Q[N - 1], h, q[j]); } else { - /* * finally we have enough info to do a proper SQUAD. */ @@ -621,38 +625,28 @@ printf("h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] = %g T[i+1] = /* * Compute the auxilliary control points needed for SQUAD */ - im1 = i-1; - ip1 = i+1; - ip2 = i+2; - Lgm_QuatSquadComputeAuxPoint( Q[im1], Q[i], Q[ip1], si ); // s_i - Lgm_QuatSquadComputeAuxPoint( Q[i], Q[ip1], Q[ip2], sip1 ); // s_i+1 + im1 = i - 1; + ip1 = i + 1; + ip2 = i + 2; + Lgm_QuatSquadComputeAuxPoint(Q[im1], Q[i], Q[ip1], si); // s_i + Lgm_QuatSquadComputeAuxPoint(Q[i], Q[ip1], Q[ip2], sip1); // s_i+1 /* * Compute the SQUAD */ - h = (t[j] - T[i])/(T[ip1] - T[i]); // fraction of the way through the interval -- is there abtter way to do this than linear? -if ((h <0.0)||(h>1.0)) { -printf("h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] = %g T[i+1] = %g\n", h, j, i, t[j], T[i], T[i+1]); -//exit(0); -} - Lgm_QuatSquad( Q[i], Q[ip1], si, sip1, h, q[j] ); - - + h = (t[j] - T[i]) / + (T[ip1] - T[i]); // fraction of the way through the interval -- + // is there abtter way to do this than linear? + if ((h < 0.0) || (h > 1.0)) { + printf( + "h not in range [0-1], h = %g j=%ld i=%ld t[j] = %g T[i] " + "= %g T[i+1] = %g\n", + h, j, i, t[j], T[i], T[i + 1]); + // exit(0); + } + Lgm_QuatSquad(Q[i], Q[ip1], si, sip1, h, q[j]); } - - - } - - - return( 1 ); - + return (1); } - - - - - - - diff --git a/libLanlGeoMag/Lgm_Sgp.c b/libLanlGeoMag/Lgm_Sgp.c index 9603cd340..22fe5c3c9 100644 --- a/libLanlGeoMag/Lgm_Sgp.c +++ b/libLanlGeoMag/Lgm_Sgp.c @@ -1,9 +1,9 @@ +#include +#include +#include #include "Lgm/Lgm_CTrans.h" #include "Lgm/Lgm_Sgp.h" #include "Lgm/qsort.h" -#include -#include -#include /* * Changes: diff --git a/libLanlGeoMag/Lgm_SummersDiffCoeff.c b/libLanlGeoMag/Lgm_SummersDiffCoeff.c index 99e91ef8d..c240f31e8 100644 --- a/libLanlGeoMag/Lgm_SummersDiffCoeff.c +++ b/libLanlGeoMag/Lgm_SummersDiffCoeff.c @@ -1,10 +1,10 @@ #include "Lgm/Lgm_SummersDiffCoeff.h" -#include +#include #include +#include #include #include -#include struct inequalityParameters {double D; double E1; double E2; double F1; double F2;}; struct normalizerForWavePowerSpectrumFunctionParams {double x; double aStar; int numberOfWaveNormalAngleDistributions; double *xmArray; double *dxArray; double *weightsOnWaveNormalAngleDistributions; double xmin; double xmax;}; diff --git a/libLanlGeoMag/Lgm_SunPosition.c b/libLanlGeoMag/Lgm_SunPosition.c index d6c39192c..c7fb7f63a 100644 --- a/libLanlGeoMag/Lgm_SunPosition.c +++ b/libLanlGeoMag/Lgm_SunPosition.c @@ -1,5 +1,5 @@ -#include #include +#include #define INCLUDE_PERTURBATIONS 1 double Frac( double x ) { diff --git a/libLanlGeoMag/Lgm_Utils.c b/libLanlGeoMag/Lgm_Utils.c index f4c7f5b03..73fd786fe 100644 --- a/libLanlGeoMag/Lgm_Utils.c +++ b/libLanlGeoMag/Lgm_Utils.c @@ -1,61 +1,63 @@ -#include #include "Lgm/Lgm_Utils.h" - +#include +#include /* * Fill an array with log spaced numbers from start to stop */ -void Lgm_LogSpace( double start, double stop, long num, double *array ){ - /* logspace is equivalent to - * y=linspace(log10(start), log10(stop), num) - * then pow(10, y) - */ - unsigned long i; - Lgm_LinSpace(log10(start), log10(stop), num, array); - for (i=0; i *max) *max = inval[i]; - if (inval[i] < *min) *min = inval[i]; - } +void Lgm_MinMax(double* inval, long len, double* min, double* max) { + uint_fast64_t i; + *min = inval[0]; + *max = inval[0]; + for (i = 1; i < len; i++) { + if (inval[i] > *max) + *max = inval[i]; + if (inval[i] < *min) + *min = inval[i]; + } } - - diff --git a/libLanlGeoMag/Lgm_Vec.c b/libLanlGeoMag/Lgm_Vec.c index 6b8c6dbbb..0753f0a68 100644 --- a/libLanlGeoMag/Lgm_Vec.c +++ b/libLanlGeoMag/Lgm_Vec.c @@ -1,6 +1,7 @@ /*! \file Lgm_Vec.c * - * \brief Routines for vector operations (e.g. dot-product, cross-product, etc.) + * \brief Routines for vector operations (e.g. dot-product, cross-product, + * etc.) * * * @@ -11,165 +12,158 @@ * */ +#include "Lgm/Lgm_Vec.h" #include -#include #include -#include "Lgm/Lgm_Vec.h" +#include #include "Lgm/Lgm_CTrans.h" /* * Create an Lgm_Vector */ -Lgm_Vector *Lgm_CreateVector( double x, double y, double z ){ - Lgm_Vector *v; - v = (Lgm_Vector *) calloc( 1, sizeof(*v) ); +Lgm_Vector* Lgm_CreateVector(double x, double y, double z) { + Lgm_Vector* v; + v = (Lgm_Vector*)calloc(1, sizeof(*v)); v->x = x; v->y = y; v->z = z; - return( v ); + return (v); } /* * Free an Lgm_Vector */ -void Lgm_FreeVector( Lgm_Vector *v ) { - free(v); +void Lgm_FreeVector(Lgm_Vector* v) { + free(v); } /* * Print an Lgm_Vector */ -void Lgm_PrintVector(Lgm_Vector *v) { - printf("x:%lf y:%lf z:%lf mag:%lf\n", v->x, v->y, v->z, Lgm_Magnitude(v)); - return; +void Lgm_PrintVector(Lgm_Vector* v) { + printf("x:%lf y:%lf z:%lf mag:%lf\n", v->x, v->y, v->z, Lgm_Magnitude(v)); + return; } /* - * Divide each component of a vector by a scalar + * Divide each component of a vector by a scalar */ -void Lgm_VecDivideScalar( Lgm_Vector *v, double x) { - v->x /= x; - v->y /= x; - v->z /= x; +void Lgm_VecDivideScalar(Lgm_Vector* v, double x) { + v->x /= x; + v->y /= x; + v->z /= x; } /* - * Multiply each component of a vector by a scalar + * Multiply each component of a vector by a scalar */ -void Lgm_VecMultiplyScalar( Lgm_Vector *v, double x) { - v->x *= x; - v->y *= x; - v->z *= x; +void Lgm_VecMultiplyScalar(Lgm_Vector* v, double x) { + v->x *= x; + v->y *= x; + v->z *= x; } - /* * Given vectors a and b, compute the angle between them in degrees */ -double Lgm_VectorAngle(Lgm_Vector *a, Lgm_Vector *b) { - double ang; - Lgm_Vector u, v; - u = *a; - v = *b; - Lgm_NormalizeVector(&u); - Lgm_NormalizeVector(&v); - ang = acos(Lgm_DotProduct(&u, &v)); - return (ang*DegPerRad); +double Lgm_VectorAngle(Lgm_Vector* a, Lgm_Vector* b) { + double ang; + Lgm_Vector u, v; + u = *a; + v = *b; + Lgm_NormalizeVector(&u); + Lgm_NormalizeVector(&v); + ang = acos(Lgm_DotProduct(&u, &v)); + return (ang * DegPerRad); } - /* * Given vectors a and b, compute the cross product, c. */ -void Lgm_CrossProduct(Lgm_Vector *a, Lgm_Vector *b, Lgm_Vector *c) { - +void Lgm_CrossProduct(Lgm_Vector* a, Lgm_Vector* b, Lgm_Vector* c) { c->x = (a->y * b->z) - (a->z * b->y); c->y = (a->z * b->x) - (a->x * b->z); c->z = (a->x * b->y) - (a->y * b->x); } - /* * Given vectors a and b, compute and return the dot product */ -double Lgm_DotProduct(Lgm_Vector *a, Lgm_Vector *b) { - return(a->x * b->x + a->y * b->y + a->z * b->z); +double Lgm_DotProduct(Lgm_Vector* a, Lgm_Vector* b) { + return (a->x * b->x + a->y * b->y + a->z * b->z); } /* * Given vectors a, b, and c compute the scalar triple product * a \cdot (b \crossprod c) */ -double Lgm_ScalarTripleProduct(Lgm_Vector *a, Lgm_Vector *b, Lgm_Vector *c) { +double Lgm_ScalarTripleProduct(Lgm_Vector* a, Lgm_Vector* b, Lgm_Vector* c) { Lgm_Vector tmp; - Lgm_CrossProduct(b,c,&tmp); - return( Lgm_DotProduct(a, &tmp ) ); + Lgm_CrossProduct(b, c, &tmp); + return (Lgm_DotProduct(a, &tmp)); } /* * Given vectors a, b, and c compute the vector triple product * a x (b x c) or (c x b) x a */ -void Lgm_VectorTripleProduct(Lgm_Vector *a, Lgm_Vector *b, Lgm_Vector *c, Lgm_Vector *d) { +void Lgm_VectorTripleProduct(Lgm_Vector* a, + Lgm_Vector* b, + Lgm_Vector* c, + Lgm_Vector* d) { Lgm_Vector tmp; Lgm_CrossProduct(b, c, &tmp); - Lgm_CrossProduct(a, &tmp, d) ; + Lgm_CrossProduct(a, &tmp, d); } - /* * Normalize the given vector. I.e. make it into a unit vector. - * plus return magnitude since you already have it! + * plus return magnitude since you already have it! */ -double Lgm_NormalizeVector(Lgm_Vector *a) { +double Lgm_NormalizeVector(Lgm_Vector* a) { double magnitude, inv; magnitude = Lgm_Magnitude(a); if (magnitude > 0.0) { - inv = 1.0/magnitude; + inv = 1.0 / magnitude; a->x *= inv; a->y *= inv; a->z *= inv; - return(magnitude); + return (magnitude); } else { - return(-1.0); + return (-1.0); } } - -/* +/* * multiply the given vector by a scalar value */ -void Lgm_ScaleVector(Lgm_Vector *a, double value) { +void Lgm_ScaleVector(Lgm_Vector* a, double value) { Lgm_VecMultiplyScalar(a, value); } - - - -/* +/* * return the magnitude of a vector */ -double Lgm_Magnitude( Lgm_Vector *a) { - return( sqrt((a->x * a->x) + (a->y * a->y) + (a->z * a->z)) ); +double Lgm_Magnitude(Lgm_Vector* a) { + return (sqrt((a->x * a->x) + (a->y * a->y) + (a->z * a->z))); } - -/* +/* * Subtract two vectors * c = a-b */ -void Lgm_VecSub(Lgm_Vector *c, Lgm_Vector *a, Lgm_Vector *b ) { +void Lgm_VecSub(Lgm_Vector* c, Lgm_Vector* a, Lgm_Vector* b) { c->x = a->x - b->x; c->y = a->y - b->y; c->z = a->z - b->z; } -/* +/* * Add two vectors * c = a+b */ -void Lgm_VecAdd(Lgm_Vector *c, Lgm_Vector *a, Lgm_Vector *b ) { +void Lgm_VecAdd(Lgm_Vector* c, Lgm_Vector* a, Lgm_Vector* b) { c->x = a->x + b->x; c->y = a->y + b->y; c->z = a->z + b->z; @@ -178,81 +172,74 @@ void Lgm_VecAdd(Lgm_Vector *c, Lgm_Vector *a, Lgm_Vector *b ) { /* * Elementwise multiplication of two vectors (e.g., c.x = a.x * b.x, etc.) */ -void Lgm_VecMult(Lgm_Vector *c, Lgm_Vector *a, Lgm_Vector *b) { +void Lgm_VecMult(Lgm_Vector* c, Lgm_Vector* a, Lgm_Vector* b) { c->x = a->x * b->x; c->y = a->y * b->y; c->z = a->z * b->z; } -/* +/* * Find Magnitude of difference between to vectors */ -double Lgm_VecDiffMag(Lgm_Vector *a, Lgm_Vector *b ) { +double Lgm_VecDiffMag(Lgm_Vector* a, Lgm_Vector* b) { Lgm_Vector c; - Lgm_VecSub( &c, a, b ); // c = a-b - return( Lgm_Magnitude( &c ) ); + Lgm_VecSub(&c, a, b); // c = a-b + return (Lgm_Magnitude(&c)); } -/* +/* * makes the given vector have a magnitude of mag */ -void Lgm_ForceMagnitude(Lgm_Vector *a, double mag) { +void Lgm_ForceMagnitude(Lgm_Vector* a, double mag) { Lgm_NormalizeVector(a); Lgm_ScaleVector(a, mag); } - /* * Routine to compute A dot V * double A[3][3]; -- Trans Matrix * Lgm_Vector *V; -- Lgm_Vector * Lgm_Vector *Result; -- the result of the product */ -void Lgm_MatTimesVec(double A[3][3], Lgm_Vector *V, Lgm_Vector *Result) { - Result->x = A[0][0]*V->x + A[1][0]*V->y + A[2][0]*V->z; - Result->y = A[0][1]*V->x + A[1][1]*V->y + A[2][1]*V->z; - Result->z = A[0][2]*V->x + A[1][2]*V->y + A[2][2]*V->z; +void Lgm_MatTimesVec(double A[3][3], Lgm_Vector* V, Lgm_Vector* Result) { + Result->x = A[0][0] * V->x + A[1][0] * V->y + A[2][0] * V->z; + Result->y = A[0][1] * V->x + A[1][1] * V->y + A[2][1] * V->z; + Result->z = A[0][2] * V->x + A[1][2] * V->y + A[2][2] * V->z; } /* * Return transpose of A in B */ -void Lgm_Transpose( double A[3][3], double B[3][3] ) { - +void Lgm_Transpose(double A[3][3], double B[3][3]) { int i, j; - for (i=0; i<3; i++){ - for (j=0; j<3; j++){ + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { B[i][j] = A[j][i]; } } - } - /* * Routine to compute A x B * double A[3][3]; -- Trans Matrix * double B[3][3]; -- Trans Matrix * double Result[3][3]; -- Trans Matrix */ -void Lgm_MatTimesMat( double A[3][3], double B[3][3], double R[3][3] ) { - - R[0][0] = A[0][0]*B[0][0] + A[1][0]*B[0][1] + A[2][0]*B[0][2]; - R[0][1] = A[0][1]*B[0][0] + A[1][1]*B[0][1] + A[2][1]*B[0][2]; - R[0][2] = A[0][2]*B[0][0] + A[1][2]*B[0][1] + A[2][2]*B[0][2]; - - R[1][0] = A[0][0]*B[1][0] + A[1][0]*B[1][1] + A[2][0]*B[1][2]; - R[1][1] = A[0][1]*B[1][0] + A[1][1]*B[1][1] + A[2][1]*B[1][2]; - R[1][2] = A[0][2]*B[1][0] + A[1][2]*B[1][1] + A[2][2]*B[1][2]; +void Lgm_MatTimesMat(double A[3][3], double B[3][3], double R[3][3]) { + R[0][0] = A[0][0] * B[0][0] + A[1][0] * B[0][1] + A[2][0] * B[0][2]; + R[0][1] = A[0][1] * B[0][0] + A[1][1] * B[0][1] + A[2][1] * B[0][2]; + R[0][2] = A[0][2] * B[0][0] + A[1][2] * B[0][1] + A[2][2] * B[0][2]; - R[2][0] = A[0][0]*B[2][0] + A[1][0]*B[2][1] + A[2][0]*B[2][2]; - R[2][1] = A[0][1]*B[2][0] + A[1][1]*B[2][1] + A[2][1]*B[2][2]; - R[2][2] = A[0][2]*B[2][0] + A[1][2]*B[2][1] + A[2][2]*B[2][2]; + R[1][0] = A[0][0] * B[1][0] + A[1][0] * B[1][1] + A[2][0] * B[1][2]; + R[1][1] = A[0][1] * B[1][0] + A[1][1] * B[1][1] + A[2][1] * B[1][2]; + R[1][2] = A[0][2] * B[1][0] + A[1][2] * B[1][1] + A[2][2] * B[1][2]; + R[2][0] = A[0][0] * B[2][0] + A[1][0] * B[2][1] + A[2][0] * B[2][2]; + R[2][1] = A[0][1] * B[2][0] + A[1][1] * B[2][1] + A[2][1] * B[2][2]; + R[2][2] = A[0][2] * B[2][0] + A[1][2] * B[2][1] + A[2][2] * B[2][2]; } - /** * Convert Spherical-Polar coords to Cartesian * @@ -263,22 +250,20 @@ void Lgm_MatTimesMat( double A[3][3], double B[3][3], double R[3][3] ) { * \param[out] u: Cartesian vector (units of whatever you used for r) * */ -void Lgm_SphToCartCoords( double Lat, double Lon, double r, Lgm_Vector *u ) { - - double rCosLat; +void Lgm_SphToCartCoords(double Lat, double Lon, double r, Lgm_Vector* u) { + double rCosLat; Lat *= RadPerDeg; Lon *= RadPerDeg; - rCosLat = r*cos(Lat); - - u->x = rCosLat*cos(Lon); - u->y = rCosLat*sin(Lon); - u->z = r*sin(Lat); + rCosLat = r * cos(Lat); + + u->x = rCosLat * cos(Lon); + u->y = rCosLat * sin(Lon); + u->z = r * sin(Lat); return; } - /** * Convert Cartesian to Spherical-Polar coords * @@ -289,26 +274,24 @@ void Lgm_SphToCartCoords( double Lat, double Lon, double r, Lgm_Vector *u ) { * \param[out] r: Geocentric Radius in Spherical Polar * */ -void Lgm_CartToSphCoords( Lgm_Vector *u, double *Lat, double *Lon, double *r) { - +void Lgm_CartToSphCoords(Lgm_Vector* u, double* Lat, double* Lon, double* r) { double sq, x2, y2, z2; - + x2 = u->x * u->x; y2 = u->y * u->y; z2 = u->z * u->z; - + *r = sqrt(x2 + y2 + z2); - //sq = sqrt(x2 + y2); - - //take care of the poles - if ((x2+y2 <= 1e-8)) { + // sq = sqrt(x2 + y2); + + // take care of the poles + if ((x2 + y2 <= 1e-8)) { *Lon = 0.0; *Lat = (u->z < 0.0) ? -90.0 : 90.0; - } - else { - *Lon = atan2(u->y,u->x)*DegPerRad; - //*Lat = 90.0 - atan2(sq, u->z)*DegPerRad; - *Lat = asin(u->z/(*r))*DegPerRad; + } else { + *Lon = atan2(u->y, u->x) * DegPerRad; + // *Lat = 90.0 - atan2(sq, u->z)*DegPerRad; + *Lat = asin(u->z / (*r)) * DegPerRad; } return; @@ -319,37 +302,35 @@ void Lgm_CartToSphCoords( Lgm_Vector *u, double *Lat, double *Lon, double *r) { * * \param[in] u: Cartesian vector (units of whatever you used for r) * - * \param[out] A: 3-element array. A[0] set to u.x, A[1] set to u.y, A[2] set to u.z. + * \param[out] A: 3-element array. A[0] set to u.x, A[1] set to u.y, + * A[2] set to u.z. * */ -void Lgm_VecToArr( Lgm_Vector *u, double *A ) { - +void Lgm_VecToArr(Lgm_Vector* u, double* A) { A[0] = u->x; A[1] = u->y; A[2] = u->z; - + return; } /** * Copies elements of a 3 element array to a vector * - * \param[in] A: 3-element array. A[0] set to u.x, A[1] set to u.y, A[2] set to u.z. + * \param[in] A: 3-element array. A[0] set to u.x, A[1] set to u.y, + * A[2] set to u.z. * * \param[out] u: Cartesian vector (units of whatever you used for r) * */ -void Lgm_ArrToVec( double *A, Lgm_Vector *u) { - +void Lgm_ArrToVec(double* A, Lgm_Vector* u) { u->x = A[0]; u->y = A[1]; u->z = A[2]; - + return; } - - /** * Sets elements of a vector to a value * @@ -358,14 +339,12 @@ void Lgm_ArrToVec( double *A, Lgm_Vector *u) { * \param[out] f: value to set all vector comonents to. * */ -void Lgm_SetVecVal( Lgm_Vector *u, double f ) { - +void Lgm_SetVecVal(Lgm_Vector* u, double f) { u->x = f; u->y = f; u->z = f; - - return; + return; } /** @@ -378,69 +357,60 @@ void Lgm_SetVecVal( Lgm_Vector *u, double f ) { * \param[out] z: z-component value. * */ -void Lgm_SetVecElements( Lgm_Vector *u, double x, double y, double z ) { - +void Lgm_SetVecElements(Lgm_Vector* u, double x, double y, double z) { u->x = x; u->y = y; u->z = z; - - return; + return; } /** * Sets elements of a 2-component array to a value * - * \param[in] A: 2-element array. + * \param[in] A: 2-element array. * * \param[out] f: value to set all vector comonents to. * */ -void Lgm_SetArrVal2( double *A, double f ) { - +void Lgm_SetArrVal2(double* A, double f) { A[0] = f; A[1] = f; - - return; + return; } /** * Sets elements of a 3-component array to a value * - * \param[in] A: 3-element array. + * \param[in] A: 3-element array. * * \param[out] f: value to set all vector comonents to. * */ -void Lgm_SetArrVal3( double *A, double f ) { - +void Lgm_SetArrVal3(double* A, double f) { A[0] = f; A[1] = f; A[2] = f; - - return; + return; } /** * Sets elements of a 4-component array to a value * - * \param[in] A: 4-element array. + * \param[in] A: 4-element array. * * \param[out] f: value to set all vector comonents to. * */ -void Lgm_SetArrVal4( double *A, double f ) { - +void Lgm_SetArrVal4(double* A, double f) { A[0] = f; A[1] = f; A[2] = f; A[3] = f; - - return; + return; } - /** * Sets individual components of a vector. * @@ -450,16 +420,13 @@ void Lgm_SetArrVal4( double *A, double f ) { * \param[out] y: y-component value. * */ -void Lgm_SetArrElements2( double *A, double x, double y ) { - +void Lgm_SetArrElements2(double* A, double x, double y) { A[0] = x; A[1] = y; - - return; + return; } - /** * Sets individual components of an array. * @@ -470,17 +437,14 @@ void Lgm_SetArrElements2( double *A, double x, double y ) { * \param[out] z: z-component value. * */ -void Lgm_SetArrElements3( double *A, double x, double y, double z ) { - +void Lgm_SetArrElements3(double* A, double x, double y, double z) { A[0] = x; A[1] = y; A[2] = z; - - return; + return; } - /** * Sets individual components of an array. * @@ -492,22 +456,18 @@ void Lgm_SetArrElements3( double *A, double x, double y, double z ) { * \param[out] d: z-component value. * */ -void Lgm_SetArrElements4( double *A, double a, double b, double c, double d ) { - +void Lgm_SetArrElements4(double* A, double a, double b, double c, double d) { A[0] = a; A[1] = b; A[2] = c; A[3] = d; - - return; + return; } - - /** * \brief - * Initialize a Lgm_SlerpInfo structure. + * Initialize a Lgm_SlerpInfo structure. * \details * This routine computes \f$\sin(\phi)\f$, \f$\cos(\phi)\f$, and * \f$\phi\f$. Where \f$\phi\f$ is the angle between the initial and final @@ -520,28 +480,26 @@ void Lgm_SetArrElements4( double *A, double a, double b, double c, double d ) { * \param[in,out] si: Lgm_SlerpInfo structure. * */ -void Lgm_InitSlerp( Lgm_Vector *a, Lgm_Vector *b, Lgm_SlerpInfo *si ) { - - Lgm_Vector v, w; +void Lgm_InitSlerp(Lgm_Vector* a, Lgm_Vector* b, Lgm_SlerpInfo* si) { + Lgm_Vector v, w; - si->CosPhi = Lgm_DotProduct( a, b ); + si->CosPhi = Lgm_DotProduct(a, b); - w = *a; Lgm_ScaleVector( &w, si->CosPhi ); // w = cos(phi)*a-hat - Lgm_VecSub( &v, b, &w ); // v = b-hat - cos(phi)*a-hat - si->SinPhi = Lgm_Magnitude( &v ); // sin(phi) - - si->Phi = atan2( si->SinPhi, si->CosPhi ); // Phi + w = *a; + Lgm_ScaleVector(&w, si->CosPhi); // w = cos(phi)*a-hat + Lgm_VecSub(&v, b, &w); // v = b-hat - cos(phi)*a-hat + si->SinPhi = Lgm_Magnitude(&v); // sin(phi) + si->Phi = atan2(si->SinPhi, si->CosPhi); // Phi } /** * \brief - * Computes Spherical Linear Interpolation (SLERP) between two unit vectors. - * \details - * Spherical linear interpolation (or slerping) is a method for smoothly - * interpolating points on a sphere (its a spherical geometry version of - * linear interpolation). Let \f$\hat{a}\f$ and \f$\hat{b}\f$ be units - * vectors and \f$\phi\f$ be the angle between them. We can interpolate to + * Computes Spherical Linear Interpolation (SLERP) between two unit + * vectors. \details Spherical linear interpolation (or slerping) is a method + * for smoothly interpolating points on a sphere (its a spherical geometry + * version of linear interpolation). Let \f$\hat{a}\f$ and \f$\hat{b}\f$ be + * units vectors and \f$\phi\f$ be the angle between them. We can interpolate to * a fraction alpha through the rotation between them using the formula; * * \f[ \hat{z} = { \sin((1-\alpha)\phi)\over\sin(\phi)} \hat{a} + { @@ -554,33 +512,34 @@ void Lgm_InitSlerp( Lgm_Vector *a, Lgm_Vector *b, Lgm_SlerpInfo *si ) { * \f[ \hat{z} = (1-\alpha) \hat{a} + \alpha \hat{b} \f]. * * - * + * * \param[in] a: initial unit vector. * \param[in] b: final unit vector. * \param[in] z: interpolated unit vector. * \param[in] alpha: fraction of the angle phi to rotate to. * \param[in] si: Lgm_SlerpInfo structure. */ -void Lgm_Slerp( Lgm_Vector *a, Lgm_Vector *b, Lgm_Vector *z, double alpha, Lgm_SlerpInfo *si ) { - - Lgm_Vector w1, w2; +void Lgm_Slerp(Lgm_Vector* a, + Lgm_Vector* b, + Lgm_Vector* z, + double alpha, + Lgm_SlerpInfo* si) { + Lgm_Vector w1, w2; /* * Check to see that Phi is small. If it is, use approximation. */ - if ( si->Phi < 1e-9 ) { - w1 = *a; Lgm_ScaleVector( &w1, (1.0-alpha) ); - w2 = *b; Lgm_ScaleVector( &w2, alpha ); + if (si->Phi < 1e-9) { + w1 = *a; + Lgm_ScaleVector(&w1, (1.0 - alpha)); + w2 = *b; + Lgm_ScaleVector(&w2, alpha); } else { - w1 = *a; Lgm_ScaleVector( &w1, sin( (1.0-alpha)*si->Phi )/ si->SinPhi ); - w2 = *b; Lgm_ScaleVector( &w2, sin( alpha*si->Phi )/ si->SinPhi ); + w1 = *a; + Lgm_ScaleVector(&w1, sin((1.0 - alpha) * si->Phi) / si->SinPhi); + w2 = *b; + Lgm_ScaleVector(&w2, sin(alpha * si->Phi) / si->SinPhi); } - Lgm_VecAdd( z, &w1, &w2 ); - - + Lgm_VecAdd(z, &w1, &w2); } - - - - diff --git a/libLanlGeoMag/TA16.c b/libLanlGeoMag/TA16.c old mode 100755 new mode 100644 index 4edd8c0dc..4b79fb9af --- a/libLanlGeoMag/TA16.c +++ b/libLanlGeoMag/TA16.c @@ -5,416 +5,461 @@ * Ported from version dated 10/19/2016, including the correction of Nov. 2021 * which was found during the porting process. * This model is based on fitting to a data set with 732,746 records - * References: (1) Tsyganenko, N. A., and V. A. Andreeva (2016), "An empirical RBF model of the magnetosphere - * parameterized by interplanetary and ground-based drivers", v.121, doi:10.1002/2016JA023217, - * accepted by JGRA, 10/17/2016. - * (2) Andreeva, V. A., and N. A. Tsyganenko (2016), "Reconstructing the magnetosphere from data - * using radial basis functions, JGRA Space Physics, v.121, 2249-2263, doi:10.1002/2015JA022242. - * ORIGINAL CODE BY: N. A. Tsyganenko AND V. A. Andreeva + * References: (1) Tsyganenko, N. A., and V. A. Andreeva (2016), "An empirical + *RBF model of the magnetosphere parameterized by interplanetary and + *ground-based drivers", v.121, doi:10.1002/2016JA023217, accepted by JGRA, + *10/17/2016. (2) Andreeva, V. A., and N. A. Tsyganenko (2016), "Reconstructing + *the magnetosphere from data using radial basis functions, JGRA Space Physics, + *v.121, 2249-2263, doi:10.1002/2015JA022242. ORIGINAL CODE BY: N. A. Tsyganenko + *AND V. A. Andreeva *------------------------------------------------------------------------------------------------------ - * NOTE: THE MODEL IS VALID ONLY UP TO Xgsw=-15 Re and should NOT be used tailward of that distance + * NOTE: THE MODEL IS VALID ONLY UP TO Xgsw=-15 Re and should NOT be used + *tailward of that distance *------------------------------------------------------------------------------------------------------ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include #include #include -#include -#include #include +#include #include "Lgm/Lgm_MagModelInfo.h" #include "Lgm/Lgm_QinDenton.h" #include "Lgm/Lgm_TA2016.h" #ifndef LGM_INDEX_DATA_DIR #warning "hard-coding LGM_INDEX_DATA_DIR because it was not in config.h" -#define LGM_INDEX_DATA_DIR /usr/local/share/LanlGeoMag/Data +#define LGM_INDEX_DATA_DIR /usr/local/share/LanlGeoMag/Data #endif static double Lgm_TA16_As[22] = { - 12.544, -0.194, 0.305, 0.0573, 2.178, - 0.0571, -0.999, 16.473, 0.00152, 0.382, 0.0, 0.0, - -0.210, 0.0, 0.0, -0.636, -2.600, 0.832, -5.328, - 1.103, -0.907, 1.450}; - + 12.544, -0.194, 0.305, 0.0573, 2.178, 0.0571, -0.999, 16.473, + 0.00152, 0.382, 0.0, 0.0, -0.210, 0.0, 0.0, -0.636, + -2.600, 0.832, -5.328, 1.103, -0.907, 1.450}; -void Lgm_Init_TA16(LgmTA16_Info *ta, int verbose){ +void Lgm_Init_TA16(LgmTA16_Info* ta, int verbose) { ta->verbosity = verbose; ta->SetupDone = FALSE; - ta->readTAparams = TRUE; //TRUE to read from Tsyganenko's files + ta->readTAparams = TRUE; // TRUE to read from Tsyganenko's files // FALSE to estimate from QD data - ta->lenA = 23329; //23328 parameter values, 1-based indexing - ta->lenL = 1297; // max val of L in fortran code is 1296 - ta->cache_psi = 99.0; //init as impossible dipole tilt (radians) + ta->lenA = 23329; // 23328 parameter values, 1-based indexing + ta->lenL = 1297; // max val of L in fortran code is 1296 + ta->cache_psi = 99.0; // init as impossible dipole tilt (radians) // grid variables - LGM_ARRAY_1D( ta->A, ta->lenA, double ); - LGM_ARRAY_1D( ta->XX, ta->lenL, double ); - LGM_ARRAY_1D( ta->YY, ta->lenL, double ); - LGM_ARRAY_1D( ta->ZZ, ta->lenL, double ); - LGM_ARRAY_1D( ta->ST, ta->lenL, double ); - LGM_ARRAY_1D( ta->RHO, ta->lenL, double ); - LGM_ARRAY_1D( ta->ZSP, ta->lenL, double ); - LGM_ARRAY_1D( ta->ZCP, ta->lenL, double ); - LGM_ARRAY_1D( ta->RHBR, ta->lenL, double ); + LGM_ARRAY_1D(ta->A, ta->lenA, double); + LGM_ARRAY_1D(ta->XX, ta->lenL, double); + LGM_ARRAY_1D(ta->YY, ta->lenL, double); + LGM_ARRAY_1D(ta->ZZ, ta->lenL, double); + LGM_ARRAY_1D(ta->ST, ta->lenL, double); + LGM_ARRAY_1D(ta->RHO, ta->lenL, double); + LGM_ARRAY_1D(ta->ZSP, ta->lenL, double); + LGM_ARRAY_1D(ta->ZCP, ta->lenL, double); + LGM_ARRAY_1D(ta->RHBR, ta->lenL, double); // cache variables - LGM_ARRAY_1D( ta->DPx, ta->lenL, double ); - LGM_ARRAY_1D( ta->DPy, ta->lenL, double ); - LGM_ARRAY_1D( ta->DPz, ta->lenL, double ); - LGM_ARRAY_1D( ta->DMx, ta->lenL, double ); - LGM_ARRAY_1D( ta->DMy, ta->lenL, double ); - LGM_ARRAY_1D( ta->DMz, ta->lenL, double ); + LGM_ARRAY_1D(ta->DPx, ta->lenL, double); + LGM_ARRAY_1D(ta->DPy, ta->lenL, double); + LGM_ARRAY_1D(ta->DPz, ta->lenL, double); + LGM_ARRAY_1D(ta->DMx, ta->lenL, double); + LGM_ARRAY_1D(ta->DMy, ta->lenL, double); + LGM_ARRAY_1D(ta->DMz, ta->lenL, double); ta->ArraysAlloced = TRUE; Lgm_GetData_TA16(ta); TA2016_SetGrid(ta); return; } -void Lgm_DeAllocate_TA16( LgmTA16_Info *t ){ - - if ( t->ArraysAlloced == TRUE ) { - LGM_ARRAY_1D_FREE( t->A ); - LGM_ARRAY_1D_FREE( t->XX ); - LGM_ARRAY_1D_FREE( t->YY ); - LGM_ARRAY_1D_FREE( t->ZZ ); - LGM_ARRAY_1D_FREE( t->ST ); - LGM_ARRAY_1D_FREE( t->RHO ); - LGM_ARRAY_1D_FREE( t->ZSP ); - LGM_ARRAY_1D_FREE( t->ZCP ); - LGM_ARRAY_1D_FREE( t->RHBR ); - LGM_ARRAY_1D_FREE( t->DPx ); - LGM_ARRAY_1D_FREE( t->DPy ); - LGM_ARRAY_1D_FREE( t->DPz ); - LGM_ARRAY_1D_FREE( t->DMx ); - LGM_ARRAY_1D_FREE( t->DMy ); - LGM_ARRAY_1D_FREE( t->DMz ); +void Lgm_DeAllocate_TA16(LgmTA16_Info* t) { + if (t->ArraysAlloced == TRUE) { + LGM_ARRAY_1D_FREE(t->A); + LGM_ARRAY_1D_FREE(t->XX); + LGM_ARRAY_1D_FREE(t->YY); + LGM_ARRAY_1D_FREE(t->ZZ); + LGM_ARRAY_1D_FREE(t->ST); + LGM_ARRAY_1D_FREE(t->RHO); + LGM_ARRAY_1D_FREE(t->ZSP); + LGM_ARRAY_1D_FREE(t->ZCP); + LGM_ARRAY_1D_FREE(t->RHBR); + LGM_ARRAY_1D_FREE(t->DPx); + LGM_ARRAY_1D_FREE(t->DPy); + LGM_ARRAY_1D_FREE(t->DPz); + LGM_ARRAY_1D_FREE(t->DMx); + LGM_ARRAY_1D_FREE(t->DMy); + LGM_ARRAY_1D_FREE(t->DMz); t->ArraysAlloced = FALSE; } } -int Lgm_Copy_TA16_Info(LgmTA16_Info *targ, LgmTA16_Info *src) { +int Lgm_Copy_TA16_Info(LgmTA16_Info* targ, LgmTA16_Info* src) { int i; - if ( src == NULL) { + if (src == NULL) { printf("Lgm_Copy_TA16_Info: Error, source structure is NULL\n"); - return(-1); + return (-1); } memcpy(targ, src, sizeof(LgmTA16_Info)); - LGM_ARRAY_1D( targ->A, targ->lenA, double ); - LGM_ARRAY_1D( targ->XX, targ->lenL, double ); - LGM_ARRAY_1D( targ->YY, targ->lenL, double ); - LGM_ARRAY_1D( targ->ZZ, targ->lenL, double ); - LGM_ARRAY_1D( targ->ST, targ->lenL, double ); - LGM_ARRAY_1D( targ->RHO, targ->lenL, double ); - LGM_ARRAY_1D( targ->ZSP, targ->lenL, double ); - LGM_ARRAY_1D( targ->ZCP, targ->lenL, double ); - LGM_ARRAY_1D( targ->RHBR, targ->lenL, double ); - LGM_ARRAY_1D( targ->DPx, targ->lenL, double ); - LGM_ARRAY_1D( targ->DPy, targ->lenL, double ); - LGM_ARRAY_1D( targ->DPz, targ->lenL, double ); - LGM_ARRAY_1D( targ->DMx, targ->lenL, double ); - LGM_ARRAY_1D( targ->DMy, targ->lenL, double ); - LGM_ARRAY_1D( targ->DMz, targ->lenL, double ); + LGM_ARRAY_1D(targ->A, targ->lenA, double); + LGM_ARRAY_1D(targ->XX, targ->lenL, double); + LGM_ARRAY_1D(targ->YY, targ->lenL, double); + LGM_ARRAY_1D(targ->ZZ, targ->lenL, double); + LGM_ARRAY_1D(targ->ST, targ->lenL, double); + LGM_ARRAY_1D(targ->RHO, targ->lenL, double); + LGM_ARRAY_1D(targ->ZSP, targ->lenL, double); + LGM_ARRAY_1D(targ->ZCP, targ->lenL, double); + LGM_ARRAY_1D(targ->RHBR, targ->lenL, double); + LGM_ARRAY_1D(targ->DPx, targ->lenL, double); + LGM_ARRAY_1D(targ->DPy, targ->lenL, double); + LGM_ARRAY_1D(targ->DPz, targ->lenL, double); + LGM_ARRAY_1D(targ->DMx, targ->lenL, double); + LGM_ARRAY_1D(targ->DMy, targ->lenL, double); + LGM_ARRAY_1D(targ->DMz, targ->lenL, double); targ->ArraysAlloced = TRUE; - for (i=0; ilenA+1; i++) { - targ->A[i] = src->A[i]; + for (i = 0; i < targ->lenA + 1; i++) { + targ->A[i] = src->A[i]; } - for (i=0; ilenL+1; i++) { - targ->XX[i] = src->XX[i]; - targ->YY[i] = src->YY[i]; - targ->ZZ[i] = src->ZZ[i]; - targ->ST[i] = src->ST[i]; - targ->RHO[i] = src->RHO[i]; - targ->ZSP[i] = src->ZSP[i]; - targ->ZCP[i] = src->ZCP[i]; - targ->RHBR[i] = src->RHBR[i]; - targ->DPx[i] = src->DPx[i]; - targ->DPy[i] = src->DPy[i]; - targ->DPz[i] = src->DPz[i]; - targ->DMx[i] = src->DMx[i]; - targ->DMy[i] = src->DMy[i]; - targ->DMz[i] = src->DMz[i]; + for (i = 0; i < targ->lenL + 1; i++) { + targ->XX[i] = src->XX[i]; + targ->YY[i] = src->YY[i]; + targ->ZZ[i] = src->ZZ[i]; + targ->ST[i] = src->ST[i]; + targ->RHO[i] = src->RHO[i]; + targ->ZSP[i] = src->ZSP[i]; + targ->ZCP[i] = src->ZCP[i]; + targ->RHBR[i] = src->RHBR[i]; + targ->DPx[i] = src->DPx[i]; + targ->DPy[i] = src->DPy[i]; + targ->DPz[i] = src->DPz[i]; + targ->DMx[i] = src->DMx[i]; + targ->DMy[i] = src->DMy[i]; + targ->DMz[i] = src->DMz[i]; } - return(1); + return (1); } - -int Lgm_GetData_TA16(LgmTA16_Info *ta) { - FILE *fp; +int Lgm_GetData_TA16(LgmTA16_Info* ta) { + FILE* fp; char line[64], Filename[1024]; - int idx=1, maxidx=23329; + int idx = 1, maxidx = 23329; + int dummy; // dummy variable for unused return values sprintf(Filename, "%s/TA_DATA/TA16_RBF.par", LGM_INDEX_DATA_DIR); if ((fp = fopen(Filename, "r")) != NULL) { - for (idx; idxA[idx]); + for (idx; idx < maxidx; ++idx) { + dummy = fscanf(fp, "%lf", &ta->A[idx]); } } fclose(fp); - return(1); + return (1); } - -void Lgm_Precalc_TA16(LgmTA16_Info *ta, double tan_psi) { +void Lgm_Precalc_TA16(LgmTA16_Info* ta, double tan_psi) { double DELTA_ZR, DTHETA, cDTM1, sDT, XX, YY, ZZ; double sdt_zcp, sdt_zsp, sdt_rho; int I; - for (I=1; I<=1296; I++) { - DELTA_ZR = ta->RHBR[I]*tan_psi; - DTHETA = -asin(DELTA_ZR)*ta->ST[I]; + for (I = 1; I <= 1296; I++) { + DELTA_ZR = ta->RHBR[I] * tan_psi; + DTHETA = -asin(DELTA_ZR) * ta->ST[I]; sDT = sin(DTHETA); - cDTM1 = cos(DTHETA)-1.0; - sdt_zcp = sDT*ta->ZCP[I]; - sdt_zsp = sDT*ta->ZSP[I]; - sdt_rho = sDT*ta->RHO[I]; + cDTM1 = cos(DTHETA) - 1.0; + sdt_zcp = sDT * ta->ZCP[I]; + sdt_zsp = sDT * ta->ZSP[I]; + sdt_rho = sDT * ta->RHO[I]; XX = ta->XX[I]; YY = ta->YY[I]; ZZ = ta->ZZ[I]; - ta->DPx[I] = XX*cDTM1 + sdt_zcp; - ta->DPy[I] = YY*cDTM1 + sdt_zsp; - ta->DPz[I] = ZZ*cDTM1 - sdt_rho; - ta->DMx[I] = XX*cDTM1 - sdt_zcp; - ta->DMy[I] = YY*cDTM1 - sdt_zsp; - ta->DMz[I] = -ZZ*cDTM1 - sdt_rho; + ta->DPx[I] = XX * cDTM1 + sdt_zcp; + ta->DPy[I] = YY * cDTM1 + sdt_zsp; + ta->DPz[I] = ZZ * cDTM1 - sdt_rho; + ta->DMx[I] = XX * cDTM1 - sdt_zcp; + ta->DMy[I] = YY * cDTM1 - sdt_zsp; + ta->DMz[I] = -ZZ * cDTM1 - sdt_rho; } } - -int Lgm_SetCoeffs_TA16(long int Date, double UTC, LgmTA16_Info *ta) { +int Lgm_SetCoeffs_TA16(long int Date, double UTC, LgmTA16_Info* ta) { double symh, bt, bz2, by2; double *symhc, *newell_norm, *clock; int idx, ncols; - FILE *fp; - char *Path, TA16_path[2048], datafile[2048], tmpstr[1300]; + FILE* fp; + char *Path, TA16_path[1024], datafile[2048], tmpstr[1300]; int inyear, inmonth, inday, indoy; int year, month, day, doy, hour, minute; double bx_av, by_av, bz_av, vx, vy, vz, nden, temp; int IMFflag, SWflag, match; double tilt, pdyn, newe_avg, boyn_avg, symhc_avg; double lineutc; - double fivemin=5./60.0; //five minutes - if ( !(ta->SetupDone) ){ - Lgm_Init_TA16( ta, 0 ); + double fivemin = 5. / 60.0; // five minutes + if (!(ta->SetupDone)) { + Lgm_Init_TA16(ta, 0); } - Lgm_Doy( Date, &inyear, &inmonth, &inday, &indoy ); + Lgm_Doy(Date, &inyear, &inmonth, &inday, &indoy); // Set default values match = 0; - ta->Pdyn = 3.; // Instantaneous Pdyn + ta->Pdyn = 3.; // Instantaneous Pdyn symh = -29.354176; // when corrected gives -46nT (6dp) // Sym-Hc is pressure corrected. Input is 30-minute // avg. of Sym-Hc centered on observation time - ta->SymHc_avg = 0.8 * symh - 13*sqrt(ta->Pdyn); - ta->Xind_avg = 1.; //Avg. of coupling param based on Newell, over previous 30 minutes + ta->SymHc_avg = 0.8 * symh - 13 * sqrt(ta->Pdyn); + ta->Xind_avg = + 1.; // Avg. of coupling param based on Newell, over previous 30 minutes ta->By_avg = 3.; // Avg. over previous 30 minutes of By // If flag set, calculate from Qin-Denton... - if ( !(ta->readTAparams) ){ - // NOT CURRENTLY IMPLEMENTED - just use the defaults set above and skip to the end - printf( "Lgm_SetCoeffs_TA16: Calculating input parameters from QD data is not currently supported. Setting default values.\n"); - return(0); - - Lgm_QinDenton *qin=Lgm_init_QinDenton(0); - Lgm_read_QinDenton(Date, qin); - // Init array for pressure corrected sym-h - symhc = (double *)calloc( qin->nPnts, sizeof(double) ); - newell_norm = (double *)calloc( qin->nPnts, sizeof(double) ); - for (idx=0; idxnPnts; idx++) { - bz2 = qin->BzIMF[idx]*qin->BzIMF[idx]; - by2 = qin->ByIMF[idx]*qin->ByIMF[idx]; - bt = sqrt(bz2 + by2); //QD files don't have Bx, so just use transverse - symhc[idx] = 0.8 * qin->Dst[idx] - 13*sqrt(qin->Pdyn[idx]); - newell_norm[idx] = 1.0e-4 * pow(qin->V_SW[idx], 4.0/3.0) * - pow(bt, 2.0/3.0) * - pow(sin(clock[idx]/2.0), 8.0/3.0); - //TODO: take window averages for given time - } - // Clean up - Lgm_destroy_QinDenton(qin); - free(symhc); - free(newell_norm); - } else { - // check that data location is set and load TA annual file - // use nearest point... - Path = getenv("TA16_DATA_PATH"); - if (Path ==NULL) { // setting path - strcpy( TA16_path, LGM_INDEX_DATA_DIR ); - strcat( TA16_path, "/TA_DATA" ); - } else { - if ( access( TA16_path, F_OK ) < 0 ) { - printf("Lgm_SetCoeffs_TA16: Warning, TA16 Data directory not found at %s. Use TA16_DATA_PATH environment variable to set path.\n", TA16_path ); - exit(-1); - } else{ - strcpy( TA16_path, Path ); + if (!(ta->readTAparams)) { + // NOT CURRENTLY IMPLEMENTED - just use the defaults set above and skip + // to the end + printf( + "Lgm_SetCoeffs_TA16: Calculating input parameters from QD data is " + "not currently supported. Setting default values.\n"); + return (0); + + Lgm_QinDenton* qin = Lgm_init_QinDenton(0); + Lgm_read_QinDenton(Date, qin); + // Init array for pressure corrected sym-h + symhc = (double*)calloc(qin->nPnts, sizeof(double)); + newell_norm = (double*)calloc(qin->nPnts, sizeof(double)); + for (idx = 0; idx < qin->nPnts; idx++) { + bz2 = qin->BzIMF[idx] * qin->BzIMF[idx]; + by2 = qin->ByIMF[idx] * qin->ByIMF[idx]; + bt = sqrt(bz2 + + by2); // QD files don't have Bx, so just use transverse + symhc[idx] = 0.8 * qin->Dst[idx] - 13 * sqrt(qin->Pdyn[idx]); + newell_norm[idx] = 1.0e-4 * pow(qin->V_SW[idx], 4.0 / 3.0) * + pow(bt, 2.0 / 3.0) * + pow(sin(clock[idx] / 2.0), 8.0 / 3.0); + // TODO(SKM): take window averages for given time } - } // done setting path - - // Now load data filea - // IYEAR i4 4-digit year - // IDAY i4 Day of year (IDAY=1 is January 1) - // IHOUR i3 UT hour (0 - 23) - // MIN i3 UT minute (0 - 59) - // f8.2 nT, in GSW coordinates, average over 30-min trailing interval - // f8.2 nT, in GSW coordinates, average over 30-min trailing interval - // f8.2 nT, in GSW coordinates, average over 30-min trailing interval - // Vx f8.1 solar wind Vx in GSE coordinates, km/s - // Vy f8.1 solar wind Vy in GSE coordinates, km/s - // Vz f8.1 solar wind Vz in GSE coordinates, km/s - // Np f7.2 solar wind proton density, cm^-3 - // T f9.0 solar wind proton temperature, degs K - // Sym-H f7.1 Sym-H index, nT - // IMF flag i5 equals 1 for actually measured or 2 for linearly interpolated IMF - // SW flag i5 equals 1 for actually measured or 2 for linearly interpolated solar wind parameters - // Tilt f8.4 geodipole tilt angle (radians!) in GSW coordinate system - // Pdyn f7.2 solar wind flow ram pressure, nPa - // f8.4 average over 30-min trailing interval, see Eq.(1) in TA16_Model_description.pdf - // f8.4 average over 30-min trailing interval, see Eq.(2) in TA16_Model_description.pdf - // f7.1 sliding average over 30-min interval, centered on the current time moment - sprintf( datafile, "%s/%ld_OMNI_5m_with_RBF_TA16_drivers.dat", TA16_path, Date/10000); - if ( (fp = fopen( datafile, "r" )) != NULL ) { - // to start with, just loop over... should we actually - // be interpolating linearly between values? - while ( fgets( &tmpstr, 1300, fp ) != NULL ) { - ncols = sscanf( tmpstr, "%d %d %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %d %lf %lf %lf %lf %lf", - &year, &doy, &hour, &minute, &bx_av, &by_av, &bz_av, - &vx, &vy, &vz, &nden, &temp, &symh, &IMFflag, &SWflag, - &tilt, &pdyn, &newe_avg, &boyn_avg, &symhc_avg); - lineutc = (double)hour + (double)minute/60.0; - if ( (abs(doy - indoy) == 0) && (fabs(lineutc - UTC) < fivemin/2.0) ) { - //nearest time, so fill ta structurea - match = 1; - if (ta->verbosity > 0) printf("Date/Time: %ld %lf\nUsing %s", Date, UTC, tmpstr); - ta->Pdyn = pdyn; - ta->Xind_avg = newe_avg; - ta->By_avg = by_av; - ta->SymHc_avg = symhc_avg; - break; + // Clean up + Lgm_destroy_QinDenton(qin); + free(symhc); + free(newell_norm); + } else { + // check that data location is set and load TA annual file + // use nearest point... + Path = getenv("TA16_DATA_PATH"); + if (Path == NULL) { // setting path + strcpy(TA16_path, LGM_INDEX_DATA_DIR); + strcat(TA16_path, "/TA_DATA"); + } else { + if (access(TA16_path, F_OK) < 0) { + printf( + "Lgm_SetCoeffs_TA16: Warning, TA16 Data directory not " + "found at %s. Use TA16_DATA_PATH environment variable to " + "set path.\n", + TA16_path); + exit(-1); + } else { + strcpy(TA16_path, Path); + } + } // done setting path + + // Now load data filea + // IYEAR i4 4-digit year + // IDAY i4 Day of year (IDAY=1 is January 1) + // IHOUR i3 UT hour (0 - 23) + // MIN i3 UT minute (0 - 59) + // f8.2 nT, in GSW coordinates, average over 30-min + // trailing interval f8.2 nT, in GSW coordinates, + // average over 30-min trailing interval f8.2 nT, in GSW + // coordinates, average over 30-min trailing interval Vx f8.1 + // solar wind Vx in GSE coordinates, km/s Vy f8.1 solar + // wind Vy in GSE coordinates, km/s Vz f8.1 solar wind Vz + // in GSE coordinates, km/s Np f7.2 solar wind proton + // density, cm^-3 T f9.0 solar wind proton temperature, + // degs K Sym-H f7.1 Sym-H index, nT IMF flag i5 equals 1 + // for actually measured or 2 for linearly interpolated IMF SW flag i5 + // equals 1 for actually measured or 2 for linearly interpolated solar + // wind parameters Tilt f8.4 geodipole tilt angle (radians!) + // in GSW coordinate system Pdyn f7.2 solar wind flow ram + // pressure, nPa f8.4 average over 30-min trailing + // interval, see Eq.(1) in TA16_Model_description.pdf f8.4 + // average over 30-min trailing interval, see Eq.(2) in + // TA16_Model_description.pdf f7.1 sliding average over + // 30-min interval, centered on the current time moment + sprintf(datafile, "%s/%ld_OMNI_5m_with_RBF_TA16_drivers.dat", TA16_path, + Date / 10000); + if ((fp = fopen(datafile, "r")) != NULL) { + // to start with, just loop over... should we actually + // be interpolating linearly between values? + while (fgets(tmpstr, 1300, fp) != NULL) { + ncols = sscanf(tmpstr, + "%d %d %d %d %lf %lf %lf %lf %lf %lf %lf %lf " + "%lf %d %d %lf %lf %lf %lf %lf", + &year, &doy, &hour, &minute, &bx_av, &by_av, + &bz_av, &vx, &vy, &vz, &nden, &temp, &symh, + &IMFflag, &SWflag, &tilt, &pdyn, &newe_avg, + &boyn_avg, &symhc_avg); + lineutc = (double)hour + (double)minute / 60.0; + if ((abs(doy - indoy) == 0) && + (fabs(lineutc - UTC) < fivemin / 2.0)) { + // nearest time, so fill ta structurea + match = 1; + if (ta->verbosity > 0) + printf("Date/Time: %ld %lf\nUsing %s", Date, UTC, + tmpstr); + ta->Pdyn = pdyn; + ta->Xind_avg = newe_avg; + ta->By_avg = by_av; + ta->SymHc_avg = symhc_avg; + break; + } } + } else { // end IF for file opened successfully + // defaults were set above, so warn and return + printf( + "Lgm_SetCoeffs_TA16(): Line %d in file %s. Could not open file " + "%s. Using default values.\n", + __LINE__, __FILE__, datafile); + return (0); } - } else {//end IF for file opened successfully - // defaults were set above, so warn and return - printf("Lgm_SetCoeffs_TA16(): Line %d in file %s. Could not open file %s. Using default values.\n", __LINE__, __FILE__, datafile ); - return(0); - } - if (!(match)) printf("Lgm_SetCoeffs_TA16: Warning, No nearby times found in %s. Using default values.\n", datafile ); + if (!(match)) + printf( + "Lgm_SetCoeffs_TA16: Warning, No nearby times found in %s. " + "Using default values.\n", + datafile); } // done loading TA files - return(-1); + return (-1); } - -int TA2016_SetGrid(LgmTA16_Info *Info) { +int TA2016_SetGrid(LgmTA16_Info* Info) { // initialize the TA2016 coefficient set, grid, etc. - int Klat, Nlat, Nlon, I, J, K, L=0; - double D=4.0; + int Klat, Nlat, Nlon, I, J, K, L = 0; + double D = 4.0; double Alpha, XXXX, YYYY, ZZZZ, RHighGrid, RLowGrid, X4sq, Y4sq, Z4sq; double Xlon, XlonD, Xcolat, XcolatD, sinXco, sinXlo, cosXlo; double R0, R1, RH, RM, Rho1, R, RLAST, STS, STT, STN; double CN, CS, CTN, CTS, CTT, DN, DS, EN, ES, CP, SP; double T, PSIN, PSIS, dLonDeg; - double B0, F1, PD_TR, PM=0.0; - - Klat = 8; // Klat IS THE NUMBER OF LATITUDE CIRCLES IN THE NORTHERN HEMISPHERE (EXCLUDING THE POLE) - RLowGrid = 3.3; // THE INNERMOST SPHERE RADIUS - RHighGrid =16.0; // UPPER LIMIT ON THE RADIUS OF OUTERMOST RBF SPHERE + double B0, F1, PD_TR, PM = 0.0; + + Klat = 8; // Klat IS THE NUMBER OF LATITUDE CIRCLES IN THE NORTHERN + // HEMISPHERE (EXCLUDING THE POLE) + RLowGrid = 3.3; // THE INNERMOST SPHERE RADIUS + RHighGrid = 16.0; // UPPER LIMIT ON THE RADIUS OF OUTERMOST RBF SPHERE // Upper limit on the data tailward limit = 20.0 - - RH=8.0; // HINGING PARAMETERS (SEE TAG-2015) - Alpha=3.0; // Alpha PARAMETER (SEE TAG-2015) - Nlat = Klat+1; // NUMBER OF LATITUDE CIRCLES IN THE N. HEMISPHERE INCLUDING THE POLE - + + RH = 8.0; // HINGING PARAMETERS (SEE TAG-2015) + Alpha = 3.0; // Alpha PARAMETER (SEE TAG-2015) + Nlat = Klat + 1; // NUMBER OF LATITUDE CIRCLES IN THE N. HEMISPHERE + // INCLUDING THE POLE + R = RLowGrid; // THE INNERMOST SPHERE RADIUS - - PD_TR = 0.5; // this is just to filter out RBF centers outside the Lin et al model magnetopause + + PD_TR = 0.5; // this is just to filter out RBF centers outside the Lin et + // al model magnetopause CTN = cos(Lgm_TA16_As[19]); CTS = CTN; STN = sin(Lgm_TA16_As[19]); STS = STN; CN = 0.0; CS = 0.0; - - for (J=1; J<=100; J++) { // J COUNTS THE NUMBER OF SPHERES WITH RBF CENTERS + + for (J = 1; J <= 100; + J++) { // J COUNTS THE NUMBER OF SPHERES WITH RBF CENTERS // (WHICH IS ACTUALLY MUCH LESS THAN 100) - for (I=1; I<=Nlat; I++) { // I COUNTS THE LATITUDE CIRCLES (FROM NORTH POLE DOWN TO EQUATOR) - XcolatD = (90.0/(Nlat-0.5))*((double)(I)-1.0); // COLATITUDE OF THE Ith CIRCLE (in degs) - Nlon=4*(I-1); // NUMBER OF RBF CENTERS ON THE ItH CIRCLE - if (I != 1) { - dLonDeg = 360.0/Nlon; // LONGITUDE INTERVAL BETWEEN CENTERS (degs) - } else { - Nlon = 1; // NUMBER OF RBF CENTERS ON THE NORTH POLE - dLonDeg = 0.0; - } - for (K=1; K<=Nlon; K++) { - XlonD = (K-1)*dLonDeg; - // number below is radian conversion... do with named variable - Xcolat = XcolatD*0.01745329252; // COLATITUDE and - Xlon = XlonD*0.01745329252; // LONGITUDE OF THE Lth RBF CENTER - - sinXco = sin(Xcolat); - sinXlo = sin(Xlon); - cosXlo = cos(Xlon); - XXXX = R*sinXco*cosXlo; - YYYY = R*sinXco*sinXlo; - ZZZZ = R*cos(Xcolat); - // HERE WE CALCULATE THE DISTANCE FROM THE RBF NODE TO THE LIN ET AL. [2010] MODEL MAGNETOPAUSE. - // THE RBF NODES LYING OUTSIDE THE BOUNDARY ARE NOT INCLUDED IN THE GRID - EN = Lgm_TA16_As[21]; - ES = Lgm_TA16_As[21]; - - X4sq = XXXX*XXXX; - Y4sq = YYYY*YYYY; - Z4sq = ZZZZ*ZZZZ; - R1 = sqrt(X4sq+Y4sq+Z4sq); - Rho1 = sqrt(Y4sq+Z4sq); - - CTT=XXXX/R1; - STT = sqrt(Y4sq+Z4sq)/R1; - T = atan2(STT, CTT); - if (Rho1 > 1.0e-5) { // WE ARE NOT ON THE X-AXIS - NO SINGULARITIES TO WORRY ABOUT - SP = ZZZZ/Rho1; - CP = YYYY/Rho1; - } else { // WE ARE ON THE X-AXIS - if (XXXX > 0.0) { // IF ON THE DAYSIDE, NO PROBLEM EITHER - SP = 0.0; - CP = 1.0; - } else { // WE ARE ON THE TAIL AXIS; TO AVOID SINGULARITY: - RM = 1000.0; // ASSIGN RM=1000 (A CONVENTIONAL SUBSTITUTE VALUE) - // Raise an error here? Or set bad values and a warning? - return(-1); // AND EXIT + for (I = 1; I <= Nlat; I++) { // I COUNTS THE LATITUDE CIRCLES (FROM + // NORTH POLE DOWN TO EQUATOR) + XcolatD = + (90.0 / (Nlat - 0.5)) * + ((double)(I)-1.0); // COLATITUDE OF THE Ith CIRCLE (in degs) + Nlon = 4 * (I - 1); // NUMBER OF RBF CENTERS ON THE ItH CIRCLE + if (I != 1) { + dLonDeg = + 360.0 / Nlon; // LONGITUDE INTERVAL BETWEEN CENTERS (degs) + } else { + Nlon = 1; // NUMBER OF RBF CENTERS ON THE NORTH POLE + dLonDeg = 0.0; } - } - - PSIN = acos(CTT*CTN+STT*STN*SP); - PSIS = acos(CTT*CTS-STT*STS*SP); - - DN = Lgm_TA16_As[16]; - DS = Lgm_TA16_As[16]; - - B0 = Lgm_TA16_As[6]; - F1 = pow(sqrt(0.5*(1.0+CTT))+Lgm_TA16_As[5]*2.0*STT*CTT*(1.0-exp(-T)), B0); - R0 = Lgm_TA16_As[0]*pow(PD_TR+PM, Lgm_TA16_As[1]); - RM = R0*F1+CN*exp(DN*pow(PSIN, EN))+CS*exp(DS*pow(PSIS, ES)); // POSITION OF THE MODEL MAGNETOPAUSE - if (R <= RM) { - L = L+1; // COUNTER OF THE RBF CENTERS - Info->XX[L] = XXXX; - Info->YY[L] = YYYY; - Info->ZZ[L] = ZZZZ; - Info->ST[L] = sinXco; - Info->RHO[L] = R*sinXco; - Info->ZSP[L] = ZZZZ*sinXlo; - Info->ZCP[L] = ZZZZ*cosXlo; - Info->RHBR[L] = RH/R*(1.0 - pow(1.0 + pow(R/RH, Alpha), 1.0/Alpha)); - } - } // End loop over K - } // End loop over I - - RLAST = R; - R = R*(Nlat-0.5+M_PI/4.0)/(Nlat-0.5-M_PI/4.0); // Increment R by a fixed factor - if (R > RHighGrid) break; // RBF centers only inside R=RHIGH - } // End loop over J - Info->SetupDone = TRUE ; - return(1); + for (K = 1; K <= Nlon; K++) { + XlonD = (K - 1) * dLonDeg; + // number below is radian conversion... do with named variable + Xcolat = XcolatD * 0.01745329252; // COLATITUDE and + Xlon = + XlonD * 0.01745329252; // LONGITUDE OF THE Lth RBF CENTER + + sinXco = sin(Xcolat); + sinXlo = sin(Xlon); + cosXlo = cos(Xlon); + XXXX = R * sinXco * cosXlo; + YYYY = R * sinXco * sinXlo; + ZZZZ = R * cos(Xcolat); + // HERE WE CALCULATE THE DISTANCE FROM THE RBF NODE TO THE LIN + // ET AL. [2010] MODEL MAGNETOPAUSE. THE RBF NODES LYING OUTSIDE + // THE BOUNDARY ARE NOT INCLUDED IN THE GRID + EN = Lgm_TA16_As[21]; + ES = Lgm_TA16_As[21]; + + X4sq = XXXX * XXXX; + Y4sq = YYYY * YYYY; + Z4sq = ZZZZ * ZZZZ; + R1 = sqrt(X4sq + Y4sq + Z4sq); + Rho1 = sqrt(Y4sq + Z4sq); + + CTT = XXXX / R1; + STT = sqrt(Y4sq + Z4sq) / R1; + T = atan2(STT, CTT); + if (Rho1 > 1.0e-5) { // WE ARE NOT ON THE X-AXIS - NO + // SINGULARITIES TO WORRY ABOUT + SP = ZZZZ / Rho1; + CP = YYYY / Rho1; + } else { // WE ARE ON THE X-AXIS + if (XXXX > 0.0) { // IF ON THE DAYSIDE, NO PROBLEM EITHER + SP = 0.0; + CP = 1.0; + } else { // WE ARE ON THE TAIL AXIS; TO AVOID SINGULARITY: + RM = 1000.0; // ASSIGN RM=1000 (A CONVENTIONAL + // SUBSTITUTE VALUE) + // Raise an error here? Or set bad values and a warning? + return (-1); // AND EXIT + } + } + + PSIN = acos(CTT * CTN + STT * STN * SP); + PSIS = acos(CTT * CTS - STT * STS * SP); + + DN = Lgm_TA16_As[16]; + DS = Lgm_TA16_As[16]; + + B0 = Lgm_TA16_As[6]; + F1 = pow(sqrt(0.5 * (1.0 + CTT)) + + Lgm_TA16_As[5] * 2.0 * STT * CTT * (1.0 - exp(-T)), + B0); + R0 = Lgm_TA16_As[0] * pow(PD_TR + PM, Lgm_TA16_As[1]); + RM = R0 * F1 + CN * exp(DN * pow(PSIN, EN)) + + CS * exp(DS * + pow(PSIS, + ES)); // POSITION OF THE MODEL MAGNETOPAUSE + if (R <= RM) { + L = L + 1; // COUNTER OF THE RBF CENTERS + Info->XX[L] = XXXX; + Info->YY[L] = YYYY; + Info->ZZ[L] = ZZZZ; + Info->ST[L] = sinXco; + Info->RHO[L] = R * sinXco; + Info->ZSP[L] = ZZZZ * sinXlo; + Info->ZCP[L] = ZZZZ * cosXlo; + Info->RHBR[L] = + RH / R * + (1.0 - pow(1.0 + pow(R / RH, Alpha), 1.0 / Alpha)); + } + } // End loop over K + } // End loop over I + + RLAST = R; + R = R * (Nlat - 0.5 + M_PI / 4.0) / + (Nlat - 0.5 - M_PI / 4.0); // Increment R by a fixed factor + if (R > RHighGrid) + break; // RBF centers only inside R=RHIGH + } // End loop over J + Info->SetupDone = TRUE; + return (1); } - -int TA2016(Lgm_Vector *posGSM, double *PARMOD, Lgm_CTrans *ctrans, Lgm_Vector *BvecGSM, LgmTA16_Info *Info) { +int TA2016(Lgm_Vector* posGSM, + double* PARMOD, + Lgm_CTrans* ctrans, + Lgm_Vector* BvecGSM, + LgmTA16_Info* Info) { int I; Lgm_Vector posSM, BvecSM; Lgm_Vector Parr, PCP, PCM, DCM, DCP, DCMsq, DCPsq; @@ -423,124 +468,138 @@ int TA2016(Lgm_Vector *posGSM, double *PARMOD, Lgm_CTrans *ctrans, Lgm_Vector *B double cPS, sPS, tPS, CM, CP; double Pdyn, SymV, Xind, ByIMF, FPD; double dcpdenx, dcpdeny, dcpdenz, dcmdenx, dcmdeny, dcmdenz; - double ACP, ACT, AP, ASP,AST, AT; + double ACP, ACT, AP, ASP, AST, AT; double DCMXY, DCMXZ, DCMYZ, DCPXY, DCPXZ, DCPYZ; - double D2=16.0; + double D2 = 16.0; cPS = ctrans->cos_psi; // cos(dipole tilt) sPS = ctrans->sin_psi; // sin(dipole tilt) tPS = ctrans->tan_psi; // tan(dipole tilt) - - posSM.x = posGSM->x*cPS - posGSM->z*sPS; // RBF EXPANSIONS ARE IN SM COORDINATES - posSM.y = posGSM->y; // -> CONVERT X,Y,Z FROM GSW TO SM - posSM.z = posGSM->z*cPS + posGSM->x*sPS; - - Pdyn = PARMOD[1]; - SymV = PARMOD[2]/50.0; // Sym-H divided by 50 - Xind = PARMOD[3]; + + posSM.x = posGSM->x * cPS - + posGSM->z * sPS; // RBF EXPANSIONS ARE IN SM COORDINATES + posSM.y = posGSM->y; // -> CONVERT X,Y,Z FROM GSW TO SM + posSM.z = posGSM->z * cPS + posGSM->x * sPS; + + Pdyn = PARMOD[1]; + SymV = PARMOD[2] / 50.0; // Sym-H divided by 50 + Xind = PARMOD[3]; ByIMF = PARMOD[4]; - FPD = sqrt(Pdyn/2.0)-1.0; - - BvecSM.x = 0.0; BvecSM.y = 0.0; BvecSM.z = 0.0; - if ( !(fabs(Info->cache_psi - ctrans->psi) <= 1.0e-6) ) { - // If the tilt angle hasn't changed since last call, - // we're probably doing something with thousands to - // millions of repeated calls (like tracing) and - // will benefit from using precalculated sDT and cDTM1 - // variables. 1e-6 radians = 5.7e-5 degrees. - Lgm_Precalc_TA16(Info, tPS); - Info->cache_psi = ctrans->psi; + FPD = sqrt(Pdyn / 2.0) - 1.0; + + BvecSM.x = 0.0; + BvecSM.y = 0.0; + BvecSM.z = 0.0; + if (!(fabs(Info->cache_psi - ctrans->psi) <= 1.0e-6)) { + // If the tilt angle hasn't changed since last call, + // we're probably doing something with thousands to + // millions of repeated calls (like tracing) and + // will benefit from using precalculated sDT and cDTM1 + // variables. 1e-6 radians = 5.7e-5 degrees. + Lgm_Precalc_TA16(Info, tPS); + Info->cache_psi = ctrans->psi; } - for (I=1; I<=1296; I++) { - Parr.x = Info->XX[I]; - Parr.y = Info->YY[I]; - Parr.z = Info->ZZ[I]; - - dcpdenx = posSM.x-Parr.x-Info->DPx[I]; - dcpdeny = posSM.y-Parr.y-Info->DPy[I]; - dcpdenz = posSM.z-Parr.z-Info->DPz[I]; - dcmdenx = posSM.x-Parr.x-Info->DMx[I]; - dcmdeny = posSM.y-Parr.y-Info->DMy[I]; - dcmdenz = posSM.z+Parr.z-Info->DMz[I]; - CP = sqrt(dcpdenx*dcpdenx + - dcpdeny*dcpdeny + - dcpdenz*dcpdenz + D2); // RBF Ch_i+ - CM = sqrt(dcmdenx*dcmdenx + - dcmdeny*dcmdeny + - dcmdenz*dcmdenz + D2); // RBF Ch_i- - - DCP.x = dcpdenx/CP; - DCP.y = dcpdeny/CP; - DCP.z = dcpdenz/CP; - DCM.x = dcmdenx/CM; - DCM.y = dcmdeny/CM; - DCM.z = dcmdenz/CM; - DCPsq.x = DCP.x * DCP.x; - DCPsq.y = DCP.y * DCP.y; - DCPsq.z = DCP.z * DCP.z; - DCPsq.x = (1.0 - DCPsq.x)/CP; - DCPsq.y = (1.0 - DCPsq.y)/CP; - DCPsq.z = (1.0 - DCPsq.z)/CP; - DCMsq.x = DCM.x * DCM.x; - DCMsq.y = DCM.y * DCM.y; - DCMsq.z = DCM.z * DCM.z; - DCMsq.x = (1.0 - DCMsq.x)/CM; - DCMsq.y = (1.0 - DCMsq.y)/CM; - DCMsq.z = (1.0 - DCMsq.z)/CM; - DCPXY = -DCP.x*DCP.y/CP; - DCPXZ = -DCP.x*DCP.z/CP; - DCPYZ = -DCP.y*DCP.z/CP; - DCMXY = -DCM.x*DCM.y/CM; - DCMXZ = -DCM.x*DCM.z/CM; - DCMYZ = -DCM.y*DCM.z/CM; - - TCP.x = posSM.z*DCP.y - posSM.y*DCP.z; - TCP.y = posSM.x*DCP.z - posSM.z*DCP.x; - TCP.z = posSM.y*DCP.x - posSM.x*DCP.y; - TCM.x = posSM.z*DCM.y - posSM.y*DCM.z; - TCM.y = posSM.x*DCM.z - posSM.z*DCM.x; - TCM.z = posSM.y*DCM.x - posSM.x*DCM.y; - - PCP.x = 2.0*DCP.x-posSM.x*(DCPsq.y+DCPsq.z)+posSM.y*DCPXY+posSM.z*DCPXZ; - PCP.y = 2.0*DCP.y-posSM.y*(DCPsq.x+DCPsq.z)+posSM.z*DCPYZ+posSM.x*DCPXY; - PCP.z = 2.0*DCP.z-posSM.z*(DCPsq.x+DCPsq.y)+posSM.x*DCPXZ+posSM.y*DCPYZ; - PCM.x = 2.0*DCM.x-posSM.x*(DCMsq.y+DCMsq.z)+posSM.y*DCMXY+posSM.z*DCMXZ; - PCM.y = 2.0*DCM.y-posSM.y*(DCMsq.x+DCMsq.z)+posSM.z*DCMYZ+posSM.x*DCMXY; - PCM.z = 2.0*DCM.z-posSM.z*(DCMsq.x+DCMsq.y)+posSM.x*DCMXZ+posSM.y*DCMYZ; - - CTarr.x = (TCP.x + TCM.x)*cPS; - CTarr.y = (TCP.y + TCM.y)*cPS; - CTarr.z = (TCP.z + TCM.z)*cPS; - STarr.x = (TCP.x - TCM.x)*sPS; - STarr.y = (TCP.y - TCM.y)*sPS; - STarr.z = (TCP.z - TCM.z)*sPS; - CParr.x = (PCP.x - PCM.x)*cPS; - CParr.y = (PCP.y - PCM.y)*cPS; - CParr.z = (PCP.z - PCM.z)*cPS; - SParr.x = (PCP.x + PCM.x)*sPS; - SParr.y = (PCP.y + PCM.y)*sPS; - SParr.z = (PCP.z + PCM.z)*sPS; - - // ----------------- TOTAL FIELD: ----------------------------------- - ACT = Info->A[I]+Info->A[I+5184]*FPD+Info->A[I+10368]*SymV+Info->A[I+15552]*Xind; - AST = Info->A[I+1296]+Info->A[I+6480]*FPD+Info->A[I+11664]*SymV+Info->A[I+16848]*Xind; - AT = Info->A[I+20736]*ByIMF; - ACP = Info->A[I+2592]+Info->A[I+7776]*FPD+Info->A[I+12960]*SymV+Info->A[I+18144]*Xind; - ASP = Info->A[I+3888]+Info->A[I+9072]*FPD+Info->A[I+14256]*SymV+Info->A[I+19440]*Xind; - AP = Info->A[I+22032]*ByIMF; - BvecSM.x += CTarr.x*ACT + STarr.x*AST + (TCP.x-TCM.x)*AT + CParr.x*ACP + SParr.x*ASP + (PCP.x+PCM.x)*AP; - BvecSM.y += CTarr.y*ACT + STarr.y*AST + (TCP.y-TCM.y)*AT + CParr.y*ACP + SParr.y*ASP + (PCP.y+PCM.y)*AP; - BvecSM.z += CTarr.z*ACT + STarr.z*AST + (TCP.z-TCM.z)*AT + CParr.z*ACP + SParr.z*ASP + (PCP.z+PCM.z)*AP; + for (I = 1; I <= 1296; I++) { + Parr.x = Info->XX[I]; + Parr.y = Info->YY[I]; + Parr.z = Info->ZZ[I]; + + dcpdenx = posSM.x - Parr.x - Info->DPx[I]; + dcpdeny = posSM.y - Parr.y - Info->DPy[I]; + dcpdenz = posSM.z - Parr.z - Info->DPz[I]; + dcmdenx = posSM.x - Parr.x - Info->DMx[I]; + dcmdeny = posSM.y - Parr.y - Info->DMy[I]; + dcmdenz = posSM.z + Parr.z - Info->DMz[I]; + CP = sqrt(dcpdenx * dcpdenx + dcpdeny * dcpdeny + dcpdenz * dcpdenz + + D2); // RBF Ch_i+ + CM = sqrt(dcmdenx * dcmdenx + dcmdeny * dcmdeny + dcmdenz * dcmdenz + + D2); // RBF Ch_i- + + DCP.x = dcpdenx / CP; + DCP.y = dcpdeny / CP; + DCP.z = dcpdenz / CP; + DCM.x = dcmdenx / CM; + DCM.y = dcmdeny / CM; + DCM.z = dcmdenz / CM; + DCPsq.x = DCP.x * DCP.x; + DCPsq.y = DCP.y * DCP.y; + DCPsq.z = DCP.z * DCP.z; + DCPsq.x = (1.0 - DCPsq.x) / CP; + DCPsq.y = (1.0 - DCPsq.y) / CP; + DCPsq.z = (1.0 - DCPsq.z) / CP; + DCMsq.x = DCM.x * DCM.x; + DCMsq.y = DCM.y * DCM.y; + DCMsq.z = DCM.z * DCM.z; + DCMsq.x = (1.0 - DCMsq.x) / CM; + DCMsq.y = (1.0 - DCMsq.y) / CM; + DCMsq.z = (1.0 - DCMsq.z) / CM; + DCPXY = -DCP.x * DCP.y / CP; + DCPXZ = -DCP.x * DCP.z / CP; + DCPYZ = -DCP.y * DCP.z / CP; + DCMXY = -DCM.x * DCM.y / CM; + DCMXZ = -DCM.x * DCM.z / CM; + DCMYZ = -DCM.y * DCM.z / CM; + + TCP.x = posSM.z * DCP.y - posSM.y * DCP.z; + TCP.y = posSM.x * DCP.z - posSM.z * DCP.x; + TCP.z = posSM.y * DCP.x - posSM.x * DCP.y; + TCM.x = posSM.z * DCM.y - posSM.y * DCM.z; + TCM.y = posSM.x * DCM.z - posSM.z * DCM.x; + TCM.z = posSM.y * DCM.x - posSM.x * DCM.y; + + PCP.x = 2.0 * DCP.x - posSM.x * (DCPsq.y + DCPsq.z) + posSM.y * DCPXY + + posSM.z * DCPXZ; + PCP.y = 2.0 * DCP.y - posSM.y * (DCPsq.x + DCPsq.z) + posSM.z * DCPYZ + + posSM.x * DCPXY; + PCP.z = 2.0 * DCP.z - posSM.z * (DCPsq.x + DCPsq.y) + posSM.x * DCPXZ + + posSM.y * DCPYZ; + PCM.x = 2.0 * DCM.x - posSM.x * (DCMsq.y + DCMsq.z) + posSM.y * DCMXY + + posSM.z * DCMXZ; + PCM.y = 2.0 * DCM.y - posSM.y * (DCMsq.x + DCMsq.z) + posSM.z * DCMYZ + + posSM.x * DCMXY; + PCM.z = 2.0 * DCM.z - posSM.z * (DCMsq.x + DCMsq.y) + posSM.x * DCMXZ + + posSM.y * DCMYZ; + + CTarr.x = (TCP.x + TCM.x) * cPS; + CTarr.y = (TCP.y + TCM.y) * cPS; + CTarr.z = (TCP.z + TCM.z) * cPS; + STarr.x = (TCP.x - TCM.x) * sPS; + STarr.y = (TCP.y - TCM.y) * sPS; + STarr.z = (TCP.z - TCM.z) * sPS; + CParr.x = (PCP.x - PCM.x) * cPS; + CParr.y = (PCP.y - PCM.y) * cPS; + CParr.z = (PCP.z - PCM.z) * cPS; + SParr.x = (PCP.x + PCM.x) * sPS; + SParr.y = (PCP.y + PCM.y) * sPS; + SParr.z = (PCP.z + PCM.z) * sPS; + + // ----------------- TOTAL FIELD: ----------------------------------- + ACT = Info->A[I] + Info->A[I + 5184] * FPD + Info->A[I + 10368] * SymV + + Info->A[I + 15552] * Xind; + AST = Info->A[I + 1296] + Info->A[I + 6480] * FPD + + Info->A[I + 11664] * SymV + Info->A[I + 16848] * Xind; + AT = Info->A[I + 20736] * ByIMF; + ACP = Info->A[I + 2592] + Info->A[I + 7776] * FPD + + Info->A[I + 12960] * SymV + Info->A[I + 18144] * Xind; + ASP = Info->A[I + 3888] + Info->A[I + 9072] * FPD + + Info->A[I + 14256] * SymV + Info->A[I + 19440] * Xind; + AP = Info->A[I + 22032] * ByIMF; + BvecSM.x += CTarr.x * ACT + STarr.x * AST + (TCP.x - TCM.x) * AT + + CParr.x * ACP + SParr.x * ASP + (PCP.x + PCM.x) * AP; + BvecSM.y += CTarr.y * ACT + STarr.y * AST + (TCP.y - TCM.y) * AT + + CParr.y * ACP + SParr.y * ASP + (PCP.y + PCM.y) * AP; + BvecSM.z += CTarr.z * ACT + STarr.z * AST + (TCP.z - TCM.z) * AT + + CParr.z * ACP + SParr.z * ASP + (PCP.z + PCM.z) * AP; } Lgm_Convert_Coords(&BvecSM, BvecGSM, SM_TO_GSM, ctrans); - return(1); + return (1); } -int Lgm_B_TA16( Lgm_Vector *rGSM, Lgm_Vector *B, Lgm_MagModelInfo *Info ) { +int Lgm_B_TA16(Lgm_Vector* rGSM, Lgm_Vector* B, Lgm_MagModelInfo* Info) { // Evaluate Tsyganenko & Andreeva 2016 model - Lgm_Vector Bext, Bint; - double PARMOD[11]; - int retval; + Lgm_Vector Bext, Bint; + double PARMOD[11]; + int retval; if (rGSM->x < -15.0) { // Model is only valid to 15 Re tailward. @@ -548,7 +607,7 @@ int Lgm_B_TA16( Lgm_Vector *rGSM, Lgm_Vector *B, Lgm_MagModelInfo *Info ) { B->x = LGM_FILL_VALUE; B->y = LGM_FILL_VALUE; B->z = LGM_FILL_VALUE; - return(-1); + return (-1); } PARMOD[1] = Info->TA16_Info.Pdyn; @@ -556,19 +615,20 @@ int Lgm_B_TA16( Lgm_Vector *rGSM, Lgm_Vector *B, Lgm_MagModelInfo *Info ) { PARMOD[3] = Info->TA16_Info.Xind_avg; PARMOD[4] = Info->TA16_Info.By_avg; retval = TA2016(rGSM, PARMOD, Info->c, &Bext, &Info->TA16_Info); - switch ( Info->InternalModel ){ + switch (Info->InternalModel) { case LGM_CDIP: - Lgm_B_cdip(rGSM, &Bint, Info); - break; + Lgm_B_cdip(rGSM, &Bint, Info); + break; case LGM_EDIP: - Lgm_B_edip(rGSM, &Bint, Info); - break; + Lgm_B_edip(rGSM, &Bint, Info); + break; case LGM_IGRF: - Lgm_B_igrf(rGSM, &Bint, Info); - break; + Lgm_B_igrf(rGSM, &Bint, Info); + break; default: - fprintf(stderr, "Lgm_B_TA16: Unknown internal model (%d)\n", Info->InternalModel ); - break; + fprintf(stderr, "Lgm_B_TA16: Unknown internal model (%d)\n", + Info->InternalModel); + break; } // Add requested internal field model to obtain total field @@ -576,6 +636,5 @@ int Lgm_B_TA16( Lgm_Vector *rGSM, Lgm_Vector *B, Lgm_MagModelInfo *Info ) { ++Info->nFunc; // increment counter of function calls - return(1); - + return (1); }