!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! TELCAL type definition modules, initialization and copy routines
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module fit_definitions
  !----------------------------------------------------------------------
  ! @ public
  ! TELCAL support module
  ! Purpose: Definitions of FIT derived types
  !----------------------------------------------------------------------
  !
  type simple_1d ! Data vector (simple precision, 1d)
     integer(kind=4)       :: n             ! Number of data
     real(kind=8), pointer :: x(:)=>null()  ! Abcissae (in)
     real(kind=8), pointer :: y(:)=>null()  ! Values   (in)
     real(kind=8), pointer :: w(:)=>null()  ! Weights  (in)
     real(kind=8), pointer :: d(:)=>null()  ! derivative of x with time, Not always allocated
  end type simple_1d
  !
  type fit_par ! Description of a fitted parameter
     character(len=32) :: name     ! Parameter name          (in)
     real(kind=8)      :: guess    ! Guess                   (in)
     real(kind=8)      :: value    ! Fit value               (out)
     real(kind=8)      :: error    ! Fit uncertainty         (out)
     real(kind=8)      :: mini     ! Minimum possible value  (in)
     real(kind=8)      :: maxi     ! Maximum possible value  (in)
     logical           :: fixed    ! Is the parameter fixed? (in)
     logical           :: padding  ! Padding for structure alignment
  end type fit_par
  !
  type fit_fun ! Description of a fitted function
     character(len=16)      :: name            ! Fitted function name (eg GAUSSIAN)
     character(len=16)      :: method          ! Fitting library (eg SLATEC)
     real(kind=4)           :: chi2            ! Fit chi square
     real(kind=4)           :: rms             ! Residual RMS
     integer(kind=4)        :: flag            ! Error/Quality code
     integer(kind=4)        :: ncall           ! Number of iterations
     integer(kind=4)        :: npar            ! Number of fitted parameters
     type(fit_par), pointer :: par(:)=>null()  ! Array of parameter descriptions
  end type fit_fun
  !
  type fit_var ! Variable fitted parameters only
     integer(kind=4)          :: n               ! Number
     real(kind=8),    pointer :: x(:)=>null()    ! Values
     real(kind=8),    pointer :: d(:)=>null()    ! Errors
     integer(kind=4), pointer :: idx(:)=>null()  ! Position index inside full parameter vector
  end type fit_var
  !
end module fit_definitions
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! User interface derived type definitions
!
module user_guess_definitions
  !----------------------------------------------------------------------
  ! TELCAL support module
  ! Purpose: Definition of types linked to user guess of fit parameters
  !----------------------------------------------------------------------
  type guess_t
     real(kind=8) :: value ! Fit value
     logical :: fixed ! Is the parameter fixed?
     logical :: padding
  end type guess_t
end module user_guess_definitions
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! POINTING derived type definitions
!
module point_definitions
  use fit_definitions
  use user_guess_definitions
  !----------------------------------------------------------------------
  ! TELCAL support module for pointing
  !----------------------------------------------------------------------
  !
  type point_guess_t
     type(guess_t) :: offset       ! 1st order baseline offset
     type(guess_t) :: slope        ! 1st order baseline slope
     type(guess_t) :: area         ! 1st Gaussian area
     type(guess_t) :: position     ! 1st Gaussian position
     type(guess_t) :: width        ! 1st Gaussian width
     type(guess_t) :: beam_throw   ! Beam  throw in dual beam case
     type(guess_t) :: area_ratio   ! Area  ratio in dual beam case
     type(guess_t) :: width_ratio  ! Width ratio in dual beam case
  end type point_guess_t
  !
  type pointing_t
     integer(kind=4) :: sys   ! Scanning coordinate system
     character(16)   :: dir   ! Scanning directions
     character(16)   :: type  ! Pointing kind (SINGLE or DUAL)
     type(simple_1d) :: dat   ! Data vectors
     type(simple_1d) :: sol   ! Solution vectors
     type(fit_fun)   :: fun   ! Fit functions
  end type pointing_t
  !
end module point_definitions
!
module pcross_definitions
  use point_definitions
  !----------------------------------------------------------------------
  ! TELCAL support module for pointing through a cross
  ! The pcross array is saved because a SIC structure will be mapped on it
  !----------------------------------------------------------------------
  !
  integer(kind=4), parameter :: mcross = 16     ! Maximum number of cross subscans
  integer(kind=4)            :: ncross          ! Actual  number of cross subscans
  type(pointing_t), save     :: pcross(mcross)  ! Array of pointing structures
  !
end module pcross_definitions
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! FOCUS derived type definitions
!
module focus_definitions
  use fit_definitions
  !----------------------------------------------------------------------
  ! TELCAL support module for focus
  !----------------------------------------------------------------------
  !
  type focus
     integer(kind=4) :: sys    ! Scanning coordinate system
     character(16)   :: dir(2) ! Scanning directions
     type(simple_1d) :: dat(2) ! Data vectors
     type(simple_1d) :: sol(2) ! Solution vectors
     type(fit_fun)   :: fun(2) ! Fit functions
  end type
  !
  type(focus), save :: zfocus
  !
