!!
!! Definitions used by UV_INVERT / UV_MAP
!!
module uvmap_def
  !! 
  type :: par_uvmap
    !! UV_MAP parameters (no longer used)
    real taper(4)              !! UV taper
    character(len=4) mode      !! Weighting mode
    real field(2)              !! Field of view
    integer size(2)            !! Image size
    real xycell(2)             !! Image cell
    real uniform(2)            !! Robust weighting parameter
    real support(2)            !! Support size in meters
    real uvcell(2)             !! Cell size in meters
    integer channels(3)        !! First, Last and Weight channels
    integer ctype              !! Convolution type
    integer beam               !! One beam every N channels
    logical shift              !! Shift phase center
    logical blocked            !! Use blocking factor, or not (Debug)
    character(len=16) ra_c
    character(len=16) dec_c
    real(kind=8) new(3)        !! New position and angle of shift/rotation
    real(kind=8) off(3)        !! Offset and angle of shift/rotation
    real(kind=8) xy(2)         !! Phase rotation !! R*4 for SortUV
    real(kind=8) cs(2)         !! Angle offsets  !! R*4 for LoadUV
    real(kind=8) freq          !! Frequency for U,V values
    integer uvcode             !! UVT or TUV order ?
  end type
  !!
  type :: gridding
    !! Gridding functions
    real ubias                 !! Bias of U coordinates
    real ubuff(4096)           !! Grid of values of the convolution
    real vbias                 !! Bias of V coordinates
    real vbuff(4096)           !! Grid of values of the convolution
  end type gridding
  integer, parameter :: code_uvt=1  !! This MUST NOT be changed
  integer, parameter :: code_tuv=2  !! This MUST NOT be changed
end module uvmap_def
!!
!! Used by IMAGER CLEAN tools
!!
module clean_def
  !! Definition of main IMAGER derived types
  type :: gridding
    !! Gridding function tables
    real ubias                 !! Bias of U coordinates
    real ubuff(4096)           !! Grid of values of the convolution
    real vbias                 !! Bias of V coordinates
    real vbuff(4096)           !! Grid of values of the convolution
  end type gridding
  !!
  type :: channel_par  
    !! Channel range and related information
    real(8) :: freq=0          !! Frequency channel
    integer :: bounds(2)=[0,0] !! Channel range
    integer :: weight=0        !! Weight channel
  end type
  !!
  type :: uvmap_par
    !! UV_MAP image construction control parameters
    real taper(4)              !! UV Taper
    integer size(2)            !! Map size
    real xycell(2)             !! Map cell
    real uvcell(2)             !! UV cell
    real uniform(2)            !! Weighting parameters
    integer wcol               !! Weighting channel
    integer ctype              !! Convolution mode
    real support(2)            !! Support of gridding function
    integer beam               !! One beam every N channels
    real field(2)              !! Field of view in arcsecond
    real precis                !! Precision at map edges
    real truncate              !! Truncation level in %
    character(len=8) mode      !! Weighting mode
    logical shift              !! Shift or rotate UV data
    character(len=16) ra_c     !! Right ascension
    character(len=16) dec_c    !! Declination
    real angle                 !! New position angle of UV data
    integer nfields            !! Number and type of fields (<0 = phase, >0 = pointing)
    integer, allocatable :: teles(:)      !! Telescope number for each field
    real, allocatable :: bsize(:)      !! Primary Beam size (for Mosaics)
    real, allocatable :: offxy(:,:)    !! Pointing or Phase offset values
    real(8), allocatable :: centers(:,:) !! Ra Dec absolute pointings
    !! real, pointer :: uvdata(:,:)       !! UV Data (not used)
  end type uvmap_par
  !!
  !!-----
  integer, parameter :: clean_mscale=5  !! Up to 5 scale sizes, including 0
  !!
  type :: clean_par
    !! CLEAN deconvolution control parameters
    sequence
    integer first,last         !! First & Last plane
    integer nlist              !! List size
    integer iplane             !! Current image plane
    integer ibeam              !! Current beam plane
    integer imask              !! Current mask plane 
    !!
    real thresh                !! Threshold for beam fit
    real gain                  !! Loop gain
    real fres                  !! Fractional residual
    real ares                  !! Absolute residual
    real ratio                 !! Smoothing ratio for MRC
    real spexp                 !! Speed up factor in Clark
    real phat                  !! Prussian hat
    real flux                  !! Cleaned Flux
    real search                !! Threshold for searching
    real restor                !!           for restoration
    real trunca                !! Beam truncation value
    real worry                 !! Worry factor in MultiScale
    integer ninflate           !! Component "inflation" factor
    integer ngoal              !! Maximum number of minor cycle components
    integer converge           !! Convergence criterium: 0 = Infty
    integer m_iter             !! Maximum number of iterations
    integer n_iter             !! Current number of iterations
    integer p_iter             !! Positive number of iterations
    integer n_major            !! Maximum number of major cycle
    !!
    !! MultiScale
    real smooth                !! Multi-Scale smoothing factor
    integer nker(clean_mscale) !! Kernel for Multi-Scale clean
    !! Multi Gaussian
    integer nscale             !! Number of Gaussian scales
    real gains(clean_mscale)   !! Clean gains
    real gsize(clean_mscale)   !! Gaussian smoothing widths
    !!
    real major                 !! Major axis
    real minor                 !! Minor axis
    real angle                 !! Clean beam angle
    real beam_min              !! Beam minimum
    real beam_max              !! Beam maximum
    real bgain                 !! Outer sidelobe
    !!
    integer blc(2)             !! Bottom Left Corner
    integer trc(2)             !! Top Right Corner
    integer box(4)             !! Cleaning Box
    integer beam0(2)           !! Beam center X,Y
    integer patch(2)           !! Beam patch sizes
    integer bzone(4)           !! Beam patch
    integer bshift(3)          !! Beam shift
    integer residual           !! Add back the residual ?
    integer restart            !! Restart Cleaning from CCT  !! (0,2,6)
    logical mosaic             !! Mosaic flag
    logical pflux              !! Flux display
    logical pcycle             !! Residual display in cycle
    logical pmrc               !! MRC display in cycle
    logical qcycle             !! Query mode
    logical pclean             !! Clean display in cycle
    logical do_mask            !! Re-compute the mask ?
    logical verbose            !! Lots of printout ?
    character(len=12) method   !! CLEAN Method
    !!
    real, pointer :: atten(:,:,:)   !! Mosaic weights (as function of freq)
  end type
  !-----
  type :: cct_par              !! Clean Component element definition
    !! Must be properly initialized, with VALUE to 0.
    real :: influx=0.          !! Current flux
    real :: value=0.           !! Component value
    integer :: ix=0            !! X pixel
    integer :: iy=0            !! Y pixel
    real :: size=0.            !! Component size (<0 = -kernel number)
  end type
  !!
  type :: cct_lst 
    !! Clean component list definition
    integer :: cur_size = 0
    integer :: max_size = 0
