program uv_template
  use gildas_def
  use gkernel_interfaces
  character(len=filename_length) :: cuvin, cuvou 
  integer :: nc(2)
  logical error
  !
  ! Code:
  call gildas_open
  call gildas_char('UV_INPUT$',cuvin)
  call gildas_char('UV_OUTPUT$',cuvou)
  !
  ! Other parameters
  ! call gildas_inte('NC$',nc,2)   ! Desired channel range for example
  call gildas_close
  !
  call sub_uv_template_whole (cuvin,cuvou,nc,error)
  if (error) call sysexi(fatale)
end program uv_template
!
subroutine sub_uv_template_block (cuvin, cuvou, nc, error)
  use gkernel_interfaces
  use image_def
  use gbl_message
  !---------------------------------------------------------------------
  ! GILDAS
  !	A template for handling UV tables, with an Input and Output one
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: cuvin 
  character(len=*), intent(in) :: cuvou 
  integer, intent(in) :: nc(2)
  logical, intent(out) :: error
  !
  ! Local variables
  character(len=*), parameter :: rname='UV_TEMPLATE'
  character(len=80)  :: mess
  type (gildas) :: uvin
  type (gildas) :: uvou
  integer :: ier, nblock, ib, nvisi
  !
  ! Simple checks 
  error = len_trim(cuvin).eq.0
  if (error) then
    call map_message(seve%e,rname,'No input UV table name')
    return
  endif
  !
  call gildas_null (uvin, type = 'UVT')     ! Define a UVTable gildas header
  call gdf_read_gildas (uvin, cuvin, '.uvt', error, data=.false.)
  if (error) then
    call map_message(seve%e,rname,'Cannot read input UV table')
    return
  endif
  !
  ! Here modify the header of the output UV table according
  ! to the desired goal
  !
  call gildas_null (uvou, type = 'UVT')     ! Define a UVTable gildas header
  call gdf_copy_header(uvin,uvou,error)
  call sic_parse_file(cuvou,' ','.uvt',uvou%file)
  !
  ! create the image
  call gdf_create_image(uvou,error)
  if (error) return
  !
  ! Define blocking factor, on largest data file, usually the input one
  ! but not always...  
  call gdf_nitems('SPACE_GILDAS',nblock,uvin%gil%dim(1)) ! Visibilities at once
  nblock = min(nblock,uvin%gil%dim(2))
  ! Allocate respective space for each file
  allocate (uvin%r2d(uvin%gil%dim(1),nblock), uvou%r2d(uvou%gil%dim(1),nblock), stat=ier)
  if (ier.ne.0) then
    write(mess,*) 'Memory allocation error ',uvin%gil%dim(1), nblock
    call map_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  ! Loop over line table - The example assumes the same
  ! number of visibilities in Input and Output, which may not
  ! be true...
  uvou%blc = 0
  uvou%trc = 0
  uvin%blc = 0
  uvin%trc = 0
  do ib = 1,uvou%gil%dim(2),nblock
    write(mess,*) ib,' / ',uvou%gil%dim(2),nblock
    call map_message(seve%d,rname,mess) 
    uvin%blc(2) = ib
    uvin%trc(2) = min(uvin%gil%dim(2),ib-1+nblock) 
    uvou%blc(2) = ib
    uvou%trc(2) = uvin%trc(2)
    call gdf_read_data(uvin,uvin%r2d,error)
    nvisi = uvin%trc(2)-uvin%blc(2)+1
    !
    ! Here do the job
    !
    ! call myjob (uvou, uvou%r2d, uvin, uvin%r2d, nvisi) 
    !
    call gdf_write_data (uvou,uvou%r2d,error)
    if (error) return
  enddo
  !
  ! Finalize the image
  call gdf_close_image(uvin,error)
  call gdf_close_image(uvou,error)
  if (error) return
  !
  call map_message(seve%i,rname,'Successful completion')
  return
end subroutine sub_uv_template_block
!
! 
subroutine sub_uv_template_whole (cuvin, cuvou, nc, error)
  use gkernel_interfaces
  use image_def
  use gbl_message
  !---------------------------------------------------------------------
  ! GILDAS
  !	A template for handling UV tables, with an Input and Output one
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: cuvin 
  character(len=*), intent(in) :: cuvou 
  integer, intent(in) :: nc(2)
  logical, intent(out) :: error
  !
  ! Local variables
  character(len=*), parameter :: rname='UV_TEMPLATE'
  type (gildas) :: uvin
  type (gildas) :: uvou
  type (gildas) :: huv
  integer :: ier
  integer :: mv,nv,ncin,nadd, my_nc(2)
  !
  !
  ! Simple checks 
  error = len_trim(cuvin).eq.0
  if (error) then
    call map_message(seve%e,rname,'No input UV table name')
    return
  endif
  !
  call gildas_null (uvin, type = 'UVT')     ! Define a UVTable gildas header
  call gdf_read_gildas (uvin, cuvin, '.uvt', error, data=.false.)
  if (error) then
    call map_message(seve%e,rname,'Cannot read input UV table')
    return
  endif
  !
  ! huv can be used as intermediate step to select a subset of all channels
  ! and specify the desired layout
  call gildas_null (huv, type = 'UVT') 
  call gdf_copy_header(uvin,huv,error)
  if (error) return
  !
  ! my_nc = nc
  my_nc = [1,uvin%gil%nchan]
  !
  ! Define number of visibilities and channels
  mv = huv%gil%dim(1)              ! Visibility size
  nv = huv%gil%nvisi               ! Number of visibilities
  ncin = huv%gil%nchan             ! Number of channels
  ! Number of additional columns, with default layout
  nadd = huv%gil%dim(1)-(huv%gil%nlead+huv%gil%natom*ncin) 
  !
  call gdf_copy_header(huv,uvou,error)
  !
  ! Here modify the header of the output UV table according
  ! to the desired goal
  !
  ! call my_header (uvou)
  !
  call sic_parse_file(cuvou,' ','.uvt',uvou%file)
  !
  allocate(huv%r2d(huv%gil%dim(1),huv%gil%dim(2)), &
       uvou%r2d(uvou%gil%dim(1),uvou%gil%dim(2)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'Memory allocation error') 
    error = .true.
    return
  endif
  !
  ! read the Input UV data
  ! nc(2) are the first and last channels to read. 
  ! 0,0 means nothing at all, only ancillary information ?
  !
  call gdf_read_uvdataset(uvin,huv,nc,huv%r2d,error)
  if (error) return
  !
  ! Here do the job
  !
  ! call myjob (uvou, uvou%r2d, huv, huv%r2d) 
  !
  ! Write the output UV table, header & data at once
  call gdf_write_image(uvou,huv%r2d,error)
  if (error) return
  !
  call map_message(seve%i,rname,'Successful completion')
  return
end subroutine sub_uv_template_whole
