!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module uvmap_types
  use gbl_message
  !
  public :: uvmap_par
  public :: uvmap_user_weight_mode_toprog
  public :: map_power,map_rounding
  private
  !
  ! Parameters for determining image size
  integer, save :: map_power = 2        ! Max exponent of powers of 3 and 5
  real,    save :: map_rounding = 0.05  ! Tolerance for rounding to floor
  !
  type uvmap_par
     integer(kind=4) :: size(2) = 0   ! [------] Map size
     real(kind=4) :: xycell(2) = 0.0  ! [arcsec] Map cell
     real(kind=4) :: uvcell(2) = 0.0  ! [     m] UV cell
     real(kind=4) :: field(2) = 0.0   ! [arcsec] Field of view in arcsecond
     !
     character(len=8) :: mode = 'NATURAL'         ! [-----------] Weighting mode
     real(kind=4) :: uniform(2) = [0.0,1.0]       ! [m,---------] uvcell size and robustness coefficient
     real(kind=4) :: taper(4) = [0.0,0.0,0.0,2.0] ! [m,m,deg,---] UV Taper
     !
     integer(kind=4) :: wcol = 0      ! [---------] Weighting channel
     integer(kind=4) :: beam = -1     ! [---------] One beam every N channels (default to precision limit)
     real(kind=4) :: precis = 0.1     ! [chan.frac] Requested precision at map edges
     !
     integer(kind=4) :: ctype = 5     ! Convolution mode
     real(kind=4) :: support(2) = 0.0 ! Support of gridding function
     !
     real(kind=4) :: truncate = 20.0  ! Truncation level in % (for mosaic or primary)
     !
     logical :: shift = .false.       ! [---] Shift or rotate UV data
     real(kind=4) :: angle = 0.0      ! [deg] Position angle of UV data
     character(len=16) :: ra_c  = ' ' ! [---] Right ascension
     character(len=16) :: dec_c = ' ' ! [---] Declination
     !
     integer(kind=4) :: nfields = 0     ! Number and type of fields (<0 = phase, >0 = pointing)
     real,    allocatable :: offxy(:,:) ! Pointing or Phase offsets
     integer, allocatable :: ifields(:) ! start and end of fields
   contains
     procedure, public :: init   => uvmap_par_init
     procedure, public :: copyto => uvmap_par_copyto
     procedure, public :: sicdef => uvmap_par_sicdef
  end type uvmap_par
  !
contains
  !
  subroutine uvmap_par_init(prog,error)
    use gkernel_interfaces, only: gi4_round_forfft
    !-----------------------------------------------------------------------
    ! Initialize by setting the intent to out
    !-----------------------------------------------------------------------
    class(uvmap_par), intent(out)   :: prog
    logical,          intent(inout) :: error
    !
    integer :: iout
    !
    call gi4_round_forfft(64,iout,error,map_rounding,map_power)
    if (error) return
  end subroutine uvmap_par_init
  !
  subroutine uvmap_par_copyto(in,out)
    !-----------------------------------------------------------------------
    ! Copy a MAP structure to another one, but avoid erasing
    ! the number of fields in it. The result must have an intent(inout)
    ! to avoid erasing the allocatable array in the derived type.
    !-----------------------------------------------------------------------
    class(uvmap_par), intent(in)    :: in
    type(uvmap_par),  intent(inout) :: out
    !
    out%size = in%size
    out%xycell = in%xycell
    out%uvcell = in%uvcell
    out%field = in%field
    !
    out%mode = in%mode
    out%uniform = in%uniform
    out%taper = in%taper
    !
    out%wcol = in%wcol
    out%beam = in%beam
    out%precis = in%precis
    !
    out%ctype = in%ctype
    out%support = in%support
    !
    out%truncate = in%truncate
    !
    out%shift = in%shift
    out%angle = in%angle
    out%ra_c = in%ra_c
    out%dec_c = in%dec_c
  end subroutine uvmap_par_copyto
  !
  subroutine uvmap_par_sicdef(prog,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! 
    !-----------------------------------------------------------------------
    class(uvmap_par), intent(out)   :: prog
    logical,          intent(inout) :: error
    !
    integer(kind=index_length) :: dim(4) = 0
    !
    dim = [2,0,0,0]
    call sic_def_inte('MAP_SIZE',prog%size,1,dim,.false.,error)
    if (error) return
    call sic_def_real('MAP_CELL',prog%xycell,1,dim,.false.,error)
    if (error) return
    call sic_def_real('MAP_FIELD',prog%field,1,dim,.false.,error)
    if (error) return
    call sic_def_real('MAP_ROUNDING',map_rounding,0,0,.false.,error)
    if (error) return
    call sic_def_inte('MAP_POWER   ',map_power,0,0,.false.,error)
    if (error) return
    !
    call sic_def_char('MAP_WEIGHT',prog%mode,.false.,error)
    if (error) return
    call sic_def_real('MAP_ROBUST',prog%uniform(2),0,0,.false.,error)
    if (error) return
    !
    call sic_def_real('MAP_UVCELL',prog%uniform(1),0,0,.false.,error)
    if (error) return
    dim = [3,0,0,0]
    call sic_def_real('MAP_UVTAPER',prog%taper,1,dim,.false.,error)
    if (error) return
    call sic_def_real('MAP_TAPEREXPO',prog%taper(4),0,0,.false.,error)
    if (error) return
    !
    call sic_def_inte('MAP_BEAM_STEP',prog%beam,0,0,.false.,error)
    if (error) return
    call sic_def_real('MAP_PRECIS',prog%precis,0,0,.false.,error)
    if (error) return
    !
    call sic_def_inte('MAP_CONVOLUTION',prog%ctype,0,0,.false.,error)
    if (error) return
    !
    call sic_def_real('MAP_TRUNCATE',prog%truncate,0,0,.false.,error)
    if (error) return
    !
    call sic_def_logi('MAP_SHIFT',prog%shift,.false.,error)
    if (error) return
    call sic_def_char('MAP_RA',prog%ra_c,.false.,error)
    if (error) return
    call sic_def_char('MAP_DEC',prog%dec_c,.false.,error)
    if (error) return
    call sic_def_real('MAP_ANGLE',prog%angle,0,0,.false.,error)
    if (error) return
  end subroutine uvmap_par_sicdef
  !
  subroutine uvmap_user_weight_mode_toprog(rname,prog,error)
    use gkernel_interfaces
    !---------------------------------------------------------------------
    ! Decode the weighting mode
    !---------------------------------------------------------------------
    character(len=*), intent(in)    :: rname
    type(uvmap_par),  intent(inout) :: prog
    logical,          intent(inout) :: error
    !
    integer :: i,n
    character(len=8) :: argum
    character(len=8) :: vweight(3)=(/'NATURAL ','UNIFORM ','ROBUST  '/)
    !
    argum = prog%mode
    call sic_get_char('MAP_WEIGHT',argum,n,error)
    call sic_upper (argum)
    call sic_ambigs (rname,argum,prog%mode,i,vweight,3,error)
    if (error) then
       call map_message(seve%e,rname,'Invalid weight mode '//argum)
    else
       call map_message(seve%i,rname,'Using '//vweight(i)//' weighting')
    endif
  end subroutine uvmap_user_weight_mode_toprog
end module uvmap_types
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
