!
subroutine gdf_read_uvonly(huv,uv,error)
  use gio_interfaces, except_this=>gdf_read_uvonly
  use image_def
  use gio_image
  use gbl_message
  !---------------------------------------------------------------------
  ! @ public
  ! GDF API
  !       Read the UV data of a GILDAS UV structure
  !       UVT and TUV order are allowed...
  !---------------------------------------------------------------------
  type (gildas), intent(inout) :: huv               ! UV table descriptor
  real(kind=4), intent(out) :: uv(huv%gil%nvisi,2)  ! Return U,V coordinates
  logical, intent(out) :: error                     ! Flag
  !
  integer(kind=size_length) :: mydims(gdf_maxdims)
  integer :: i
  integer :: is,ms,jcode,codes(2), form, ier
  real(kind=4), allocatable :: work(:,:)
  character(len=*), parameter :: rname = 'GDF_READ_UVONLY'
  !
  huv%status = code_read_image
  !
  is = huv%loca%islo
  if (gdf_stis(is).eq.-1) then
    call gio_message(seve%e,rname,'No such UV data')
    error = .true.
    return
  endif
  !
  huv%blc = 0
  huv%trc = 0
  !
  if (huv%gil%type_gdf.eq.code_gdf_tuv) then
    huv%status = code_read_image
    !
    ! Reshape slot to current image shape
    mydims = huv%gil%dim
    call gio_cdim(is,huv%gil%ndim,mydims)
    !
    ! Compute the BLC, TRC
    codes = (/code_uvt_u,code_uvt_v/)
    do i = 1, 2
      jcode = codes(i)
      huv%blc(2) = huv%gil%column_pointer(jcode)
      huv%trc(2) = huv%gil%column_pointer(jcode)+huv%gil%column_size(jcode)-1
      !
      ! Now test the type of data
      form = fmt_r4
      if (iconv(is).ne.0 .and. huv%gil%column_size(jcode).eq.2) then
        allocate (work(2,huv%gil%nvisi),stat=ier)
        call gio_dams(ms,is,huv%blc,huv%trc,work,form,error)
        call gio_swap4to8 (work,huv%gil%nvisi)
        call r8tor4(work,uv(1,i),huv%gil%nvisi)
        deallocate (work,stat=ier)
      else
        call gio_dams(ms,is,huv%blc,huv%trc,uv(:,i),form,error)
      endif
      call gio_frms(ms,error)
    enddo
    huv%status = 0
  !
  else if (huv%gil%type_gdf.eq.code_gdf_uvt) then
    !
    ! Compute the BLC, TRC
    codes = (/code_uvt_u,code_uvt_v/)
    allocate (work(2,huv%gil%nvisi),stat=ier)
    call gdf_read_uvonly_codes(huv,work,codes,2,error)
    uv = transpose(work)
    deallocate (work,stat=ier)
  else
    call gio_message(seve%e,rname,'Data set is not a UV data')
    error = .true.
    return
  endif
