
>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_mod.f90 <<<<<<<<<<<<<<<<<<<

module obs_mod

use constants_mod
use get_unit_mod
use obscode_mod

implicit none
save
private ! by default

! Public procedures:
public :: obs_ini, obs_write, obs_clear, obs_clear_resid, obs_sort, &
    obs_get, obs_put, obs_n_comment, obs_get_comment, obs_put_comment, &
    obs_epoch, read_ra, read_dec, obs_get_coords, put_resid, obs_complete, &
    obs_get_observatory, obs_put_observatory, obs_wrt_rec, obs_load
! Public variables:
public :: obsmsg, num_obs, max_files, max_obs, max_header, num_header, &
    header_comment, cmod_str, cmod_soln, obsgen_str
! Field sizes are public
public :: len_reject, len_obs_type, len_obs_code, len_rss_resid, &
    len_designation, len_time_str, len_ref, len_note, len_catalog, len_frame, &
    len_ra, len_dec, len_ra_sigma, len_ra_sigma_flag, len_ra_resid, &
    len_dec_sigma, len_dec_sigma_flag, len_dec_resid, len_mag_reject, &
    len_magnitude, len_mag_sigma, len_mag_sigma_flag, len_mag_resid, &
    len_discovery, len_obs_code_trx, len_bounce_pt, len_observable, len_freq, &
    len_sigma, len_sigma_flag, len_resid, len_comment, len_ert_delay

!===============================================================================
! This is the obs_mod observation manager. It is designed to be the sole 
! interface between all programs and any observation files. The public 
! variables are fairly limited; the module is designed so that access to the
! observational data is through public subroutines.
!
! The general scheme is that there are a number of internal arrays
! each of which can hold a single "file" of observations. Observations
! can be copied from one internal file to another, so that one may merge
! two observation sets by loading each into its own array, and then
! copying the contents of both arrays into a third scratch array. This
! copying is done one observation at a time.
!
! An observation may have associated comments. These comments are
! stored with the observation by the module and are accessed through the
! appropriate public routines in much the same way that the
! observational data is accessed.
!
! Public routines: 
! (detailed documentation is in the associated source file)
!    obs_ini         - load a file of observations, or open a scratch file
!    obs_write       - output a file to disk
!    obs_clear       - delete all of the observations from a file
!    obs_clear_resid - erase all of the residuals rfrom a file
!    obs_sort        - sort the observations in reveres chronological order
!    obs_get         - retrieve observational data
!    obs_put         - add/modify observational data
!    obs_n_comment   - get the number of comments associated with an observation
!    obs_get_comment - get a particular comment associated with an observation
!    obs_put_comment - append a comment to an observation's comment list
!    obs_epoch       - get the index of the earliest observation after an epoch
!    read_ra         - extract real RA in radians from sessagesimal string
!    read_dec        - extract real DEC in radians from sessagesimal string
!    obs_get_coords  - get the coordinates of the observatory
!    put_resid       - upload residuals and rejection flags to the obs_manager
!    obs_complete    - mark file as complete and upload fingerprints
!    obs_get_observatory - get the observatory data of an existing SAT/ROV obs
!    obs_put_observatory - upload the observatory of an existing SAT/ROV obs
!    obs_wrt_rec     - generates the observable record for a particular obs
!
! Public variables:
!    num_obs(i)         - The current number of obs in file 'i'
!    obsmsg             - Error message for diagnostics
!    max_files          - The maximum number of files that can be used (def=1)
!    max_obs            - The maximum number of obs in a file (parameter)
!    max_header         - The maximum number of freeform header comments 
!                         in a file (parameter)
!    obs_verbose        - Flag to turn on console output (def=.false.=silent)
!    num_header(i)      - The number of freeform header comments in file 'i'
!    header_comment(j,i)- The j-th header comment in file 'i'
!    cmod_str(i)        - The CMOD fingerprint for file 'i'
!    cmod_soln(i)       - The CMOD solution number for file 'i'
!    obsgen_str(i)      - The OBSTOM/MPC2OBS fingerprint for file 'i'
!
! Private routines:
!    is_comment   - (function) returns .true. if a record is a comment
!    open_memory  - allocates all necessary dynamic memory
!    get_time_utc - (function) returns the real value of an obs time string
!    get_str      - formats real sigma/residual values into character strings
!    check_index  - checks to see if the relevant internal file and obs is valid
!    obs_check    - does format checking of a loaded observation
!    allocate_obs - allocates an observation
!    
! Notes:
!     - The observation format is described in the nearby file README.format
!     - The max_files variable defaults to 1. If more files are needed this 
!       variable must be assigned before the first call to obs_ini.
!     - Each internal file has a flag called 'obs_complete_flag(i)' that 
!       is used to keep track of whether the file residuals are currently 
!       under revision (.false.) or if the residuals are fully consistent 
!       (.true.). This flag is set .true. by obs_ini when the file is 
!       initialized. A call to put_resid() checks this flag and if .true. 
!       all existing residuals are deleted and the flag set .false. 
!       Under normal operation, after all residuals have been updated, 
!       a call to obs_complete() will update the fingerprint of the calling
!       program and set the flag .true. The flag is also set to .true. by
!       obs_write() in case no call to obs_complete() is needed. If residuals 
!       are loaded via obs_put then the residual set could become inconsistent,
!       thus the calling program must take care to use either put_resid(), 
!       or ensure that only consistent residuals are loaded with obs_put().
!     - The file header contains some records that are formatted by the 
!       obs_mod module. The following items may appear:
!            VERSION - used internally to manage format changes
!            OBSGEN  - the fingerprint of the most recent program to generate 
!               the file (normally either mpc2obs or obs_merge)
!            CMOD    - the CMOD fingerprint
!            SOLN    - the CMOD solution number of the orbit
!       All of these except VERSION are loaded into the module either via 
!       obs_complete or through the respective public variables.
!     - Persistent header comments may be entered manually. Such comments 
!       must begin with '$' in column 1 and appear before any observation 
!       records. Conventional ('!') comments appearing before the first 
!       observation are permitted, but they will ignored by the module. 
!       No more than max_header records of this form are permitted.
!
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 16, 2000       Steve Chesley
!   - Improved checking of ra_sigma and dec_sigma fields in obs_check().
!   - Changed private parameter ref_time to public variable obs_ref_time.
!   - Changed default reference time from MJD to JD.
!   - Improved documentation.
!   - Made num_obs(i) private.
! Modified      Jun 19, 2000       Steve Chesley
!   - Added private routine allocate_obs().
!   - Added public variable 'verbose' to control console output.
!   - Eliminated public variable obs_ref_time.
!   - The ONLY reference time available is JD.
! Modified      Jun 20, 2000       Steve Chesley
!   - Reduced comment field length to 130
! Modified      Jun 23, 2000       Steve Chesley
!   - Added initializations to allocate_obs()
! Modified      Jul 12, 2000       Steve Chesley
!   - Fixed bug in get_str() related to large sigma values.
!   - Changed variable "verbose" to "obs_verbose".
! Modified      Aug 29, 2000       Steve Chesley
!   - Made num_obs public.
! Modified      Nov 14, 2000       Steve Chesley
!   - Added obs_wrt_rec routine.
! Modified      Mar 05, 2001       Steve Chesley
!   - Tweaked documentation.
!   - Fixed (another) bug in get_str() related to large residual values.
! Modified      Jul 30, 2001       Steve Chesley
!   - Obs format v. 1.1 to include ERT delay for S/C obs (type 'S').
! Modified      Sep 20, 2001       Alan B. Chamberlin
!   - added len_ert_delay parameter to public list
! Modified      Sep 26, 2001       Steve Chesley
!   - Added private variable tref, to allow loading time relative to 
!     t_ref in obs_ini. This also affects the calday call in get_time_utc.
! Modified      Feb 14, 2003       Steve Chesley
!   - Changed rad_time_fmt to fix bug in reading non-zero seconds.
! Modified      Sep 16, 2003       Steve Chesley
!   - Pointless change to documentation format
!
! $Id: obs_mod.f90,v 1.12 2003/09/25 22:19:25 chesley Exp $
!===============================================================================