end module focus_definitions
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! CHOPPER derived type definitions
!
module chopper_definitions
  !----------------------------------------------------------------------
  ! TELCAL support module for chopper wheel calibration
  !----------------------------------------------------------------------
  !
  ! Parameters for searching water
  integer(kind=4), parameter :: chopper_water_fixed=0  ! Fixed water, no minimization
  integer(kind=4), parameter :: chopper_water_elem=1   ! Free water, 1 per frequency
  integer(kind=4), parameter :: chopper_water_set=2    ! Free water, 1 for all frequencies
  !
  ! Flags used in telcal_chopper and associated subroutines
  integer(kind=4), parameter :: flag_valid=0
  integer(kind=4), parameter :: flag_nosky=1
  integer(kind=4), parameter :: flag_badatm=2
  integer(kind=4), parameter :: flag_calfailed=3
  !
  type chop_mode !
     logical         :: strict = .true.              ! Should telcal_chopper be strict or tolerant?
     integer(kind=4) :: water  = chopper_water_elem  ! Search mode for water?
     logical         :: atm    = .true.              ! Compute opacities?
     logical         :: trec   = .true.              ! Compute trec?
     logical         :: tcal   = .true.              ! Compute tcal?
     logical         :: tsys   = .true.              ! Compute tsys?
  end type chop_mode
  !
  type telescope ! Site description
     real(kind=8) :: alti = 0d0 ! [  km] Telescope altitude
     real(kind=8) :: lati = 0d0 ! [ rad] Telescope latitude
     real(kind=8) :: elev = 0d0 ! [ rad] Telescope elevation
     real(kind=8) :: hwat = 0d0 ! [  km] Water scale height
     real(kind=8) :: tout = 0d0 ! [   K] Outside temperature
     real(kind=8) :: tcab = 0d0 ! [   K] Cabin   temperature
     real(kind=8) :: pres = 0d0 ! [mbar] Ambiant pressure
  end type telescope
  !
  type dsb_value ! (e.g. frequency, temperature)
     real(kind=8) :: s = 0d0 ! Signal value
     real(kind=8) :: i = 0d0 ! Image  value
  end type dsb_value
  !
  type mixer ! Comment: feff+fout+fcab = 1.0
     real(kind=8) :: sbgr = 0d0 ! [   ] Sideband gain ratio
     real(kind=8) :: beff = 0d0 ! [   ] Beam efficiency
     real(kind=8) :: feff = 1d0 ! [   ] Forward efficiency
     real(kind=8) :: fout = 0d0 ! [   ] Coupling to ground
     real(kind=8) :: fcab = 0d0 ! [   ] Coupling to cabin
     real(kind=8) :: temp = 0d0 ! [  K] Noise temperature
  end type mixer
  !
  type chop_load ! Load description
     real(kind=8) :: count = 0d0 ! [ ] Power expressed in counts
     real(kind=8) :: temp  = 0d0 ! [K] Power expressed in Rayleigh-Jeans temperature
     real(kind=8) :: ceff  = 1d0 ! [ ] Coupling. Comment: 1-coupling = sky coupling
  end type chop_load
  !
  type chop_meas ! Measurements to perform a "chopper" calibration
     real(kind=8)    :: dark_count = 0d0 ! [ ] Dark power expressed in counts
     real(kind=8)    ::  sky_count = 0d0 ! [ ] Sky  power expressed in counts
     type(chop_load) :: cold             ! [ ] Cold load description
     type(chop_load) :: hot              ! [ ] Hot  load description
  end type chop_meas
  !
  integer, parameter :: msky=10
  type skydip_meas ! Measurements to perform a skydip reduction
     type(dsb_value) :: freq         ! [MHz] Signal and Image frequencies
     integer(kind=4) :: nsky         ! [   ] Number of sky measurements
     real(kind=8)    :: elev(msky)   ! [rad] Elevations
     type(chop_load) :: emiss(msky)  !       Power (counts and temp) measured
     integer(kind=4) :: nhot         ! [   ] Number of hot load measurements
     type(chop_load) :: hot(msky)    !       Power (counts and temp) on hot load (chopper)
     integer(kind=4) :: ncold        ! [   ] Number of cold load measurements
     type(chop_load) :: cold(msky)   !       Power (counts and temp) on cold load
  end type skydip_meas
  !
  type opacity !
     real(kind=8) :: wat = 0d0 ! [neper] Opacity due to water
     real(kind=8) :: oth = 0d0 ! [neper] Opacity due to other components
     real(kind=8) :: tot = 0d0 ! [neper] Total opacity
  end type opacity
  !
  type atm_prop ! Atmospheric properties
     real(kind=8) :: airmass = 0d0 ! [     ] Air mass number (about 1/sin(elev))
     real(kind=8) :: h2omm   = 0d0 ! [   mm] Zenith water vapor content
     type(opacity)   :: taus ! [neper] Zenith opacities at signal frequency
     type(opacity)   :: taui ! [neper] Zenith opacities at image  frequency
     type(dsb_value) :: temp ! [    K] Sky mean     temperatures (signal and image)
     type(dsb_value) :: temi ! [    K] Sky emission temperatures (signal and image)
  end type atm_prop
  !
  type chopper_t !
     type(chop_mode)          :: search              ! [] Control routine behaviour
     type(telescope)          :: tel                 ! [] Site description
     integer(kind=4)          :: n = 0               ! [] Array size
     real(kind=8)             :: bad                 ! [] Bad value for all floating points here
     type(dsb_value), pointer :: freqs(:) => null()  ! [] Frequencies
     type(chop_meas), pointer :: loads(:) => null()  ! [] Load description
     type(mixer),     pointer :: recs(:) => null()   ! [] Receiver description
     type(atm_prop),  pointer :: atms(:) => null()   ! [] Properties of the atmosphere
     type(dsb_value), pointer :: tcals(:) => null()  ! [] Calibration temperatures
     type(dsb_value), pointer :: tsyss(:) => null()  ! [] System temperatures
     type(dsb_value), pointer :: atsyss(:) => null() ! [] System temperatures attenuated by the atmosphere (= Tsys * exp(-airmass*tauzen))
     logical,         pointer :: errors(:) => null() ! []
  end type chopper_t
  !
end module chopper_definitions
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