end subroutine gdf_read_uvonly
!
subroutine gdf_read_uvonly_codes(huv,uv,codes,ncode,error)
  use gio_interfaces, except_this=>gdf_read_uvonly_codes
  use image_def
  use gio_image
  use gbl_message
  !---------------------------------------------------------------------
  ! @ public
  ! GDF API
  !       Read the Time-Baseline data of a GILDAS UV structure
  !       UVT and TUV order are allowed...
  !---------------------------------------------------------------------
  type (gildas), intent(inout) :: huv               ! UV table descriptor
  integer(4), intent(in) :: ncode                   ! Number of codes
  integer(4), intent(in) :: codes(ncode)            ! Desired codes
  real(kind=4), intent(out) :: uv(ncode,huv%gil%nvisi)  ! Return Values
  logical, intent(out) :: error                     ! Flag
  !
  real, allocatable :: duvin(:,:)
  integer(kind=index_length) :: nleft, nblock, next, kblock, iv, kv, jv, i
  integer(kind=4) :: ipin, ipou, isin, isou, l
  real :: next_percentage, percentage_step
  character(len=80) :: mess
  !
  integer(kind=size_length) :: mydims(gdf_maxdims)
  integer(kind=index_length) :: j
  integer :: is,ms,jcode, form, ier
  real, allocatable :: work(:,:)
  character(len=*), parameter :: rname = 'GDF_READ_UVONLY_CODES'
  logical :: warn
  !
  huv%status = code_read_image
  form = fmt_r4
  !
  is = huv%loca%islo
  if (gdf_stis(is).eq.-1) then
    call gio_message(seve%e,rname,'No such UV data')
    error = .true.
    return
  endif
  !
  ! Check if Code is present
  do i = 1, ncode
    jcode = codes(i)
    ipin = huv%gil%column_pointer(jcode)
    isin = huv%gil%column_size(jcode)
    !!Print *,l,'Ipin ',ipin,isin,'Ipou ',ipou,isou
    if (isin.eq.0) then
      write(mess,'(A,I6,A,I6,I6)') 'Column ',jcode,' not found in UV table'
      warn = .true.
    else if (ipin+isin-1 .gt. huv%gil%dim(1)) then
      write(mess,'(A,I6,A,I6,I6)') '#1 Inconsistent input UV Table: Column ',jcode,' out of bound ', &
      huv%gil%dim(1),jcode
      warn = .true.
    else
      warn = .false.
    endif
    if (warn) then
      error = .true.
      call gio_message(seve%w,rname,mess)
    endif
  enddo
  if (error) return
  !
  huv%blc = 0
  huv%trc = 0
  !
  if (huv%gil%type_gdf.eq.code_gdf_tuv) then
    ! Read a TUV order table.  Simply get the right columns then,
    ! and put in place by a transposition
    mydims = huv%gil%dim
    call gio_cdim(is,huv%gil%ndim,mydims)
    allocate (work(huv%gil%nvisi,2),stat=ier)
    !
    do i = 1, ncode
      jcode = codes(i)
      huv%blc(2) = huv%gil%column_pointer(jcode)
      huv%trc(2) = huv%gil%column_pointer(jcode)+huv%gil%column_size(jcode)-1
      !
      ! Now test the type of data
      form = fmt_r4
      call gio_dams(ms,is,huv%blc,huv%trc,work,form,error)
      if (iconv(is).ne.0 .and. huv%gil%column_size(jcode).eq.2) then
        call gio_swap4to8 (work,huv%gil%nvisi)
        do j=1,huv%gil%nvisi
          call r8tor4(work(j,1),uv(i,j),1)
        enddo
      else
        do j=1,huv%gil%nvisi
          uv(i,j) = work(j,1)
        enddo
      endif
      !
      call gio_frms(ms,error)
    enddo
    deallocate (work)
    !
  else if (huv%gil%type_gdf.eq.code_gdf_uvt) then
    !
    ! Reshape slot to current image shape
    mydims = huv%gil%dim
    call gio_cdim(is,huv%gil%ndim,mydims)
    !
    ! Doing this visibility by visibility is a catastrophy.
    ! We need to do that by reading by blocks...
    !
    ! Read and extract by block
    nblock = 1024
    kblock = huv%gil%dim(2)/nblock
    if (kblock.lt.10) then
       percentage_step = 100.
    else if (kblock.lt.100) then
       percentage_step = 25.
    else
       percentage_step = 10.
    endif
    !
    ! We do not use the "non-contiguous" subset mode of gdf_read_data
    ! as it would allocate the minimally contiguous subset anyway.
    !
    huv%blc = 0
    huv%trc = 0
    allocate (duvin(huv%gil%dim(1),nblock), stat=ier)
    if (ier.ne.0) then
      error = .true.
      return
    endif
    next_percentage = percentage_step
    next = next_percentage*(huv%gil%dim(2)/100)
    write(*,'(A)',ADVANCE="NO") 'Read % '
    do iv =1, huv%gil%dim(2), nblock
      huv%blc(2) = iv
      nleft = min (nblock,huv%gil%dim(2)-iv+1)
      huv%trc(2) = iv+nleft-1
      call gdf_read_data (huv,duvin,error)
      if (error) then
        deallocate(duvin)
        return
      endif
      if (iv.lt.next.and.iv+nleft.gt.next) then
        write(*,'(F6.0)',ADVANCE="NO") next_percentage
        next_percentage = next_percentage+percentage_step
        next = next_percentage*(huv%gil%dim(2)/100)
      endif
      !
      ! The required columns ...
      do i = 1, ncode
        jcode = codes(i)
        ipin = huv%gil%column_pointer(jcode)
        isin = huv%gil%column_size(jcode)
        if (ipin+isin-1 .gt. huv%gil%dim(1)) then
          write(mess,'(A,I6,A,I6,I6)') '#2 Inconsistent input UV Table: Column ',l,' out of bound ', &
          huv%gil%dim(1),jcode
          call gio_message(seve%w,rname,mess)
          Print *,l,'Ipin ',ipin,isin,'Ipou ',ipou,isou
          cycle
        endif
        !
        jv = iv
        do kv = 1,nleft
          if (isin.eq.2) then
            call r8tor4 (duvin(ipin,kv), uv(i,jv), 1)
          else
            uv(i,jv) = duvin(ipin,kv)
          endif
          jv = jv+1
        enddo
      enddo
      !
    enddo
    write(*,'(A)') '  ... Done '
    deallocate(duvin)
    !
  else
    call gio_message(seve%e,rname,'Data set is not a UV data')
    error = .true.
    return
  endif
  !
  huv%status = 0
  huv%loca%getvm = .false.
  !!write(99,*) 'Tested gdf_read_uvonly_codes ',huv%loca%size