!===============================================================================
!=================          FIELD SIZES               ==========================
!===============================================================================
! Generic fields
integer, parameter :: len_reject         = 1 
integer, parameter :: len_obs_type       = 1 
integer, parameter :: len_obs_code       = 3 
integer, parameter :: len_rss_resid      = 6 
integer, parameter :: len_designation    = 12
integer, parameter :: len_time_str       = 19
integer, parameter :: len_ref            = 6
! Optical fields                         
integer, parameter :: len_note           = 1
integer, parameter :: len_catalog        = 1
integer, parameter :: len_frame          = 1
integer, parameter :: len_ra             = 12
integer, parameter :: len_dec            = 12
integer, parameter :: len_ra_sigma       = 5
integer, parameter :: len_ra_sigma_flag  = 1
integer, parameter :: len_ra_resid       = 7
integer, parameter :: len_dec_sigma      = 5
integer, parameter :: len_dec_sigma_flag = 1
integer, parameter :: len_dec_resid      = 7
integer, parameter :: len_mag_reject     = 1
integer, parameter :: len_magnitude      = 7
integer, parameter :: len_mag_sigma      = 3
integer, parameter :: len_mag_sigma_flag = 1
integer, parameter :: len_mag_resid      = 5
integer, parameter :: len_discovery      = 1
integer, parameter :: len_ert_delay      = 10
! Radar fields                           
integer, parameter :: len_obs_code_trx   = 3
integer, parameter :: len_bounce_pt      = 1
integer, parameter :: len_observable     = 13
integer, parameter :: len_freq           = 13
integer, parameter :: len_sigma          = 5
integer, parameter :: len_sigma_flag     = 1
integer, parameter :: len_resid          = 7
! Misc. fields
integer, parameter :: len_comment        = 130
integer, parameter :: len_fingerprint    = 50

!===============================================================================
!=================          DATA TYPES                ==========================
!===============================================================================
type observation_pointer
  type(observation), pointer :: obs
end type observation_pointer

type observation
  character (len=len_reject)      :: reject
  character (len=len_obs_type)    :: obs_type 
  character (len=len_obs_code)    :: obs_code
  integer                         :: obs_code_index
  character (len=len_rss_resid)   :: rss_resid
  character (len=len_designation) :: designation
  character (len=len_time_str)    :: time_str
  character (len=len_ref)         :: ref
  real (kind=wp)                  :: time_utc
  type (opt_data_type), pointer   :: opt_data
  type (rad_data_type), pointer   :: rad_data
  type (comment_node), pointer    :: first_comment
  type (observatory_type), pointer:: observatory
end type observation

type comment_node
  character (len=len_comment)  :: comment
  type (comment_node), pointer :: next_comment
end type comment_node

