!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine wifisyn_wifi2visi_command(line,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_command
  use wifisyn_sic_buffer
  use wifisyn_cube_buffer
  !----------------------------------------------------------------------
  ! @ private
  !----------------------------------------------------------------------
  character(len=*), intent(inout) :: line
  logical,          intent(inout) :: error
  !
  character(len=*), parameter :: rname='WIFI2VISI/COMMAND'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  call wifisyn_wifi2visi_main(progmap,wifi,visi,error)
  if (error) return
  !
end subroutine wifisyn_wifi2visi_command
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine wifisyn_wifi2visi_main(map,wifi,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_main
  use wifisyn_cube_types
  use wifisyn_gridding_types
  !----------------------------------------------------------------------
  ! @ private
  !----------------------------------------------------------------------
  type(map_t),     intent(in)    :: map
  type(wifi_t),    intent(in)    :: wifi
  type(visi_t),    intent(inout) :: visi
  logical,         intent(inout) :: error
  !
  integer :: na,nb,nc
  character(len=*), parameter :: rname='WIFI2VISI/MAIN'
  !
  nc = wifi%cub%nc
  na = map%axes(1)%a%uvp%n
  nb = map%axes(2)%a%uvp%n
  call wifisyn_reallocate_complex_xyc('visi%cub',na,nb,nc,visi%cub,error)
  if (error) return
  call wifisyn_visi_wei_header(map,visi,error)
  if (error) return
  call wifisyn_cube_reallocate_r2d('visi%wei',visi%wei,error)
  if (error) return
  visi%uvkind = .true.
  call wifisyn_cube_sicdef(code_readonly,'visiwei',visi%wei,error)
  if (error) return
  !
!  call wifisyn_wifi2visi_average(map%axes,wifi,visi,error)
!  if (error) return
!  call wifisyn_wifi2visi_average_and_symmetry(map%axes,wifi,visi,error)
!  if (error) return
  call wifisyn_wifi2visi_shift_and_sum(map%axes,wifi,visi,error)
  if (error) return
!  call wifisyn_wifi2visi_sum(map%axes,wifi,visi,error)
!  if (error) return
  call wifisyn_cube_minmax_r2d(code_linscale,visi%wei,error)
  if (error) return
  !
end subroutine wifisyn_wifi2visi_main
!
subroutine wifisyn_visi_wei_header(map,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_visi_wei_header
  use wifisyn_gridding_types
  use wifisyn_cube_types
  !----------------------------------------------------------------------
  ! @ private
  ! This one should be merged with wifisyn_wifi_header *** JP
  !----------------------------------------------------------------------
  type(map_t),     intent(in)    :: map
  type(visi_t),    intent(inout) :: visi
  logical,         intent(inout) :: error
  !
  character(len=*), parameter :: rname='VISI/WEI/HEADER'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  call wifisyn_common_header(map,visi%wei,error)
  if (error) return
  visi%wei%gil%faxi = 0
  if (visi%uvkind) then
     ! 1st axis
     visi%wei%char%code(1) = 'U'
     visi%wei%gil%dim(1) = map%axes(1)%a%uvp%n
     visi%wei%gil%ref(1) = map%axes(1)%a%uvp%ref
     visi%wei%gil%val(1) = map%axes(1)%a%uvp%val
     visi%wei%gil%inc(1) = map%axes(1)%a%uvp%inc
     visi%wei%gil%xaxi = 0
     ! 2nd axis
     visi%wei%char%code(2) = 'V'
     visi%wei%gil%dim(2) = map%axes(2)%a%uvp%n
     visi%wei%gil%ref(2) = map%axes(2)%a%uvp%ref
     visi%wei%gil%val(2) = map%axes(2)%a%uvp%val
     visi%wei%gil%inc(2) = map%axes(2)%a%uvp%inc
     visi%wei%gil%yaxi = 0
  else
     ! 1st axis
     visi%wei%char%code(1) = 'RA'
     visi%wei%gil%dim(1) = map%axes(1)%a%sky%n
     visi%wei%gil%ref(1) = map%axes(1)%a%sky%ref
     visi%wei%gil%val(1) = map%axes(1)%a%sky%val
     visi%wei%gil%inc(1) = map%axes(1)%a%sky%inc
     visi%wei%gil%xaxi = 1
     ! 2nd axis
     visi%wei%char%code(2) = 'DEC'
     visi%wei%gil%dim(2) = map%axes(2)%a%sky%n
     visi%wei%gil%ref(2) = map%axes(2)%a%sky%ref
     visi%wei%gil%val(2) = map%axes(2)%a%sky%val
     visi%wei%gil%inc(2) = map%axes(2)%a%sky%inc
     visi%wei%gil%yaxi = 2
  endif
  !
end subroutine wifisyn_visi_wei_header
!
subroutine wifisyn_wifi2visi_average(axes,wifi,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_average
  use wifisyn_cube_types
  use wifisyn_gridding_types
  !----------------------------------------------------------------------
  ! @ private
  !----------------------------------------------------------------------
  type(axis_t), intent(in)    :: axes(2)
  type(wifi_t), intent(in)    :: wifi
  type(visi_t), intent(inout) :: visi
  logical,      intent(inout) :: error
  !
  integer :: nout,uf_per_up,vf_per_vp
  integer :: nup,mup,iup,jup
  integer :: nvp,mvp,ivp,jvp
  integer :: nus,mus,ius
  integer :: nvs,mvs,ivs
  integer :: nuf,muf,iuf
  integer :: nvf,mvf,ivf
  character(len=80) :: mess
  character(len=*), parameter :: rname='WIFI2VISI/AVERAGE'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  ! Initialization
  visi%wei%r2d = 0.0
  visi%cub%val = (0.0,0.0)
  !
  nup = axes(1)%u%uvp%n
  nvp = axes(2)%u%uvp%n
  nus = axes(1)%x%uvp%n
  nvs = axes(2)%x%uvp%n
  nuf = axes(1)%a%uvp%n
  nvf = axes(2)%a%uvp%n
  !
  uf_per_up = axes(1)%dup_per_duf
  vf_per_vp = axes(2)%dup_per_duf
  !
  mus = nus/2
  mvs = nvs/2
  mup = nup/2
  mvp = nvp/2
  muf = nuf/2
  mvf = nvf/2
  !
do ivp=1,nvp
   jvp = mvf + (ivp-mvp-1)*vf_per_vp
   do ivs=1,nvs
      ivf = jvp + (ivs-mvs)
      write(mess,*) ivp,jvp,ivs,ivf,nvf
      call wifisyn_message(seve%i,rname,mess)
   enddo
enddo
  !
  ! Summation
  nout = 0
  do ivp=1,nvp
     jvp = mvf + (ivp-mvp-1)*vf_per_vp
     do iup=1,nup
        jup = muf + (iup-mup-1)*uf_per_up
        do ivs=1,nvs
           ivf = jvp + (ivs-mvs)
           if ((1.le.ivf).and.(ivf.le.nvf)) then
              do ius=1,nus
                 iuf = jup + (ius-mus)
                 if ((1.le.iuf).and.(iuf.le.nuf)) then
                    visi%wei%r2d(iuf,ivf) = visi%wei%r2d(iuf,ivf)+1.0
                    visi%cub%val(iuf,ivf,:) = visi%cub%val(iuf,ivf,:)+wifi%cub%val(:,ius,ivs,iup,ivp)
                 else
                    nout = nout+1
                 endif ! ((1.le.iuf).and.(iuf.le.nuf))
              enddo ! ius
           else
              nout = nout + nus
           endif ! ((1.le.ivf).and.(ivf.le.nvf))
        enddo ! ivs
     enddo ! iup
  enddo ! ivp
  write(mess,'(a,i0,a,i0)') 'Number of frequencies falling outside: ',nout,' over ',nus*nvs*nup*nvp
  call wifisyn_message(seve%i,rname,mess)
  !
end subroutine wifisyn_wifi2visi_average
!
subroutine wifisyn_wifi2visi_average_and_symmetry(axes,wifi,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_average_and_symmetry
  use wifisyn_cube_types
  use wifisyn_gridding_types
  !----------------------------------------------------------------------
  ! @ private
  !----------------------------------------------------------------------
  type(axis_t), intent(in)    :: axes(2)
  type(wifi_t), intent(in)    :: wifi
  type(visi_t), intent(inout) :: visi
  logical,      intent(inout) :: error
  !
  integer :: nout,uf_per_up,vf_per_vp
  integer :: nup,mup,iup,jup
  integer :: nvp,mvp,ivp,jvp
  integer :: nus,mus,ius
  integer :: nvs,mvs,ivs
  integer :: nuf,muf,iuf,juf
  integer :: nvf,mvf,ivf,jvf
  character(len=80) :: mess
  character(len=*), parameter :: rname='WIFI2VISI/AVERAGE+SYMMETRY'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  ! Initialization
  visi%wei%r2d = 0.0
  visi%cub%val = (0.0,0.0)
  !
  uf_per_up = axes(1)%dup_per_duf
  nup = axes(1)%u%uvp%n
  nus = axes(1)%x%uvp%n
  nuf = axes(1)%a%uvp%n
  mus = nus/2
  mup = nup/2
  muf = nuf/2
  !
  vf_per_vp = axes(2)%dup_per_duf
  nvp = axes(2)%u%uvp%n
  nvs = axes(2)%x%uvp%n
  nvf = axes(2)%a%uvp%n
  mvs = nvs/2
  mvp = nvp/2
  mvf = nvf/2
  !
  ! Summation
  nout = 0
  do ivp=1,mvp+1
     jvp = mvf+1 + (ivp-mvp-1)*vf_per_vp
     do iup=1,nup
        jup = muf+1 + (iup-mup-1)*uf_per_up
        do ivs=1,nvs
           ivf = jvp + (ivs-mvs-1)
           if ((1.le.ivf).and.(ivf.le.nvf)) then
              do ius=1,nus
                 iuf = jup + (ius-mus-1)
                 if ((1.le.iuf).and.(iuf.le.nuf)) then
                    visi%wei%r2d(iuf,ivf) = visi%wei%r2d(iuf,ivf)+1.0
                    visi%cub%val(iuf,ivf,:) = visi%cub%val(iuf,ivf,:)+wifi%cub%val(:,ius,ivs,iup,ivp)
                 else
                    nout = nout+1
                 endif ! ((1.le.iuf).and.(iuf.le.nuf))
              enddo ! ius
           else
              nout = nout + nus
           endif ! ((1.le.ivf).and.(ivf.le.nvf))
           ! Symmetrical part
           jvf = nvf+2-ivf
           if ((1.le.jvf).and.(jvf.le.nvf)) then
              do ius=1,nus
                 iuf = jup + (ius-mus-1)
                 juf = nuf+2-iuf
                 if ((1.le.juf).and.(juf.le.nuf)) then
                    visi%wei%r2d(juf,jvf) = visi%wei%r2d(juf,jvf)+1.0
                    visi%cub%val(juf,jvf,:) = visi%cub%val(juf,jvf,:)+conjg(wifi%cub%val(:,ius,ivs,iup,ivp))
                 else
                    nout = nout+1
                 endif ! ((1.le.juf).and.(juf.le.nuf))
              enddo ! ius
           else
              nout = nout + nus
           endif ! ((1.le.jvf).and.(jvf.le.nvf))
        enddo ! ivs
     enddo ! iup
  enddo ! ivp
  write(mess,'(a,i0,a,i0)') 'Number of frequencies falling outside: ',nout,' over ',nus*nvs*nup*nvp
  call wifisyn_message(seve%i,rname,mess)
  !
end subroutine wifisyn_wifi2visi_average_and_symmetry
!
subroutine wifisyn_wifi2visi_shift_and_sum(axes,wifi,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_shift_and_sum
  use wifisyn_cube_types
  use wifisyn_gridding_types
  !----------------------------------------------------------------------
  ! @ private
  !----------------------------------------------------------------------
  type(axis_t), intent(in)    :: axes(2)
  type(wifi_t), intent(in)    :: wifi
  type(visi_t), intent(inout) :: visi
  logical,      intent(inout) :: error
  !
  real(kind=8) :: uf_per_up,vf_per_vp
  integer :: nusout,nvsout
  integer :: nup,mup,iup,jup,iupmin,iupmax,iupzero,kupmin,kupmax
  integer :: nvp,mvp,ivp,jvp,ivpmin,ivpmax,ivpzero,kvpmin,kvpmax
  integer :: nus,mus,ius,jus,iusmin,iusmax,iuszero
  integer :: nvs,mvs,ivs,jvs,ivsmin,ivsmax,ivszero
  integer :: nuf,muf,iuf,juf,iufmin,iufmax,iufzero,kuf
  integer :: nvf,mvf,ivf,jvf,ivfmin,ivfmax,ivfzero,kvf
  character(len=80) :: mess
  character(len=*), parameter :: rname='WIFI2VISI/SHIFT&SUM'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  uf_per_up = axes(1)%dup_per_duf
  nup = axes(1)%u%uvp%n
  nus = axes(1)%x%uvp%n
  nuf = axes(1)%a%uvp%n
  mus = nus/2
  mup = nup/2
  muf = nuf/2
  iupmin = -mup
  iusmin = -mus
  iufmin = -muf
  iupmax = mup-1
  iusmax = mus-1
  iufmax = muf-1
  iupzero = mup+1
  iuszero = mus+1
  iufzero = muf+1
  !
  vf_per_vp = axes(2)%dup_per_duf
  nvp = axes(2)%u%uvp%n
  nvs = axes(2)%x%uvp%n
  nvf = axes(2)%a%uvp%n
  mvs = nvs/2
  mvp = nvp/2
  mvf = nvf/2
  ivpmin = -mvp
  ivsmin = -mvs
  ivfmin = -mvf
  ivpmax = mvp-1
  ivsmax = mvs-1
  ivfmax = mvf-1
  ivpzero = mvp+1
  ivszero = mvs+1
  ivfzero = mvf+1
  !
  ! Initialization
  nusout = 0
  nvsout = 0
  visi%wei%r2d = 0.0
  visi%cub%val = (0.0,0.0)
  ! Summation
  do ivf=ivfmin,0
     jvf = ivf+ivfzero
     kvpmin = max(1+floor  ((ivf-ivsmax)/vf_per_vp),ivpmin)
     kvpmax = min(1+ceiling((ivf-ivsmin)/vf_per_vp),ivpmax)
     do ivp=kvpmin,kvpmax
        ivs = ivf-ivp*vf_per_vp
        jvp = ivp+ivpzero
        jvs = ivs+ivszero
        if ((ivsmin.le.ivs).and.(ivs.le.ivsmax)) then
           do iuf=iufmin,iufmax
              juf = iuf+iufzero
              kupmin = max(1+floor  ((iuf-iusmax)/uf_per_up),iupmin)
              kupmax = min(1+ceiling((iuf-iusmin)/uf_per_up),iupmax)
              do iup=kupmin,kupmax
                 ius = iuf-iup*uf_per_up
                 jup = iup+iupzero
                 jus = ius+iuszero
                 if ((iusmin.le.ius).and.(ius.le.iusmax)) then
                    visi%wei%r2d(juf,jvf) = visi%wei%r2d(juf,jvf)+1.0
                    visi%cub%val(juf,jvf,:) = visi%cub%val(juf,jvf,:)+wifi%cub%val(:,jus,jvs,jup,jvp)
                 else
                    nusout = nusout+1
                 endif !
              enddo ! iup
           enddo ! iuf
        else
           nvsout = nvsout+1
        endif !
     enddo ! ivp
  enddo ! ivf
  write(mess,'(a,i0,a,i0)') 'Number of frequencies falling outside: ',nusout,' and ',nvsout
  call wifisyn_message(seve%i,rname,mess)
  ! Symmetrical part
  do ivf=1,ivfmax
     jvf = ivfzero-ivf
     kvf = ivfzero+ivf
     do iuf=iufmin,iufmax
        juf = iufzero-iuf
        kuf = iufzero+iuf
        visi%wei%r2d(kuf,kvf) = visi%wei%r2d(juf,jvf)
        visi%cub%val(kuf,kvf,:) = conjg(visi%cub%val(juf,jvf,:))
     enddo ! iuf
  enddo ! ivf
  do iuf=1,iufmax
     juf = iufzero-iuf
     kuf = iufzero+iuf
     visi%wei%r2d(kuf,ivfzero) = visi%wei%r2d(juf,ivfzero)
     visi%cub%val(kuf,ivfzero,:) = conjg(visi%cub%val(juf,ivfzero,:))
  enddo ! iuf
  if (any(visi%cub%val(iufzero,ivfzero,:).ne.0.0)) then
     print *,visi%cub%val(iufzero,ivfzero,:)
     visi%cub%val(iufzero,ivfzero,:) = cmplx(real(visi%cub%val(iufzero,ivfzero,:)),0.0)
     call wifisyn_message(seve%i,rname,'Setting zero spacing imaginary part to 0')
  endif
  !
end subroutine wifisyn_wifi2visi_shift_and_sum
!
subroutine wifisyn_wifi2visi_sum(axes,wifi,visi,error)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_wifi2visi_sum
  use wifisyn_cube_types
  use wifisyn_gridding_types
  !----------------------------------------------------------------------
  ! @ private
  ! *** JP This requires the same us and uf axes to actually work...
  !----------------------------------------------------------------------
  type(axis_t), intent(in)    :: axes(2)
  type(wifi_t), intent(in)    :: wifi
  type(visi_t), intent(inout) :: visi
  logical,      intent(inout) :: error
  !
  integer :: nusout,nvsout
  integer :: nup,mup,iup,jup,iupmin,iupmax,iupzero
  integer :: nvp,mvp,ivp,jvp,ivpmin,ivpmax,ivpzero
  integer :: nus,mus,ius,jus,iusmin,iusmax,iuszero
  integer :: nvs,mvs,ivs,jvs,ivsmin,ivsmax,ivszero
  integer :: nuf,muf,iuf,juf,iufmin,iufmax,iufzero,kuf
  integer :: nvf,mvf,ivf,jvf,ivfmin,ivfmax,ivfzero,kvf
  character(len=80) :: mess
  character(len=*), parameter :: rname='WIFI2VISI/SUM'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  nup = axes(1)%u%uvp%n
  nus = axes(1)%x%uvp%n
  nuf = axes(1)%a%uvp%n
  mus = nus/2
  mup = nup/2
  muf = nuf/2
  iupmin = -mup
  iusmin = -mus
  iufmin = -muf
  iupmax = mup-1
  iusmax = mus-1
  iufmax = muf-1
  iupzero = mup+1
  iuszero = mus+1
  iufzero = muf+1
  !
  nvp = axes(2)%u%uvp%n
  nvs = axes(2)%x%uvp%n
  nvf = axes(2)%a%uvp%n
  mvs = nvs/2
  mvp = nvp/2
  mvf = nvf/2
  ivpmin = -mvp
  ivsmin = -mvs
  ivfmin = -mvf
  ivpmax = mvp-1
  ivsmax = mvs-1
  ivfmax = mvf-1
  ivpzero = mvp+1
  ivszero = mvs+1
  ivfzero = mvf+1
  !
  ! Initialization
  nusout = 0
  nvsout = 0
  visi%wei%r2d = 0.0
  visi%cub%val = (0.0,0.0)
  ! Summation
  do ivf=ivfmin,0
     jvf = ivfzero+ivf
     jvs = ivszero+ivf
     if ((1.le.jvs).and.(jvs.le.nvs)) then
        do ivp=ivpmin,ivpmax
           jvp = ivpzero+ivp
           do iuf=iufmin,iufmax
              juf = iufzero+iuf
              jus = iuszero+iuf
              if ((1.le.jus).and.(jus.le.nus)) then
                 do iup=iupmin,iupmax
                    jup = iupzero+iup
                    visi%wei%r2d(juf,jvf) = visi%wei%r2d(juf,jvf)+1.0
                    visi%cub%val(juf,jvf,:) = visi%cub%val(juf,jvf,:)+wifi%cub%val(:,jus,jvs,jup,jvp)
                 enddo ! iup
              else
                 nusout = nusout+1
              endif !
           enddo ! iuf
        enddo ! ivp
     else
        nvsout = nvsout+1
     endif !
  enddo ! ivf
  write(mess,'(a,i0,a,i0)') 'Number of frequencies falling outside: ',nusout,' and ',nvsout
  call wifisyn_message(seve%i,rname,mess)
  ! Symmetrical part
  do ivf=1,ivfmax
     jvf = ivfzero-ivf
     kvf = ivfzero+ivf
     do iuf=iufmin,iufmax
        juf = iufzero-iuf
        kuf = iufzero+iuf
        visi%wei%r2d(kuf,kvf) = visi%wei%r2d(juf,jvf)
        visi%cub%val(kuf,kvf,:) = conjg(visi%cub%val(juf,jvf,:))
     enddo ! iuf
  enddo ! ivf
  do iuf=1,iufmax
     juf = iufzero-iuf
     kuf = iufzero+iuf
     visi%wei%r2d(kuf,ivfzero) = visi%wei%r2d(juf,ivfzero)
     visi%cub%val(kuf,ivfzero,:) = conjg(visi%cub%val(juf,ivfzero,:))
  enddo ! iuf
  if (any(visi%cub%val(iufzero,ivfzero,:).ne.0.0)) then
     print *,visi%cub%val(iufzero,ivfzero,:)
     visi%cub%val(iufzero,ivfzero,:) = cmplx(real(visi%cub%val(iufzero,ivfzero,:)),0.0)
     call wifisyn_message(seve%i,rname,'Setting zero spacing imaginary part to 0')
  endif
  !
end subroutine wifisyn_wifi2visi_sum
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