end subroutine gdf_read_uvonly_codes
!
subroutine gio_swap4to8 (work,n)
  !---------------------------------------------------------------------
  ! @ no-interface
  !---------------------------------------------------------------------
  integer(kind=4) :: n
  integer(kind=4) :: work(2,n)
  ! Local
  integer(kind=4) :: l
  integer(kind=4) :: itmp
  !
  do l=1,n
    itmp = work(1,l)
    work(1,l) = work(2,l)
    work(2,l) = itmp
  enddo
  !
end subroutine gio_swap4to8
!
subroutine gdf_read_uvall (huv,array,error)
  use gio_interfaces
  use image_def
  use gio_image
  use gbl_message
  use gbl_format
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  !       Read data from a GILDAS UV structure and
  !       place it in the specified array
  !---------------------------------------------------------------------
  type(gildas), intent(inout) :: huv       ! Image descriptor
  real(kind=4), intent(inout) :: array(*)  ! Data
  logical,      intent(out)   :: error     ! Flag
  ! Local
  integer(kind=4) :: is,ms,form
  integer(kind=size_length) :: mydims(gdf_maxdims), ip, l, i, istart
  character(len=*), parameter :: rname = 'GDF_READ_UVDATA'
  logical :: do_conv
  !
  huv%status = code_read_data
  is = huv%loca%islo
  if (gdf_stis(is).eq.-1) then
    call gio_message(seve%e,rname,'No such UV data')
    error = .true.
    return
  endif
  !
  ! Only valid for a full array
  if (any(huv%blc.ne.0) .or. any(huv%trc.ne.0)) then
    call gio_message(seve%e,rname,'Only valid for all channels')
    error = .true.
    return
  endif
  !
  ! Case  UVT
  if (huv%gil%type_gdf.eq.code_gdf_uvt) then
    mydims = huv%gil%dim
      !!  call gdf_print_header(huv)
    call gio_cdim(is,huv%gil%ndim,mydims)
    form = fmt_r4
    ! Read data
    !!Print *,'DAMS ', huv%blc,huv%trc
    call gio_dams(ms,is,huv%blc,huv%trc,array,form,error)
    !!Print *,'DAMS ', huv%gil%ndim,huv%gil%dim
    if (error) return
    !
    ! Free it
    call gio_frms(ms,error)
    huv%loca%mslo = ms
    huv%status = 0
    !
    ! Check if any conversion must be applied
    if (iconv(is).lt.0) return
    !
    ! Convert the extra values
    do_conv = maxval(huv%gil%column_size).gt.1
    !
    if (do_conv) then
      ip = 0
      do l=1,huv%gil%nvisi
        do i=1,code_uvt_last
          if (huv%gil%column_size(i).eq.2) then
            istart = huv%gil%column_pointer(i)
            call gio_swap4to8 (array(ip+istart),1)
          endif
        enddo
        ip = ip+huv%gil%dim(1)
      enddo
    endif
    !
    ! Case  TUV
  else if (huv%gil%type_gdf.eq.code_gdf_tuv) then
    mydims = huv%gil%dim
    call gio_cdim(is,huv%gil%ndim,mydims)
    form = fmt_r4
    ! Read data
    !!Print *,'DAMS ', huv%blc,huv%trc
    call gio_dams(ms,is,huv%blc,huv%trc,array,form,error)
    !!Print *,'DAMS ', huv%gil%ndim,huv%gil%dim
    if (error) return
    !
    ! Free it
    call gio_frms(ms,error)
    huv%loca%mslo = ms
    huv%status = 0
    !
    ! Check if any conversion must be applied
    if (iconv(is).lt.0) return
    !
    ! Convert the extra columns
    do i=1,code_uvt_last
      if (huv%gil%column_size(i).eq.2) then
        istart = (huv%gil%column_pointer(i)-1)*huv%gil%nvisi + 1
        call gio_swap4to8 (array(istart),huv%gil%nvisi)
      endif
    enddo
    !
  else
    call gio_message(seve%e,rname,'Data set is not a UV data')
    error = .true.
    return
  endif