type opt_data_type
  logical                            :: obs_hp_flag
  character (len=len_note)           :: note
  character (len=len_catalog)        :: catalog
  character (len=len_frame)          :: frame
  character (len=len_ra)             :: ra
  character (len=len_dec)            :: dec
  character (len=len_ra_sigma)       :: ra_sigma
  character (len=len_ra_sigma_flag)  :: ra_sigma_flag
  character (len=len_ra_resid)       :: ra_resid
  character (len=len_dec_sigma)      :: dec_sigma
  character (len=len_dec_sigma_flag) :: dec_sigma_flag
  character (len=len_dec_resid)      :: dec_resid
  character (len=len_mag_reject)     :: mag_reject
  character (len=len_magnitude)      :: magnitude
  character (len=len_mag_sigma)      :: mag_sigma
  character (len=len_mag_sigma_flag) :: mag_sigma_flag
  character (len=len_mag_resid)      :: mag_resid
  character (len=len_discovery)      :: discovery
  character (len=len_ert_delay)      :: ert_delay
end type opt_data_type

type rad_data_type                   
  character (len=len_obs_code_trx) :: obs_code_trx  
  integer                          :: obs_code_trx_index  
  character (len=len_bounce_pt)    :: bounce_pt     
  character (len=len_observable)   :: observable    
  character (len=len_freq)         :: freq          
  character (len=len_sigma)        :: sigma         
  character (len=len_sigma_flag)   :: sigma_flag    
  character (len=len_resid)        :: resid
end type rad_data_type

!===============================================================================
!=================          PUBLIC DATA               ==========================
!===============================================================================

! The maximum number of observations and freeform header comments in a file
! Halley has 8765 obs as of 2000.
integer, parameter :: max_obs = 9000
integer, parameter :: max_header = 5

! The number of internal arrays to initialize.
integer :: max_files = 1

! The current number of observations in each file index
integer, allocatable :: num_obs(:)

! Flag to turn on and off console output
logical :: obs_verbose = .false.

! Retrievable error message
character (len=180) :: obsmsg

! Header stuff
integer, allocatable :: num_header(:) ! Number of freeform comments
character (len=100), allocatable :: header_comment(:, :)
character (len=len_fingerprint), allocatable :: cmod_str(:), cmod_soln(:), &
    obsgen_str(:)
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_ini.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_ini(filename, errcod, file_num, tref)

character (len=*),           intent(in)  :: filename
integer,                     intent(out) :: errcod
integer,           optional, intent(in)  :: file_num
real (kind=wp),    optional, intent(in)  :: tref

!===============================================================================
! obs_ini loads a file of observations into an internal array
!
! Input:
!   filename - for input file. Use "" to initialize a scratch file.
! Output:
!   n_obs    - number of observations in the file
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
!   tref     - reference time in JD
!
! Notes:
!   - The max_files variable defaults to 1. If more files are needed this 
!     variable must be assigned before the first call to obs_ini.
!   - The file specified will be opened with status='old' and action='read'
!   - The observation pointer arrays (actually a matrix) are allocated on 
!     the first call with a call to the private routine 'open_memory'
!   - The file_ini_flag and file_complete_flag are both set to .true. on 
!     successful exit
!   - If obs_verbose is .true. then a short message indicating success is 
!     written to stdout.
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 16, 2000       Steve Chesley
!     - improved handling of roving obscodes.
! Modified      Jun 19, 2000       Steve Chesley
!     - changed to use allocate_obs()
! Modified      Jul 13, 2000       Steve Chesley
!     - added documentation.
!     - changed variable "verbose" to "obs_verbose"
! Modified      Aug 29, 2000       Steve Chesley
!     - Removed n_obs from calling sequence. (This can now be
! obtained 
!       through the public module variable num_obs).
! Modified      Nov 15, 2000       Steve Chesley
!     - Skip blank records before calling is_comment
! Modified      Jan 26, 2001       Steve Chesley
!     - Minor change in reporting of errcod 5.
! Modified      Jul 30, 2001       Steve Chesley
!     - Handle new version 1.1 with ERT delay in second record of SAT obs
!     - Don't warn when encountering obscode: "S/C".
! Modified      Sep 26, 2001       Steve Chesley
!     - Added optional argument tref
! Modified      Feb 10, 2004       Steve Chesley
!     - Added end_obs variable to deal with possible end-of-record comments.
!
! $Id: obs_ini.f90,v 1.8 2004/02/10 23:40:49 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_load.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_load(reject, obs_type, obs_code, time_utc, n_obs, errcod, &
   ra, ra_sig, dec, dec_sig, &
   freq, bounce_pt, obs_code_trx, file_num, tref)

! General Data
character (len=1),              intent(in)  :: reject
character (len=1),              intent(in)  :: obs_type
character (len=3),              intent(in)  :: obs_code
real (kind=wp),                 intent(in)  :: time_utc

! Output
integer,                        intent(out) :: n_obs
integer,                        intent(out) :: errcod

! Optical Obs
real (kind=wp),       optional, intent(in)  :: ra
real (kind=wp),       optional, intent(in)  :: ra_sig
real (kind=wp),       optional, intent(in)  :: dec
real (kind=wp),       optional, intent(in)  :: dec_sig

! Radar extensions
real (kind=wp),       optional, intent(in)  :: freq
character (len=1),    optional, intent(in)  :: bounce_pt
character (len=3),    optional, intent(in)  :: obs_code_trx

! Other
integer,              optional, intent(in)  :: file_num
real (kind=wp),       optional, intent(in)  :: tref