!    integer :: n_scales = 0   !! Number of scales
!    integer :: t_scales = 0   !! Type of scales (Currently, only Gaussian)
!    real :: scales(6)         !! Scale sizes
    !
    type(cct_par), allocatable :: cc(:) !! A list of clean component
    !
    contains
      procedure reallocate     !! List resize 
      procedure initialize     !! List initialization
  end type
  !!
  contains
    subroutine initialize(cct_list,usize)
      !!-------------------------------------------------------------------
      !! IMAGER
      !!   Initialize a Clean Component Table
      !!-------------------------------------------------------------------
      class(cct_lst), intent(inout) :: cct_list    !! Clean Component List
      integer, optional, intent(in) :: usize !! Specified minimum size
      !!
      integer :: ier
      !!
      if (allocated(cct_list%cc)) deallocate(cct_list%cc)
      cct_list%cur_size = 0
      cct_list%max_size = 0
!!      cct_list%n_scales = 0
!!      cct_list%scales = 0.0
      if (.not.present(usize)) return
      !!
      if (usize.le.0) return
      allocate(cct_list%cc(usize),stat=ier)
      if (ier.ne.0) return
      cct_list%max_size = usize
    end subroutine initialize
    !!
    subroutine reallocate(cct_list,usize) 
      !!-------------------------------------------------------------------
      !! IMAGER
      !!   Extend the size of a Clean Component Table
      !!-------------------------------------------------------------------
      class(cct_lst), intent(inout) :: cct_list    !! Clean Component List
      integer, optional, intent(in) :: usize !! Specified minimum size
      !!
      type(cct_par), allocatable :: tmp(:)
      integer(kind=4) :: nsize,ier
      character(len=80) :: mess
      !!
      ier = 0
      nsize = max(2*cct_list%max_size,500)
      if (present(usize)) then
        nsize = usize
        if (cct_list%max_size.ge.usize) return
      endif
      !!
      if (cct_list%max_size.ne.0) then
        !!
        if (cct_list%cur_size.ne.0) then
          allocate(tmp(cct_list%cur_size),stat=ier,errmsg=mess)
          if (ier.ne.0) then
            write(*,'(A,I0,A)') 'Memory TMP allocation error for CCT_LIS%CC ',nsize,trim(mess)
            return
          endif
          tmp = cct_list%cc(1:cct_list%cur_size)
          if (allocated(cct_list%cc)) then
            deallocate(cct_list%cc)
          else
            write(*,'(A,I0,A)') 'Unallocated CCT_LIST%CC with Cur size ',cct_list%cur_size
          endif
          allocate(cct_list%cc(nsize),stat=ier,errmsg=mess)
          if (ier.ne.0) then
            write(*,'(A,I0,A)') 'Memory re-allocation error for CCT_LIS%CC ',nsize,trim(mess)
            return
          endif
          cct_list%cc(1:cct_list%cur_size) = tmp
          !!write(*,'(A,I0,A,I0)') 'CCT_LIST Re-allocation with copy from ',cct_list%max_size,' to ',nsize
          deallocate(tmp)
        else
          if (allocated(cct_list%cc)) deallocate(cct_list%cc)
          allocate(cct_list%cc(nsize),stat=ier,errmsg=mess)
          if (ier.ne.0) then
            write(*,'(A,I0,A)') 'Memory re-allocation error for CCT_LIS%CC ',nsize,trim(mess)
            return
          endif
          !!write(*,'(A,I0,A,I0)') 'CCT_LIST Extension from ',cct_list%max_size,' to ',nsize
        endif
      else
        allocate(cct_list%cc(nsize),stat=ier,errmsg=mess)
        if (ier.ne.0) then
          write(*,'(A,I0,A)') 'Memory allocation error for CCT_LIST%CC ',nsize,trim(mess)
          return
        endif
        !!write(*,'(A,I0)') 'CCT_LIST Allocation to ',nsize
      endif
      cct_list%max_size = nsize
    end subroutine reallocate
  !!