end subroutine gdf_read_uvall
!
subroutine gdf_write_uvall(huv,array,error)
  use image_def
  use gbl_message
  use gio_dependencies_interfaces
  use gio_interfaces
  use gio_image
  !---------------------------------------------------------------------
  ! @ no-interface  (Yet...)
  !       Write UV data to an image file specified
  !       by its image structure. The image must have been
  !       opened for write before
  !---------------------------------------------------------------------
  type(gildas), intent(inout) :: huv        ! Image descriptor
  real, intent(inout) :: array(*)           ! Data
  logical, intent(out) :: error             ! Flag
  ! Local
  integer :: ms, is, form
  integer(kind=size_length) :: mydims(gdf_maxdims), i, l, ip, istart
  character(len=*), parameter :: rname = 'GDF_WRITE_UVDATA'
  logical :: do_conv
  !
  huv%status = code_write_data
  is = huv%loca%islo
  if (gdf_stis(is).eq.-1) then
    call gio_message(seve%e,rname,'No such UV data set')
    error = .true.
    return
  endif
  ! Reshape slot to current image shape
  mydims = huv%gil%dim
  call gio_cdim(is,huv%gil%ndim,mydims)
  !
  ! Only valid for a full array
  if (any(huv%blc.ne.0) .or. any(huv%trc.ne.0)) then
    call gio_message(seve%e,rname,'Only valid for all channels')
    error = .true.
    return
  endif
  !
  ! Check if any conversion
  do_conv = .false.
  if (iconv(is).ge.0) then
    do i=1,code_uvt_last
      if (huv%gil%column_size(i).eq.2) then
        do_conv =.true.
        exit
      endif
    enddo
  endif
  !
  mydims = huv%gil%dim
  call gio_cdim(is,huv%gil%ndim,mydims)
  form = fmt_r4
  !
  ! Case  UVT
  if (huv%gil%type_gdf.eq.code_gdf_uvt) then
    if (do_conv) then
      ip = 0
      do l=1,huv%gil%nvisi
        do i=1,code_uvt_last
          if (huv%gil%column_size(i).eq.2) then
            istart = huv%gil%column_pointer(i)
            call gio_swap4to8 (array(ip+istart),1)
          endif
        enddo
        ip = ip+huv%gil%dim(1)
      enddo
    endif
    !
    ! Associate pre-defined memory area to image
    huv%loca%addr = locwrd(array)
    call gio_pums (ms,is,huv%blc,huv%trc,huv%loca%addr,huv%gil%form,error)
    if (error) return
    !
    ! Dump to disk
    call gio_frms(ms,error)
    !
    ! Re-establish the proper Word order if needed
    if (do_conv) then
      ip = 0
      do l=1,huv%gil%nvisi
        do i=1,code_uvt_last
          if (huv%gil%column_size(i).eq.2) then
            istart = huv%gil%column_pointer(i)
            call gio_swap4to8 (array(ip+istart),1)
          endif
        enddo
        ip = ip+huv%gil%dim(1)
      enddo
    endif
    !
    ! Case  TUV
  else if (huv%gil%type_gdf.eq.code_gdf_tuv) then
    !
    ! Convert the extra columns
    if (do_conv) then
      do i=1,code_uvt_last
        if (huv%gil%column_size(i).eq.2) then
          istart = (huv%gil%column_pointer(i)-1)*huv%gil%nvisi + 1
          call gio_swap4to8 (array(istart),huv%gil%nvisi)
        endif
      enddo
    endif
    !
    ! Associate pre-defined memory area to image
    huv%loca%addr = locwrd(array)
    call gio_pums (ms,is,huv%blc,huv%trc,huv%loca%addr,huv%gil%form,error)
    if (error) return
    !
    ! Dump to disk
    call gio_frms(ms,error)
    !
    ! Re-establish the proper Word order if needed
    if (do_conv) then
      do i=1,code_uvt_last
        if (huv%gil%column_size(i).eq.2) then
          istart = (huv%gil%column_pointer(i)-1)*huv%gil%nvisi + 1
          call gio_swap4to8 (array(istart),huv%gil%nvisi)
        endif
      enddo
    endif
    !
  else
    call gio_message(seve%e,rname,'Data set is not a UV data')
    error = .true.
    return
  endif
  !
  huv%loca%mslo = ms
  huv%status = 0