!===============================================================================
! obs_load loads input observations into an internal array
!
! Input:
!   reject   - Outlier rejection flag, (' ', 'a', 'D', or 'd')
!   obs_type - Observation type
!   obs_code - Observatory code
!   t_utc    - UTC time, days relative to t_ref
!
! Output:
!   errcod   - n_obs. Observation count, after loading the present observation.
!   errcod   - error code. Zero indicates success.
!
! Optional Input:
!   ra       - Right ascension - radians
!   ra_sig   - RA sigma - arcsec
!   dec      - Declination - radians
!   dec_sig  - DEC sigma - arcsec
!   freq     - Radar frequency, Hz
!   bounce_pt- Radar bounce point ('P' for peak-power, 'C' for center-of mass)
!   obs_code_trx - Observatory code of the transmitter
! 
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
!   tref     - reference time in JD
!
! Notes:
!   * Radar observations are not supported yet.
!   * Roving and satellite observations are not supported yet.
!
!-------------------------------------------------------------------------------
! Written       Mar. 01, 2005       Steve Chesley
!
! $Id: $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_sort.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_sort(errcod, file_num)

integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_sort sorts a module array in reverse chronological order.
!
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input: 
!   file_num - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jul 30, 2001       Steve Chesley
!     - Incorporate ert_delay into sorting for S/C observations.
!
! $Id: obs_sort.f90,v 1.3 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_put_observatory.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_put_observatory(i_obs, observatory, errcod, file_num)

integer,                           intent(in)  :: i_obs
type (observatory_type),           intent(in)  :: observatory
integer,                           intent(out) :: errcod
integer,                 optional, intent(in)  :: file_num

!===============================================================================
! obs_put_observatory is used to add the observatory data type to an existing 
!   satellite or roving observatory observation. The observation must already 
!   exist, and the obs_type must be 'V' or 'S'.
!
! Input:
!   i_obs       - index of the observation
!   observatory - the data to be loaded
! Output:
!   errcod      - error code. Zero indicates success.
! Optional Input:
!   file_num    - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       Jun 02, 2000       Steve Chesley
!
! $Id: obs_put_observatory.f90,v 1.3 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_put_comment.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_put_comment(i_obs, comment, errcod, i_comment, file_num)

integer,                     intent(in)  :: i_obs
character (len=*),           intent(in)  :: comment
integer,                     intent(out) :: errcod
integer,           optional, intent(in)  :: i_comment
integer,           optional, intent(in)  :: file_num

!===============================================================================
! obs_put_comment uploads a comment to the existing list of comments 
!   for a particular observation. It either appends, or overwrites the 
!   existing comment at i_comment.
!
! Input:
!   i_obs    - index of the observation to be commented
!   comment  - comment string
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   i_comment- specifies the target index for the uploaded comment.
!              Must be no more than one greater than the number of comments.
!   file_num - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Dec 15, 2000       Steve Chesley
!     - add i_comment optional arg to enable overwriting of comments
!
! $Id: obs_put_comment.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_n_comment.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_n_comment(i_obs, n_comment, errcod, file_num)

integer,           intent(in)  :: i_obs
integer,           intent(out) :: n_comment
integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_n_comment counts the number of comments associated with an observation.
!
! Input:
!   i_obs     - index of the observation in question
! Output:
!   n_comment - the number of comments present
!   errcod    - error code. Zero indicates success.
! Optional Input:
!   file_num  - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_n_comment.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_get_coords.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_get_coords(i_obs, coords_xyz, errcod, file_num, coords_xyz_trx)

integer,                   intent(in)  :: i_obs
real (kind=wp),            intent(out) :: coords_xyz(3)
integer,                   intent(out) :: errcod
integer,         optional, intent(in)  :: file_num
real (kind=wp),  optional, intent(out) :: coords_xyz_trx(3)

!===============================================================================
! obs_get_coords retrieves the observatory coordinates for a particular 
!    observation.
!
! Input:
!   i_obs          - index of the observation in question
! Output:
!   coords_xyz     - the geocentric XYZ coordinates in AU
!   errcod         - error code. Zero indicates success.
! Optional Input:
!   file_num       - specifies the internal obs_manager file (default=1)
! Optional Output:
!   coords_xyz_trx - the geocentric XYZ coordinates in AU of the 
!                    radar transmitter
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_get_coords.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_get_comment.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_get_comment(i_obs, i_comment, comment, errcod, file_num)

integer,                               intent(in)  :: i_obs
integer,                               intent(in)  :: i_comment
character (len=len_comment),           intent(out) :: comment
integer,                               intent(out) :: errcod
integer,                     optional, intent(in)  :: file_num

!===============================================================================
! obs_get_comment retrieves a particular comment from the existing list of 
!   comments for a particular observation.
!
! Input:
!   i_obs     - index of the observation in question
!   i_comment - index of the comment to be retrieved
! Output:
!   comment  - comment string
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_get_comment.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_complete.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_complete(errcod, file_num, cmod_string, cmod_solution, &
    obsgen_string)

integer,                     intent(out) :: errcod
integer,           optional, intent(in)  :: file_num
character (len=*), optional, intent(in)  :: cmod_string
character (len=*), optional, intent(in)  :: cmod_solution
character (len=*), optional, intent(in)  :: obsgen_string

