module mapping_interfaces_public
  interface
    subroutine dispatch_clean(line,error)
      use gbl_message
      use clean_arrays
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   Main CLEAN routine
      !   Call appropriate subroutine according to METHOD%METHOD
      !----------------------------------------------------------------------
      character(len=*), intent(inout) :: line  ! Command line
      logical,          intent(out)   :: error ! Logical error flag
    end subroutine dispatch_clean
  end interface
  !
  interface
    subroutine run_clean (line,comm,error)
      use clean_arrays
      use clean_default
      use gbl_message
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   Main routine
      !   Call appropriate subroutine according to COMM
      !----------------------------------------------------------------------
      character(len=*), intent(inout) :: line  ! Command line
      character(len=*), intent(in)    :: comm  ! Command name
      logical,          intent(out)   :: error ! Logical error flag
    end subroutine run_clean
  end interface
  !
  interface
    subroutine init_clean
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Initialize Mapping Languages
      !----------------------------------------------------------------------
      use clean_def
      use clean_arrays
      use clean_default
      !
    end subroutine init_clean
  end interface
  !
  interface
    subroutine rmask_to_list(rmask,m,list,n)
      !---------------------------------------------------
      ! @ public
      !   Get list of positions from a Real mask.
      !---------------------------------------------------
      integer, intent(in) :: m  ! Number of entries
      real, intent(in) :: rmask(m)  ! Mask values
      integer, intent(out) :: n  ! Number of TRUE values
      integer, intent(out) :: list(m) ! Position of entries 
    end subroutine rmask_to_list
  end interface
  !
  interface
    subroutine lmask_to_list(lmask,m,list,n)
      !---------------------------------------------------
      ! @ public
      !   Get list of positions from a Logical mask.
      !---------------------------------------------------
      integer, intent(in) :: m  ! Number of entries
      logical, intent(in) :: lmask(m)  ! Mask values
      integer, intent(out) :: n  ! Number of TRUE values
      integer, intent(out) :: list(m) ! Position of entries 
    end subroutine lmask_to_list
  end interface
  !
  interface
    subroutine get_listsize (mask,m,n)
      !---------------------------------------------------
      ! @ public
      !   Count number of TRUE values
      !---------------------------------------------------
      integer, intent(in) :: m  ! Number of entries
      integer, intent(out) :: n ! Number of TRUE values
      logical, intent(in) :: mask(m)  ! Mask values
    end subroutine get_listsize
  end interface
  !
  interface
    subroutine get_listindex(mask,m,list,n)
      !---------------------------------------------------
      ! @ public
      !   Get list of positions in mask.
      !---------------------------------------------------
      integer, intent(in) :: m  ! Number of entries
      integer, intent(in) :: n  ! Number of TRUE values
      logical, intent(in) :: mask(m)  ! Mask values
      integer, intent(out) :: list(n) ! Position of entries 
    end subroutine get_listindex
  end interface
  !
  interface
    subroutine set_weight(nx,ny,np,weight,primary,mask,   &
         &    wsear,wrest,wmin)
      use gbl_message
      !---------------------------------------------------
      ! @ public
      !   Set the mosaic weights
      !---------------------------------------------------
      integer, intent(in) :: nx  ! X size
      integer, intent(in) :: ny  ! Y size 
      integer, intent(in) :: np  ! Number of pointings
      real, intent(out) ::  weight(nx,ny)     ! Weight map
      real, intent(in) ::  primary(np,nx,ny)  ! Primary beams
      real, intent(in) ::  wsear              ! Search threshold
      real, intent(in) ::  wrest              ! Restore threshold   
      real, intent(in) ::  wmin               ! Minimum beal value  
      logical, intent(inout) ::  mask(nx,ny)  ! Search mask
    end subroutine set_weight
  end interface
  !
  interface
    subroutine check_box(nx,ny,blc,trc)
      !----------------------------------------------
      ! @ public
      !   Define default search box corners
      !-----------------------------------------------
      integer, intent(in) :: nx,ny
      integer, intent(out) :: blc(2)
      integer, intent(out) :: trc(2)
    end subroutine check_box
  end interface
  !
  interface
    subroutine major_multi90 (rname,method,head,   &
         &    dirty,resid,beam,mask,clean,nx,ny,   &
         &    tcc,miter,limit,niter, &
         &    smask, sresid, trans, cdata, sbeam, &
         &    tfbeam, wfft)
    ! Need to add
    !    &    nf, primary, weight)
      use image_def
      use gbl_message
      use clean_def
      !$  use omp_lib
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !     Multi-Resolution CLEAN - with NS (parameter) scales
      !
      !     Algorithm
      !     For each iteration, search at which scale the signal to noise
      !     is largest. Use the strongest S/N to determine the "component"
      !     intensity and shape at this iteration.
      !
      !     Restore the ("infinite" resolution) image from the list of location
      !     types, and intensities of the "components"
      !
      !     The noise level at each scale is computed from the Fourier transform
      !     of the smoothed dirty beams, since the FT is the weight distribution
      !     and the noise level is the inverse square root of the sum of the
      !     weights.
      !-----------------------------------------------------------------------
      character(len=*), intent(in) :: rname
      type (clean_par), intent(inout) :: method
      type (gildas), intent(inout) :: head         ! Unused, but here for consistency...
      integer, intent(in)  :: nx,ny                ! Image size
      integer, intent(in)  :: miter                ! Maximum number of clean components
      integer, intent(out) :: niter                ! Number of found components
      real, intent(in)  :: dirty(nx,ny)            ! Dirty image
      real, intent(inout) :: resid(nx,ny)          ! Residual image (initialized to Dirty image)
      real, intent(in)  :: beam(nx,ny)             ! Dirty beam
      real, intent(inout) :: clean(nx,ny)          ! "CLEAN" image (not convolved yet)
      logical, intent(in)  :: mask(nx,ny)          ! Search area
      real, intent(in)  :: limit                   ! Maximum residual
      real, intent(in)  :: tfbeam(nx,ny)           ! Real Beam TF
      real, intent(inout) :: wfft(*)
      type (cct_par), intent(out) :: tcc(miter)
      !
      ! In call sequence
      real, intent(inout) ::  sbeam(nx,ny,*)          ! Smoothed beams
      real, intent(inout) ::  sresid(nx,ny)           ! Smoothed residuals
      real, intent(inout) ::  trans(nx,ny)            ! Translated beam
      complex, intent(inout) ::  cdata(nx,ny)         ! Work array
      logical, intent(inout) ::  smask(nx,ny)         ! Smoothed mask
    end subroutine major_multi90
  end interface
  !
  interface
    subroutine map_message(mkind,procname,message)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Messaging facility for the current library. Calls the low-level
      !   (internal) messaging routine with its own identifier.
      !---------------------------------------------------------------------
      integer,          intent(in) :: mkind     ! Message kind
      character(len=*), intent(in) :: procname  ! Name of calling procedure
      character(len=*), intent(in) :: message   ! Message string
    end subroutine map_message
  end interface
  !
  interface
    subroutine get_i4list_fromsic(rname,line,opt,nf,list,error)
      use gkernel_types
      use gbl_message
      use gbl_format
      !
      ! @ public-mandatory
      !
      ! Return in the allocatable array the content of the 1-D
      ! SIC variable given as argument of Option # opt.
      ! Return the size of the array in NF
      ! If NF is non zero on entry, the size must match and the
      ! array is pre-allocated.
      !
      character(len=*), intent(in) :: rname
      character(len=*), intent(in) :: line
      integer, intent(in) :: opt
      integer, intent(inout) :: nf
      integer, allocatable, intent(inout) :: list(:)
      logical, intent(out) :: error
    end subroutine get_i4list_fromsic
  end interface
  !
  interface
    subroutine get_r4list_fromsic(rname,line,opt,nf,list,error)
      use gkernel_types
      use gbl_message
      use gbl_format
      !
      ! @ public-mandatory
      !
      ! Return in the allocatable array the content of the 1-D
      ! SIC variable given as argument of Option # opt.
      ! Return the size of the array in NF
      ! If NF is non zero on entry, the size must match and the
      ! array is pre-allocated.
      !
      character(len=*), intent(in) :: rname
      character(len=*), intent(in) :: line
      integer, intent(in) :: opt
      integer, intent(inout) :: nf
      real, allocatable, intent(inout) :: list(:)
      logical, intent(out) :: error
    end subroutine get_r4list_fromsic
  end interface
  !
  interface
    subroutine maxcct (x,n,nomin,rmin,nomax,rmax)
      use clean_def
      !----------------------------------------------------------------------
      ! @ public
      !
      ! Mapping:	Utility routine
      ! 	Compute position and values of Min and Max of Clean Component Array X
      !----------------------------------------------------------------------
      integer, intent(in) :: n              ! taille du vecteur
      type(cct_par), intent(in) :: x(n)     ! Clean components 
      integer, intent(out) :: nomin,nomax   ! Resultat de la recherche:indices
      real, intent(out) :: rmin,rmax        ! et valeurs
    end subroutine maxcct
  end interface
  !
  interface
    subroutine maxvec (x,n,nomin,rmin,nomax,rmax)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	Utility routine
      ! 	Compute position and values of Min and Max of array X
      !----------------------------------------------------------------------
      integer, intent(in) :: n             ! taille du vecteur
      real, intent(in) :: x(n)             ! Vecteur donne
      integer, intent(out) :: nomin,nomax   ! Resultat de la recherche:indices
      real, intent(out) :: rmin,rmax        ! et valeurs
    end subroutine maxvec
  end interface
  !
  interface
    subroutine maxmap(ary,nx,ny,box,amax,imax,jmax,amin,imin,jmin)
      !--------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	Utility routine
      !	Find max and min in specified region of real array
      !--------------------------------------------------------------------
      integer, intent(in) :: nx, ny         ! X,Y size
      real, intent(in) :: ary(nx,ny)        ! Array of values
      integer, intent(in) :: box(4)         ! Search box
      integer, intent(out) :: imax, jmax    ! Position of Max
      integer, intent(out) :: imin, jmin    ! Position of Min
      real, intent(out) :: amax, amin       ! Max and Min
    end subroutine maxmap
  end interface
  !
  interface
    subroutine maxmsk(ary,nx,ny,msk,box,   &
         &    amax,imax,jmax,amin,imin,jmin)
      !--------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	Utility routine
      !	  Find max and min in specified region of real array
      !   Version with mask
      !--------------------------------------------------------------------
      integer, intent(in) :: nx, ny         ! X,Y size
      real, intent(in) :: ary(nx,ny)        ! Array of values
      logical, intent(in) ::  msk(nx,ny)    ! Search mask
      integer, intent(in) :: box(4)         ! Search box
      integer, intent(out) :: imax, jmax    ! Position of Max
      integer, intent(out) :: imin, jmin    ! Position of Min
      real, intent(out) :: amax, amin       ! Max and Min
    end subroutine maxmsk
  end interface
  !
  interface
    subroutine maxlst(ary,nx,ny,list,nl,   &
         &    amax,imax,jmax,amin,imin,jmin)
      !--------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	Utility routine
      !	  Find max and min in specified region of real array
      !   using a list of valid pixels
      !--------------------------------------------------------------------
      integer, intent(in) :: nx, ny         ! X,Y size
      real, intent(in) :: ary(nx*ny)        ! Array of values
      integer, intent(in) :: nl             ! List size
      integer, intent(in) :: list(nl)       ! Search list 
      integer, intent(out) :: imax, jmax    ! Position of Max
      integer, intent(out) :: imin, jmin    ! Position of Min
      real, intent(out) :: amax, amin       ! Max and Min
    end subroutine maxlst
  end interface
  !
  interface
    subroutine mosaic_sortuv (np,nv,ntrail,vin,vout,xy,cs,uvmax,uvmin, &
      & error,ixoff,iyoff,nf,doff,voff)
      use gildas_def
      !---------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAPPING
      !     Sort a UV table by fields
      !     Rotate, Shift and Sort a UV table for map making
      !     Differential precession should have been applied before.
      !---------------------------------------------------------------------
      integer, intent(in) :: np        ! Size of a visibility
      integer, intent(in) :: nv        ! Number of visibilities
      integer, intent(in) :: ntrail    ! Number of trailing daps
      real, intent(in) :: vin(np,nv)   ! Input visibilities
      real, intent(out) :: vout(np,nv) ! Output visibilities
      real, intent(in) :: xy(2)        ! Phase shift
      real, intent(in) :: cs(2)        ! Frame Rotation
      real, intent(out) :: uvmax       ! Max UV value
      real, intent(out) :: uvmin       ! Min UV value
      integer, intent(in) :: ixoff, iyoff
      integer, intent(out) :: nf
      real, intent(out), allocatable :: doff(:,:)
      integer, intent(out), allocatable :: voff(:)
      logical, intent(out) :: error    !
    end subroutine mosaic_sortuv
  end interface
  !
  interface
    subroutine loadfiuv (visi,np,nv,dtr,it,sorted,ixoff,iyoff,rpv,nf,doff)
      !----------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAP    UVSORT routines
      !     Load field numbers into work arrays for sorting.
      !----------------------------------------------------------------------
      integer, intent(in)  :: np                   ! Size of a visibility
      integer, intent(in)  :: nv                   ! Number of visibilities
      real, intent(in) :: visi(np,nv)              ! Input visibilities
      real(8), intent(out) :: dtr(nv)              ! Output field number
      integer, intent(out) :: it(nv)               ! Indexes
      logical, intent(out) :: sorted               !
      integer, intent(in)  :: ixoff                ! X pointer
      integer, intent(in)  :: iyoff                ! Y pointer
      real(4), intent(in)  :: rpv(nv)              ! V Values
      integer, intent(out) :: nf                   ! Number of fields
      real(kind=4), intent(out), allocatable :: doff(:,:)  ! Fields offsets
    end subroutine loadfiuv
  end interface
  !
  interface
    subroutine mulgau(data,nx,ny,bmaj,bmin,pa,scale,xinc,yinc)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      ! 	Multiply the TF of an image by the TF of
      !	  a convolving gaussian function. BMAJ and BMIN are the
      !	  widths of the original gaussian. PA is the position angle of major
      !	  axis (from north towards east). SCALE is a scaling factor.
      !----------------------------------------------------------------------
      integer, intent(in) :: nx,ny    ! X,Y size
      real, intent(in) :: bmaj        ! Major axis
      real, intent(in) :: bmin        ! Minor axis
      real, intent(in) :: pa          ! Position Angle
      real, intent(in) :: scale       ! Flux scale factor
      real, intent(in) :: xinc        ! X pixel size
      real, intent(in) :: yinc        ! Y pixel size
      complex, intent(inout) :: data(nx,ny)  ! TF of Data to be smoothed
    end subroutine mulgau
  end interface
  !
  interface
    subroutine convolve (image,dirty,nx,ny,fbeam,fcomp,wfft)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !	  Convolve an image by a beam through Fourier Transform
      !----------------------------------------------------------------------
      integer, intent(in) :: nx,ny          ! Problem size
      complex, intent(in) :: fbeam(nx,ny)    ! Beam TF
      complex, intent(inout) :: fcomp(nx,ny) ! TF workspace
      real, intent(in) :: image(nx,ny)      ! Input image
      real, intent(out) :: dirty(nx,ny)     ! Convolved image
      real, intent(inout) :: wfft(*)        ! Work area
    end subroutine convolve
  end interface
  !
  interface
    subroutine compress(nx,ny,large,wl,mx,my,small,ws,wfft)
      !----------------------------------------------------------------------
      !	@ public
      ! 
      ! MAPPING
      !   Compress an image through FT truncation
      !----------------------------------------------------------------------
      integer, intent(in) :: nx,ny,mx,my
      real, intent(in) :: large(nx,ny)
      complex, intent(inout) :: wl(nx,ny)
      real, intent(out) :: small(mx,my)
      complex, intent(inout) :: ws(mx,my)
      real, intent(inout) :: wfft(*)
    end subroutine compress
  end interface
  !
  interface
    subroutine expand (nx,ny,large,wl,mx,my,small,ws,wfft)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !	  Expand an image through FT zero extension
      !----------------------------------------------------------------------
      integer, intent(in) :: nx,ny,mx,my
      real, intent(out) :: large(nx,ny)
      complex, intent(inout) :: wl(nx,ny)
      real, intent(in) :: small(mx,my)
      complex, intent(inout) :: ws(mx,my)
      real, intent(inout) :: wfft(*)
    end subroutine expand
  end interface
  !
  interface
    function beam_for_channel(iplane,hdirty,hbeam)
      use image_def
      !
      ! @ public
      !
      integer :: beam_for_channel !! intent(out)
      type(gildas), intent(in) :: hdirty
      type(gildas), intent(in) :: hbeam
      integer, intent(in) :: iplane
    end function beam_for_channel
  end interface
  !
  interface
    subroutine histos (r,nx,ny, list, nl, hx,nh,hmin,hstep)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GDF	Internal routine
      !
      !	Computes the histogram of part of an image
      !----------------------------------------------------------------------
      integer, intent(in) :: nx        ! X size
      integer, intent(in) :: ny        ! Y size
      real, intent(in)  :: r(nx*ny)    ! Input array 
      integer, intent(in) :: nl        ! List size
      integer, intent(in) :: list(nl)  ! List of values
      integer, intent(in) :: nh        ! Histogram size
      integer, intent(out) :: hx(nh)   ! Histogram
      real, intent(in) :: hmin         ! Min bin
      real, intent(in) :: hstep        ! Bin size
    end subroutine histos
  end interface
  !
  interface
    subroutine choice (r,nx,ny,list,nl,limite,   &
         &    mcl,wcl,ncl,rmax,ngoal)
      use clean_def
      !----------------------------------------------------------------------
      ! @ public
      !
      !  GILDAS:	CLEAN 	Internal routine
      !	Select possible clean components in residual map.
      !	Components are returned ordered in increasing I and J.
      ! 
      ! Search list is built if ngoal>0, re-used otherwise.
      !----------------------------------------------------------------------
      integer, intent(in) :: nx          ! X size
      integer, intent(in) :: ny          ! Y size
      integer, intent(in) :: nl          ! List size
      integer, intent(in) :: mcl         ! Maximum number of components
      integer, intent(out) :: ncl        ! Number of components found
      real, intent(in) :: r(nx*ny)       ! Input array
      type(cct_par), intent(out) :: wcl(mcl)      ! Components
      integer, intent(in) :: list(nl)    ! List of pixels 
      real, intent(inout) ::  limite     ! selection threshold
      real, intent(in) :: rmax           ! Maximum value
      integer, intent(in) :: ngoal       ! Intended number   
    end subroutine choice
  end interface
  !
  interface
    subroutine find_sidelobe (beam,nx,ny,i0,j0,nxp,nyp,bgain)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	CLEAN	Internal routine
      !	Find the maximum sidelobe outside the beam patch defined
      !	by the beam center (I0,J0) and patch size (NXP,NYP)
      !----------------------------------------------------------------------
      integer, intent(in) :: nx       ! X size
      integer, intent(in) :: ny       ! Y size
      real, intent(in) :: beam(nx,ny) ! Input beam
      integer, intent(in) :: i0       ! X beam center
      integer, intent(in) :: j0       ! Y beam center
      integer, intent(in) :: nxp      ! X beam patch
      integer, intent(in) :: nyp      ! Y beam patch
      real, intent(out) :: bgain      ! Maximum sidelobe
    end subroutine find_sidelobe
  end interface
  !
  interface
    subroutine mos_sidelobe (beam,nx,ny,i0,j0,nxp,nyp,bgain,nf)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS:	CLEAN	Internal routine
      !	Find the maximum sidelobe outside the beam patch defined
      !	by the beam center (I0,J0) and patch size (NXP,NYP)
      ! Adapted for Mosaic
      !----------------------------------------------------------------------
      integer nx,ny,i0,j0,nxp,nyp,nf
      real beam(nx,ny,nf),bgain
    end subroutine mos_sidelobe
  end interface
  !
  interface
    subroutine t_setextrema(h,rmi,jmi,rma,jma)
      use gildas_def
      use image_def
      !------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Put extrema into the specified header
      !------------------------------------------------
      type (gildas), intent(inout), target :: h
      real(kind=4), intent(in) :: rmi     ! Value of minimum
      integer(kind=size_length), intent(in) :: jmi  ! Position of minimum
      real(kind=4), intent(in) :: rma     ! Value of maximum
      integer(kind=size_length), intent(in) :: jma  ! Position of maximum
    end subroutine t_setextrema
  end interface
  !
  interface
    subroutine fibeam (name,dirty,nx,ny,nbx,nby,thre,majo,mino,pa,convert,error)
      use gildas_def
      use mod_fitbeam
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Find beam parameters for deconvolution
      !   Fit an elliptical gaussian clean beam to main beam
      !---------------------------------------------------------------------
      character(len=*), intent(in) :: name          ! Caller's name
      integer, intent(in) :: nx                     ! X size
      integer, intent(in) :: ny                     ! Y size
      real, intent(in) :: dirty(nx,ny)              ! Dirty beam
      integer, intent(in) :: nbx                    ! X patch
      integer, intent(in) :: nby                    ! Y patch
      real, intent(inout) :: thre                   ! Threshold
      real, intent(inout) :: majo                   ! Major axis
      real, intent(inout) :: mino                   ! Minor axis
      real, intent(inout) :: pa                     ! Position Angle
      real(8), intent(in) :: convert(3,2)           ! Conversion formula
      logical, intent(inout) :: error               ! Error flag
    end subroutine fibeam
  end interface
  !
  interface
    subroutine dofft (np,nv,visi,jx,jy,jo   &
         &    ,nc,nx,ny,map,mapx,mapy,sup,cell,taper,we,vv   &
         &    ,ubias,vbias,ubuff,vbuff,ctype)
      use gildas_def
      use clean_default
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS  UV_MAP
      !   Compute FFT of image by gridding UV data
      !   Operational version using the fastest method.
      !----------------------------------------------------------------------
      integer, intent(in) :: nv                   ! number of values
      integer, intent(in) :: np                   ! Number of "visibilities", normally 7+3*nc
      real, intent(in) :: visi(np,nv)             ! values
      integer, intent(in) :: nc                   ! number of channels
      integer, intent(in) :: jx                   ! X coord location in VISI
      integer, intent(in) :: jy                   ! Y coord location in VISI
      integer, intent(in) :: jo                   ! first channel to map
      integer, intent(in) :: nx                   ! X map size
      integer, intent(in) :: ny                   ! Y map size
      complex, intent(out) :: map(nc+1,nx,ny)     ! gridded visibilities
      real, intent(in) :: mapx(nx)                ! X Coordinates of grid
      real, intent(in) :: mapy(ny)                ! Y Coordinates of grid
      real, intent(in) :: sup(2)                  ! Support of convolving function in Meters
      real, intent(in) :: cell(2)                 ! cell size in Meters
      real, intent(in) :: taper(4)                ! 1/e taper in Meters + Angle in Radians
      real, intent(in) :: we(nv)                  ! Weight array
      real, intent(in) :: vv(nv)                  ! V Values
      real, intent(in) :: ubias                   ! U gridding offset
      real, intent(in) :: vbias                   ! V gridding offset
      real, intent(in) :: ubuff(4096)             ! U gridding buffer
      real, intent(in) :: vbuff(4096)             ! V gridding buffer
      integer, intent(in) :: ctype                ! type of gridding
    end subroutine dofft
  end interface
  !
  interface
    subroutine remisajour (nxy,clean,resid,tfbeam,fcomp,   &
         &    wcl,ncl,nx,ny,wfft,   &
         &    np,primary,weight,wtrun)
      use clean_def
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   CLEAN   Internal routine
      !   Subtract last major cycle components from residual map.
      !----------------------------------------------------------------------
      integer, intent(in) :: nxy      ! Problem size
      integer, intent(in) :: nx,ny    ! Problem size
      integer, intent(in) :: ncl      ! Number of clean components
      integer, intent(in) :: np       ! Number of primary beams
      type(cct_par), intent(in) :: wcl(ncl)   ! Clean component list
      real, intent(in) :: tfbeam(nx,ny,np)    ! TF of dirty beams
      complex, intent(inout) :: fcomp(nx,ny)  ! Work area
      real, intent(inout) :: clean(nx,ny)     ! Clean map
      real, intent(inout) :: resid(nx,ny)     ! Residual map
      real, intent(in) :: primary(np,nx,ny)   ! Primary beams
      real, intent(in) :: weight(nx,ny)       ! Flat field weights
      real, intent(in) :: wtrun               ! Truncation of mosaic
      real, intent(in) :: wfft(*)             ! work fft area
    end subroutine remisajour
  end interface
  !
  interface
    subroutine soustraire (wcl,ncl,        &
         &    dirty,nx,ny,ixbeam,iybeam,   &
         &    ixpatch,iypatch,kcl,gain,    &
         &    nf, primary, weight, wtrun)
      use clean_def
      !$ use omp_lib
      !----------------------------------------------------------------------
      ! @ public
      !
      ! GILDAS: CLEAN   Internal routine
      ! Subtract the clean component, convolved with dirty beam
      ! restricted to beam patch, from the list of selected points.
      ! Caution : points must be ordered according I and J
      !----------------------------------------------------------------------
      integer, intent(in) :: nf                   ! Number of fields
      integer, intent(in) :: ncl                  ! nombre de points retenus
      integer, intent(in) :: nx,ny,ixbeam,iybeam  ! dimension et centre du beam
      real, intent(in) :: dirty(nx,ny,nf)         ! Dirty Beam
      integer, intent(in) :: ixpatch,iypatch      ! taille du centre BEAM retenu
      type(cct_par), intent(inout) :: wcl(ncl)
      integer, intent(in) :: kcl                  ! No de la composante introduite
      real, intent(in) :: gain                    ! gain de clean
      real, intent(in) :: primary (nf,nx,ny)      ! Primary beams
      real, intent(in) :: weight (nx,ny)          ! Effective weights on sky
      real, intent(in) :: wtrun
    end subroutine soustraire
  end interface
  !
  interface
    subroutine domima(a,rmi,rma,imi,ima,n)
      !----------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Compute minmax and location
      !----------------------------------------------------------
      integer, intent(in) :: n
      integer, intent(out) :: ima,imi
      real, intent(in) ::  a(n)
      real, intent(inout) :: rmi,rma
    end subroutine domima
  end interface
  !
  interface
    subroutine mosaic_loadfield (visi,np,nv,ixoff,iyoff,nf,doff,voff,uvmax,uvmin)
      !----------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAP    MOSAIC routines
      !     Load field coordinates into work arrays after sorting.
      !----------------------------------------------------------------------
      integer, intent(in)  :: np                   ! Size of a visibility
      integer, intent(in)  :: nv                   ! Number of visibilities
      real, intent(in) :: visi(np,nv)              ! Input visibilities
      integer, intent(in)  :: ixoff                ! X pointer
      integer, intent(in)  :: iyoff                ! Y pointer
      integer, intent(out) :: nf                   ! Number of fields
      real(kind=4), intent(out), allocatable :: doff(:,:)  ! Fields offsets
      integer, intent(out), allocatable :: voff(:)  ! Fields visibility offsets
      real, intent(inout) :: uvmax    ! Maximum length
      real, intent(inout) :: uvmin    ! Minimum baseline
    end subroutine mosaic_loadfield
  end interface
  !
  interface
    subroutine mosaic_getfields (visi,np,nv,ixoff,iyoff,nf,doff)
      !----------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAP    MOSAIC routines
      !     Count number of fields and Get their coordinates
      !----------------------------------------------------------------------
      integer, intent(in)  :: np                   ! Size of a visibility
      integer, intent(in)  :: nv                   ! Number of visibilities
      real, intent(inout)  :: visi(np,nv)              ! Input visibilities
      integer, intent(in)  :: ixoff                ! X pointer
      integer, intent(in)  :: iyoff                ! Y pointer
      integer, intent(out) :: nf                   ! Number of fields
      real, intent(out), allocatable :: doff(:,:)  ! Field offsets
    end subroutine mosaic_getfields
  end interface
  !
  interface
    subroutine init_kernel(ker,mk,nk,smooth)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for MULTISCALE clean
      !   Initialize a smoothing Kernel by a Gaussian shape
      !-----------------------------------------------------------------------
      integer, intent(in) :: mk            ! Kernel size
      integer, intent(in) :: nk            ! Kernel size
      real(4), intent(inout) :: ker(mk,mk) ! Kernel, centered on (NK+1)/2
      real(4), intent(in) :: smooth
    end subroutine init_kernel
  end interface
  !
  interface
    subroutine smooth_mask (mask,smask,nx,ny,nk)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for MULTISCALE clean
      !   Enlarge a mask using a kernel
      !   Only based on kernel size
      !-----------------------------------------------------------------------
      integer, intent(in) :: nx             !
      integer, intent(in) :: ny             !
      logical, intent(in) :: mask(nx,ny)    ! Input array
      logical, intent(out) :: smask(nx,ny)  ! Smoothed array
      integer, intent(in) :: nk             !
    end subroutine smooth_mask
  end interface
  !
  interface
    subroutine smooth_kernel (beam,sbeam,nx,ny,mk,nk,ker)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for MULTISCALE clean
      !   Smooth an array using a kernel
      !-----------------------------------------------------------------------
      integer, intent(in) :: nx             !
      integer, intent(in) :: ny             !
      real, intent(in) :: beam(nx,ny)       ! Input array
      real, intent(out) :: sbeam(nx,ny)     ! Smoothed array
      integer, intent(in) :: nk             !
      integer, intent(in) :: mk             !
      real, intent(in) :: ker(mk,mk)        ! Smoothing kernel, centered on (nk+1)/2
    end subroutine smooth_kernel
  end interface
  !
  interface
    subroutine smooth_masked (nx,ny,sbeam,beam,mask,mk,nk,ker)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for MULTISCALE
      !   Smooth an array using a kernel, but only in a mask
      !-----------------------------------------------------------------------
      integer, intent(in) :: nx             !
      integer, intent(in) :: ny             !
      real, intent(in) :: beam(nx,ny)       ! Input array
      real, intent(out) :: sbeam(nx,ny)     ! Smoothed array
      logical, intent(in) :: mask(nx,ny)    ! Valid area
      integer, intent(in) :: mk             !
      integer, intent(in) :: nk             !
      real, intent(in) :: ker(mk,mk)        ! Smoothing kernel, centered on (nk+1)/2
    end subroutine smooth_masked
  end interface
  !
  interface
    subroutine add_kernel (clean,nx,ny,value,kx,ky,mk,nk,ker)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for MULTISCALE Clean
      !   Spread a value using a Kernel and add it to result
      !-----------------------------------------------------------------------
      integer, intent(in) :: nx           ! X Image size
      integer, intent(in) :: ny           ! Y Image size
      real, intent(inout) :: clean(nx,ny) ! Summed output array
      real, intent(in) :: value           ! Input value
      integer, intent(in) :: kx           ! X Center of value
      integer, intent(in) :: ky           ! Y Center of value
      integer, intent(in) :: mk           ! Kernel size
      integer, intent(in) :: nk           ! Kernel size
      real, intent(in) :: ker(mk,mk)      ! Smoothing kernel, centered on (nk+1)/2
    end subroutine add_kernel
  end interface
  !
  interface
    subroutine amaxmask (a,mask,nx,ny,ix,iy)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !     Support for deconvolution
      !     Search the absolute maximum, in a masked region
      !-----------------------------------------------------------------------
      integer, intent(in) :: nx           ! X size
      integer, intent(in) :: ny           ! Y size
      real, intent(in) :: a(nx,ny)        ! Values
      logical, intent(in) :: mask(nx,ny)  ! Mask
      integer, intent(out) :: ix          ! X position of max
      integer, intent(out) :: iy          ! Y position of max
    end subroutine amaxmask
  end interface
  !
  interface
    function primary_beam(rname,head,fromressection)
      use phys_const
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Get telescope beamsize for the frequency of a GILDAS data set
      !---------------------------------------------------------------------  
      real(kind=4) :: primary_beam
      character(len=*), intent(in) :: rname
      type(gildas),     intent(in) :: head
      logical,          intent(in) :: fromressection
    end function primary_beam
  end interface
  !
  interface
    subroutine no_major_plot (method,head   &
         &    ,conv,niter,nx,ny,np,tcc  &
         &    ,clean,resid,poids)
      use clean_def
      use image_def
      !---------------------------------------------------------
      ! @ public
      !
      ! MAPPING 
      !   Do not Plot result of Major Cycle
      !---------------------------------------------------------
      type (clean_par), intent(inout) :: method
      type (gildas), intent(in) :: head
      !
      logical, intent(in) ::  conv        ! Convergence status
      integer, intent(in) ::  niter         ! Number of iterations
      integer, intent(in) ::  nx            ! X size
      integer, intent(in) ::  ny            ! Y size
      integer, intent(in) ::  np            ! Number of planes
      real, intent(in) :: clean(nx,ny)      ! Clean image
      real, intent(in) :: resid(nx,ny)      ! Residuals
      real, intent(in) :: poids(nx,ny)         ! Weight image
      type (cct_par), intent(in) :: tcc(niter)
    end subroutine no_major_plot
  end interface
  !
  interface
    subroutine no_next_flux(niter,cum)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Do not draw in the <FLUX window
      !---------------------------------------------------------------------
      integer, intent(in) :: niter
      real, intent(in) :: cum
    end subroutine no_next_flux
  end interface
  !
  interface
    subroutine no_remask(method,head,nl,error)
      use clean_def
      use image_def
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for Clean
      !   Re-compute mask in Major Cycles
      !---------------------------------------------------------------------
      type (clean_par), intent(in) :: method
      type (gildas), intent(in) :: head
      integer, intent(in) :: nl
      logical, intent(in) :: error
    end subroutine no_remask
  end interface
  !
  interface
    subroutine get_rlist (rmsk,nx,ny,box,list,nl)
      !---------------------------------------------------------------------
      ! @ public
      !     Return a LOGICAL mask from the a (0 - non zero) mask, and also
      !       computes its boundaries
      ! Arguments
      !     RMSK    R*4(*)  Real mask                       Input
      !     NX,NY   I*4     Size of mask                    Input
      !     BOX     I(4)    Mask boundary (xblc,yblc,xtrc,ytrc)     Output
      !     LIST    I*4(*)  List of pixels                  Output
      !---------------------------------------------------------------------
      integer, intent(in) :: nx                     ! X size
      integer, intent(in) :: ny                     ! Y size
      real(kind=4), intent(in) :: rmsk(nx,ny)       ! Real mask
      integer, intent(out) :: box(4)                ! Mask Boundary
      integer, intent(out) :: list(nx*ny)           ! List of pixels in mask
      integer, intent(out) :: nl
    end subroutine get_rlist
  end interface
  !
  interface
    subroutine gr4_slmsk (rmsk,lmsk,nx,ny,box)
      !---------------------------------------------------------------------
      ! @ public
      !     Return a LOGICAL mask from the a (0 - non zero) mask, and also
      !       computes its boundaries
      !---------------------------------------------------------------------
      integer, intent(in) :: nx                ! X size
      integer, intent(in) :: ny                ! Y size
      real(kind=4), intent(in) :: rmsk(nx,ny)  ! Real mask
      logical, intent(out) :: lmsk(nx,ny)      ! Logical mask
      integer, intent(out) :: box(4)           ! Mask boundary (xblc,yblc,xtrc,ytrc)
    end subroutine gr4_slmsk
  end interface
  !
  interface
    subroutine get_lmask(hmask,rmask,hmap,lmask,box)
      use image_def
      !---------------------------------------------------------------------
      ! @ public
      !     Return a LOGICAL mask from the a (0 - non zero) mask, and also
      !       computes its boundaries
      !---------------------------------------------------------------------
      type(gildas), intent(in) :: hmask        ! Mask header
      type(gildas), intent(in) :: hmap         ! Map header  
      real(kind=4), intent(in) :: rmask(:,:)   ! Real mask
      logical, intent(out) :: lmask(:,:)       ! Logical mask
      integer, intent(out) :: box(4)           ! Mask boundary (xblc,yblc,xtrc,ytrc)
    end subroutine get_lmask
  end interface
  !
  interface
    subroutine getuv_conversion(uvout,nc,convert)
      use gildas_def
      use image_def
      use phys_const
      !---------------------------------------------------------------------
      ! MAPPING
      !   @ public
      !   Derive the frequency axis corresponding to a specified
      !   Velocity sampling.
      !---------------------------------------------------------------------
      type (gildas), intent(inout) :: uvout   ! Output UV table header
      integer, intent(in) :: nc               ! Number of desired channels
      real(8), intent(inout) :: convert(3)    ! Velocity conversion formula
    end subroutine getuv_conversion
  end interface
  !
  interface
    subroutine resample_uv (uvint,uvout,uvint_data,uvout_data,nt)
      use image_def
      !------------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for command UV_RESAMPLE
      !   Resample (in memory) a UV data set
      !------------------------------------------------------------------------
      type (gildas), intent(in) :: uvint  ! Input UV header
      type (gildas), intent(in) :: uvout  ! Output UV header
      real(4), intent(in) :: uvint_data(uvint%gil%dim(1),uvint%gil%dim(2))
      real(4), intent(out) :: uvout_data(uvout%gil%dim(1),uvout%gil%dim(2))
      integer, intent(in) :: nt         ! Number of trailing informations
    end subroutine resample_uv
  end interface
  !
  interface
    subroutine interpolate_uv(x,xdim,xinc,xref,xval, y,ydim,yinc,yref,yval)
      !-----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   Support for UV_RESAMPLE
      ! Performs the linear interpolation/integration for visibilities
      !
      ! 1) if actual interpolation (XINC <= YINC)
      !     this is a 2-point linear interpolation formula.
      !     the data is untouched if the resolution is unchanged and the shift
      !     is an integer number of channels.
      !
      ! 2) if not (XINC > YINC)
      !     boxcar convolution (width xinc-yinc) followed by linear interpolation
      !
      !-----------------------------------------------------------------------------
      integer, intent(in) :: ydim             ! Input axis size
      integer, intent(in) :: xdim             ! Output axis size
      real(8), intent(in) :: yref,yval,yinc   ! Input conversion formula
      real(8), intent(in) :: xref,xval,xinc   ! Output conversion formula
      real(4), intent(in) :: y(3,xdim)        ! Input values
      real(4), intent(out) :: x(3,ydim)       ! Output values
    end subroutine interpolate_uv
  end interface
  !
  interface
    subroutine average_uv (out,nx,nv,inp,ny,nc,num,nt)
      !------------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for command UV_AVERAGE
      !   Average (in memory) a series of channels of a UV data set
      !------------------------------------------------------------------------
      integer, intent(in) :: num        ! Number of selected channels
      integer, intent(in) :: nx         ! Output Visibility size
      integer, intent(in) :: nv         ! Number of visibilities
      real, intent(out) :: out(nx,nv)   ! Output Visibilities
      integer, intent(in) :: ny         ! Input visibility size
      real, intent(in) :: inp(ny,nv)    ! Input visibilities
      integer, intent(in) :: nc(num)    ! Selected Channels, first & last pairs
      integer, intent(in) :: nt         ! Number of trailing informations
    end subroutine average_uv
  end interface
  !
  interface
    subroutine compress_uv(out,nx,nv,mx,inp,ny,nc,nt)
      !------------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Support for command UV_COMPRESS
      !   Compress (in memory) by NC channels a UV data set
      !------------------------------------------------------------------------
      integer, intent(in) :: nx         ! Output Visibility size
      integer, intent(in) :: nv         ! Number of visibilities
      integer, intent(in) :: mx         ! Number of Output Channels
      real, intent(out) :: out(nx,nv)   ! Output Visibilities
      integer, intent(in) :: ny         ! Input visibility size
      real, intent(in) :: inp(ny,nv)    ! Input visibilities
      integer, intent(in) :: nc         ! Number of Channels to average
      integer, intent(in) :: nt         ! Number of trailing informations
    end subroutine compress_uv
  end interface
  !
  interface
    subroutine doself (model,resul,itype,self,weight)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !   Compute self calibraton factor
      !---------------------------------------------------------------------
      complex, intent(in) :: model   ! Model visibility
      complex, intent(in) :: resul   ! Actual observation
      integer, intent(in) :: itype   ! Type of self calibration
      complex, intent(out) :: self   ! Self calibration factor
      real, intent(out) :: weight    ! Weight scaling factor
    end subroutine doself
  end interface
  !
  interface
    subroutine doscal (nc,visi,cosi,sinu,sreel,simag,weight)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !	  Apply the self-calibration factor to the current visibility
      !	  Set weight to zero if no self-cal factor
      !---------------------------------------------------------------------
      integer, intent(in) :: nc           !  Number of channels
      real, intent(inout) :: visi(*)      !  Visibility
      real, intent(in) :: sreel           !  Real part to subtract
      real, intent(in) :: simag           !  Imaginary part to subtract
      real, intent(in) :: cosi            !  Phase rotation cos
      real, intent(in) :: sinu            !  Phase rotation sin
      real, intent(in) :: weight          !  Scaling factor of weight
    end subroutine doscal
  end interface
  !
  interface
    subroutine dosubt (nc,visi,sreel,simag)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !   Subtract a continuum value from a line visibility
      !---------------------------------------------------------------------
      integer, intent(in) :: nc           !  Number of channels
      real, intent(inout) :: visi(*)      !  Visibility
      real, intent(in) :: sreel           !  Real part
      real, intent(in) :: simag           !  Imaginary part
    end subroutine dosubt
  end interface
  !
  interface
    subroutine doflag (nc,visi)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !   Flag (by zero) a line visibility
      !---------------------------------------------------------------------
      integer, intent(in) :: nc           !  Number of channels
      real, intent(inout) :: visi(*)      !  Visibility
    end subroutine doflag
  end interface
  !
  interface
    subroutine getiba (visi,stime,time,base,uv)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !   Get baseline and time information
      !---------------------------------------------------------------------
      real, intent(in)  :: visi(*)                   ! Visibility
      real(8), intent(in) :: stime                   ! Reference time
      real(8), intent(out) :: time                   ! Time offset
      real, intent(out)  :: base(2)                  ! First and Last antenna
      real, intent(out)  :: uv(2)                    ! U and V
    end subroutine getiba
  end interface
  !
  interface
    subroutine dotime (mv,nv,visi,wtime,it,stime)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !	  Compute the observing times of the data, 
      !	  sort it and return sorting index
      !---------------------------------------------------------------------
      integer, intent(in) :: mv           ! Size of visibility
      integer, intent(in) :: nv           ! Number of visibilities
      real, intent(in) :: visi(mv,nv)     ! Visibilities
      real(8), intent(out) :: wtime(nv)   ! Sorted times
      integer, intent(inout) :: it(nv)    ! Sorting index
      real(8), intent(out) :: stime       ! Reference time
    end subroutine dotime
  end interface
  !
  interface
    subroutine geself (mv,nv,iw,visi,time,ftime,wtime,it,   &
         &    rbase,complx,uv)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !	  Compute the Observed Visibility of the "model source"
      !---------------------------------------------------------------------
      integer, intent(in) :: mv           ! Size of visibility
      integer, intent(in) :: nv           ! Number of visibilities
      real, intent(in) :: visi(mv,nv)     ! Visibilities
      real(8), intent(out) :: wtime(nv)   ! Sorted times
      integer, intent(in) :: iw(2)        ! First and Last channel
      real(8), intent(in) :: time         ! Time of observation
      real(8), intent(in) :: ftime        ! Tolerance on time +/-
      integer, intent(in) :: it(nv)       ! Ordering of visibilities
      real, intent(in) :: rbase(2)        ! Antennas
      real, intent(in) :: uv(2)           ! U and V
      complex, intent(out) :: complx      ! Result
    end subroutine geself
  end interface
  !
  interface
    subroutine findr (np,x,xlim,nlim)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   UV Tools
      !	  Find NLIM such as
      !	 	    X(NLIM-1) < XLIM <= X(NLIM)
      !	  for input data ordered.
      !	  Use a dichotomic search for that
      !---------------------------------------------------------------------
      integer, intent(in) :: np          ! Number of data points
      real(8), intent(in) :: x(np)       ! Data values
      real(8), intent(in) :: xlim        ! Value to be localized
      integer, intent(out) :: nlim       ! Found position
    end subroutine findr
  end interface
  !
  interface
    subroutine uvsort_uv (np,nv,ntrail,vin,vout,xy,cs,uvmax,uvmin,error)
      use gildas_def
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !     Rotate, Shift and Sort a UV table for map making
      !     Differential precession should have been applied before.
      !---------------------------------------------------------------------
      integer, intent(in) :: np        ! Size of a visibility
      integer, intent(in) :: nv        ! Number of visibilities
      integer, intent(in) :: ntrail    ! Number of trailing daps
      real, intent(in) :: vin(np,nv)   ! Input visibilities
      real, intent(out) :: vout(np,nv) ! Output visibilities
      real, intent(in) :: xy(2)        ! Phase shift
      real, intent(in) :: cs(2)        ! Frame Rotation
      real, intent(out) :: uvmax       ! Max UV value
      real, intent(out) :: uvmin       ! Min UV value
      logical, intent(out) :: error    !
    end subroutine uvsort_uv
  end interface
  !
  interface
    subroutine loaduv (visi,np,nv,cs,u,v,s,uvmax,uvmin)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING    UVSORT routines
      !     Load new U,V coordinates and sign indicator into work arrays
      !     for sorting.
      !---------------------------------------------------------------------
      integer, intent(in) :: np       ! Size of a visibility
      integer, intent(in) :: nv       ! Number of visibilities
      real, intent(in) :: visi(np,nv) ! Input visibilities
      real, intent(in) :: cs(2)       ! Rotation parameter
      real, intent(out) :: u(nv)      ! Output U and V coordinates
      real, intent(out) :: v(nv)      ! Output U and V coordinates
      logical, intent(out) :: s(nv)   ! V Sign indicator
      real, intent(inout) :: uvmax    ! Maximum length
      real, intent(inout) :: uvmin    ! Minimum baseline
    end subroutine loaduv
  end interface
  !
  interface
    subroutine chksuv (nv,v,it,sorted)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING    UVSORT routines
      !   Check if visibilities are sorted
      !---------------------------------------------------------------------
      integer, intent(in) :: nv      ! Number of visibilities
      real, intent(in) :: v(nv)      ! Visibilities
      integer, intent(out) :: it(nv) ! Sorting pointer
      logical, intent(out) :: sorted ! short cut
    end subroutine chksuv
  end interface
  !
  interface
    subroutine sortuv (vin,vout,np,nv,ntrail,xy,u,v,s,it)
      !---------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING    UVSORT routines
      !     Sort an input UV table into an output one.
      !     The output UV table is a rotated, phase shifted copy of
      !     the input one, with all V negative and increasing
      !---------------------------------------------------------------------
      integer, intent(in) :: np         ! Size of a visibility
      integer, intent(in) :: nv         ! Number of visibilities
      integer, intent(in) :: ntrail     ! Number of trailing daps
      real, intent(in) :: vin(np,nv)    ! Input visibilities
      real, intent(out) :: vout(np,nv)  ! Output visibilities
      real, intent(in) :: xy(2)         ! Phase shifting factors
      real, intent(in) :: u(nv)         ! New U coordinates
      real, intent(in) :: v(nv)         ! New V coordinates
      logical, intent(in) :: s(nv)      ! Sign of new visibility
      integer, intent(in) :: it(nv)     ! Pointer to old visibility
    end subroutine sortuv
  end interface
  !
  interface
    subroutine uniform_beam (map_name,uv_taper,map_size,map_cell,   &
            &    uniform,wcol,mcol,work,error,mode,                 &
            &    beams,mbeam,start,step,uvmax,result,huv,duv)
      use gildas_def
      use image_def
      use gbl_message
      !------------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   UV_STAT Compute a map from a CLIC UV Sorted Table
      !   by Gridding and Fast Fourier Transform, with
      !   one single beam for all channels.
      !
      ! Input :
      ! a precessed UV table, sorted in V, ordered in
      ! (U,V,W,D,T,iant,jant,nchan(real,imag,weig))
      ! Output :
      ! a beam image
      ! a VLM cube
      ! Work space :
      ! a  VLM complex Fourier cube (first V value is for beam)
      !------------------------------------------------------------------------
      type(gildas), intent(in) :: huv               ! UV Table Header
      real, intent(inout) :: duv(:,:)               ! Visibility Array
      character(len=*), intent(in) :: map_name      ! Name of image (void)
      character(len=*), intent(in) :: mode          ! Mode of statistics
      real, intent(in) :: uv_taper(3)               ! UV Taper
      integer, intent(in) :: map_size(2)            ! Number of pixels
      real, intent(in) :: map_cell(2)               ! Pixel size
      real, intent(in) :: uniform(2)                ! Robust parameter
      integer, intent(inout) :: wcol                ! Weight column
      integer, intent(inout) :: mcol(2)             ! Channel range
      integer, intent(in) :: mbeam      ! Number of beams
      real :: work(*)                   ! Work array
      logical :: error                  ! Error flag
      real, intent(out) :: beams(map_size(1),map_size(2),mbeam)
      real, intent(inout) :: start      ! Starting value for range
      real, intent(inout) :: step       ! Step for range
      real, intent(in) :: uvmax         ! Max UV distance
      real, intent(out) :: result(10,8) ! Resulting beam characteristics
    end subroutine uniform_beam
  end interface
  !
  interface
    function map_frequency(huv,rcol)
      use image_def
      !---------------------------------------------------------------
      ! @ public
      !   Return the observing frequency at the specified channel
      !---------------------------------------------------------------
      type(gildas), intent(in) :: huv
      real(8), intent(in) :: rcol
      real(8) :: map_frequency  ! Intent(out)
    end function map_frequency
  end interface
  !
  interface
    subroutine extracs (np,nx,ny,ip,in,out,lx,ly)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !     Extract a Fourier plane from the FFT cube
      !     Plane and Cube may have different X,Y dimensions
      !----------------------------------------------------------------------
      integer,intent(in) :: np  ! Number of planes
      integer,intent(in) :: nx  ! output FFT X plane size
      integer,intent(in) :: ny  ! output FFT Y plane size
      integer,intent(in) :: ip  ! Plane to be extracted
      integer,intent(in) :: lx  ! input FFT cube X plane size
      integer,intent(in) :: ly  ! input FFT cube Y plane size
      complex,intent(in) :: in(np,lx,ly) ! Input FFT cube
      complex,intent(out) :: out(nx,ny)  ! Output 2-D FFT
    end subroutine extracs
  end interface
  !
  interface
    subroutine extrac (np,nx,ny,ip,in,out)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !     Extract a Fourier plane from an FFT cube
      !     Plane and Cube must have same X,Y dimensions
      !----------------------------------------------------------------------
      integer,intent(in) :: np  ! Number of planes
      integer,intent(in) :: nx  ! FFT X plane size
      integer,intent(in) :: ny  ! FFT Y plane size
      integer,intent(in) :: ip  ! Plane to be extracted
      complex,intent(in) :: in(np,nx,ny) ! Input FFT cube
      complex,intent(out) :: out(nx,ny)  ! Output 2-D FFT
    end subroutine extrac
  end interface
  !
  interface
    subroutine dovisi (np,nv,visi,vv,ww,jw)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Extract V coordinate and Weight value
      !----------------------------------------------------------------------
      integer, intent(in) :: np        ! Size of visibilities
      integer, intent(in) :: nv        ! Number of visibilities
      real, intent(in) :: visi(np,nv)  ! Visibilities
      real, intent(out) :: vv(nv)      ! V values
      real, intent(out) :: ww(nv)      ! Weight values
      integer, intent(in) :: jw        ! Weight column
    end subroutine dovisi
  end interface
  !
  interface
    subroutine dogrid (corr,corx,cory,nx,ny,beam)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Compute grid correction array, with normalisation
      !   of beam to 1.0 at maximum pixel
      !----------------------------------------------------------------------
      integer, intent(in) :: nx     ! X size
      integer, intent(in) :: ny     ! Y size
      real, intent(in) :: beam(nx,ny) ! Denormalized beam
      real, intent(in) :: corx(nx)    ! X grid correction
      real, intent(in) :: cory(ny)    ! Y Grid correction
      real, intent(out) :: corr(nx,ny) ! Final grid correction and beam normalization
    end subroutine dogrid
  end interface
  !
  interface
    subroutine docorr (map,corr,nd)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Apply grid correction to map
      !----------------------------------------------------------------------
      integer, intent(in) :: nd
      real, intent(inout) :: map(nd)
      real, intent(in) :: corr(nd)
    end subroutine docorr
  end interface
  !
  interface
    subroutine docoor (n,xinc,x)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Compute FFT grid coordinates in U or V
      !----------------------------------------------------------------------
      integer,intent(in) :: n
      real, intent(out) :: x(n)
      real, intent(in) :: xinc
    end subroutine docoor
  end interface
  !
  interface
    subroutine findp (nv,xx,xlim,nlim)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING  Utility
      !   Find NLIM such as
      !   XX(NLIM-1) < XLIM < XX(NLIM)
      !   for input data ordered, retrieved from memory
      !   Assumes NLIM already preset so that XX(NLIM-1) < XLIM
      !----------------------------------------------------------------------
      integer, intent(in) :: nv       ! Number of values
      integer, intent(inout) :: nlim  ! Preset Position
      real, intent(in) :: xx(nv)  ! Input order value
      real, intent(in) :: xlim    ! Value to be located
    end subroutine findp
  end interface
  !
  interface
    subroutine findm (nv,xx,xlim,nlim)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING  Utility
      !   Find NLIM such as
      !     XX(NLIM-1) < XLIM < XX(NLIM)
      !   for input data ordered, retrieved from memory
      !   Assumes NLIM already preset so that XLIM < XX(NLIM)
      !----------------------------------------------------------------------
      integer, intent(in) :: nv       ! Number of values
      integer, intent(inout) :: nlim  ! Preset Position
      real, intent(in) :: xx(nv)  ! Input order value
      real, intent(in) :: xlim    ! Value to be located
    end subroutine findm
  end interface
  !
  interface
    subroutine grdtab (n, buff, bias, corr)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING  Utility
      !   Compute fourier transform of gridding function
      !----------------------------------------------------------------------
      integer, intent(in) :: n     ! Number of pixels, assuming center on N/2+1
      real, intent(in) :: buff(*)  ! Gridding function, tabulated every 1/100 cell
      real, intent(in) :: bias     ! Center of gridding function
      real, intent(out) :: corr(n) ! Gridding correction FT
    end subroutine grdtab
  end interface
  !
  interface
    subroutine retocm(r,z,nx,ny)
      !------------------------------------------------------------------------
      ! @  public
      ! MAPPING
      !   Convert real to complex, with Shifting in corners for FFT
      !------------------------------------------------------------------------
      integer, intent(in) :: nx, ny         ! Problem size
      real, intent(in) :: r(nx,ny)          ! Real values
      complex, intent(out) :: z(nx, ny)     ! Complex shifted values
    end subroutine retocm
  end interface
  !
  interface
    subroutine cmtore (in,out,nx,ny)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING Utility
      !   Extract Real image from Fourier Transform of its complex FFT
      !   with appropriate recentering
      !----------------------------------------------------------------------
      integer, intent(in) :: nx         ! Size of map
      integer, intent(in) :: ny         ! Size of map
      complex, intent(in) :: in(nx,ny)  ! Complex FFT
      real, intent(out) :: out(nx,ny)   ! Extracted real image
    end subroutine cmtore
  end interface
  !
  interface
    subroutine convfn (ctype, parm, buffer, bias)
      use gildas_def
      use gbl_message
      !----------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAPPING
      !   CONVFN computes the convolving functions and stores them in
      !   the supplied buffer. Values are tabulated every 1/100 cell.
      !----------------------------------------------------------------------
      integer, intent(inout) :: ctype
      real(4), intent(inout) :: parm(10)
      real(4), intent(out)   :: buffer(:)
      real(4), intent(out)   :: bias
    end subroutine convfn
  end interface
  !
  interface
    subroutine grdflt (ctypx, ctypy, xparm, yparm)
      !----------------------------------------------------------------------
      ! @ public
      !
      !     GRDFLT determines default parameters for the convolution functions
      !     If no convolving type is chosen, an Spheroidal is picked.
      !     Otherwise any unspecified values ( = 0.0) will be set to some
      !     value.
      ! Arguments:
      !     CTYPX,CTYPY           I  Convolution types for X and Y direction
      !                                1 = pill box
      !                                2 = exponential
      !                                3 = sinc
      !                                4 = expontntial * sinc
      !                                5 = spheroidal function
      !     XPARM(10),YPARM(10)   R*4  Parameters for the convolution fns.
      !                                (1) = support radius (cells)
      !
      !----------------------------------------------------------------------
      integer, intent(inout) :: ctypx,ctypy
      real(4), intent(inout) :: xparm(10), yparm(10)
    end subroutine grdflt
  end interface
  !
  interface
    subroutine uvgmax(huv,visi,uvmax,uvmin)
      use image_def
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING Support for UV_MAP
      !       Get the Min Max of UV distances
      !----------------------------------------------------------------------
      type (gildas), intent(inout) :: huv
      real, intent(in) ::  visi(:,:) ! Visibilities
      real, intent(out) :: uvmax ! Max baseline
      real, intent(out) :: uvmin ! Min baseline
    end subroutine uvgmax
  end interface
  !
  interface
    function sump(n,a)
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   Support for UV_MAP
      !       Return the sum of positive values in array
      !----------------------------------------------------------------------
      real :: sump    ! Return value, intent(out)
      integer, intent(in) :: n   ! Number of values
      real, intent(in) :: a(n)   ! Values
    end function sump
  end interface
  !
  interface
    subroutine dotape (jc,nv,visi,jx,jy,taper,we)
      use gildas_def
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING  Support for UV_MAP
      !     Apply taper to the weights of the visibility points.
      !----------------------------------------------------------------------
      integer, intent(in) :: nv          ! number of values
      integer, intent(in) :: jc          ! Size of a visibility
      integer, intent(in) :: jx          ! X coord location in VISI
      integer, intent(in) :: jy          ! Y coord location in VISI
      real, intent(in) :: visi(jc,nv)    ! Visibilities
      real, intent(in) :: taper(4)       ! Taper definition
      real, intent(inout) :: we(nv)      ! Weights
    end subroutine dotape
  end interface
  !
  interface
    subroutine doweig (jc,nv,visi,jx,jy,jw,unif,we,wm,vv,error,code)
      use gildas_def
      use gbl_message
      !----------------------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAPPING   Support for UV_MAP
      !     Compute weights of the visibility points.
      !----------------------------------------------------------------------
      integer, intent(in) ::  nv          ! number of values
      integer, intent(in) ::  jc          ! Number of "visibilities"
      integer, intent(in) ::  jx          ! X coord location in VISI
      integer, intent(in) ::  jy          ! Y coord location in VISI
      integer, intent(in) ::  jw          ! Location of weights. If .LE.0, uniform weight
      real, intent(in) ::  visi(jc,nv)    ! Visibilities
      real, intent(in) ::  unif           ! uniform cell size in Meters
      real, intent(inout) ::  we(nv)      ! Weight array
      real, intent(in) ::  wm             ! on input: % of uniformity
      real, intent(in) ::  vv(nv)         ! V values, pre-sorted
      logical, intent(inout) :: error
      integer, intent(in), optional :: code
    end subroutine doweig
  end interface
  !
  interface
    subroutine doweig_sph (jc,nv,visi,jx,jy,jw,unif,we,wm,vv,error,code)
      use gildas_def
      use gbl_message
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING   Support for UV_MAP
      !     Compute weights of the visibility points.
      !----------------------------------------------------------------------
      integer, intent(in) ::  nv          ! number of values
      integer, intent(in) ::  jc          ! Number of "visibilities"
      integer, intent(in) ::  jx          ! X coord location in VISI
      integer, intent(in) ::  jy          ! Y coord location in VISI
      integer, intent(in) ::  jw          ! Location of weights. If .LE.0, uniform weight
      real, intent(in) ::  visi(jc,nv)    ! Visibilities
      real, intent(in) ::  unif           ! uniform cell size in Meters
      real, intent(inout) ::  we(nv)      ! Weight array
      real, intent(in) ::  wm             ! on input: % of uniformity
      real, intent(in) ::  vv(nv)         ! V values, pre-sorted
      logical, intent(inout) :: error
      integer, intent(in), optional :: code  ! Number of sub-cells per UV uniform cell size
    end subroutine doweig_sph
  end interface
  !
  interface
    subroutine scawei (nv,uni,ori,wall)
      !---------------------------------------------------------
      ! @ public
      !
      ! MAPPING
      !   Scale the weights
      !---------------------------------------------------------
      integer, intent(in) :: nv     ! Number of visibilities
      real, intent(out) :: uni(nv)  ! Re-weighted weights
      real, intent(in)  :: ori(nv)  ! Original weights
      real, intent(out) :: wall     ! Sum of weights
    end subroutine scawei
  end interface
  !
  interface
    subroutine howmany_beams(uvin, nvisi, din, cases, ncase, error)
      use image_def
      !----------------------------------------------------------------------
      ! @ public
      !
      ! MAPPING support routine for command
      !     UV_CHECK
      !----------------------------------------------------------------------
      type(gildas), intent(in) :: uvin                  ! UV table header
      integer, intent(in) :: nvisi                      ! Number of visibilities
      real, intent(in), target :: din(uvin%gil%dim(1),nvisi)    ! UV data
      integer, intent(inout) :: cases(uvin%gil%nchan)   ! Possible cases for beams
      integer, intent(inout) :: ncase                   ! Number of cases
      logical, intent(out) :: error                     ! flag
    end subroutine howmany_beams
  end interface
  !
  interface
    subroutine t_channel_sampling(rname,huv,nident,msize)
      use image_def
      use clean_default
      use gbl_message
      !----------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAPPING
      !   Check how many channels can have the same beam
      !----------------------------------------------------------
      character(len=*), intent(in) :: rname      ! Caller's name
      type(gildas), intent(in) :: huv            ! UV data header
      integer, intent(out) :: nident             ! returned step
      integer, intent(in) :: msize               ! Current map_size
    end subroutine t_channel_sampling
  end interface
  !
  interface
    subroutine t_continuum(hluv,hcuv,channels,uvcode,error,alpha)
      use gildas_def
      use image_def
      use uvmap_def
      use gbl_message
      !$ use omp_lib
      !----------------------------------------------------------
      ! @ public-mandatory
      !
      ! MAPPING
      !   Support routine for UV_CONT / UV_LINE2CONT
      !   create a continuum UV table from a Line one
      !----------------------------------------------------------
      !
      type (gildas), intent(in) :: hluv          ! Line UV header
      type (gildas), intent(inout) :: hcuv       ! Continuum UV header
      integer, intent(in) :: channels(3)      ! Channel selection
      integer, intent(in) :: uvcode           ! Type of UV data
      logical, intent(out) :: error
      real, intent(in), optional :: alpha     ! Spectral index
    end subroutine t_continuum
  end interface
  !
  interface
    subroutine map_beamsize(huv,duv,uvmax,error)
      use image_def
      use gbl_message
      !
      ! @ public
      !     Get the natural synthesized beam size
      !
      type(gildas), intent(in) :: huv   ! UV Header
      real, intent(in) :: duv(:,:)      ! UV data
      real, intent(in) :: uvmax         ! Maximum UV value
      logical, intent(out) :: error     ! Error flag
    end subroutine map_beamsize
  end interface
  !
  interface
    subroutine time_compress(invisi,nd,first,last,wcol, out, ovisi, jv, &
      & mvisi, error)
      use gildas_def
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !   Time compress a UV table
      !   Compute visibilities for a single output time
      !---------------------------------------------------------------------
      type(gildas), intent(in) :: out
      integer, intent(in) :: nd                     ! Visibility size
      real, intent(in) :: invisi(:,:)               ! Input visibilities
      integer, intent(in) :: wcol                   ! Weight column
      real, intent(inout) :: ovisi(:,:)             ! Output visibilities
      integer, intent(in) :: first, last            ! First and last input visibilities
      integer, intent(inout) :: jv                  ! Current output visibility number
      integer, intent(in) :: mvisi
      logical, intent(out) :: error
    end subroutine time_compress
  end interface
  !
  interface
    subroutine add_visiw(out,ovisi,aw,avisi,sw)
      use image_def
      !---------------------------------------------------------------------
      ! @ public
      !   Add a visibility to current output one
      !---------------------------------------------------------------------
      type(gildas), intent(in) :: out   ! Input image header
      real, intent(inout) :: ovisi(:)   ! Output visibilities
      real, intent(in) :: aw            ! Input weight
      real, intent(inout) :: avisi(:)   ! Input visibilities
      real, intent(inout) :: sw         ! Output weight
    end subroutine add_visiw
  end interface
  !
  interface
    subroutine mean_visiw(out,ovisi,sw)
      use image_def
      !---------------------------------------------------------------------
      ! @ public
      !   Normalize the final visibility
      !---------------------------------------------------------------------
      type(gildas), intent(in) :: out   ! Input image header
      real, intent(inout) :: ovisi(:)   ! Output visibilities
      real, intent(inout) :: sw         ! Output weight
    end subroutine mean_visiw
  end interface
  !
  interface
    subroutine time_integrate(rname,huv,mytime,wcol,nu,nv,vin,vout,nvout,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! Time-Average a UV data set
      !---------------------------------------------------------------------
      character(len=*), intent(in) :: rname  ! Calling routine
      type(gildas), intent(in) :: huv        ! UV Header
      real(4), intent(in) :: mytime          ! Integration time
      integer, intent(in) :: wcol            ! Weight column
      integer, intent(in) :: nu              ! Size of a visibility
      integer, intent(in) :: nv              ! Number of input visibilities
      real, intent(in) :: vin(:,:)           ! input visibilities
      real, intent(inout) :: vout(:,:)       ! output visibilities
      integer, intent(out) :: nvout          ! Number of output visibilities
      logical, intent(out) :: error          ! Error flag
    end subroutine time_integrate
  end interface
  !
end module mapping_interfaces_public