end subroutine gdf_write_uvall
!
subroutine gdf_read_uvdataset(huvin,huvou,nc,duvou,error)
  use gio_interfaces, except_this=>gdf_read_uvdataset
  use image_def
  use gio_image
  use gbl_message
  use gbl_format
  !---------------------------------------------------------------------
  ! @ public
  !       Read UV data and Associated parameters from a GILDAS UV
  !       structure and place it in the specified array
  !---------------------------------------------------------------------
  type(gildas), intent(inout) :: huvin     ! Input UV header (data file)
  type(gildas), intent(inout) :: huvou     ! Output UV header (program used)
  integer(kind=4), intent(in) :: nc(2)     ! Selected channels
  real(kind=4), intent(inout) :: duvou(huvou%gil%dim(1),huvou%gil%dim(2))  ! Data
  logical,      intent(out)   :: error     ! Flag
  !
  ! Local
  character(len=*), parameter :: rname = 'GDF_READ_UVDATASET'
  real, allocatable :: duvin(:,:)
  integer(kind=index_length) :: nleft, nblock, next, kblock, iv, kv, jv, i
  integer(kind=4) :: ipin, ipou, isin, isou, l, is, local_nc(2)
  real :: next_percentage, percentage_step
  integer :: ier, imiss, imore
  integer :: ifcol, ofcol, ilcol, olcol, nchan
  character(len=80) :: mess
  !
  huvin%status = code_read_data
  is = huvin%loca%islo
  if (gdf_stis(is).eq.-1) then
    call gio_message(seve%e,rname,'No such UV data')
    error = .true.
    return
  endif
  !
  if (any(huvin%gil%dim(1:2).eq.0)) then
    call gio_message(seve%e,rname,'Empty UV data set')
    error = .true.
    return
  endif
  !
  local_nc = nc
  ier = gdf_range(local_nc, huvin%gil%nchan)
  if (ier.ne.0) then
    call gio_message(seve%e,rname,'Invalid channel range')
    error = .true.
    return
  endif
  !
  ! Get the subset boundaries
  nchan = local_nc(2)-local_nc(1)+1
  ofcol = huvou%gil%fcol
  olcol = huvou%gil%fcol+huvin%gil%natom*huvou%gil%nstokes*nchan-1  ! Or huvou%gil%natom
  huvou%gil%lcol = olcol  ! Precaution ?...
  ifcol = huvin%gil%fcol+huvin%gil%natom*huvin%gil%nstokes*(local_nc(1)-1)
  ilcol = huvin%gil%fcol+huvin%gil%natom*huvin%gil%nstokes*local_nc(2)-1
  !!Print *,'Range ',ifcol,ilcol, ofcol,olcol
  !!Print *,'OUT ',huvou%gil%dim
  ! Shift the trailing columns of the output table by the right amount
  do l=1,code_uvt_last
    if (huvou%gil%column_pointer(l).gt.huvin%gil%lcol) then
      !!Print *,'Shifting ',l,' by ',-huvin%gil%lcol+huvou%gil%lcol
      huvou%gil%column_pointer(l) = &
      huvou%gil%column_pointer(l)-huvin%gil%lcol+huvou%gil%lcol
    endif
  enddo
  !
  ! Shift the Frequency & Stokes arrays if present
  if (huvin%gil%nfreq.ne.0) then
    huvou%gil%nfreq = nchan
    if (associated(huvou%gil%freqs)) then
      deallocate(huvou%gil%freqs,huvou%gil%stokes,stat=ier)
      if (ier.ne.0) then
        call gio_message(seve%w,rname,'Frequency array deallocation error')
      endif
    endif
    allocate(huvou%gil%freqs(nchan),huvou%gil%stokes(nchan),stat=ier)
    if (ier.ne.0) then
      call gio_message(seve%e,rname,'Frequency array allocation error')
      error = .true.
      return
    endif
    huvou%gil%freqs = huvin%gil%freqs(local_nc(1):local_nc(2))
    huvou%gil%stokes = huvin%gil%stokes(local_nc(1):local_nc(2))
    ! Squeeze it if possible
    call gio_setuv_freq(huvou%gil,error)
    call gio_message(seve%i,rname,'Frequency array has been shifted')
  endif
  !
  imiss = 0
  imore = 0
  if (huvou%gil%type_gdf.eq.code_gdf_tuv) then
    call gio_message(seve%w,rname,'Producing a TUV order')
    if (huvin%gil%type_gdf.eq.code_gdf_tuv) then
      !
      ! Case  TUV in --> TUV out
      !
      ! Test "conforming" UV tables...
      if (local_nc(1).eq.1 .and. local_nc(2).eq.huvin%gil%nchan .and. &
       &  huvin%gil%dim(2).eq.huvou%gil%dim(2)) then
        call gdf_read_uvall(huvin,duvou,error)
        return
      endif
      !
      ! The associated stuff is also read Entity by Entity
      allocate (duvin(huvin%gil%nvisi,2), stat=ier)   ! Large enough to handle a Real*8 array
      if (ier.ne.0) then
        call gio_message(seve%e,rname,'Memory allocation error')
        error = .true.
        return
      endif
      !
      do l=1,code_uvt_last
        ipou = huvou%gil%column_pointer(l)
        isou = huvou%gil%column_size(l)
        ipin = huvin%gil%column_pointer(l)
        isin = huvin%gil%column_size(l)
        if (ipou.ne.0) then
          if (ipin.eq.0) then
            write(mess,'(A,I6,A)') 'Missing column of type ',l,' in input UV table'
            call gio_message(seve%w,rname,mess)
            imiss = code_gio_miscol
          else
            huvin%blc(2) = ipin
            huvin%trc(2) = ipin+isin-1
            call gdf_read_data(huvin,duvin,error)
            if (error) return
            !
            ! Swap converted Real*8 if needed
            if (isin.eq.2 .and. iconv(is).ne.0) call gio_swap4to8 (duvin, huvin%gil%nvisi)
            !
            ! Put in place and transform according to desired Format
            if (isin.eq.2) then
              if (isou.eq.2) then
                call r8tor8 (duvin, duvou(1,ipou), huvin%gil%nvisi)
              else
                call r8tor4 (duvin, duvou(1,ipou), huvin%gil%nvisi)
              endif
            else
              if (isou.eq.2) then
                call r4tor8 (duvin, duvou(1, ipou), huvin%gil%nvisi)
              else
                call r4tor4 (duvin, duvou(1, ipou), huvin%gil%nvisi)
              endif
            endif
          endif
        else if (ipin.ne.0) then
          imore = code_gio_extcol   ! Input column ignored...
        endif
      enddo
      deallocate (duvin, stat=ier)
      !
      ! The data block is read plane by plane...
      nblock = local_nc(2)-local_nc(1)+1
      huvin%blc(1) = 0
      huvin%trc(1) = 0
      !
      do i=1,nblock
        huvin%blc(2) = huvin%gil%natom*(local_nc(1)+i-2)+huvin%gil%fcol
        huvin%trc(2) = huvin%blc(2)+huvin%gil%natom-1
        call gdf_read_data(huvin,duvou(1,huvou%gil%fcol+huvou%gil%natom*(i-1)),error)
        if (error) return
      enddo
      !
    else
      ! Case  UVT in --> TUV out
      call gio_message(seve%w,rname,'Input UV data is not in TUV order')
      !
      ! Read and extract by block
      nblock = 1024
      kblock = huvin%gil%dim(2)/nblock
      if (kblock.lt.10) then
        percentage_step = 100.
      else if (kblock.lt.100) then
        percentage_step = 25.
      else
        percentage_step = 10.
      endif
      write(*,'(A)',ADVANCE="NO") 'Read % '
      !
      ! We do not use the "non-contiguous" subset mode of gdf_read_data
      ! as it would allocate the minimimally contiguous subset anyway.
      !
      huvin%blc = 0
      huvin%trc = 0
      allocate (duvin(huvin%gil%dim(1),nblock), stat=ier)
      if (ier.ne.0) then
        call gio_message(seve%e,rname,'Memory allocation error')
        error = .true.
        return
      endif
      next_percentage = percentage_step
      next = next_percentage*(huvin%gil%dim(2)/100)
      do iv =1, huvin%gil%dim(2), nblock
        huvin%blc(2) = iv
        nleft = min (nblock,huvin%gil%dim(2)-iv+1)
        huvin%trc(2) = iv+nleft-1
        call gdf_read_data (huvin,duvin,error)
        if (error) then
          deallocate(duvin)
          return
        endif
        if (iv.lt.next.and.iv+nleft.gt.next) then
          write(*,'(F6.0)',ADVANCE="NO") next_percentage
          next_percentage = next_percentage+percentage_step
          next = next_percentage*(huvin%gil%dim(2)/100)
        endif
        !
        ! Now put it in place... Loop ordering inefficient as duvou is the
        ! biggest array ?... Will change later ?...
        jv = iv
        do kv = 1,nleft
          ! Channel data
          duvou(jv, ofcol:olcol) =  duvin (ifcol:ilcol, kv)
          jv = jv+1
        enddo
        !
        ! Associated stuff.
        do l=1,code_uvt_last
          ipou = huvou%gil%column_pointer(l)
          isou = huvou%gil%column_size(l)
          ipin = huvin%gil%column_pointer(l)
          isin = huvin%gil%column_size(l)
          if (isou.ne.0) then
            if (ipin.eq.0) then
              write(mess,'(A,I6,A)') 'Missing column of type ',l,' in input UV table'
              call gio_message(seve%w,rname,mess)
              imiss = code_gio_miscol
            else
              if (isin.eq.2 .and. iconv(is).ne.0) call gio_swap4to8 (duvin, 1)
              jv = iv
              do kv = 1,nleft
                if (isin.eq.2) then
                  if (isou.eq.2) then
                    call r8tor8 (duvin(ipin, kv), duvou(jv,ipou), 1)
                  else if (isou.eq.1) then
                    call r8tor4 (duvin(ipin, kv), duvou(jv,ipou), 1)
                  endif
                else if (isin.eq.1) then
                  if (isou.eq.2) then
                    call r4tor8 (duvin (ipin, kv), duvou(jv,ipou), 1)
                  else if (isou.eq.1) then
                    duvou(jv,ipou) = duvin(ipin,kv)
                  endif
                endif
                jv = jv+1
              enddo
            endif
          else if (isin.ne.0) then
            imore = code_gio_extcol
          endif              ! isou
        enddo                ! l
      enddo                  ! block
      !
      write(*,'(A)') ' ...Done'
      deallocate(duvin)
    endif
  else if (huvou%gil%type_gdf.eq.code_gdf_uvt) then
    call gio_message(seve%w,rname,'Producing a UVT order')
    !
    if (huvin%gil%type_gdf.eq.code_gdf_uvt) then
      ! Case  UVT --> UVT
      if (local_nc(1).eq.1 .and. local_nc(2).eq.huvin%gil%nchan .and. &
       &  huvin%gil%dim(1).eq.huvou%gil%dim(1)) then
        call gdf_read_uvall(huvin,duvou,error)
        return
      endif
      !
      ! Read and extract by block
      nblock = 1024
      kblock = huvin%gil%dim(2)/nblock
      if (kblock.lt.10) then
         percentage_step = 100.
      else if (kblock.lt.100) then
         percentage_step = 25.
      else
         percentage_step = 10.
      endif
      !
      ! We do not use the "non-contiguous" subset mode of gdf_read_data
      ! as it would allocate the minimally contiguous subset anyway.
      !
      huvin%blc = 0
      huvin%trc = 0
      allocate (duvin(huvin%gil%dim(1),nblock), stat=ier)
      if (ier.ne.0) then
        error = .true.
        return
      endif
      next_percentage = percentage_step
      next = next_percentage*(huvin%gil%dim(2)/100)
      do iv =1, huvin%gil%dim(2), nblock
        huvin%blc(2) = iv
        nleft = min (nblock,huvin%gil%dim(2)-iv+1)
        huvin%trc(2) = iv+nleft-1
        call gdf_read_data (huvin,duvin,error)
        if (error) then
          deallocate(duvin)
          return
        endif
        if (iv.lt.next.and.iv+nleft.gt.next) then
          if (next_percentage.eq.percentage_step) then
            write(*,'(A,F6.0)',ADVANCE="NO") 'Read % ',next_percentage
          else
            write(*,'(F6.0)',ADVANCE="NO") next_percentage
          endif
          next_percentage = next_percentage+percentage_step
          next = next_percentage*(huvin%gil%dim(2)/100)
        endif
        !
        ! Now put it in place...
        ! Channel data
        !!Print *, 'OFCOL ', ofcol, olcol, huvou%gil%dim(1)
        !!Print *, 'IFCOL ', ifcol, ilcol, huvin%gil%dim(1)
        !!Print *,'IV ',iv,iv+nleft-1,huvou%gil%dim(2)
        duvou(ofcol:olcol, iv:iv+nleft-1) =  duvin (ifcol:ilcol, 1:nleft)
        !
        ! Associated stuff
        do l=1,code_uvt_last
          ipou = huvou%gil%column_pointer(l)
          isou = huvou%gil%column_size(l)
          ipin = huvin%gil%column_pointer(l)
          isin = huvin%gil%column_size(l)
          !!Print *,l,'Ipin ',ipin,isin,'Ipou ',ipou,isou
          if (ipin+isin-1 .gt. huvin%gil%dim(1)) then
            write(mess,'(A,I6,A,I6)') '#3 Inconsistent input UV Table: Column ',l,' out of bound ', &
            huvin%gil%dim(1)
            call gio_message(seve%w,rname,mess)
            Print *,l,'Ipin ',ipin,isin,'Ipou ',ipou,isou
            cycle
          endif
          if (ipou+isou-1 .gt. huvou%gil%dim(1)) then
            write(mess,'(A,I6,A,I6)') 'Inconsistent output UV Table: Column ',l,' out of bound ', &
            huvou%gil%dim(1)
            call gio_message(seve%w,rname,mess)
            Print *,l,'Ipin ',ipin,isin,'Ipou ',ipou,isou
            cycle
          endif
          if (isou.ne.0) then
            if (ipin.eq.0) then
              write(mess,'(A,I6,A)') 'Missing column of type ',l,' in input UV table'
              call gio_message(seve%w,rname,mess)
              imiss = code_gio_miscol
            else
              jv = iv
              do kv = 1,nleft
                if (isin.eq.2) then
                  if (isou.eq.2) then
                    if (iconv(is).ne.0) call gio_swap4to8 (duvin(ipin,kv), 1)
                    call r8tor8 (duvin (ipin, kv), duvou(ipou,jv), 1)
                  else if (isou.eq.1) then
                    call r8tor4 (duvin(ipin, kv), duvou(ipou, jv), 1)
                  endif
                else if (isin.eq.1) then
                  if (isou.eq.2) then
                    call r4tor8 (duvin (ipin, kv), duvou(ipou,jv), 1)
                  else if (isou.eq.1) then
                    duvou(ipou, jv) = duvin(ipin, kv)
                  endif
                endif
                jv = jv+1
              enddo
            endif
          else if (isin.ne.0) then
            imore = code_gio_extcol
          endif
        enddo
      enddo
      !
      write(*,'(A)') ' ...Done'
      deallocate(duvin)
      !
    else if (huvin%gil%type_gdf.eq.code_gdf_tuv) then
      !
      ! Case  TUV --> UVT
      call gio_message(seve%w,rname,'Input data is in TUV order')
      !
      ! The data block is read plane by plane...
      allocate (duvin(huvin%gil%dim(1),max(huvin%gil%natom,2)), stat=ier)  ! Large enough to handle a Real*8
      if (ier.ne.0) then
        error = .true.
        return
      endif
      !
      nblock = local_nc(2)-local_nc(1)+1
      huvin%blc = 0
      huvin%trc = 0
      !
      do i=1,nblock
        huvin%blc(2) = huvin%gil%natom*(local_nc(1)+i-2)+huvin%gil%fcol
        huvin%trc(2) = huvin%blc(2)+huvin%gil%natom-1
        call gdf_read_data(huvin,duvin,error)
        if (error) return
        do iv = 1,huvou%gil%nvisi
           duvou(ofcol+huvou%gil%natom*(i-1):ofcol+huvou%gil%natom*i-1,iv) = duvin(iv,1:huvin%gil%natom)
        enddo
      enddo
      !
      ! The associated stuff is also read Entity by Entity
      do l=1,code_uvt_last
        ipou = huvou%gil%column_pointer(l)
        isou = huvou%gil%column_size(l)
        ipin = huvin%gil%column_pointer(l)
        isin = huvin%gil%column_size(l)
        if (ipou.ne.0) then
          if (ipin.eq.0) then
            write(mess,'(A,I6,A)') 'Missing column of type ',l,' in input UV table'
            call gio_message(seve%w,rname,mess)
            imiss = code_gio_miscol
          else
            huvin%blc(2) = ipin
            huvin%trc(2) = ipin+isin-1
            call gdf_read_data(huvin,duvin,error)
            if (error) return
            !
            ! Swap converted Real*8 if needed
            if (isin.eq.2 .and. iconv(is).ne.0) call gio_swap4to8 (duvin, huvin%gil%nvisi)
            !
            ! Put in place and transform according to desired Format
            if (isin.eq.2) then
              if (isou.eq.2) then
                do iv = 1,huvin%gil%nvisi
                  call r8tor8 (duvin(iv,1), duvou(ipou, iv), 1)
                enddo
              else
                do iv = 1,huvin%gil%nvisi
                  call r8tor4 (duvin(iv,1), duvou(ipou, iv), 1)
                enddo
              endif
            else
              if (isou.eq.2) then
                do iv = 1,huvin%gil%nvisi
                  call r4tor8 (duvin(iv,1), duvou(ipou, iv), 1)
                enddo
              else
                do iv = 1,huvin%gil%nvisi
                  duvou(ipou, iv) = duvin(iv,1)
                enddo
              endif
            endif
          endif
        else if (isin.ne.0) then
          imore = code_gio_extcol
        endif
      enddo
      deallocate (duvin,stat=ier)
      !
    else
      call gio_message(seve%e,rname,'Input Data set is not a UV data')
      error = .true.
      return
    endif
  else
    call gio_message(seve%e,rname,'Output Data set is not a UV data')
    error = .true.
    return
  endif
  if (imiss.ne.0) error = .true.
  huvou%status = imiss + imore
end subroutine gdf_read_uvdataset