!===============================================================================
! obs_complete does two things. In every case it sets the file_complete_flag 
!   to .T. to mark the end of residual updates. It optionally adds fingerprint 
!   information to the internal observation array for output to file.
!
! Output:
!   errcod     - error code. Zero indicates success.
! Optional Input:
!   file_num   - specifies the internal obs_manager file (default=1)
!   cmod_string   - the CMOD fingerprint
!   cmod_solution  - the CMOD solution number
!   obsgen_string - the MPC2OBS/OBSTOM fingerprint
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_complete.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_clear_resid.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_clear_resid(errcod, file_num)

integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_clear_resid clears all residuals for the specified module array
!
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_clear_resid.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_write.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_write (filename, errcod, file_num, file_status, &
    make_backup, single_format)

character (len=*),           intent(in)  :: filename
integer,                     intent(out) :: errcod
integer,           optional, intent(in)  :: file_num
character (len=*), optional, intent(in)  :: file_status
logical,           optional, intent(in)  :: make_backup
logical,           optional, intent(in)  :: single_format

!===============================================================================
! obs_write writes a module array to file. 
!
! Input:
!   filename      - for output file
! Output:
!   errcod        - error code. Zero indicates success.
! Optional Inputs:
!   file_num      - specifies the internal obs_manager file (default=1)
!   file_status   - passed directly to open statement (default='unknown')
!   make_backup   - If .true. and the file exists a backup copy will be made 
!                   by copying to a new file with '.bak' appended to the 
!                   filename. If .false. then no backup will be made. 
!                   (default = .true.)
!   single-format - should be set .false. to write each record in narrowest 
!                   possible format. If set to .true. the routine writes 
!                   entire file at same width (default=.true.)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 19, 2000       Steve Chesley
!    - Fixed bug with naming of backup file.
! Modified      Jun 29, 2000       Steve Chesley
!    - Changed rules associated with make_backup.
! Modified      Jun 30, 2000       Steve Chesley
!    - No trailing blanks.
! Modified      Jul 30, 2001       Steve Chesley
!    - Handle ert delay in second record of SAT obs.
!    - Sort observations before writing to file.
!
! $Id: obs_write.f90,v 1.5 2002/01/26 00:43:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_put.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_put(i_obs, errcod, file_num, &
    reject, obs_type, obs_code, rss_resid_real, rss_resid, designation, &
    time_str, ref, &
    note, catalog, frame, ra, dec, ra_sigma_real, &
    ra_sigma, ra_sigma_flag, ra_resid_real, ra_resid, dec_sigma_real, &
    dec_sigma, dec_sigma_flag, dec_resid_real, dec_resid, mag_reject, &
    magnitude, mag_sigma_real, mag_sigma, mag_sigma_flag, &
    mag_resid_real, mag_resid, discovery, &
    obs_code_trx, bounce_pt, observable, freq, &
    sigma_real, sigma, sigma_flag, resid_real, resid, &
    ert_delay_real)

integer,           intent(in)  :: i_obs
integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_put is used to add observational information to an obs_manager
!   array. It can be used to add a new observation or modify an existing
!   observation.
!
! Input:
!   i_obs    - index of the observation
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
!   [optional obs data inputs are specified by the declarations below]
!
! Notes:
!   - Data must be input as strings except all residual and sigma values, 
!     which may be input as either real or string, in either case the units 
!     are in arcsec.
!   - For SAT obs only, the time can be uploaded as a real (JD).
!   - New observations must be added at i_obs = num_obs(file_num) + 1.
!   - New observations must be added with a certain minimum of arguments:
!        all:    (reject, obs_type, obs_code, designation, time_str, ref)
!        optical:(note, catalog, frame, ra, ra_sigma[_real], ra_sigma_flag, 
!                 dec, dec_sigma[_real], dec_sigma_flag, magnitude, mag_reject, 
!                 mag_sigma[_real], mag_sigma_flag, discovery)
!        radar:  (obs_code_trx, bounce_pt, observable, freq, 
!                 sigma[_real], sigma_flag)
!   - If it is an existing observation then the obs_type argument must not be 
!     present for SAT, ROV, or radar observations, the idea being that you 
!     cannot change the type of such an observation.
!   - There is consistency checking to ensure that both radar and optical data 
!     is not modified by the same call.
!   - If the new or modified data fails the internal consistency checking, 
!     presumably due to a format error then the errcod will be negative, 
!     and the internal obs_manager file will be left in its original state.
!     Thus if the error code is negative, the user could be given the 
!     opportunity to reenter the data. The obsmsg string will indicate what 
!     was wrong with the input data.
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 19, 2000       Steve Chesley
!   - Fixed bug relating to computing ra_sigma string before computing 
!     obs_hp_flag.
!   - Changed to use allocate_obs().
! Modified      Jun 23, 2000       Steve Chesley
!   - If mag_sigma is present without magnitude it is ignored
! Modified      Jun 28, 2000       Steve Chesley
!   - If mag_sigma_flag is present without magnitude it is ignored
! Modified      Mar 23, 2001       Steve Chesley
!   - Allow changes to obs_type for all but SVRP types
! Modified      Jul 30, 2001       Steve Chesley
!   - Allow input of ert_delay_real
! Modified      Jan 24, 2002       Steve Chesley
!   - Documentation: Noted inefficiency of obs_check call.
!
! $Id: obs_put.f90,v 1.7 2002/01/26 00:43:10 chesley Exp $
!===============================================================================

! Arguments used for all obs types:
character (len=len_reject),         optional, intent(in) :: reject
character (len=len_obs_type),       optional, intent(in) :: obs_type
character (len=len_obs_code),       optional, intent(in) :: obs_code
real      (kind=wp),                optional, intent(in) :: rss_resid_real
character (len=len_rss_resid),      optional, intent(in) :: rss_resid
character (len=len_designation),    optional, intent(in) :: designation
character (len=len_time_str),       optional, intent(in) :: time_str
character (len=len_ref),            optional, intent(in) :: ref

