subroutine mrtindex_variable_entry(struct,head,ro,error)
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_entry
  use mrtindex_types
  !---------------------------------------------------------------------
  ! @ public
  !  Map a Sic structure on an entry
  !---------------------------------------------------------------------
  character(len=*),        intent(in)    :: struct  ! Structure name
  type(mrtindex_header_t), intent(inout) :: head    !
  logical,                 intent(in)    :: ro      ! Read-Only?
  logical,                 intent(inout) :: error   ! Logical error flag
  ! Local
  logical :: userreq
  !
  userreq = .false.
  !
  call sic_delvariable(struct,userreq,error)
  call sic_defstructure(struct,.true.,error)
  if (error)  return
  !
  call mrtindex_variable_entry_key(struct,head%key,ro,error)
  if (error)  return
  call mrtindex_variable_entry_prim(struct,head%pri,ro,error)
  if (error)  return
  call head%cal%variable(struct,ro,error)
  if (error)  return
  call head%sci%variable(struct,ro,error)
  if (error)  return
  call head%poi%variable(struct,ro,error)
  if (error)  return
  !
end subroutine mrtindex_variable_entry
!
subroutine mrtindex_variable_entry_key(struct,key,ro,error)
  use gildas_def
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_entry_key
  use mrtindex_types
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  character(len=*),   intent(in)    :: struct  ! Structure name
  type(mrtindex_key_t), intent(in)    :: key     !
  logical,            intent(in)    :: ro      ! Read-Only?
  logical,            intent(inout) :: error   ! Logical error flag
  ! Local
  logical :: userreq
  character(len=32) :: str
  integer(kind=index_length) :: dims(sic_maxdims)
  !
  userreq = .false.
  str = trim(struct)//'%KEY'
  !
  call sic_delvariable(str,userreq,error)
  call sic_defstructure(str,.true.,error)
  if (error)  return
  !
  call sic_def_inte (trim(str)//'%VERSION',     key%version,     0,0,   ro,error)
  call sic_def_inte (trim(str)//'%TELESCOPE',   key%telescope,   0,0,   ro,error)
  call sic_def_char (trim(str)//'%PROJID',      key%projid,             ro,error)
  call sic_def_char (trim(str)//'%SOURCE',      key%source,             ro,error)
  call sic_def_inte (trim(str)//'%DOBS',        key%dobs,        0,0,   ro,error)
  call sic_def_dble (trim(str)//'%UT',          key%ut,          0,0,   ro,error)
  call sic_def_dble (trim(str)//'%LST',         key%lst,         0,0,   ro,error)
  call sic_def_real (trim(str)//'%AZ',          key%az,          0,0,   ro,error)
  call sic_def_real (trim(str)//'%EL',          key%el,          0,0,   ro,error)
  call sic_def_dble (trim(str)//'%LON',         key%lon,         0,0,   ro,error)
  call sic_def_dble (trim(str)//'%LAT',         key%lat,         0,0,   ro,error)
  call sic_def_inte (trim(str)//'%SYSTEM',      key%system,      0,0,   ro,error)
  call sic_def_real (trim(str)//'%EQUINOX',     key%equinox,     0,0,   ro,error)
  dims(1) = mrtcal_indx_mfrontend
  call sic_def_charn(trim(str)//'%FRONTEND',    key%frontend,    1,dims,ro,error)
  call sic_def_inte (trim(str)//'%SCAN',        key%scan,        0,0,   ro,error)
  call sic_def_inte (trim(str)//'%BACKEND',     key%backend,     0,0,   ro,error)
  call sic_def_inte (trim(str)//'%OBSTYPE',     key%obstype,     0,0,   ro,error)
  call sic_def_inte (trim(str)//'%SWITCHMODE',  key%switchmode,  0,0,   ro,error)
  call sic_def_inte (trim(str)//'%POLARIMETRY', key%polstatus,   0,0,   ro,error)
  call sic_def_inte (trim(str)//'%FILSTATUS',   key%filstatus,   0,0,   ro,error)
  call sic_def_inte (trim(str)//'%CALSTATUS',   key%calstatus,   0,0,   ro,error)
  call sic_def_inte (trim(str)//'%SOLSTATUS',   key%solstatus,   0,0,   ro,error)
  call sic_def_char (trim(str)//'%FILENAME',    key%filename,           ro,error)
  !
end subroutine mrtindex_variable_entry_key
!
subroutine mrtindex_variable_entry_prim(struct,prim,ro,error)
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_entry_prim
  use mrtindex_types
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  character(len=*),    intent(in)    :: struct  ! Structure name
  type(sec_primary_t), intent(in)    :: prim    !
  logical,             intent(in)    :: ro      ! Read-Only?
  logical,             intent(inout) :: error   ! Logical error flag
  ! Local
  logical :: userreq
  character(len=32) :: str
  !
  userreq = .false.
  str = trim(struct)//'%PRI'
  !
  call sic_delvariable(str,userreq,error)
  call sic_defstructure(str,.true.,error)
  if (error)  return
  !
  call sic_def_real(trim(str)//'%IMBFVERS',prim%imbfvers,0,0,ro,error)
  !
end subroutine mrtindex_variable_entry_prim
!
!-----------------------------------------------------------------------
!
subroutine mrtindex_variable_index(cx,error)
  use mrtindex_types
  use mrtindex_interfaces, except_this=>mrtindex_variable_index
  !---------------------------------------------------------------------
  ! @ public
  ! Support for command
  !  VARIABLE /INDEX
  !---------------------------------------------------------------------
  type(mrtindex_optimize_t), intent(in)    :: cx
  logical,                   intent(inout) :: error
  !
  ! Delete support variables
  call mrtindex_variable_index_delvar(error)
  if (error)  return
  !
  call mrtindex_variable_index_fill(cx,error)
  if (error)  return
  !
  ! Create support variables
  call mrtindex_variable_index_defvar(cx,error)
  if (error)  return
end subroutine mrtindex_variable_index
!
subroutine mrtindex_variable_index_delvar(error)
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_index_delvar
  !---------------------------------------------------------------------
  ! @ private
  ! Delete variables (structures) in MDX%HEAD%
  !---------------------------------------------------------------------
  logical, intent(inout) :: error               !
  !
  call sic_delvariable('MDX%HEAD%KEY',.false.,error)
  call sic_delvariable('MDX%HEAD%PRI',.false.,error)
  call sic_delvariable('MDX%HEAD%CAL',.false.,error)
  call sic_delvariable('MDX%HEAD%SCI',.false.,error)
  call sic_delvariable('MDX%HEAD%POI',.false.,error)
  if (error)  return
end subroutine mrtindex_variable_index_delvar
!
subroutine mrtindex_variable_index_reallocate(mfreq,mset,mpix,msol,nent,error)
  use mrtindex_types
  use mrtindex_array_types
  use mrtindex_dependencies_interfaces
  !---------------------------------------------------------------------
  ! @ private
  ! Reallocate (if needed) the MDX support arrays, section by section.
  ! nent <= 0 means deallocate only.
  !---------------------------------------------------------------------
  integer(kind=4), intent(in)    :: mfreq  !
  integer(kind=4), intent(in)    :: mset   !
  integer(kind=4), intent(in)    :: mpix   !
  integer(kind=4), intent(in)    :: msol   ! Maximum number of solutions to be stored for pointing
  integer(kind=8), intent(in)    :: nent   ! Size of reallocation
  logical,         intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='REALLOCATE'
  logical :: realloc
  integer(kind=4) :: ier
  !
  ! --- Key ------------------------------------------------------------
  if (allocated(mdxhead%key%version)) then
    realloc = size(mdxhead%key%version).lt.nent
    if (nent.le.0 .or. realloc) then
      deallocate(mdxhead%key%version,  mdxhead%key%telescope,mdxhead%key%projid)
      deallocate(mdxhead%key%source,   mdxhead%key%dobs,     mdxhead%key%ut)
      deallocate(mdxhead%key%lst,      mdxhead%key%az,       mdxhead%key%el)
      deallocate(mdxhead%key%lon,      mdxhead%key%lat,      mdxhead%key%system)
      deallocate(mdxhead%key%equinox,  mdxhead%key%frontend, mdxhead%key%scan)
      deallocate(mdxhead%key%backend,  mdxhead%key%obstype,  mdxhead%key%switchmode)
      deallocate(mdxhead%key%polstatus,mdxhead%key%filstatus,mdxhead%key%calstatus)
      deallocate(mdxhead%key%solstatus,mdxhead%key%filename)
    endif
  else
    realloc = nent.gt.0
  endif
  !
  if (realloc) then
    allocate(mdxhead%key%version(nent),  mdxhead%key%telescope(nent), stat=ier)
    allocate(mdxhead%key%projid(nent),   mdxhead%key%source(nent),    stat=ier)
    allocate(mdxhead%key%dobs(nent),     mdxhead%key%ut(nent),        stat=ier)
    allocate(mdxhead%key%lst(nent),      mdxhead%key%az(nent),        stat=ier)
    allocate(mdxhead%key%el(nent),       mdxhead%key%lon(nent),       stat=ier)
    allocate(mdxhead%key%lat(nent),      mdxhead%key%system(nent),    stat=ier)
    allocate(mdxhead%key%equinox(nent),                               stat=ier)
    allocate(mdxhead%key%frontend(mrtcal_indx_mfrontend,nent),        stat=ier)
    allocate(mdxhead%key%scan(nent),     mdxhead%key%backend(nent),   stat=ier)
    allocate(mdxhead%key%obstype(nent),  mdxhead%key%switchmode(nent),stat=ier)
    allocate(mdxhead%key%polstatus(nent),mdxhead%key%filstatus(nent), stat=ier)
    allocate(mdxhead%key%calstatus(nent),mdxhead%key%solstatus(nent), stat=ier)
    allocate(mdxhead%key%filename(nent),                              stat=ier)
    if (failed_allocate(rname,'MDX%HEAD%Key arrays',ier,error))  return
  endif
  !
  ! --- Calibration ----------------------------------------------------
  call mdxhead%cal%reallocate(mfreq,mset,mpix,nent,error)
  if (error)  return
  !
  ! --- Science --------------------------------------------------------
  call mdxhead%sci%reallocate(nent,error)
  if (error)  return
  !
  ! --- Pointing -------------------------------------------------------
  call mdxhead%poi%reallocate(msol,nent,error)
  if (error)  return
  !
end subroutine mrtindex_variable_index_reallocate
!
subroutine mrtindex_variable_index_fill(cx,error)
  use gbl_message
  use mrtindex_types
  use mrtindex_array_types
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_index_fill
  !---------------------------------------------------------------------
  ! @ private
  ! Fill the section arrays for the MDX%HEAD% Sic structure
  !---------------------------------------------------------------------
  type(mrtindex_optimize_t), intent(in)    :: cx
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='VARIABLE'
  type(mrtindex_entry_t) :: entry
  integer(kind=4) :: mfreq,mset,mpix,msol
  integer(kind=entry_length) :: ient
  !
  if (cx%next.le.1) then
    call mrtindex_message(seve%w,rname,'Current index is empty')
    return
  endif
  !
  ! Compute maximum number of pointing solutions. If you feel the
  ! computing cost is too large you can use an arbitrary large enough
  ! size instead
  mfreq = 0
  mset = 0
  mpix = 0
  msol = 0
  do ient=1,cx%next-1
    call mrtindex_optimize_to_entry(cx,ient,entry,error)
    if (error)  return
    if (entry%head%cal%nfreq.gt.mfreq)  mfreq = entry%head%cal%nfreq
    if (entry%head%cal%nset.gt.mset)    mset = entry%head%cal%nset
    if (entry%head%cal%npix.gt.mpix)    mpix = entry%head%cal%npix
    if (entry%head%poi%nsol.gt.msol)    msol = entry%head%poi%nsol
  enddo
  !
  ! (Re)allocations
  call mrtindex_variable_index_reallocate(mfreq,mset,mpix,msol,cx%next-1,error)
  if (error)  return
  !
  ! (Re)fill
  do ient=1,cx%next-1
    call mrtindex_optimize_to_entry(cx,ient,entry,error)
    if (error)  return
    !
    ! --- Key ----------------------------------------------------------
    mdxhead%key%version(ient)    = entry%head%key%version
    mdxhead%key%telescope(ient)  = entry%head%key%telescope
    mdxhead%key%projid(ient)     = entry%head%key%projid
    mdxhead%key%source(ient)     = entry%head%key%source
    mdxhead%key%dobs(ient)       = entry%head%key%dobs
    mdxhead%key%ut(ient)         = entry%head%key%ut
    mdxhead%key%lst(ient)        = entry%head%key%lst
    mdxhead%key%az(ient)         = entry%head%key%az
    mdxhead%key%el(ient)         = entry%head%key%el
    mdxhead%key%lon(ient)        = entry%head%key%lon
    mdxhead%key%lat(ient)        = entry%head%key%lat
    mdxhead%key%system(ient)     = entry%head%key%system
    mdxhead%key%equinox(ient)    = entry%head%key%equinox
    mdxhead%key%frontend(:,ient) = entry%head%key%frontend(:)
    mdxhead%key%scan(ient)       = entry%head%key%scan
    mdxhead%key%backend(ient)    = entry%head%key%backend
    mdxhead%key%obstype(ient)    = entry%head%key%obstype
    mdxhead%key%switchmode(ient) = entry%head%key%switchmode
    mdxhead%key%polstatus(ient)  = entry%head%key%polstatus
    mdxhead%key%filstatus(ient)  = entry%head%key%filstatus
    mdxhead%key%calstatus(ient)  = entry%head%key%calstatus
    mdxhead%key%solstatus(ient)  = entry%head%key%solstatus
    mdxhead%key%filename(ient)   = entry%head%key%filename
    !
    ! --- Calibration --------------------------------------------------
    call mdxhead%cal%set(ient,entry%head%cal,error)
    if (error)  return
    !
    ! --- Science ------------------------------------------------------
    call mdxhead%sci%set(ient,entry%head%sci,error)
    if (error)  return
    !
    ! --- Pointing -----------------------------------------------------
    call mdxhead%poi%set(ient,entry%head%poi,error)
    if (error)  return
  enddo

end subroutine mrtindex_variable_index_fill
!
subroutine mrtindex_variable_index_defvar(cx,error)
  use mrtindex_types
  use mrtindex_array_types
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_variable_index_defvar
  !---------------------------------------------------------------------
  ! @ private
  ! Create the sections in the MDX%HEAD% Sic structure
  !---------------------------------------------------------------------
  type(mrtindex_optimize_t), intent(in)    :: cx
  logical,                   intent(inout) :: error
  ! Local
  character(len=10) :: struct
  integer(kind=index_length) :: dims(4)
  !
  if (.not.sic_varexist('MDX')) then
    call sic_defstructure('MDX',.true.,error)
    if (error)  return
  endif
  !
  struct = 'MDX%HEAD'
  if (.not.sic_varexist(struct)) then
    call sic_defstructure(struct,.true.,error)
    if (error)  return
  endif
  !
  ! --- Key ------------------------------------------------------------
  call sic_defstructure(trim(struct)//'%KEY',.true.,error)
  if (error)  return
  dims(1) = cx%next-1
  call sic_def_inte (trim(struct)//'%KEY%VERSION',   mdxhead%key%version,   1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%TELESCOPE', mdxhead%key%telescope, 1,dims,.true.,error)
  call sic_def_charn(trim(struct)//'%KEY%PROJID',    mdxhead%key%projid,    1,dims,.true.,error)
  call sic_def_charn(trim(struct)//'%KEY%SOURCE',    mdxhead%key%source,    1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%DOBS',      mdxhead%key%dobs,      1,dims,.true.,error)
  call sic_def_dble (trim(struct)//'%KEY%UT',        mdxhead%key%ut,        1,dims,.true.,error)
  call sic_def_dble (trim(struct)//'%KEY%LST',       mdxhead%key%lst,       1,dims,.true.,error)
  call sic_def_real (trim(struct)//'%KEY%AZ',        mdxhead%key%az,        1,dims,.true.,error)
  call sic_def_real (trim(struct)//'%KEY%EL',        mdxhead%key%el,        1,dims,.true.,error)
  call sic_def_dble (trim(struct)//'%KEY%LON',       mdxhead%key%lon,       1,dims,.true.,error)
  call sic_def_dble (trim(struct)//'%KEY%LAT',       mdxhead%key%lat,       1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%SYSTEM',    mdxhead%key%system,    1,dims,.true.,error)
  call sic_def_real (trim(struct)//'%KEY%EQUINOX',   mdxhead%key%equinox,   1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%SCAN',      mdxhead%key%scan,      1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%BACKEND',   mdxhead%key%backend,   1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%OBSTYPE',   mdxhead%key%obstype,   1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%SWITCHMODE',mdxhead%key%switchmode,1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%POLSTATUS', mdxhead%key%polstatus, 1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%FILSTATUS', mdxhead%key%filstatus, 1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%CALSTATUS', mdxhead%key%calstatus, 1,dims,.true.,error)
  call sic_def_inte (trim(struct)//'%KEY%SOLSTATUS', mdxhead%key%solstatus, 1,dims,.true.,error)
  call sic_def_charn(trim(struct)//'%KEY%FILENAME',  mdxhead%key%filename,  1,dims,.true.,error)
  if (error)  return
  dims(1) = mrtcal_indx_mfrontend
  dims(2) = cx%next-1
  call sic_def_charn(trim(struct)//'%KEY%FRONTEND',  mdxhead%key%frontend,  2,dims,.true.,error)
  if (error)  return
  !
  ! --- Calibration ----------------------------------------------------
  call mdxhead%cal%variable(struct,error)
  if (error)  return
  !
  ! --- Science --------------------------------------------------------
  call mdxhead%sci%variable(struct,error)
  if (error)  return
  !
  ! --- Pointing -------------------------------------------------------
  call mdxhead%poi%variable(struct,error)
  if (error)  return
end subroutine mrtindex_variable_index_defvar