end module clean_def
!
module mod_fitbeam
  !! Module to handle Fitting of the Dirty beam size
  integer :: nv                !! Number of values
  real :: par(6)               !! Fitted parameters
  real :: err(6)               !! Errorbars
  real :: spar(6)              !! Last fitted values
  real :: sigbas               !! rms on baseline
  real :: sigrai               !! rms on line
  integer :: kpar(6)           !! Code for parameter
  real, allocatable :: ip_values(:)    !! Values
  real, allocatable :: ip_coords(:,:)  !! Coordinates
end module mod_fitbeam
!
module short_def
  !! Define short_spacings, a structure to control the XY_SHORT
  !! command
  integer, parameter :: code_short_old=0    !! Old method: one file per field
  integer, parameter :: code_short_phase=1  !! Mosaic UV table with phase offsets
  integer, parameter :: code_short_point=2  !! Mosaic UV table with pointing offsets
  integer, parameter :: code_short_auto=3   !! Automatic derivation of UV table offsets type
  !!
  type :: short_spacings
    integer              :: mode=3
    real                 :: sd_factor=0.0  !! Single dish flux factor
    real                 :: minw=0.01      !! Minimum weight retained
    real                 :: ptole=0.0      !! Position tolerance
    real                 :: ftole=0.01     !! Frequency tolerance (in channel width)
    real                 :: uv_minr=0.     !! Minimum radius
    real                 :: uv_maxr=0.     !! Maximum radius
    real                 :: sd_weight=0.   !! Single dish weight factor
    integer              :: xcol=0         !! X column
    integer              :: ycol=0         !! Y column
    integer              :: wcol=0         !! Weight column
    integer              :: mcol(2)=[0,0]  !! Columns to be imaged
    real                 :: sd_beam(3)=[0.,0.,0.] !! Single dish beam values
    real                 :: sd_diam=0.     ! Single Dish diameter
    real                 :: ip_beam=0.     !! Array primary beam
    real                 :: ip_diam=0.     !! Array antennas diameter
    logical              :: do_single=.true.   !! Use single dish
    logical              :: do_primary=.true.  !! Correct for primary beam
    character(len=4)     :: weight_mode='NATU' !! Weighting mode
    character(len=16)    :: chra=' '       !! RA of phase center
    character(len=16)    :: chde=' '       !! Dec of phase center
    integer              :: nf=0           !! Number of fields
    real, allocatable    :: raoff(:)
    real, allocatable    :: deoff(:)
  end type 
  !!
end module short_def