! Optical only arguments:                               
character (len=len_note),           optional, intent(in) :: note
character (len=len_catalog),        optional, intent(in) :: catalog
character (len=len_frame),          optional, intent(in) :: frame
character (len=len_ra),             optional, intent(in) :: ra
character (len=len_dec),            optional, intent(in) :: dec
real      (kind=wp),                optional, intent(in) :: ra_sigma_real
character (len=len_ra_sigma),       optional, intent(in) :: ra_sigma
character (len=len_ra_sigma_flag),  optional, intent(in) :: ra_sigma_flag
real      (kind=wp),                optional, intent(in) :: ra_resid_real
character (len=len_ra_resid),       optional, intent(in) :: ra_resid
real      (kind=wp),                optional, intent(in) :: dec_sigma_real
character (len=len_dec_sigma),      optional, intent(in) :: dec_sigma
character (len=len_dec_sigma_flag), optional, intent(in) :: dec_sigma_flag
real      (kind=wp),                optional, intent(in) :: dec_resid_real
character (len=len_dec_resid),      optional, intent(in) :: dec_resid
character (len=len_mag_reject),     optional, intent(in) :: mag_reject
character (len=len_magnitude),      optional, intent(in) :: magnitude
real      (kind=wp),                optional, intent(in) :: mag_sigma_real
character (len=len_mag_sigma),      optional, intent(in) :: mag_sigma
character (len=len_mag_sigma_flag), optional, intent(in) :: mag_sigma_flag
real      (kind=wp),                optional, intent(in) :: mag_resid_real
character (len=len_mag_resid),      optional, intent(in) :: mag_resid
character (len=len_discovery),      optional, intent(in) :: discovery

! Radar only arguments:                                 
character (len=len_obs_code_trx),   optional, intent(in) :: obs_code_trx
character (len=len_bounce_pt),      optional, intent(in) :: bounce_pt
character (len=len_observable),     optional, intent(in) :: observable
character (len=len_freq),           optional, intent(in) :: freq
real      (kind=wp),                optional, intent(in) :: sigma_real
character (len=len_sigma),          optional, intent(in) :: sigma
character (len=len_sigma_flag),     optional, intent(in) :: sigma_flag
real      (kind=wp),                optional, intent(in) :: resid_real
character (len=len_resid),          optional, intent(in) :: resid

! SAT only
real (kind=wp),                     optional, intent(in) :: ert_delay_real
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_get_observatory.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_get_observatory(i_obs, observatory, errcod, file_num)

integer,                           intent(in)  :: i_obs
type (observatory_type),           intent(out) :: observatory
integer,                           intent(out) :: errcod
integer,                 optional, intent(in)  :: file_num

!===============================================================================
! obs_get_observatory is used to get the observatory data type of an existing 
!   satellite/roving observatory observation. The obs_type must be 'V' or 'S'.
!
! Input:
!   i_obs       - index of the observation
! Output:
!   observatory - the data to be loaded
!   errcod      - error code. Zero indicates success.
! Optional Input:
!   file_num    - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       Jun 02, 2000       Steve Chesley
!
! $Id: obs_get_observatory.f90,v 1.3 2002/01/26 00:43:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_get.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_get(i_obs, errcod, file_num, &
    reject, obs_type, obs_code, rss_resid_real, rss_resid, designation, &
    time_utc, time_str, ref, &
    note, catalog, frame, ra_real, ra, dec_real, dec, ra_sigma_real, &
    ra_sigma, ra_sigma_flag, ra_resid_real, ra_resid, dec_sigma_real, &
    dec_sigma, dec_sigma_flag, dec_resid_real, dec_resid, mag_reject, &
    magnitude, mag_sigma_real, mag_sigma, mag_sigma_flag, &
    mag_resid_real, mag_resid, discovery, &
    obs_code_trx, bounce_pt, observable_real, observable, freq_real, freq, &
    sigma_real, sigma, sigma_flag, resid_real, resid, &
    ert_delay, ert_delay_real)

integer,           intent(in)  :: i_obs
integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_get is used to retrieve observational information from an obs_manager
!   array.
!
! Input:
!   i_obs    - index of the observation
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input:
!   file_num - specifies the internal obs_manager file (default=1)
! Optional Outputs:
!   [optional obs data outputs are specified by the declarations below]
!
! Note:
!   - All data may be retrieved as strings, additionally the following 
!     can be retrieved in real format:
!        - all residual and sigma fields (in arcsec for optical astrometry)
!        - observation time (JD)
!        - ERT dealy time (SAT obs only)
!        - ra and dec (radians if real, sessagesimal if string)
!        - radar observable (Hz, or microsec as appropriate)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! Modified      Jul 30, 2001       Steve Chesley
!     - Added ert_delay, ert_delay_real arguments.
!
! $Id: obs_get.f90,v 1.5 2002/01/26 00:43:10 chesley Exp $
!===============================================================================

! Arguments used for all obs types:
character (len=len_reject),         optional, intent(out) :: reject
character (len=len_obs_type),       optional, intent(out) :: obs_type
character (len=len_obs_code),       optional, intent(out) :: obs_code
real      (kind=wp),                optional, intent(out) :: rss_resid_real
character (len=len_rss_resid),      optional, intent(out) :: rss_resid
character (len=len_designation),    optional, intent(out) :: designation
real      (kind=wp),                optional, intent(out) :: time_utc
character (len=len_time_str),       optional, intent(out) :: time_str
character (len=len_ref),            optional, intent(out) :: ref

