|
|
SUBROUTINE CONVERT_GEO_COORD(R_LAT_IN,R_LON_IN,R_HEIGHT_IN,
|
|
|
* R_LAT_OUT,R_LON_OUT,I_FLAG,I_ERROR)
|
|
|
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
|
|
c $Revision: 1.2 $
|
|
|
c The initial version of this subroutine was written by RADEX, INC.
|
|
|
c for use on VAX/VMS systems.
|
|
|
c
|
|
|
c Subsequent revisions for UNIX systems have been made by KBB at
|
|
|
c The Johns Hopkins Univ. Applied Physics Laboratory. These revisions
|
|
|
c have been managed using the Revision Control System (RCS) and a
|
|
|
c log of the revisions will be found at the end of the comments.
|
|
|
c
|
|
|
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
|
|
C
|
|
|
C
|
|
|
C Purpose:
|
|
|
C
|
|
|
C This subroutine uses a set of spherical harmonic coefficients to
|
|
|
C perform a coordinate conversion between geographic and corrected
|
|
|
C geomagnetic coordinates (or vice versa).
|
|
|
C
|
|
|
C The spherical harmonics for the geographic to corrected geomagnetic
|
|
|
C coordinate system correspond to a conversion from geographic to
|
|
|
C the corrected geomagnetic coordinates (expressed in terms of
|
|
|
C centered dipole coordinates at the input altitude), and are then
|
|
|
C transformed to ground level.
|
|
|
C
|
|
|
C The spherical harmonic coefficients used for the inverse are
|
|
|
C computed relative to centered dipole coordinates at the input
|
|
|
C altitude. The input CGM coordinates are converted to equivalent
|
|
|
C values in this coordinate sytem using the inverse altitude
|
|
|
C algorithm before the evaluation of the geographic spherical
|
|
|
C harmonic expansion.
|
|
|
C
|
|
|
C Method:
|
|
|
C
|
|
|
C This subroutine uses a five-step process in converting a position
|
|
|
C in one coordinate system to a position in the other.
|
|
|
C The five steps are as follows:
|
|
|
C
|
|
|
C 1. The appropriate spherical harmonic coefficients for the
|
|
|
C coordinate conversion are computed for the input altitude.
|
|
|
C
|
|
|
C 2. The appropriate coordinates for use in the spherical harmonic
|
|
|
C expansion are computed. For the geographic ==> corrected
|
|
|
C geomagnetic coordinate version, these are geographic colatitude
|
|
|
C and longitude. For the inverse coordinate conversion, the
|
|
|
C input coordinates are first converted into equivalent dipole
|
|
|
C coordinates at the input altitude.
|
|
|
C
|
|
|
C 3. The Cartesian coordinates of the unit vector in the desired
|
|
|
C coordinate system are then computed using the appropriate
|
|
|
C spherical harmonic expansion.
|
|
|
C
|
|
|
C 4. For the geographic ==> corrected geomagnetic coordinate
|
|
|
C conversion, the dipole-equivalent coordinates at input
|
|
|
C altitude are converted to their cgm cartesian coordinates.
|
|
|
C
|
|
|
C 5. Standard trigonometric identities are used to compute the
|
|
|
C latitude and longitude in the desired output coordinate system.
|
|
|
C
|
|
|
C Input Arguments:
|
|
|
C
|
|
|
C R_LAT_IN - REAL*4 - The input latitude in degrees.
|
|
|
C This could be either geographic latitude
|
|
|
C or corrected geomagnetic latitude. The
|
|
|
C acceptable range of values is (-90 to +90
|
|
|
C degrees).
|
|
|
C
|
|
|
C R_LON_IN - REAL*4 - The input longitude in degrees east.
|
|
|
C This could be either geographic longitude
|
|
|
C or corrected geomagnetic longitude. The
|
|
|
C acceptable range of values is (0 to 360 degrees).
|
|
|
C
|
|
|
C R_HEIGHT_IN - REAL*4 - The height in kilometers for which the
|
|
|
C coordinate transformation will be accomplished.
|
|
|
C The acceptable range of values is (0 km to
|
|
|
C 7200 km)
|
|
|
C
|
|
|
C I_FLAG - INTEGER - The flag that indicates which way
|
|
|
C the conversion will proceed.
|
|
|
C
|
|
|
C = 1 convert geographic to corrected
|
|
|
C geomagnetic coordinates
|
|
|
C
|
|
|
C = 2 convert corrected geomagnetic
|
|
|
C to geographic coordinates
|
|
|
C
|
|
|
C Output Arguments:
|
|
|
C
|
|
|
C R_LAT_OUT - REAL*4 - The output latitude in degrees.
|
|
|
C This could be either the geographic latitude
|
|
|
C or corrected geomagnetic latitude. This
|
|
|
C value will be between -90 and +90 degrees.
|
|
|
C
|
|
|
C R_LON_OUT - REAL*4 - The output longitude in degrees.
|
|
|
C This could be either geographic longitude or
|
|
|
C corrected geomagnetic longitude. This
|
|
|
C value will be between 0 and 360 degrees.
|
|
|
C
|
|
|
C I_ERROR - INTEGER - The error flag
|
|
|
C
|
|
|
C = 0 normal processing
|
|
|
C = -2 R_HEIGHT_IN is outside the allowable range
|
|
|
C = -4 I_FLAG value is invalid
|
|
|
C = -8 R_LAT_IN is outside the allowable range
|
|
|
C = -16 R_LON_IN is outside the allowable range
|
|
|
C = -32 Magnitude of the "unit vector" of the
|
|
|
C target coordinate system deviates
|
|
|
C significantly (+/- 20% or more) from 1.
|
|
|
C = -64 For altitudes > 0, for the corrected
|
|
|
C geomagnetic to geographic coordinate
|
|
|
C conversion there is a range of latitudes
|
|
|
C for which the transformation is invalid.
|
|
|
C This flag is set when the requested input
|
|
|
C cgm latitude falls within the invalid
|
|
|
C region.
|
|
|
C
|
|
|
C Local Variables:
|
|
|
C
|
|
|
C C_CLASS - Character String, used to identify message
|
|
|
C class in error messages.
|
|
|
C
|
|
|
C C_FLAG - Character String used to store I_FLAG
|
|
|
C as a character string for use in error
|
|
|
C message.
|
|
|
C
|
|
|
C C_HEIGHT_IN - Character String used to store R_HEIGHT_IN
|
|
|
C as a character string for use in error
|
|
|
C message.
|
|
|
C
|
|
|
C C_LAT_IN - Character String used to store R_LAT_IN
|
|
|
C as a character string for use in error
|
|
|
C message.
|
|
|
C
|
|
|
C C_LON_IN - Character String used to store R_LON_IN
|
|
|
C as a character string for use in error
|
|
|
C message.
|
|
|
C
|
|
|
C C_R - Character String used to store D_R
|
|
|
C as a character string for use in error
|
|
|
C message.
|
|
|
C
|
|
|
C C_REP_PARAMS - Character String used to store error
|
|
|
C message.
|
|
|
C
|
|
|
C
|
|
|
C C_ROUTINE_NAME - Character String containing name of
|
|
|
C subroutine generating error message.
|
|
|
C
|
|
|
C C_UNDEFINED - Character String used to store input data
|
|
|
C (R_HEIGHT, R_LAT_IN, R_LON_IN) as a
|
|
|
C character string for use in error message.
|
|
|
C
|
|
|
C D_CINT(,,) - Double Precision Array (3-D) -
|
|
|
C Contains the spherical harmonic coefficients
|
|
|
C interpolated to the input height, R_HEIGHT_IN.
|
|
|
C
|
|
|
C D_COEF(,,,) - Double Precision Array (3-D) -
|
|
|
C Contains the spherical harmonic coefficients
|
|
|
C used to compute the Cartesian coordinates of
|
|
|
C unit vector in the target coordinate system.
|
|
|
C
|
|
|
C First index: sp. harm. coeff. index
|
|
|
C Second x, y, z components of unit vector
|
|
|
C Third altitude indices
|
|
|
C Fourth direction of conversion index
|
|
|
C
|
|
|
C coefficients for a given altitude have the form
|
|
|
C
|
|
|
C a0 + h a1 + h^2 * a2 + h^3 * a3
|
|
|
C where h = alt/7000 [km]
|
|
|
C
|
|
|
C D_COLAT_INPUT - Double Precision - colatitude (radians) in the
|
|
|
C input coordinate system
|
|
|
C
|
|
|
C D_COLAT_OUTPUT - Double Precision - colatitude (radians) in the
|
|
|
C output coordinate system
|
|
|
C
|
|
|
C D_LON_INPUT - Double Precision - longitude (radians) in the
|
|
|
C input input system
|
|
|
C
|
|
|
C D_LON_OUTPUT - Double Precision - longitude (radians) in the
|
|
|
C output coordinate system
|
|
|
C
|
|
|
C D_R - Double Precision - magnitude of the
|
|
|
C unit radius vector in the target coordinate
|
|
|
C system. The target coordinate system is
|
|
|
C the system to which this subroutine is
|
|
|
C converting the latitude and longitude.
|
|
|
C
|
|
|
C D_X - Double Precision - the X-component of the
|
|
|
C unit radius vector in the target coordinate
|
|
|
C system
|
|
|
C
|
|
|
C D_Y - Double Precision - the Y-component of the
|
|
|
C unit radius vector in the target coordinate
|
|
|
C system
|
|
|
C
|
|
|
C D_Z - Double Precision - the Z-component of the
|
|
|
C unit radius vector in the target coordinate
|
|
|
C system
|
|
|
C
|
|
|
C D_YLMVAL - Double Precision - the array of spherical
|
|
|
C harmonic basis functions evaluated at
|
|
|
C a particular colatitude and longitude.
|
|
|
C
|
|
|
C
|
|
|
C I_COND_VALUE - Integer - the condition value returned from the
|
|
|
C call to SFC$$PUT_USER_MSG
|
|
|
C
|
|
|
C I_ERR64 - Logical - error flag for CGM_TO_ALTITUDE
|
|
|
C Routine.
|
|
|
C
|
|
|
C
|
|
|
C I_SYSTEM_ERR - Integer - Set to the value, SFC$$_NORMAL in
|
|
|
C all calls to SFC$$PUT_USER_MSG
|
|
|
C
|
|
|
C K - Integer - first index of the D_CINT
|
|
|
C interpolated spherical harmonic coefficient
|
|
|
C array.
|
|
|
C
|
|
|
C L - Integer - order of each spherical harmonic
|
|
|
C coefficient and spherical harmonic function.
|
|
|
C
|
|
|
C M - Integer - zonal index of the spherical
|
|
|
C harmonic functions.
|
|
|
C
|
|
|
C R_HEIGHT_OLD() - Real*4 Array (1-D) - Variable containing
|
|
|
C previous height (km) used to determine whether
|
|
|
C the interpolation to compute D_CINT() from
|
|
|
C D_COEF() needs to be done.
|
|
|
C
|
|
|
C R_LAT_ADJ - Real*4 Variable used to store result of
|
|
|
C ALTITUDE_TO_CGM or CGM_TO_ALTITUDE
|
|
|
C conversion.
|
|
|
C
|
|
|
C R_LAT_ALT - Real*4 Variable used to store at altitude
|
|
|
C dipole latitude.
|
|
|
C
|
|
|
C R_R - Real*4 - magnitude of unit vector (= D_R)
|
|
|
C (D_X, D_Y, D_Z) in single precision
|
|
|
C
|
|
|
C Constants:
|
|
|
C
|
|
|
C
|
|
|
C I_MAX_LENGTH - Integer - the length of the D_COEF(,,,)
|
|
|
C and D_YLMVAL spherical harmonic function
|
|
|
C arrays, corresponding to the order of the
|
|
|
C spherical harmonic expansion used.
|
|
|
C I_MAX_LENGTH = (I_ORDER + 1) * (I_ORDER + 1)
|
|
|
C
|
|
|
C I_MSGID - Integer - contains a message shell number of
|
|
|
C 4014 which will be used in all calls to
|
|
|
C SFC$$PUT_USER_MSG
|
|
|
C
|
|
|
C I_NUM_AXES - Integer - the number of axes in a Cartesian
|
|
|
C coordinate system (3)
|
|
|
C
|
|
|
C I_NUM_FLAG - Integer - the number of coordinate trans-
|
|
|
C formation flags available (2)
|
|
|
C
|
|
|
C I_NUM_LEVEL - Integer - the number of grid levels
|
|
|
C available. This is the number of
|
|
|
C distinct heights for which there are
|
|
|
C spherical harmonic coefficients available
|
|
|
C
|
|
|
C I_ORDER - Integer - the order of the spherical harmonic
|
|
|
C expansion used.
|
|
|
C
|
|
|
C DEGRAD - Double Precision - the multiplicative
|
|
|
C conversion factor for converting degrees
|
|
|
C to radians
|
|
|
C
|
|
|
C PI - Double Precision - mathematical constant
|
|
|
C
|
|
|
C Subroutines Required:
|
|
|
C
|
|
|
C RYLM - This subroutine returns the spherical harmonic
|
|
|
C function value array for a given colatitude and
|
|
|
C longitude. The spherical harmonics are returned
|
|
|
C in the D_YLMVAL array.
|
|
|
C
|
|
|
C CG_ALT_DIP - Given altitude (km), latitude, and a direction
|
|
|
C flag, returns altitude corrected latitude, and
|
|
|
C an error flag. See comments in subroutine for
|
|
|
C additional information.
|
|
|
C
|
|
|
C
|
|
|
C SFC$$PUT_USER_MSG - This subroutine is used to send error messages
|
|
|
C to the Message Handling System.
|
|
|
C
|
|
|
C Files Used at Compile Time:
|
|
|
C
|
|
|
C SFCLIB$$DEFS$$:SFC$$SFCDEF/LIST
|
|
|
C
|
|
|
C - This include file contains useful system
|
|
|
C constants and definitions. (eg. this is where
|
|
|
C SFC$$_NORMAL is defined)
|
|
|
C
|
|
|
C
|
|
|
C Files Used at Run Time: None
|
|
|
C
|
|
|
C
|
|
|
C Databases Accessed: None
|
|
|
C
|
|
|
C
|
|
|
C Warnings:
|
|
|
C
|
|
|
C 1. For certain values of Corrected Geomagnetic Coordinates, the
|
|
|
C transformation to Geographic Coordinates (Geocentric) is
|
|
|
C undefined. When this situation occurs, an error flag is set
|
|
|
C I_ERROR = -64 and returned to the calling routine.
|
|
|
C
|
|
|
C
|
|
|
C 2. This subroutine contains the non-standard include statement
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C Revision History:
|
|
|
C
|
|
|
C Original Routine, based upon the Kyle Baker routine was converted
|
|
|
C to a standard library subroutine for SFC$$ by MFS on 14 OCT 1992.
|
|
|
C
|
|
|
C 09/17/93 SPR1993-0203 (SWS) The return condition value needs to
|
|
|
C be initialized before coordinate conversion processing begins
|
|
|
C
|
|
|
C 08/18/93 SPR1993-0175 (SWS) Routine performed a comparison of
|
|
|
C Z with a -1.D0. The variable Z should be D_Z.
|
|
|
C
|
|
|
C The present routine represents the use of an improved algorithm for
|
|
|
C the computation of corrected geomagnetic coordinates and (where
|
|
|
C it exists) the inverse, together with the use of an updated
|
|
|
C magnetic field model (IGRF 1995).
|
|
|
C
|
|
|
C The present routine incorporates the functionality of Kyle Baker
|
|
|
C routine, and, uses the same subroutine calls. Relevent portions of
|
|
|
C the old FORTRAN code have been retained where possible.
|
|
|
C
|
|
|
C The new algorithm and the current code have been developed by
|
|
|
C Radex, Inc, 3 Preston Court, Bedford, MA 01730. A technical
|
|
|
C report describing the improved algorithm, and discussing its
|
|
|
C limitations is in preparation, and will be published in early
|
|
|
C 1997 as a Philips Laboratory technical report entitled:.
|
|
|
C
|
|
|
C An Expanded Algorithm for the Computation of Corrected Geomagnetic
|
|
|
C Coordinates, by C. Hein and K. Bhavnani.
|
|
|
C
|
|
|
C The principal changes implementing the new algorithm and code are
|
|
|
C as follows:
|
|
|
C
|
|
|
C (1) The set of spherical harmonic function values are computed
|
|
|
C recursively using a single call to a new subroutine RYLM
|
|
|
C rather than using repetitive function call. The Kyle Baker
|
|
|
C routine calculated each of the spherical harmonics separately
|
|
|
C as needed.
|
|
|
C
|
|
|
C Computationally the recursive caluclation is much faster.
|
|
|
C
|
|
|
C (2) The spherical harmonic coefficients are based upon
|
|
|
C the IGRF 95 magnetic field model. The order of the
|
|
|
C spherical harmonic expansion used here is 10 (previously
|
|
|
C was 4).
|
|
|
C
|
|
|
C (3) The coefficients represent a cubic fit to the spherical
|
|
|
C harmonic coefficients over a range of 24 altitudes from 0 to
|
|
|
C 7200 km. The previous (7/17/95) version used a quadratic fit
|
|
|
C at 0, 300 and 1200 km altitude, and had an allowable
|
|
|
C range of altitudes is 0 - 2000 km. The original Kyle Baker
|
|
|
C routine used polynomial interpolations of the coefficients
|
|
|
C at 0, 150, 300 and 450 km.
|
|
|
C
|
|
|
C (4) The spherical harmonic coefficients are computed in an
|
|
|
C auxilliary coordinate system, which is aligned with the
|
|
|
C desired target coordinate system. This results in a
|
|
|
C considerable simplification of the code, eliminating the
|
|
|
C need to perform multiple coordinate system rotations
|
|
|
C as was the case in the Kyle Baker routine.
|
|
|
C
|
|
|
C 07/17/95
|
|
|
C
|
|
|
C MODIFIED FOR THE IGRF 95 MAGNETIC FIELD MODEL.
|
|
|
C
|
|
|
C CHANGES: BLOCKDATA SECTION HAS BEEN REPLACED WITH COEFFICIENTS
|
|
|
C APPROPRIATE FOR THE IGRF 1995 MODEL
|
|
|
C
|
|
|
C REFERENCES TO IGRF 90 IN THE COMMENT LINES HAVE BEEN
|
|
|
C CHANGED TO IGRF 95.
|
|
|
C
|
|
|
C 07/01/96
|
|
|
C
|
|
|
C The BLOCKDATA section has been expanded to accomodate spherical
|
|
|
C harmonic coefficients for a cubic interpolation, in order to
|
|
|
C accomodate the expanded 0 - 7200 km altitude range. The
|
|
|
C spherical harmonic coefficients were caluclated on the basis
|
|
|
C of the IGRF 95 magnetic field model.
|
|
|
C
|
|
|
C **********************************************************************
|
|
|
C
|
|
|
C The version provided here does not include the BLOCK DATA source
|
|
|
C code. Instead individual BLOCK DATA files are provided as follows
|
|
|
C for the following Magnetic Field Models:
|
|
|
C
|
|
|
C Field Model File Name
|
|
|
c
|
|
|
C DGRF 1975 BLKDAT75.FOR
|
|
|
C DGRF 1980 BLKDAT80.FOR
|
|
|
C DGRF 1985 BLKDAT85.FOR
|
|
|
C DGRF 1990 BLKDAT90.FOR
|
|
|
C IGRF 1995 BLKDAT95.FOR
|
|
|
C
|
|
|
C Line 3 of the BLKDATxx.FOR files contains an identification field
|
|
|
C for the magnetic field model used to generate the coefficients.
|
|
|
C
|
|
|
C **********************************************************************
|
|
|
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
|
|
c
|
|
|
c RCS revision log for POSIX systems
|
|
|
c
|
|
|
c $Log: not supported by cvs2svn $
|
|
|
c Revision 1.1 2004/07/08 18:01:56 brideout
|
|
|
c files added to support AACGM conversion
|
|
|
c
|
|
|
c Revision 1.8 1997/11/14 19:27:49 baker
|
|
|
c implementation of modifications to extend the coordinate
|
|
|
c system to 7200 km in altitude.
|
|
|
c
|
|
|
c Revision 1.7 1997/10/28 21:04:24 baker
|
|
|
c There was an error in the value of PI that has been fixed.
|
|
|
c
|
|
|
c Revision 1.6 1996/03/20 22:53:03 baker
|
|
|
c Explicitly declared the sizes of the arguments to the
|
|
|
c subroutine. This should help avoid compatibility
|
|
|
c problems when mixing C and Fortran with different
|
|
|
c machines and different compilers.
|
|
|
c
|
|
|
c Revision 1.5 1996/03/12 18:59:18 baker
|
|
|
c Added code to force a recomputation of the
|
|
|
c conversion coefficients at a given ghheight if the
|
|
|
c coordinates model has changed from the last call.
|
|
|
c
|
|
|
c Revision 1.4 1996/03/11 19:25:36 baker
|
|
|
c Modifications for the 1995 version of AACGM.
|
|
|
c
|
|
|
c
|
|
|
c Revision 1.3 94/10/17 12:35:32 12:35:32 baker (Kile Baker S1G)
|
|
|
cadded error code -64 to indicate invalid magnetic coordinates specified
|
|
|
c as input. This also requires a change in the call to cg_alt_dip
|
|
|
c
|
|
|
c Revision 1.2 94/10/14 10:53:36 10:53:36 baker (Kile Baker S1G)
|
|
|
c Added the SAVE instruction to make variables static
|
|
|
c
|
|
|
c Revision 1.1 94/10/12 15:28:38 15:28:38 baker (Kile Baker S1G)
|
|
|
c Initial revision
|
|
|
c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C Set the order used in this algorithm to 10.
|
|
|
C
|
|
|
C
|
|
|
C Parameterize the maximum values of the indices of the
|
|
|
C spherical harmonic coefficient array D_COEF( , , , ) and the
|
|
|
C interpolated spherical harmonic coefficient array, D_CINT( , , ).
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
c
|
|
|
c The APL version of this code needs to keep track of
|
|
|
c the previous set of coefficients defining the conversion
|
|
|
c model (date). This is done by looking at the first coefficient
|
|
|
c in the model.
|
|
|
c
|
|
|
C
|
|
|
C CHARACTER*300 C_REP_PARAMS
|
|
|
C CHARACTER*8 C_LAT_IN
|
|
|
C CHARACTER*8 C_LON_IN
|
|
|
C CHARACTER*8 C_HEIGHT_IN
|
|
|
C CHARACTER*2 C_FLAG
|
|
|
C CHARACTER*6 C_R
|
|
|
C CHARACTER*70 C_UNDEFINED
|
|
|
C
|
|
|
C .. Parameters ..
|
|
|
DOUBLE PRECISION PI
|
|
|
PARAMETER (PI=3.141592653589793D0)
|
|
|
DOUBLE PRECISION DEGRAD
|
|
|
PARAMETER (DEGRAD=1.745329251994330D-2)
|
|
|
INTEGER I_ORDER
|
|
|
PARAMETER (I_ORDER=10)
|
|
|
INTEGER I_NUM_TERMS
|
|
|
PARAMETER (I_NUM_TERMS=121)
|
|
|
INTEGER I_NUM_AXES
|
|
|
PARAMETER (I_NUM_AXES=3)
|
|
|
INTEGER I_NUM_LEVEL
|
|
|
PARAMETER (I_NUM_LEVEL=5)
|
|
|
INTEGER I_NUM_FLAG
|
|
|
PARAMETER (I_NUM_FLAG=2)
|
|
|
C ..
|
|
|
C .. Scalar Arguments ..
|
|
|
DOUBLE PRECISION R_HEIGHT_IN,R_LAT_IN,R_LAT_OUT,R_LON_IN,R_LON_OUT
|
|
|
INTEGER I_ERROR,I_FLAG
|
|
|
C ..
|
|
|
C .. Local Scalars ..
|
|
|
DOUBLE PRECISION ALT_VAR,ALT_VAR_CU,ALT_VAR_QU,ALT_VAR_SQ,
|
|
|
* D_COLAT_INPUT,D_COLAT_OUTPUT,D_COLAT_TEMP,
|
|
|
* D_LON_INPUT,D_LON_OUTPUT,D_LON_TEMP,D_R,D_X,D_Y,
|
|
|
* D_Z,FIRST_COEFF_OLD,R_LAT_ADJ,R_LAT_ALT,R_R
|
|
|
INTEGER I,J,K,L,M
|
|
|
LOGICAL I_ERR64
|
|
|
C ..
|
|
|
C .. Local Arrays ..
|
|
|
DOUBLE PRECISION D_CINT(I_NUM_TERMS,I_NUM_AXES,I_NUM_FLAG),
|
|
|
* D_YLMVAL(I_NUM_TERMS),R_HEIGHT_OLD(2)
|
|
|
C ..
|
|
|
C .. External Subroutines ..
|
|
|
EXTERNAL ALTITUDE_TO_CGM,CGM_TO_ALTITUDE,RYLM
|
|
|
C ..
|
|
|
C .. Intrinsic Functions ..
|
|
|
INTRINSIC ABS,DACOS,DATAN2,DBLE,SQRT
|
|
|
C ..
|
|
|
C .. Common blocks ..
|
|
|
COMMON /SPH_HARM_MODEL/D_COEF
|
|
|
DOUBLE PRECISION D_COEF(I_NUM_TERMS,I_NUM_AXES,I_NUM_LEVEL,
|
|
|
* I_NUM_FLAG)
|
|
|
C ..
|
|
|
C .. Save statement ..
|
|
|
SAVE D_CINT,R_HEIGHT_OLD,FIRST_COEFF_OLD
|
|
|
C ..
|
|
|
C .. Data statements ..
|
|
|
C
|
|
|
C Initialize R_HEIGHT_OLD() to impossible values.
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
DATA R_HEIGHT_OLD(1)/-1.D0/
|
|
|
DATA R_HEIGHT_OLD(2)/-1.D0/
|
|
|
C ..
|
|
|
C **** DATA I_SYSTEM_ERR /SFC$$_NORMAL/
|
|
|
C
|
|
|
C
|
|
|
C
|
|
|
C The COMMON block / SPH_HARM_MODEL / array D_COEF contains
|
|
|
C the spherical harmonic coefficients used to generate the
|
|
|
C Cartesian coordinates of the unit vector in the target coordinate
|
|
|
C system. The target coordinate system is the system to which
|
|
|
C the algorithm is converting and is the coordinate system
|
|
|
C corresponding to the output variables, R_LAT_OUT and R_LON_OUT.
|
|
|
C
|
|
|
C The coefficient set is stored in a 4-dimensional array with
|
|
|
C indices defined as follows:
|
|
|
C
|
|
|
C First Index - Represents the number of terms used in the
|
|
|
C spherical harmonic expansion. Equal to
|
|
|
C (I_ORDER + 1) * (I_ORDER + 1)
|
|
|
C
|
|
|
C Second Index - Represents the Cartesian coordinate a particular
|
|
|
C coefficient will be used to generate. Indices are
|
|
|
C defined as follows:
|
|
|
C
|
|
|
C 1 - X-coordinate (the X-axis points from the
|
|
|
C center of the earth to where the prime
|
|
|
C meridian crosses the equator.
|
|
|
C
|
|
|
C 2 - Y-coordinate (the Y-axis points from the
|
|
|
C center of the earth to 90 degrees east
|
|
|
C of the X-axis)
|
|
|
C
|
|
|
C 3 - Z-coordinate (the Z-axis points from the
|
|
|
C center of the earth to the north pole)
|
|
|
C
|
|
|
C Third Index - Represents the terms of a quadratic fit to
|
|
|
C altitude (independent variable h =
|
|
|
C altitude [km]/1200) for a given spharical
|
|
|
C harmonic coefficient. The indices are defined
|
|
|
C as follows:
|
|
|
C
|
|
|
C 1 - Constant term: corresponds to the fit at
|
|
|
C 0 km altitude
|
|
|
C 2 - linear term
|
|
|
C 3 - quadratic term
|
|
|
C 4 - cubic term
|
|
|
C
|
|
|
C Fourth Index - Represents the direction of the coordinate
|
|
|
C transformation. Indices are defined as follows:
|
|
|
C
|
|
|
C 1 - Conversion of geographic coordinates to
|
|
|
C corrected geomagnetic coordinates.
|
|
|
C
|
|
|
C 2 - Conversion of corrected geomagnetic coordinates
|
|
|
C to geographic coordinates.
|
|
|
C
|
|
|
C
|
|
|
C The Data for D_COEF is provided in a BLOCK DATA file (see below)
|
|
|
C
|
|
|
C
|
|
|
C Initialize the error return condition indicator
|
|
|
C
|
|
|
I_ERROR = 0
|
|
|
C
|
|
|
C The APL version of this program allows the magnetic field
|
|
|
c model to change during the execution of the program.
|
|
|
c We therefore have to check to make sure that if the model
|
|
|
c has been changed that we recalculate the coordinate
|
|
|
c conversion coefficients.
|
|
|
C
|
|
|
C This IF statement checks to see if the magnetic
|
|
|
C coordinates model has been changed. If so, we
|
|
|
C have to force the recalculation of the conversion
|
|
|
C coefficients, by resetting the values of the old height
|
|
|
C
|
|
|
IF (FIRST_COEFF_OLD.NE.D_COEF(1,1,1,1)) THEN
|
|
|
R_HEIGHT_OLD(1) = -1
|
|
|
R_HEIGHT_OLD(2) = -1
|
|
|
END IF
|
|
|
FIRST_COEFF_OLD = D_COEF(1,1,1,1)
|
|
|
C
|
|
|
C
|
|
|
C The following IF-THEN-ELSE block checks the input arguments to
|
|
|
C ensure they are within allowable ranges. If any argument is
|
|
|
C outside the acceptable range, the error flag, I_ERROR will be
|
|
|
C set to some non-zero value, and control will be returned to the
|
|
|
C calling program.
|
|
|
C
|
|
|
IF ((R_HEIGHT_IN.LT.0.D0) .OR. (R_HEIGHT_IN.GT.7200.D0)) THEN
|
|
|
C
|
|
|
C The height in kilometers is outside the allowable range.
|
|
|
C
|
|
|
C Convert the height value R_HEIGHT_IN to a character string
|
|
|
C and send an error message to the user.
|
|
|
C
|
|
|
C WRITE(UNIT = C_HEIGHT_IN,
|
|
|
C $ FMT = '(F8.2)',
|
|
|
C $ IOSTAT = I_STATUS) R_HEIGHT_IN
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//'\\HEIGHT\\'//C_HEIGHT_IN
|
|
|
C PRINT *, C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
C Set the error flag to the appropriate value and return
|
|
|
C
|
|
|
I_ERROR = -2
|
|
|
RETURN
|
|
|
C
|
|
|
ELSE IF ((I_FLAG.LT.1) .OR. (I_FLAG.GT.2)) THEN
|
|
|
C
|
|
|
C The conversion flag is neither 1 nor 2.
|
|
|
C
|
|
|
C Convert I_FLAG to a character string C_FLAG and send an error
|
|
|
C message to the user
|
|
|
C
|
|
|
C WRITE(UNIT = C_FLAG,
|
|
|
C $ FMT = '(I2)',
|
|
|
C $ IOSTAT = I_STATUS) I_FLAG
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//'\\CONVERSION FLAG\\'//C_FLAG
|
|
|
C PRINT*,C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
C Set the error flag to the appropriate value and return
|
|
|
C
|
|
|
I_ERROR = -4
|
|
|
RETURN
|
|
|
C
|
|
|
ELSE IF (ABS(R_LAT_IN).GT.90.D0) THEN
|
|
|
C
|
|
|
C The latitude is outside the allowable range.
|
|
|
C
|
|
|
C Convert R_LAT_IN to a character string C_LAT_IN and send
|
|
|
C an error message to the user.
|
|
|
C
|
|
|
C WRITE(UNIT = C_LAT_IN,
|
|
|
C $ FMT = '(F8.2)',
|
|
|
C $ IOSTAT = I_STATUS) R_LAT_IN
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//'\\LATITUDE\\'//C_LAT_IN
|
|
|
C PRINT*,C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
C Set the error flag to the appropriate value and return
|
|
|
C
|
|
|
I_ERROR = -8
|
|
|
RETURN
|
|
|
C
|
|
|
ELSE IF ((R_LON_IN.LT.0.D0) .OR. (R_LON_IN.GT.360.D0)) THEN
|
|
|
C
|
|
|
C The longitude is outside the allowable range.
|
|
|
C
|
|
|
C Convert R_LON_IN into a character string C_LON_IN and send
|
|
|
C an error message to the user.
|
|
|
C
|
|
|
C WRITE(UNIT = C_LON_IN,
|
|
|
C $ FMT = '(F8.2)',
|
|
|
C $ IOSTAT = I_STATUS) R_LON_IN
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//'\\LONGITUDE\\'//C_LON_IN
|
|
|
C PRINT*,C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
C Set the error flag to the appropriate value and return
|
|
|
C
|
|
|
I_ERROR = -16
|
|
|
RETURN
|
|
|
C
|
|
|
END IF
|
|
|
C
|
|
|
C All input arguments are within allowable ranges.
|
|
|
C
|
|
|
C Compute Spherical Harmonic Coefficients for current
|
|
|
C altitude if required
|
|
|
C
|
|
|
IF (R_HEIGHT_IN.NE.R_HEIGHT_OLD(I_FLAG)) THEN
|
|
|
C
|
|
|
ALT_VAR = R_HEIGHT_IN/7200.0D0
|
|
|
ALT_VAR_SQ = ALT_VAR*ALT_VAR
|
|
|
ALT_VAR_CU = ALT_VAR*ALT_VAR_SQ
|
|
|
ALT_VAR_QU = ALT_VAR*ALT_VAR_CU
|
|
|
C
|
|
|
DO 20 I = 1,3
|
|
|
C
|
|
|
DO 10 J = 1,121
|
|
|
C
|
|
|
D_CINT(J,I,I_FLAG) = D_COEF(J,I,1,I_FLAG) +
|
|
|
* ALT_VAR*D_COEF(J,I,2,I_FLAG) +
|
|
|
* ALT_VAR_SQ*D_COEF(J,I,3,I_FLAG) +
|
|
|
* ALT_VAR_CU*D_COEF(J,I,4,I_FLAG) +
|
|
|
* ALT_VAR_QU*D_COEF(J,I,5,I_FLAG)
|
|
|
C
|
|
|
10 CONTINUE
|
|
|
C
|
|
|
20 CONTINUE
|
|
|
C
|
|
|
R_HEIGHT_OLD(I_FLAG) = R_HEIGHT_IN
|
|
|
C
|
|
|
END IF
|
|
|
C
|
|
|
C Zero Sums for Spherical Harmonic Expansion Computation
|
|
|
C
|
|
|
D_X = 0.0D0
|
|
|
D_Y = 0.0D0
|
|
|
D_Z = 0.0D0
|
|
|
C
|
|
|
C
|
|
|
C Prepare for Spherical Harmonic Expansion Computation
|
|
|
C
|
|
|
C
|
|
|
D_LON_INPUT = DBLE(R_LON_IN)*DEGRAD
|
|
|
C
|
|
|
IF (I_FLAG.EQ.1) THEN
|
|
|
C
|
|
|
C Computing CGM from Geographic Coordinates. No altitude
|
|
|
C correction required
|
|
|
C
|
|
|
D_COLAT_INPUT = (90.0D0-DBLE(R_LAT_IN))*DEGRAD
|
|
|
C
|
|
|
ELSE
|
|
|
C
|
|
|
C Computing Geographic Coordinates from CGM Coordinates.
|
|
|
C
|
|
|
C Convert CGM Latitude to Dipole Latitude at Altitude R_HEIGHT
|
|
|
C
|
|
|
CALL CGM_TO_ALTITUDE(R_HEIGHT_IN,R_LAT_IN,R_LAT_ADJ,I_ERR64)
|
|
|
C
|
|
|
IF (I_ERR64 .EQV. .TRUE.) THEN
|
|
|
C
|
|
|
C WRITE(UNIT = C_UNDEFINED,
|
|
|
C $ FMT = 90,
|
|
|
C $ IOSTAT = I_STATUS) R_LAT_IN, R_LON_IN, R_HEIGHT_IN
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//C_UNDEFINED
|
|
|
C PRINT*,C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
I_ERROR = -64
|
|
|
RETURN
|
|
|
END IF
|
|
|
C
|
|
|
D_COLAT_INPUT = (90.0D0-DBLE(R_LAT_ADJ))*DEGRAD
|
|
|
C
|
|
|
END IF
|
|
|
C
|
|
|
C Generate the spherical harmonics at the coordinate point
|
|
|
C
|
|
|
CALL RYLM(D_COLAT_INPUT,D_LON_INPUT,I_ORDER,D_YLMVAL)
|
|
|
C
|
|
|
C Calculate the Cartesian coordinates of the unit vector
|
|
|
C in the target coordinate system.
|
|
|
C
|
|
|
DO 40 L = 0,I_ORDER
|
|
|
DO 30 M = -L,L
|
|
|
C
|
|
|
K = L*(L+1) + M + 1
|
|
|
C
|
|
|
C Add the contribution of each spherical harmonic to the
|
|
|
C Cartesian components of the unit vector in the
|
|
|
C appropriate coordinate system.
|
|
|
C
|
|
|
C
|
|
|
D_X = D_X + D_CINT(K,1,I_FLAG)*D_YLMVAL(K)
|
|
|
D_Y = D_Y + D_CINT(K,2,I_FLAG)*D_YLMVAL(K)
|
|
|
D_Z = D_Z + D_CINT(K,3,I_FLAG)*D_YLMVAL(K)
|
|
|
C
|
|
|
30 CONTINUE
|
|
|
40 CONTINUE
|
|
|
C
|
|
|
C Compute the magnitude of the Cartesian unit vector of the
|
|
|
C magnetic dipole coordinate system.
|
|
|
C
|
|
|
D_R = SQRT(D_X*D_X+D_Y*D_Y+D_Z*D_Z)
|
|
|
C
|
|
|
C If the magnitude of the unit vector differs significantly
|
|
|
C from 1, set the error flag and continue processing.
|
|
|
C
|
|
|
IF ((D_R.LT.0.9D0) .OR. (D_R.GT.1.1D0)) THEN
|
|
|
C
|
|
|
C The magnitude of the target unit vector differs significantly
|
|
|
C from 1. Convert the value D_R into the character string C_R,
|
|
|
C send a routine message to the user, and continue processing.
|
|
|
C
|
|
|
R_R = D_R
|
|
|
C
|
|
|
C WRITE(UNIT = C_R,
|
|
|
C $ FMT = '(F6.2)',
|
|
|
C $ IOSTAT = I_STATUS) R_R
|
|
|
C
|
|
|
C C_REP_PARAMS = C_ROUTINE_NAME//'\\UNIT VECTOR\\'//C_R
|
|
|
C PRINT*,C_REP_PARAMS
|
|
|
C CALL PUT_USER_MSG(I_MSGID, C_CLASS, C_REP_PARAMS,
|
|
|
C $ I_SYSTEM_ERR, I_COND_VALUE)
|
|
|
C
|
|
|
C Set the error flag to the appropriate value and return.
|
|
|
C
|
|
|
I_ERROR = -32
|
|
|
RETURN
|
|
|
END IF
|
|
|
C
|
|
|
C Adjust the components so they do represent the components of
|
|
|
C a unit vector. If D_R is equal to 1.0D0, this step will not
|
|
|
C change the values of D_X, D_Y, or D_Z.
|
|
|
C
|
|
|
D_Z = D_Z/D_R
|
|
|
D_X = D_X/D_R
|
|
|
D_Y = D_Y/D_R
|
|
|
C
|
|
|
C Obtain output co_latitude and longitude from the unit
|
|
|
C vector using standard formulas
|
|
|
C
|
|
|
IF (D_Z.GT.1.0D0) THEN
|
|
|
D_COLAT_TEMP = 0.0D0
|
|
|
ELSE IF (D_Z.LT.-1.0D0) THEN
|
|
|
D_COLAT_TEMP = PI
|
|
|
ELSE
|
|
|
D_COLAT_TEMP = DACOS(D_Z)
|
|
|
END IF
|
|
|
C
|
|
|
IF ((ABS(D_X).LT.1.0D-8) .AND. (ABS(D_Y).LT.1.0D-8)) THEN
|
|
|
D_LON_TEMP = 0.0D0
|
|
|
ELSE
|
|
|
D_LON_TEMP = DATAN2(D_Y,D_X)
|
|
|
END IF
|
|
|
C
|
|
|
C Prepare Latitude Data for Output
|
|
|
C
|
|
|
D_LON_OUTPUT = D_LON_TEMP
|
|
|
C
|
|
|
IF (I_FLAG.EQ.1) THEN
|
|
|
C
|
|
|
R_LAT_ALT = 90.0D0 - D_COLAT_TEMP/DEGRAD
|
|
|
C
|
|
|
CALL ALTITUDE_TO_CGM(R_HEIGHT_IN,R_LAT_ALT,R_LAT_ADJ)
|
|
|
C
|
|
|
D_COLAT_OUTPUT = (90.0D0-DBLE(R_LAT_ADJ))*DEGRAD
|
|
|
C
|
|
|
ELSE
|
|
|
C
|
|
|
D_COLAT_OUTPUT = D_COLAT_TEMP
|
|
|
C
|
|
|
END IF
|
|
|
C
|
|
|
C Convert colatitude into latitude and convert both coordinates
|
|
|
C from DOUBLE PRECISION radians to REAL degrees.
|
|
|
C
|
|
|
R_LAT_OUT = 90.0D0 - D_COLAT_OUTPUT/DEGRAD
|
|
|
R_LON_OUT = D_LON_OUTPUT/DEGRAD
|
|
|
C
|
|
|
IF (R_LON_OUT.LT.0.0D0) R_LON_OUT = R_LON_OUT + 360.D0
|
|
|
C
|
|
|
C
|
|
|
RETURN
|
|
|
9000 FORMAT (' INVERSE UNDEFINED AT CGM LAT ',F6.2,' CGM LON ',F7.2,
|
|
|
* ' ALTITUDE ',F8.2)
|
|
|
END
|
|
|
|