! Optical only arguments:                                
character (len=len_note),           optional, intent(out) :: note
character (len=len_catalog),        optional, intent(out) :: catalog
character (len=len_frame),          optional, intent(out) :: frame
real      (kind=wp),                optional, intent(out) :: ra_real
character (len=len_ra),             optional, intent(out) :: ra
real      (kind=wp),                optional, intent(out) :: dec_real
character (len=len_dec),            optional, intent(out) :: dec
real      (kind=wp),                optional, intent(out) :: ra_sigma_real
character (len=len_ra_sigma),       optional, intent(out) :: ra_sigma
character (len=len_ra_sigma_flag),  optional, intent(out) :: ra_sigma_flag
real      (kind=wp),                optional, intent(out) :: ra_resid_real
character (len=len_ra_resid),       optional, intent(out) :: ra_resid
real      (kind=wp),                optional, intent(out) :: dec_sigma_real
character (len=len_dec_sigma),      optional, intent(out) :: dec_sigma
character (len=len_dec_sigma_flag), optional, intent(out) :: dec_sigma_flag
real      (kind=wp),                optional, intent(out) :: dec_resid_real
character (len=len_dec_resid),      optional, intent(out) :: dec_resid
character (len=len_mag_reject),     optional, intent(out) :: mag_reject
character (len=len_magnitude),      optional, intent(out) :: magnitude
real      (kind=wp),                optional, intent(out) :: mag_sigma_real
character (len=len_mag_sigma),      optional, intent(out) :: mag_sigma
character (len=len_mag_sigma_flag), optional, intent(out) :: mag_sigma_flag
real      (kind=wp),                optional, intent(out) :: mag_resid_real
character (len=len_mag_resid),      optional, intent(out) :: mag_resid
character (len=len_discovery),      optional, intent(out) :: discovery

! Radar only arguments:                                  
character (len=len_obs_code_trx),   optional, intent(out) :: obs_code_trx    
character (len=len_bounce_pt),      optional, intent(out) :: bounce_pt       
real      (kind=wp),                optional, intent(out) :: observable_real 
character (len=len_observable),     optional, intent(out) :: observable      
real      (kind=wp),                optional, intent(out) :: freq_real       
character (len=len_freq),           optional, intent(out) :: freq            
real      (kind=wp),                optional, intent(out) :: sigma_real      
character (len=len_sigma),          optional, intent(out) :: sigma           
character (len=len_sigma_flag),     optional, intent(out) :: sigma_flag      
real      (kind=wp),                optional, intent(out) :: resid_real      
character (len=len_resid),          optional, intent(out) :: resid

! Satellite only arguments
character (len=len_ert_delay),      optional, intent(out) :: ert_delay
real      (kind=wp),                optional, intent(out) :: ert_delay_real
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_clear.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_clear(errcod, file_num)

integer,           intent(out) :: errcod
integer, optional, intent(in)  :: file_num

!===============================================================================
! obs_clear removes all observations from an internal array
!
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Input: 
!   file_num - specifies the internal obs_manager file (default=1)
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
!
! $Id: obs_clear.f90,v 1.3 2002/01/26 00:43:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_wrt_rec.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_wrt_rec (obs_index, file_index, record, errcod, &
                        write_hp, no_resid)

integer,           intent(in)  :: obs_index
integer,           intent(in)  :: file_index
character (len=*), intent(out) :: record
integer,           intent(out) :: errcod
logical, optional, intent(in)  :: write_hp
logical, optional, intent(in)  :: no_resid

!===============================================================================
! obs_wrt_rec generates the main observation record in the obs_mod format
!
! Input:
!   obs_index       - observation index
!   file_index      - file index
! Output:
!   record        - the composed record
!   errcod        - error code. Zero indicates success.
! Optional Inputs:
!   write_hp      - Write the record in high precision format no matter what. 
!                   If set .false. then only high precision observations will 
!                   be written in high precision format. (Default: .false.)
!   no_resid      - Force all residuals fields to be output blank.
!-------------------------------------------------------------------------------
! Written       Nov 14, 2000       Steve Chesley
! Modified      Mar 11, 2002       Alan B. Chamberlin
!  - added no_resid argument for use by merge_obs.
!
! $Id: obs_wrt_rec.f90,v 1.3 2002/03/13 18:53:02 chamber Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/obs_epoch.f90 <<<<<<<<<<<<<<<<<<<

subroutine obs_epoch(epoch_jd, errcod, compute_epoch, file_num, i_obs)

real (kind=wp),           intent(inout) :: epoch_jd
integer,                  intent(out)   :: errcod
logical,        optional, intent(in)    :: compute_epoch
integer,        optional, intent(in)    :: file_num
integer,        optional, intent(out)   :: i_obs

!===============================================================================
! obs_epoch can optionally do either or both of two things. 
!    1) It computes the central epoch of an observation set, using the
!       weighted mean of the observations. This is always done unless 
!       the optional argument compute_epoch is .false.
!    2) If the optional argument i_obs is present it computes the index 
!       of the earliest observation after the specified or computed epoch.
!       If i_obs > num_obs then all observations are before the epoch.
!
! Input/Output:
!   epoch_jd - the desired epoch in JD. If compute_epoch is .false. 
!      this is an input. Otherwise, it is computed as the weighted midpoint 
!      of the available arc.
! Output:
!   errcod   - error code. Zero indicates success.
! Optional Inputs:
!   compute_epoch - This flag tells the routine whether the first 
!        argument (epoch_jd) is input or an output. (default=.true.)
!   file_num - specifies the internal obs_manager file (default=1)
! Optional Outputs:
!   i_obs - the index of the earliest observation after 'epoch'
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 19, 2000       Steve Chesley
!    - Eliminated optional time_ref argument so that the input epoch 
!      must always be in JD.
! Modified      Sep 05, 2000       Steve Chesley
!    - Added compute_epoch argument and code to compute the epoch if requested.
! Modified      Sep 15, 2000       Steve Chesley
!    - Changed the calling sequence again. Now compute_epoch and i_obs are 
!      optional arguments.
!
! $Id: obs_epoch.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/read_ra.f90 <<<<<<<<<<<<<<<<<<<

subroutine read_ra(ra_string, ra_real, errcod, ra_precision)

character (len=*),           intent(in)  :: ra_string
real (kind=wp),              intent(out) :: ra_real
integer,                     intent(out) :: errcod
real (kind=wp),    optional, intent(out) :: ra_precision

!===============================================================================
! read_ra converts a string sessagesimal right ascension to a real right 
!   ascencion in radians.
!
! Inputs:
!   ra_string    - the input string, sessagesimal format: 
!                 'HHMMSS.sssss' or 'HHMM.mmmmmm '
! Outputs:
!   ra_real      - ra in radians (-pi to pi)
!   errcod       - error code. Zero indicates success.
! Optional Outputs:
!   ra_precision - the significance of the last digit in seconds of *time*
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 13, 2000       Steve Chesley
!     - allow fields without decimal point
! Modified      Jan 10, 2001       Alan B. Chamberlin
!     - fixed bug related to detecting decimal minutes properly
! Modified      Mar 05, 2001       Steve Chesley
!     - enforced -pi < ra_real < pi
! Modified      Sep 19, 2001       Alan B. Chamberlin
!     - removed the previous modification (now: 0 <= ra_real < 2*pi)
!
! $Id: read_ra.f90,v 1.6 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/read_dec.f90 <<<<<<<<<<<<<<<<<<<

subroutine read_dec(dec_string, dec_real, errcod, dec_precision)

character (len=*),           intent(in)  :: dec_string
real (kind=wp),              intent(out) :: dec_real
integer,                     intent(out) :: errcod
real (kind=wp),    optional, intent(out) :: dec_precision

!===============================================================================
! read_dec converts a string sessagesimal declination to a real declination 
!   in radians.
!
! Inputs:
!   dec_string    - the input string, sessagesimal format: 
!                 'GDDMMSS.ssss' or 'GDDMM.mmmmm '
! Outputs:
!   dec_real      - dec in radians
!   errcod        - error code. Zero indicates success.
! Optional Output:
!   dec_precision - the significance of the last digit in seconds of *arc*
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Jun 13, 2000       Steve Chesley
!     - allow fields without decimal point
! Modified      Jun 28, 2000       Steve Chesley
!     - added format check on sign character in declination
! Modified      Jan 10, 2001       Alan B. Chamberlin
!     - fixed bug related to detecting decimal minutes proberly
!
! $Id: read_dec.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================

>>>>>>>>>>>>>>>>>>> FILE: ../obs_mod/put_resid.f90 <<<<<<<<<<<<<<<<<<<

subroutine put_resid(i_obs, errcod, file_num, rss_resid, ra_resid, dec_resid, &
    resid, reject, mag_reject, mag_resid)

integer,                                  intent(in)  :: i_obs
integer,                                  intent(out) :: errcod
integer,                        optional, intent(in)  :: file_num
real (kind=wp),                 optional, intent(in)  :: rss_resid
real (kind=wp),                 optional, intent(in)  :: ra_resid
real (kind=wp),                 optional, intent(in)  :: dec_resid
real (kind=wp),                 optional, intent(in)  :: resid
character (len=len_reject),     optional, intent(in)  :: reject
character (len=len_mag_reject), optional, intent(in)  :: mag_reject
real (kind=wp),                 optional, intent(in)  :: mag_resid

!===============================================================================
! put_resid is used to update the residuals and rejection flag for an 
!   obs_manager observation.
!
! Input:
!   i_obs     - index of the observation
! Output:
!   errcod    - error code. Zero indicates success.
! Optional Input:
!   file_num  - specifies the internal obs_manager file (default=1)
!   rss_resid - Weighted (i.e., dimensionless) RSS residual
!   ra_resid  - RA residual
!   dec_resid - DEC residual
!   resid     - radar residual
!   reject    - the outlier rejection flag (aka accept/delete character)
!   mag_reject- magnitude outlier rejection flag
!   mag_resid - magnitude residual
!
! Notes:
!   - errcod and obsmsg are set by obs_put.
!   - If file_complete_flag is .T. on entry then it calls obs_clear_resid.
!   - In every case file_complete_flag is false upon exit.
!   - If ever yuo wanted to only update the magnitude data without altering 
!     the astrometry information you must not use this routine as it clears 
!     all residuals.
!-------------------------------------------------------------------------------
! Written       May 31, 2000       Steve Chesley
! Modified      Oct 09, 2000       Steve Chesley
!    - Added mag_reject and mag_resid as optional arguments.
!
! $Id: put_resid.f90,v 1.2 2002/01/25 23:12:10 chesley Exp $
!$==============================================================================
