module classcore_interfaces_private
  interface
    subroutine abscissa_chan2obsfre(head,chan,obsfre)
      use class_types
      !--------------------------------------------------------------------
      ! @ private
      ! Compute absolute observatory frequency at channel #chan
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: chan    !
      real(kind=8), intent(out) :: obsfre  !
    end subroutine abscissa_chan2obsfre
  end interface
  !
  interface
    subroutine abscissa_any2chan(set,obs,val,chan)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert a X coordinate in current unit to channel value.
      ! Signal (F) and Image (I) frequencies are assumed to be offset
      ! frequencies. Support for spectro and continuum, and also for
      ! irregular axes.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set   !
      type(observation),   intent(in)  :: obs   !
      real(kind=8),        intent(in)  :: val   ! The value to be converted
      real(kind=8),        intent(out) :: chan  ! The corresponding channel
    end subroutine abscissa_any2chan
  end interface
  !
  interface
    subroutine abscissa_chan2any(set,obs,chan,val)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert a X coordinate from channel value to current unit.
      ! Signal (F) and Image (I) frequencies are assumed to be offset
      ! frequencies. Support for spectro and continuum, and also for
      ! irregular axes.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set   !
      type(observation),   intent(in)  :: obs   !
      real(kind=8),        intent(in)  :: chan  ! The channel to be converted
      real(kind=8),        intent(out) :: val   ! The corresponding value
    end subroutine abscissa_chan2any
  end interface
  !
  interface
    subroutine abscissa_sigoff_left(head,sigoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the leftmost (channelwise) offset signal frequency of
      ! input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: sigoff  !
    end subroutine abscissa_sigoff_left
  end interface
  !
  interface
    subroutine abscissa_sigoff_right(head,sigoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the rightmost (channelwise) offset signal frequency of
      ! input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: sigoff  !
    end subroutine abscissa_sigoff_right
  end interface
  !
  interface
    subroutine abscissa_imaoff_left(head,imaoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the leftmost (channelwise) offset image frequency of
      ! input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: imaoff  !
    end subroutine abscissa_imaoff_left
  end interface
  !
  interface
    subroutine abscissa_imaoff_right(head,imaoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the rightmost (channelwise) offset image frequency of
      ! input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: imaoff  !
    end subroutine abscissa_imaoff_right
  end interface
  !
  interface
    subroutine abscissa_obsfre_left(head,obsfre)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the leftmost (channelwise) absolute observatory frequency of
      ! input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: obsfre  !
    end subroutine abscissa_obsfre_left
  end interface
  !
  interface
    subroutine abscissa_obsfre_middle(head,obsfre)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the middle absolute observatory frequency of input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: obsfre  !
    end subroutine abscissa_obsfre_middle
  end interface
  !
  interface
    subroutine abscissa_obsfre_right(head,obsfre)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the rightmost (channelwise) absolute observatory frequency
      ! of input spectrum
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(out) :: obsfre  !
    end subroutine abscissa_obsfre_right
  end interface
  !
  interface
    subroutine abscissa_angl_left(head,angl)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the leftmost (channelwise) position angle of input drift
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(out) :: angl  !
    end subroutine abscissa_angl_left
  end interface
  !
  interface
    subroutine abscissa_angl_right(head,angl)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the rightmost (channelwise) position angle of input drift
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(out) :: angl  !
    end subroutine abscissa_angl_right
  end interface
  !
  interface abscissa_angl
    subroutine abscissa_angl_r4(head,angl,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_angl
      !    Given the angle axis parameters in the observation header,
      ! fill the array 'angl' with appropriate angles in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_angl'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: angl(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_angl_r4
    subroutine abscissa_angl_r8(head,angl,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_angl
      !    Given the angle axis parameters in the observation header,
      ! fill the array 'angl' with appropriate angles in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_angl'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: angl(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_angl_r8
  end interface abscissa_angl
  !
  interface abscissa_angl2chan
    subroutine abscissa_angl2chan_r4(head,angl,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_angl2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: angl  !
      real(kind=4), intent(out) :: chan  !
    end subroutine abscissa_angl2chan_r4
    subroutine abscissa_angl2chan_r8(head,angl,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_angl2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: angl  !
      real(kind=8), intent(out) :: chan  !
    end subroutine abscissa_angl2chan_r8
  end interface abscissa_angl2chan
  !
  interface abscissa_chan2angl
    subroutine abscissa_chan2angl_r4(head,chan,angl)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2angl
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: chan  !
      real(kind=4), intent(out) :: angl  !
    end subroutine abscissa_chan2angl_r4
    subroutine abscissa_chan2angl_r8(head,chan,angl)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2angl
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: chan  !
      real(kind=8), intent(out) :: angl  !
    end subroutine abscissa_chan2angl_r8
  end interface abscissa_chan2angl
  !
  interface abscissa_chan2imaoff
    subroutine abscissa_chan2imaoff_r4(head,chan,imaoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2imaoff
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=4), intent(in)  :: chan    !
      real(kind=4), intent(out) :: imaoff  !
    end subroutine abscissa_chan2imaoff_r4
    subroutine abscissa_chan2imaoff_r8(head,chan,imaoff)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2imaoff
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: chan    !
      real(kind=8), intent(out) :: imaoff  !
    end subroutine abscissa_chan2imaoff_r8
  end interface abscissa_chan2imaoff
  !
  interface abscissa_chan2sigoff
    subroutine abscissa_chan2sigoff_r4(head,chan,sigoff)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_chan2sigoff
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=4), intent(in)  :: chan    !
      real(kind=4), intent(out) :: sigoff  !
    end subroutine abscissa_chan2sigoff_r4
    subroutine abscissa_chan2sigoff_r8(head,chan,sigoff)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_chan2sigoff
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: chan    !
      real(kind=8), intent(out) :: sigoff  !
    end subroutine abscissa_chan2sigoff_r8
  end interface abscissa_chan2sigoff
  !
  interface abscissa_chan2time
    subroutine abscissa_chan2time_r4(head,chan,time)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2time
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: chan  !
      real(kind=4), intent(out) :: time  !
    end subroutine abscissa_chan2time_r4
    subroutine abscissa_chan2time_r8(head,chan,time)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_chan2time
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: chan  !
      real(kind=8), intent(out) :: time  !
    end subroutine abscissa_chan2time_r8
  end interface abscissa_chan2time
  !
  interface abscissa_chan2velo
    subroutine abscissa_chan2velo_r4(head,chan,velo)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_chan2velo
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: chan  !
      real(kind=4), intent(out) :: velo  !
    end subroutine abscissa_chan2velo_r4
    subroutine abscissa_chan2velo_r8(head,chan,velo)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_chan2velo
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: chan  !
      real(kind=8), intent(out) :: velo  !
    end subroutine abscissa_chan2velo_r8
  end interface abscissa_chan2velo
  !
  interface abscissa_imaabs
    subroutine abscissa_imaabs_r4(head,iabs,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaabs
      !    Given the image frequency axis parameters in the observation
      ! header, fill the array 'iabs' with appropriate absolute image
      ! frequencies in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_imaabs'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: iabs(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_imaabs_r4
    subroutine abscissa_imaabs_r8(head,iabs,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaabs
      !    Given the image frequency axis parameters in the observation
      ! header, fill the array 'iabs' with appropriate absolute image
      ! frequencies in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_imaabs'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: iabs(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_imaabs_r8
  end interface abscissa_imaabs
  !
  interface abscissa_imaabs2chan
    subroutine abscissa_imaabs2chan_r4(head,imaabs,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaabs2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=4), intent(in)  :: imaabs  !
      real(kind=4), intent(out) :: chan    !
    end subroutine abscissa_imaabs2chan_r4
    subroutine abscissa_imaabs2chan_r8(head,imaabs,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaabs2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: imaabs  !
      real(kind=8), intent(out) :: chan    !
    end subroutine abscissa_imaabs2chan_r8
  end interface abscissa_imaabs2chan
  !
  interface abscissa_imaoff
    subroutine abscissa_imaoff_r4(head,ioff,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaoff
      !    Given the image frequency axis parameters in the observation
      ! header, fill the array 'ioff' with appropriate image frequency
      ! offsets in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_imaoff'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: ioff(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_imaoff_r4
    subroutine abscissa_imaoff_r8(head,ioff,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaoff
      !    Given the image frequency axis parameters in the observation
      ! header, fill the array 'ioff' with appropriate image frequency
      ! offsets in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_imaoff'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: ioff(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_imaoff_r8
  end interface abscissa_imaoff
  !
  interface abscissa_imaoff2chan
    subroutine abscissa_imaoff2chan_r4(head,imaoff,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaoff2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=4), intent(in)  :: imaoff  !
      real(kind=4), intent(out) :: chan    !
    end subroutine abscissa_imaoff2chan_r4
    subroutine abscissa_imaoff2chan_r8(head,imaoff,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_imaoff2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: imaoff  !
      real(kind=8), intent(out) :: chan    !
    end subroutine abscissa_imaoff2chan_r8
  end interface abscissa_imaoff2chan
  !
  interface abscissa_sigabs
    subroutine abscissa_sigabs_r4(head,sabs,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_sigabs
      !    Given the signal frequency axis parameters in the observation
      ! header, fill the array 'sabs' with appropriate absolute signal
      ! frequencies in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_sigabs'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: sabs(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_sigabs_r4
    subroutine abscissa_sigabs_r8(head,sabs,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_sigabs
      !    Given the signal frequency axis parameters in the observation
      ! header, fill the array 'sabs' with appropriate absolute signal
      ! frequencies in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_sigabs'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: sabs(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_sigabs_r8
  end interface abscissa_sigabs
  !
  interface abscissa_sigoff
    subroutine abscissa_sigoff_r4(head,soff,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_sigoff
      !    Given the signal frequency axis parameters in the observation
      ! header, fill the array 'soff' with appropriate signal frequency
      ! offsets in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_sigoff'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: soff(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_sigoff_r4
    subroutine abscissa_sigoff_r8(head,soff,c1,c2)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_sigoff
      !    Given the signal frequency axis parameters in the observation
      ! header, fill the array 'soff' with appropriate signal frequency
      ! offsets in the channel range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_sigoff'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: soff(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_sigoff_r8
  end interface abscissa_sigoff
  !
  interface abscissa_sigoff2chan
    subroutine abscissa_sigoff2chan_r4(head,sigoff,chan)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_sigoff2chan
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=4), intent(in)  :: sigoff  !
      real(kind=4), intent(out) :: chan    !
    end subroutine abscissa_sigoff2chan_r4
    subroutine abscissa_sigoff2chan_r8(head,sigoff,chan)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_sigoff2chan
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head    !
      real(kind=8), intent(in)  :: sigoff  !
      real(kind=8), intent(out) :: chan    !
    end subroutine abscissa_sigoff2chan_r8
  end interface abscissa_sigoff2chan
  !
  interface abscissa_time
    subroutine abscissa_time_r4(head,time,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_time
      !    Given the time axis parameters in the observation header,
      ! fill the array 'time' with appropriate times in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_time'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: time(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_time_r4
    subroutine abscissa_time_r8(head,time,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_time
      !    Given the time axis parameters in the observation header,
      ! fill the array 'time' with appropriate times in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_time'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: time(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_time_r8
  end interface abscissa_time
  !
  interface abscissa_time2chan
    subroutine abscissa_time2chan_r4(head,time,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_time2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: time  !
      real(kind=4), intent(out) :: chan  !
    end subroutine abscissa_time2chan_r4
    subroutine abscissa_time2chan_r8(head,time,chan)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_time2chan
      !---------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: time  !
      real(kind=8), intent(out) :: chan  !
    end subroutine abscissa_time2chan_r8
  end interface abscissa_time2chan
  !
  interface abscissa_velo
    subroutine abscissa_velo_r4(head,velo,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_velo
      !    Given the velocity axis parameters in the observation header,
      ! fill the array 'velo' with appropriate velocities in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Single precision version. Use generic entry point 'abscissa_velo'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=4),    intent(inout) :: velo(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_velo_r4
    subroutine abscissa_velo_r8(head,velo,c1,c2)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic abscissa_velo
      !    Given the velocity axis parameters in the observation header,
      ! fill the array 'velo' with appropriate velocities in the channel
      ! range c1 to c2 (assume c1<=c2)
      ! ---
      !   Double precision version. Use generic entry point 'abscissa_velo'
      ! to access this routine.
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: head     !
      real(kind=8),    intent(inout) :: velo(*)  ! Array to be filled/updated
      integer(kind=4), intent(in)    :: c1,c2    ! Channel range
    end subroutine abscissa_velo_r8
  end interface abscissa_velo
  !
  interface abscissa_velo2chan
    subroutine abscissa_velo2chan_r4(head,velo,chan)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_velo2chan
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=4), intent(in)  :: velo  !
      real(kind=4), intent(out) :: chan  !
    end subroutine abscissa_velo2chan_r4
    subroutine abscissa_velo2chan_r8(head,velo,chan)
      use class_types
      !--------------------------------------------------------------------
      ! @ private-generic abscissa_velo2chan
      !--------------------------------------------------------------------
      type(header), intent(in)  :: head  !
      real(kind=8), intent(in)  :: velo  !
      real(kind=8), intent(out) :: chan  !
    end subroutine abscissa_velo2chan_r8
  end interface abscissa_velo2chan
  !
  interface
    subroutine accumulate_generic(set,line,r,t,error)
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !    AVERAGE all scans of current index together with
      !    various weights and options. Update the origin information and
      !    reset the plotting constants
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      type(observation),   intent(inout) :: r,t    ! The observations to be added
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine accumulate_generic
  end interface
  !
  interface
    subroutine class_associate_add(set,line,r,error)
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Add an Associated Array in the dedicated section
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      character(len=*),    intent(in)    :: line
      type(observation),   intent(inout) :: r
      logical,             intent(inout) :: error
    end subroutine class_associate_add
  end interface
  !
  interface
    subroutine class_associate_delete(line,r,error)
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Add an Associated Array in the dedicated section
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: line
      type(observation), intent(inout) :: r
      logical,           intent(inout) :: error
    end subroutine class_associate_delete
  end interface
  !
  interface
    function class_assoc_isreserved(name)
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if the name is a reserved Associated Array
      !---------------------------------------------------------------------
      logical :: class_assoc_isreserved
      character(len=*), intent(in) :: name
    end function class_assoc_isreserved
  end interface
  !
  interface
    subroutine class_assoc_add_sub2(obs,name,unit,form,dim2,numarray,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  DO NOT CALL DIRECTLY: use generic entry point 'class_assoc_add'
      ! instead.
      ! ---
      !   Add an array to the Associated Section of the input observation
      ! The array is allocated but not initialized for efficiency purpose
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       ! Observation
      character(len=*),  intent(in)    :: name      ! The array name
      character(len=*),  intent(in)    :: unit      ! Unit for values
      integer(kind=4),   intent(in)    :: form      ! Format on disk
      integer(kind=4),   intent(in)    :: dim2      ! 2nd dimension, 0 for 1D array
      integer(kind=4),   intent(out)   :: numarray  ! Array number
      logical,           intent(inout) :: error     ! Logical error flag
    end subroutine class_assoc_add_sub2
  end interface
  !
  interface
    subroutine class_assoc_delete(obs,name,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Delete the named array from the section.
      !  No error if no such array
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Observation
      character(len=*),  intent(in)    :: name   ! The array name
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine class_assoc_delete
  end interface
  !
  interface
    subroutine nullify_assoc_sub(array)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Initialize an Associated Array. This does not take care of previous
      ! allocation status. If or an array which already exists, use the
      ! reallocation, reassociation, or deallocation subroutines
      !---------------------------------------------------------------------
      type(class_assoc_sub_t), intent(out)   :: array
    end subroutine nullify_assoc_sub
  end interface
  !
  interface
    recursive subroutine reallocate_assoc(assoc,narray,keep,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Allocates or reallocates the section Associated Arrays depending on
      ! the 'narray' value. In case of reallocation, previous data can be
      ! preserved.
      !  Subroutine is recursive because it calls reassociate_assoc which
      ! calls back here (no infinite loop though).
      !---------------------------------------------------------------------
      type(class_assoc_t), intent(inout) :: assoc   !
      integer(kind=4),     intent(in)    :: narray  ! Number of Associated Arrays needed
      logical,             intent(in)    :: keep    ! Keep the previous data when enlarging?
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine reallocate_assoc
  end interface
  !
  interface
    subroutine reallocate_assoc_sub(array,error)
      use gbl_format
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Reallocate the appropriate array according to its format
      !---------------------------------------------------------------------
      type(class_assoc_sub_t), intent(inout) :: array
      logical,                 intent(inout) :: error
    end subroutine reallocate_assoc_sub
  end interface
  !
  interface
    subroutine reassociate_assoc(in,ou,steal,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy a class_assoc_t, but use pointers instead of actual copies for
      ! the data arrays.
      ! - If 'steal' is .false., the output instance will point to the input
      !   one, and its pointer status is 'code_pointer_associated' in
      !   return.
      ! - If 'steal' is .true., the ownership of the actual allocation
      !   (code_pointer_allocated) is stolen to the input instance. It is an
      !   error to try to steal the ownership to a non-owner
      !   (code_pointer_associated).
      !---------------------------------------------------------------------
      type(class_assoc_t), intent(inout) :: in
      type(class_assoc_t), intent(inout) :: ou
      logical,             intent(in)    :: steal
      logical,             intent(inout) :: error
    end subroutine reassociate_assoc
  end interface
  !
  interface
    subroutine reassociate_assoc_sub(in,ou,steal,error)
      use gildas_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy a class_assoc_sub_t, but use pointers instead of actual
      ! copies for the data arrays
      ! - If 'steal' is .false., the output instance will point to the input
      !   one, and its pointer status is 'code_pointer_associated' in
      !   return.
      ! - If 'steal' is .true., the ownership of the actual allocation
      !   (code_pointer_allocated) is stolen to the input instance. It is an
      !   error to try to steal the ownership to a non-owner
      !   (code_pointer_associated).
      !---------------------------------------------------------------------
      type(class_assoc_sub_t), intent(inout), target :: in
      type(class_assoc_sub_t), intent(inout)         :: ou
      logical,                 intent(in)            :: steal
      logical,                 intent(inout)         :: error
    end subroutine reassociate_assoc_sub
  end interface
  !
  interface
    subroutine copy_assoc(in,out,error,dim1)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy an Associated Arrays section.
      !  - If dim1 is present, the output arrays will have this size,
      !    and the data is left unitialized.
      !  - If dim1 is absent, the output arrays have same size as input,
      !    and the input data is duplicated to the output.
      !---------------------------------------------------------------------
      type(class_assoc_t),       intent(in)    :: in
      type(class_assoc_t),       intent(inout) :: out
      logical,                   intent(inout) :: error
      integer(kind=4), optional, intent(in)    :: dim1
    end subroutine copy_assoc
  end interface
  !
  interface
    subroutine copy_assoc_sub(in,out,error,dim1)
      use gbl_format
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy an Associated Arrays subsection.
      !  - If dim1 is present, the output arrays will have this size,
      !    and the data is left unitialized.
      !  - If dim1 is absent, the output arrays have same size as input,
      !    and the input data is duplicated to the output.
      !---------------------------------------------------------------------
      type(class_assoc_sub_t),   intent(in)    :: in
      type(class_assoc_sub_t),   intent(inout) :: out
      logical,                   intent(inout) :: error
      integer(kind=4), optional, intent(in)    :: dim1
    end subroutine copy_assoc_sub
  end interface
  !
  interface
    subroutine copy_assoc_r4toaa(caller,in,out,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy the input section of Associated Arrays into the inout updated
      ! section. Input data is ignored and their dim1 may differ. The data
      ! of the inout section is reused but incarnated from R*4 to the
      ! appropriate format and bad value.
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: caller  ! Calling routine name
      type(class_assoc_t), intent(in)    :: in      ! Reference section
      type(class_assoc_t), intent(inout) :: out     ! Updated section
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine copy_assoc_r4toaa
  end interface
  !
  interface
    subroutine copy_assoc_sub_aator4(caller,array,r4,badr4,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy (including incarnation) the Associated Array data into
      ! the R*4 array. Target must be of appropriate size.
      !---------------------------------------------------------------------
      character(len=*),        intent(in)    :: caller  ! Calling routine name
      type(class_assoc_sub_t), intent(in)    :: array   !
      real(kind=4),            intent(out)   :: r4(:)   !
      real(kind=4),            intent(out)   :: badr4   !
      logical,                 intent(inout) :: error   !
    end subroutine copy_assoc_sub_aator4
  end interface
  !
  interface
    subroutine copy_assoc_sub_r4toaa(caller,array,r4,badr4,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy (including incarnation) the R*4 array into the Associated
      ! Array data. The Associated Array is reallocated to appropriate
      ! size if needed.
      !---------------------------------------------------------------------
      character(len=*),        intent(in)    :: caller  ! Calling routine name
      type(class_assoc_sub_t), intent(inout) :: array   ! Updated Associated Array
      real(kind=4),            intent(in)    :: r4(:)   !
      real(kind=4),            intent(in)    :: badr4   !
      logical,                 intent(inout) :: error   !
    end subroutine copy_assoc_sub_r4toaa
  end interface
  !
  interface
    subroutine deallocate_assoc(assoc,error)
      use gbl_format
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_assoc_t), intent(inout) :: assoc
      logical,             intent(inout) :: error
    end subroutine deallocate_assoc
  end interface
  !
  interface
    subroutine deallocate_assoc_sub(array,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_assoc_sub_t), intent(inout) :: array
      logical,                 intent(inout) :: error
    end subroutine deallocate_assoc_sub
  end interface
  !
  interface class_assoc_add_sub1
    subroutine class_assoc_add_sub1_i4(obs,name,unit,form,dim2,badi4,numarray,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_add_sub1
      !  DO NOT CALL DIRECTLY: use generic entry point 'class_assoc_add'
      ! instead.
      ! ---
      !  Add an array to the Associated Section, with an integer bad value.
      ! Check that the array format supports such an integer bad value.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       ! Observation
      character(len=*),  intent(in)    :: name      ! The array name
      character(len=*),  intent(in)    :: unit      ! Unit for values
      integer(kind=4),   intent(in)    :: form      ! Format on disk
      integer(kind=4),   intent(in)    :: dim2      ! 2nd dimension, 0 for 1D array
      integer(kind=4),   intent(in)    :: badi4     ! Bad value
      integer(kind=4),   intent(out)   :: numarray  ! Array number
      logical,           intent(inout) :: error     ! Logical error flag
    end subroutine class_assoc_add_sub1_i4
    subroutine class_assoc_add_sub1_r4(obs,name,unit,form,dim2,badr4,numarray,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_add_sub1
      !  DO NOT CALL DIRECTLY: use generic entry point 'class_assoc_add'
      ! instead.
      ! ---
      !  Add an array to the Associated Section, with a real bad value.
      ! Check that the array format supports such an integer bad value.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       ! Observation
      character(len=*),  intent(in)    :: name      ! The array name
      character(len=*),  intent(in)    :: unit      ! Unit for values
      integer(kind=4),   intent(in)    :: form      ! Format on disk
      integer(kind=4),   intent(in)    :: dim2      ! 2nd dimension, 0 for 1D array
      real(kind=4),      intent(in)    :: badr4     ! Bad value
      integer(kind=4),   intent(out)   :: numarray  ! Array number
      logical,           intent(inout) :: error     ! Logical error flag
    end subroutine class_assoc_add_sub1_r4
  end interface class_assoc_add_sub1
  !
  interface class_assoc_exists
    function class_assoc_exists_noarg(obs,name)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_exists
      !  Search an Associated Array by its name (name is assumed already
      ! upcased).
      ! ---
      !  This version returns nothing
      !---------------------------------------------------------------------
      logical :: class_assoc_exists_noarg  ! Function value on return
      type(observation), intent(in)  :: obs
      character(len=*),  intent(in)  :: name
    end function class_assoc_exists_noarg
    function class_assoc_exists_bynum(obs,name,iarray)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_exists
      !  Search an Associated Array by its name (name is assumed already
      ! upcased). Return index 0 if no such array exists.
      ! ---
      !  This version returns the array index
      !---------------------------------------------------------------------
      logical :: class_assoc_exists_bynum  ! Function value on return
      type(observation), intent(in)  :: obs
      character(len=*),  intent(in)  :: name
      integer(kind=4),   intent(out) :: iarray
    end function class_assoc_exists_bynum
    function class_assoc_exists_array(obs,name,array)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_exists
      !  Search an Associated Array by its name (name is assumed already
      ! upcased).
      ! ---
      !  This version returns a sub Associated Array
      !---------------------------------------------------------------------
      logical :: class_assoc_exists_array  ! Function value on return
      type(observation),       intent(in)  :: obs
      character(len=*),        intent(in)  :: name
      type(class_assoc_sub_t), intent(out) :: array
    end function class_assoc_exists_array
    function class_assoc_exists_i41d(obs,name,ptr)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_exists
      !  Search an Associated Array by its name (name is assumed already
      ! upcased).
      ! ---
      !  This version returns a pointer to the 1D I*4 data
      !---------------------------------------------------------------------
      logical :: class_assoc_exists_i41d  ! Function value on return
      type(observation), intent(in) :: obs
      character(len=*),  intent(in) :: name
      integer(kind=4),   pointer    :: ptr(:)
    end function class_assoc_exists_i41d
    function class_assoc_exists_r41d(obs,name,ptr)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic class_assoc_exists
      !  Search an Associated Array by its name (name is assumed already
      ! upcased).
      ! ---
      !  This version returns a pointer to the 1D R*4 data
      !---------------------------------------------------------------------
      logical :: class_assoc_exists_r41d  ! Function value on return
      type(observation), intent(in) :: obs
      character(len=*),  intent(in) :: name
      real(kind=4),      pointer    :: ptr(:)
    end function class_assoc_exists_r41d
  end interface class_assoc_exists
  !
  interface
    subroutine extract_assoc(assoc,extr,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Extract a subset of each Associated Array. Extraction is made
      ! inplace
      !---------------------------------------------------------------------
      type(class_assoc_t), intent(inout) :: assoc
      type(extract_t),     intent(in)    :: extr   ! Extraction descriptor
      logical,             intent(inout) :: error
    end subroutine extract_assoc
  end interface
  !
  interface
    subroutine smooth_assoc(assoc,skind,width,space,ushift,nx,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Smooth the associated array section
      !---------------------------------------------------------------------
      type(class_assoc_t), intent(inout) :: assoc   !
      character(len=*),    intent(in)    :: skind   ! SMOOTH kind
      real(kind=4),        intent(in)    :: width   ! Width (SMOOTH GAUSS|HANN)
      real(kind=4),        intent(in)    :: space   ! Channel space (SMOOTH HANN)
      real(kind=4),        intent(in)    :: ushift  ! User shift (SMOOTH HANN)
      integer(kind=4),     intent(in)    :: nx      ! Nchan per box (SMOOTH BOX)
      logical,             intent(inout) :: error   !
    end subroutine smooth_assoc
  end interface
  !
  interface
    subroutine resample_assoc(set,assoc,idatax,isirreg,old,new,dofft,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for resampling Associated Arrays
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set        !
      type(class_assoc_t),   intent(inout) :: assoc      !
      real(kind=xdata_kind), intent(in)    :: idatax(:)  ! Size old%nchan
      logical,               intent(inout) :: isirreg    !
      type(resampling),      intent(in)    :: old        ! Old X-axis sampling
      type(resampling),      intent(inout) :: new        ! New X-axis sampling
      logical,               intent(in)    :: dofft      ! In frequency or time domain
      logical,               intent(inout) :: error      !
    end subroutine resample_assoc
  end interface
  !
  interface
    subroutine resample_interpolate_regul_assoc(set,rname,in,idataw,iaxis,  &
      out,odataw,oaxis,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for resampling Associated Arrays in the context
      ! of AVERAGE
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      character(len=*),    intent(in)    :: rname      ! Calling routine name
      type(class_assoc_t), intent(in)    :: in         !
      real(kind=4),        intent(in)    :: idataw(:)  !
      type(resampling),    intent(in)    :: iaxis      !
      type(class_assoc_t), intent(inout) :: out        !
      real(kind=4),        intent(out)   :: odataw(:)  !
      type(resampling),    intent(in)    :: oaxis      !
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate_regul_assoc
  end interface
  !
  interface
    subroutine waverage_assoc(rname,one,rdataw,sumio,sdataw,schanmin,schanmax,  &
      contaminate,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for averaging Associated Arrays
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: rname        ! Calling routine name
      type(class_assoc_t), intent(in)    :: one          ! Section to be added to the running sum
      real(kind=4),        intent(in)    :: rdataw(:)    ! Weight of input arrays (all the same)
      type(class_assoc_t), intent(inout) :: sumio        ! Running sum
      real(kind=4),        intent(inout) :: sdataw(:)    ! Weight of the running sum (input only, not updated here)
      integer(kind=4),     intent(in)    :: schanmin     ! First channel
      integer(kind=4),     intent(in)    :: schanmax     ! Last channel
      logical,             intent(in)    :: contaminate  ! Bad channels contaminate output or not?
      logical,             intent(inout) :: error        ! Logical error flag
    end subroutine waverage_assoc
  end interface
  !
  interface
    subroutine wrms_assoc(rname,one,odataw,aver,adataw,rms,rdataw,  &
      chanmin,chanmax,contaminate,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for weighted-rms of Associated Arrays
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: rname        ! Calling routine name
      type(class_assoc_t), intent(in)    :: one          ! Section to be added to the running RMS
      real(kind=4),        intent(in)    :: odataw(:)    ! Weight of input arrays (all arrays have the same)
      type(class_assoc_t), intent(in)    :: aver         ! Average of all sections
      real(kind=4),        intent(in)    :: adataw(:)    ! Weight of the average (all arrays have the same)
      type(class_assoc_t), intent(inout) :: rms          ! Running RMS
      real(kind=4),        intent(inout) :: rdataw(:)    ! Weight of the running RMS (input only, not updated here)
      integer(kind=4),     intent(in)    :: chanmin      ! First channel
      integer(kind=4),     intent(in)    :: chanmax      ! Last channel
      logical,             intent(in)    :: contaminate  ! Bad channels contaminate output or not?
      logical,             intent(inout) :: error        ! Logical error flag
    end subroutine wrms_assoc
  end interface
  !
  interface
    subroutine fold_assoc(set,assoc,nphase,throw,weight,omin,omax,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for folding Associated Arrays
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set             !
      type(class_assoc_t), intent(inout) :: assoc           !
      integer(kind=4),     intent(in)    :: nphase          !
      real(kind=4),        intent(in)    :: throw(nphase)   ! [chan]
      real(kind=4),        intent(in)    :: weight(nphase)  !
      integer(kind=4),     intent(in)    :: omin            !
      integer(kind=4),     intent(in)    :: omax            !
      logical,             intent(inout) :: error           !
    end subroutine fold_assoc
  end interface
  !
  interface
    subroutine rzero_assoc(obs)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Reset the Associated Arrays section to default value
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs  !
    end subroutine rzero_assoc
  end interface
  !
  interface
    subroutine class_assoc_dump(obs,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Dump all the Associated Arrays from the input observation
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! Observation
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine class_assoc_dump
  end interface
  !
  interface
    subroutine class_assoc_minmax(obs,aaname,rmin,rmax,error)
      use gbl_format
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Compute the min max range, in the current SET MODE X, plus some
      ! MARGIN. This is suited for plotting (same as subroutine class_minmax
      ! for RY).
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs
      character(len=*),  intent(in)    :: aaname
      real(kind=4),      intent(out)   :: rmin
      real(kind=4),      intent(out)   :: rmax
      logical,           intent(inout) :: error
    end subroutine class_assoc_minmax
  end interface
  !
  interface
    subroutine sumlin_data_prepro(aver,io,assoc,error)
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Data pre-preprocessing: initialize data before computing
      !---------------------------------------------------------------------
      type(average_t),     intent(in)    :: aver   !
      type(observation),   intent(inout) :: io     ! I/O sum
      type(class_assoc_t), intent(in)    :: assoc  ! Associated Array section (can be empty)
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_data_prepro
  end interface
  !
  interface
    subroutine sumlin_wadd_new(set,obs,aver,sumio,error)
      use gildas_def
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Weighted addition. Average 'obs' and 'sumin' observations
      ! together into an output observation. 'sumin' can not be handled as
      ! a simple observation since its weight (which may be different for
      ! each channel, because of the history of all previous observations
      ! accumulated) must not be touched. On the contrary a single weight
      ! value for all channels is computed for 'obs'.
      !   This routine is totally generic for both COMPOSITE and INTERSECT
      ! cases. The only difference is the range of X values for ouput sum,
      ! but it is handled in subroutine 'sumout_param'.
      !   Alignment is performed with respect to:
      !   signal frequency if set%align = 'F'
      !   velocity         if set%align = 'V'
      !   channel number   if set%align = 'C' (default)
      ! Called by ACCUMULATE and AVERAGE.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Spectrum to add. Inout because obs%dataw is set here
      type(average_t),     intent(in)    :: aver   !
      type(observation),   intent(inout) :: sumio  ! I/O sum
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_wadd_new
  end interface
  !
  interface
    subroutine sumlin_wrms(set,obs,aver,sumio,rmsio,error)
      use gildas_def
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Weighted rms.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(in)    :: obs    ! Spectrum to add
      type(average_t),     intent(in)    :: aver   !
      type(observation),   intent(in)    :: sumio  ! The previous sum
      type(observation),   intent(inout) :: rmsio  ! The running RMS
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_wrms
  end interface
  !
  interface
    subroutine simple_wrms(odata1,odataw,obad,  &
                           adata1,adataw,abad,  &
                           rdata1,rdataw,rbad,  &
                           schanmin,schanmax,contaminate,wup)
      !---------------------------------------------------------------------
      ! @ private
      !  RMS - RMS - RMS - RMS - RMS - RMS - RMS - RMS - RMS - RMS - RMS
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)    :: odata1(:)    ! Data to be RMS'd
      real(kind=4),    intent(in)    :: odataw(:)    ! Weight of data to be RMS'd
      real(kind=4),    intent(in)    :: obad         ! Bad channel value for input data
      real(kind=4),    intent(in)    :: adata1(:)    ! Average
      real(kind=4),    intent(in)    :: adataw(:)    ! Average weights (unused)
      real(kind=4),    intent(in)    :: abad         ! Bad channel value for average
      real(kind=4),    intent(inout) :: rdata1(:)    ! The RMS
      real(kind=4),    intent(inout) :: rdataw(:)    ! Weight of RMS
      real(kind=4),    intent(in)    :: rbad         ! Bad channel value for RMS
      integer(kind=4), intent(in)    :: schanmin     ! First channel
      integer(kind=4), intent(in)    :: schanmax     ! Last channel
      logical,         intent(in)    :: contaminate  ! Bad channels contaminate output or not?
      logical,         intent(in)    :: wup          ! Update weight in return?
    end subroutine simple_wrms
  end interface
  !
  interface
    subroutine sumlin_resample(set,aver,obsin,obsout,ismin,ismax,error)
      use gildas_def
      use gbl_constant
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set     !
      type(average_t),     intent(in)    :: aver    !
      type(observation),   intent(in)    :: obsin   ! Input observation
      type(observation),   intent(inout) :: obsout  ! Resampled observation
      integer(kind=4),     intent(out)   :: ismin   !
      integer(kind=4),     intent(out)   :: ismax   !
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine sumlin_resample
  end interface
  !
  interface
    subroutine sumlin_data_postpro_waverage(aver,sumio,error)
      use gbl_constant
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Data post-preprocessing for weighted average
      !---------------------------------------------------------------------
      type(average_t),   intent(in)    :: aver   !
      type(observation), intent(inout) :: sumio  !
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_data_postpro_waverage
  end interface
  !
  interface
    subroutine sumlin_data_postpro_wrms(aver,rmsio,error)
      use gbl_constant
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Data post-preprocessing for weighted rms
      !---------------------------------------------------------------------
      type(average_t),   intent(in)    :: aver
      type(observation), intent(inout) :: rmsio
      logical,           intent(inout) :: error
    end subroutine sumlin_data_postpro_wrms
  end interface
  !
  interface
    subroutine sumlin_header(set,aver,refer,cons,sumio,error,user_function)
      use gbl_constant
      use gbl_message
      use gkernel_types
      use class_averaging
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Run through the index to set the sum header. If required,
      ! automatically define the X axis resampling.
      ! 'sumlin_init' must have been called before.
      ! ---
      !  WARNING: this subroutine is duplicated in 'accumulate_generic'
      !  in order to loop on R & T instead of CX. Please duplicate there
      !  any modification made here!
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(average_t),     intent(inout) :: aver      !
      type(header),        intent(in)    :: refer     ! Reference header
      type(consistency_t), intent(inout) :: cons      !
      type(observation),   intent(inout) :: sumio     ! The sum. Header set on return
      logical,             intent(inout) :: error     ! Logical error flag
      logical,             external      :: user_function
    end subroutine sumlin_header
  end interface
  !
  interface
    subroutine sumlin_init(set,cons,aver,error)
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set some shared variables, ruled by SET methods, which we do not
      ! want to test each time in the addition loop for efficiency reasons.
      ! Should be called once, out the addition loop, i.e. not in
      ! sumlin_wadd.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(consistency_t), intent(in)    :: cons   !
      type(average_t),     intent(inout) :: aver   !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_init
  end interface
  !
  interface
    subroutine sumlin_header_init(aver,refer,sumio,error)
      use phys_const
      use class_parameter
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize the header of the output sum
      !---------------------------------------------------------------------
      type(average_t),   intent(in)    :: aver   !
      type(header),      intent(in)    :: refer  ! Spectrum to add
      type(observation), intent(inout) :: sumio  ! Future sum
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_init
  end interface
  !
  interface
    subroutine sumlin_init_variables(aver,refer,sumio,error)
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize some global variables related to the output sum: running
      ! means, some extrema, and so on. Must be called *after* the
      ! I/O sum header is set.
      !---------------------------------------------------------------------
      type(average_t), intent(inout) :: aver   !
      type(header),    intent(in)    :: refer  ! Reference header
      type(header),    intent(in)    :: sumio  ! Future sum header
      logical,         intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_init_variables
  end interface
  !
  interface
    subroutine sumlin_header_register(obs,refer,aver,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! Spectrum to add
      type(observation), intent(in)    :: refer  ! The reference spectrum
      type(average_t),   intent(inout) :: aver   ! The new axis resolution may be updated on return
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_register
  end interface
  !
  interface
    subroutine sumlin_header_check(aver,obs,refer,error)
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(average_t),   intent(in)    :: aver   !
      type(observation), intent(in)    :: obs    ! The new spectrum
      type(observation), intent(in)    :: refer  ! The reference spectrum
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_check
  end interface
  !
  interface
    subroutine sumlin_header_xaxis(set,aver,sumio,nobs,error)
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set the global variables defining the X axis of the output sum.
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set    !
      type(average_t),            intent(inout) :: aver   !
      type(observation),          intent(inout) :: sumio  ! I/O sum
      integer(kind=entry_length), intent(in)    :: nobs   ! Number of observations averaged
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_xaxis
  end interface
  !
  interface
    subroutine sumlin_header_xaxis_compute(aver,sumio,nobs,error)
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(average_t),            intent(inout) :: aver   !
      type(observation),          intent(inout) :: sumio  ! I/O sum
      integer(kind=entry_length), intent(in)    :: nobs   ! Number of observations averaged
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_xaxis_compute
  end interface
  !
  interface
    subroutine sumlin_header_xaxis_resample(aver,sumio,error)
      use phys_const
      use class_types
      use class_averaging
      !---------------------------------------------------------------------
      ! @ private
      !  AUTOMATIC resampling of the header to the coarsest resolution <=>
      ! all but channel alignment.
      !---------------------------------------------------------------------
      type(average_t),   intent(inout) :: aver   !
      type(observation), intent(inout) :: sumio  ! I/O sum
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_xaxis_resample
  end interface
  !
  interface
    subroutine sumlin_header_xaxis_range(aver,sumio,error)
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Apply a range cut. The range unit can be in any unit (i.e. other
      ! than aver%done%align)
      !  NB: the sumio spectroscopic axis must have been fully set
      ! (resolution, Doppler, etc) so that it is usable with the abscissa
      ! routines
      !---------------------------------------------------------------------
      type(average_t),   intent(inout) :: aver   !
      type(observation), intent(inout) :: sumio  ! I/O sum
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine sumlin_header_xaxis_range
  end interface
  !
  interface
    subroutine sumlin_header_xaxis_feedback(set,aver,sumio)
      use gbl_message
      use class_averaging
      use class_types
      use class_setup_new
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set    !
      type(average_t),     intent(in) :: aver   !
      type(observation),   intent(in) :: sumio  !
    end subroutine sumlin_header_xaxis_feedback
  end interface
  !
  interface
    subroutine add_history_new(in1,in2,out)
      use class_types
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Add histories input observations into output observation
      ! * nseq     : the number of sequences of consecutive scan numbers
      ! * start(i) : the first scan of sequence 'i'
      ! * end(i)   : the last  scan of sequence 'i'
      !---------------------------------------------------------------------
      type (observation), intent(inout) :: in1  ! New observation
      type (observation), intent(inout) :: in2  ! Old sum
      type (observation), intent(inout) :: out  ! New sum
    end subroutine add_history_new
  end interface
  !
  interface
    subroutine average_generic(set,aver,line,obs,error,user_function)
      use gildas_def
      use gbl_message
      use gbl_constant
      use class_averaging
      use class_data
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !    AVERAGE all scans of current index together with
      !    various weights and options. Update the origin information and
      !    reset the plotting constants
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set            !
      type(average_t),     intent(inout) :: aver           !
      character(len=*),    intent(in)    :: line           ! Input command line
      type(observation),   intent(inout) :: obs            ! Output observation
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  !
    end subroutine average_generic
  end interface
  !
  interface
    subroutine average_one(set,aver,sumio,error,user_function)
      use gbl_constant
      use gbl_message
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(average_t),     intent(in)    :: aver           !
      type(observation),   intent(inout) :: sumio          !
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  !
    end subroutine average_one
  end interface
  !
  interface
    subroutine average_many(set,aver,line,sumio,error,user_function)
      use gbl_constant
      use gbl_message
      use gkernel_types
      use class_averaging
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set            !
      type(average_t),     intent(inout) :: aver           !
      character(len=*),    intent(in)    :: line           ! Input command line
      type(observation),   intent(inout) :: sumio          !
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  !
    end subroutine average_many
  end interface
  !
  interface
    subroutine baseline_index(set,deg,sinuspar,last,cont,flux,error,user_function)
      use gbl_message
      use class_data
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command BASE.
      ! This version for the whole index.
      ! Make the loop on records.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      integer(kind=4),     intent(in)    :: deg            ! Degree of polynom
      real(kind=4),        intent(in)    :: sinuspar(3)    ! Sine guess if sinus fitting
      logical,             intent(inout) :: last           ! Use last baseline determination
      logical,             intent(in)    :: cont           ! Continuum?
      real(kind=4),        intent(inout) :: flux           ! Flux value (if 0, average of base channels)
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  ! External function
    end subroutine baseline_index
  end interface
  !
  interface
    subroutine baseline_obs_prepro(set,obs,ir,deg,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private (?)
      ! Support routine for command BASE.
      !  This version for a single observation. Prepare the observation
      ! header for ongoing baseline fit.
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set    !
      type(observation),          intent(inout) :: obs    ! The input observation to work on
      integer(kind=entry_length), intent(in)    :: ir     ! Position of observation in index
      integer(kind=4),            intent(in)    :: deg    ! Degree of polynom
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine baseline_obs_prepro
  end interface
  !
  interface
    subroutine baseline_obs(set,obs,dooldsinus,donewsinus,sinuspar,lplot,  &
      plot_pen,last,cont,flux,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private (?)
      ! Support routine for command BASE.
      ! This version for a single observation. Fit polynomial or sine.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: obs            ! The input observation to work on
      logical,             intent(in)    :: dooldsinus     ! BASE SINUS
      logical,             intent(in)    :: donewsinus(3)  ! BASE NEWSINUS
      real(kind=4),        intent(in)    :: sinuspar(3)    ! Sine initial guess if sinus fitting
      logical,             intent(in)    :: lplot          ! Plot the baseline or not
      integer(kind=4),     intent(in)    :: plot_pen       ! Pen number, if plot is enabled
      logical,             intent(inout) :: last           ! Use last baseline determination
      logical,             intent(in)    :: cont           ! Divide rather than subtract baseline
      real(kind=4),        intent(inout) :: flux           ! Flux value (if 0, average of base channels)
      logical,             intent(inout) :: error          ! Logical error flag
    end subroutine baseline_obs
  end interface
  !
  interface
    subroutine baseline_obs_postpro(obs,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private (?)
      ! Support routine for command BASE.
      ! This version for a single observation. Fit polynomial or sine.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! The input observation to work on
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine baseline_obs_postpro
  end interface
  !
  interface
    subroutine baseline_plot(obs,z,ipen,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Plot the baseline for a single observation
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! The observation to work on
      real(kind=4),      intent(in)    :: z(*)   ! The model Z values
      integer(kind=4),   intent(in)    :: ipen   ! Pen to be used for the plot
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine baseline_plot
  end interface
  !
  interface
    subroutine class_box_default(set,doindex,r,aaname,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Plot a default box, suited for RY or index or the given Associated
      ! Array, i.e. shortcut for
      !         PLOT [Array] /OBS
      !      or PLOT /INDEX
      !  without any other customization.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set      !
      logical,             intent(in)    :: doindex  !
      type(observation),   intent(in)    :: r        !
      character(len=*),    intent(in)    :: aaname   ! Assoc Array name, Y means RY
      logical,             intent(inout) :: error    !
    end subroutine class_box_default
  end interface
  !
  interface
    subroutine class_box_do(set,doindex,r,aaname,chlow,chup,ch1,ch2,ch3,ch4,error)
      use gbl_message
      use class_data
      !---------------------------------------------------------------------
      ! @ private
      !  Check arguments and do the job
      !  Empty arguments mean to use internal default
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set              !
      logical,             intent(in)    :: doindex          !
      type(observation),   intent(in)    :: r                !
      character(len=*),    intent(in)    :: aaname           ! Assoc Array name, Y means RY
      character(len=*),    intent(in)    :: chlow,chup       !
      character(len=*),    intent(in)    :: ch1,ch2,ch3,ch4  !
      logical,             intent(inout) :: error            !
    end subroutine class_box_do
  end interface
  !
  interface
    subroutine class_box_sub(set,obs,aaname,unit_low,unit_up,c1,c2,c3,c4,  &
      plot2d,error)
      use gbl_constant
      use class_setup_new
      use class_data
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Plot a standard box, with the requested X axis units for lower
      ! and upper axis.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(observation),   intent(in)    :: obs       !
      character(len=*),    intent(in)    :: aaname    ! Assoc Array name, Y means RY
      character(len=*),    intent(in)    :: unit_low  ! Lower axis unit
      character(len=*),    intent(in)    :: unit_up   ! Upper axis unit
      character(len=*),    intent(in)    :: c1        ! Parallel   Orthogonal None
      character(len=*),    intent(in)    :: c2        ! Orthogonal Parallel None
      character(len=*),    intent(in)    :: c3        ! In Out
      character(len=*),    intent(in)    :: c4        ! X Y (for labels)
      logical,             intent(in)    :: plot2d    ! 2D data
      logical,             intent(inout) :: error     ! flag
    end subroutine class_box_sub
  end interface
  !
  interface
    subroutine textx(unit,text,ntext,kind)
      use gbl_constant
      !-------------------------------------------------------------------
      ! @ private
      ! Return a text for axis labels according to specified unit and
      ! observation type
      !-------------------------------------------------------------------
      character(len=1), intent(in)  :: unit   ! X axis unit
      character(len=*), intent(out) :: text   ! Output full text
      integer(kind=4),  intent(out) :: ntext  ! TEXT length
      integer(kind=4),  intent(in)  :: kind   ! Observation kind
    end subroutine textx
  end interface
  !
  interface
    subroutine texty(unit,text,ntext,kind)
      use gbl_constant
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Return a text for axis labels according to specified unit and
      ! observation type
      !-------------------------------------------------------------------
      character(len=*), intent(in)  :: unit   ! X axis unit
      character(len=*), intent(out) :: text   ! Output full text
      integer(kind=4),  intent(out) :: ntext  ! TEXT length
      integer(kind=4),  intent(in)  :: kind   ! Observation kind
    end subroutine texty
  end interface
  !
  interface
    subroutine class_cells_do(set,match,keep,wher,docell,disx,disy,grid,  &
      donolabel,donumber,dobase,basepen,error,user_function)
      use gbl_message
      use class_setup_new
      use class_index
      use class_popup
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command  ANA\MAP
      !  Do the actual job
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      logical,             intent(in)    :: match          !
      logical,             intent(in)    :: keep           !
      logical,             intent(in)    :: wher           !
      logical,             intent(in)    :: docell         !
      real(kind=4),        intent(inout) :: disx,disy      !
      logical,             intent(in)    :: grid           !
      logical,             intent(in)    :: donolabel      !
      logical,             intent(in)    :: donumber       !
      logical,             intent(in)    :: dobase         !
      integer(kind=4),     intent(in)    :: basepen        !
      logical,             intent(inout) :: error          !
      logical,             external      :: user_function  !
    end subroutine class_cells_do
  end interface
  !
  interface
    subroutine lmv_read(set,inname,linename,nway,lstep,bstep,dounit,yunit,  &
      error,user_function)
      use gildas_def
      use image_def
      use gbl_constant
      use gbl_message
      use class_parameter
      use class_types
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Support routine for command
      !    LMV DataCube
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      character(len=*),    intent(in)    :: inname         ! Input LMV table
      character(len=*),    intent(in)    :: linename       ! LINE cube (blank if none)
      integer(kind=4),     intent(in)    :: nway           ! Scan through which direction?
      integer(kind=4),     intent(in)    :: lstep          ! Take 1 value other 'lstep' in lambda direction
      integer(kind=4),     intent(in)    :: bstep          ! Take 1 value other 'bstep' in beta direction
      logical,             intent(in)    :: dounit         ! /FORCE UNIT?
      integer(kind=4),     intent(in)    :: yunit          ! Desired unit if /FORCE UNIT
      logical,             intent(inout) :: error          ! Error flag
      logical,             external      :: user_function  !
    end subroutine lmv_read
  end interface
  !
  interface
    function class_lmv_match(rname,h1,h2)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Check if the 2 lmv header match
      !---------------------------------------------------------------------
      logical :: class_lmv_match
      character(len=*), intent(in) :: rname
      type(gildas),     intent(in) :: h1,h2
    end function class_lmv_match
  end interface
  !
  interface
    subroutine lmv_get_axis(hin,iaxis,ref,val,inc,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Return the ref, val, and inc value of i-th axis in input header.
      !---------------------------------------------------------------------
      type(gildas),    intent(in)    :: hin    ! Get axis from this header
      integer(kind=4), intent(in)    :: iaxis  ! Axis number to get
      real(kind=8),    intent(out)   :: ref    ! Reference pixel
      real(kind=8),    intent(out)   :: val    ! Value at reference pixel
      real(kind=8),    intent(out)   :: inc    ! Increment per pixel
      logical,         intent(inout) :: error  ! Error flag
    end subroutine lmv_get_axis
  end interface
  !
  interface
    subroutine class_file_read_gdfhead(rname,filename,head,velofirst,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Read a GDF header, check it is suited for use by Class
      ! (position-position-velocity cube or variants), and modify the
      ! header so that it can be imported into the Class spectroscopic
      ! section in rspec_gdf
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname      ! Calling routine name
      character(len=*), intent(in)    :: filename   !
      type(gildas),     intent(inout) :: head       !
      logical,          intent(in)    :: velofirst  ! Should the 1st dim be freq/velo?
      logical,          intent(inout) :: error      !
    end subroutine class_file_read_gdfhead
  end interface
  !
  interface
    subroutine class_file_2to3_gdfhead(rname,head,velofirst,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Extend a 2D spatial to a pseudo 3D cube with Velocity as 3rd
      ! dimension
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname      ! Calling routine name
      type(gildas),     intent(inout) :: head       ! Header to be extended
      logical,          intent(in)    :: velofirst  ! Should the 1st dim be freq/velo?
      logical,          intent(inout) :: error      ! Logical error flag
    end subroutine class_file_2to3_gdfhead
  end interface
  !
  interface
    subroutine class_file_check_gdfhead(rname,hin,velofirst,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Check if the GDF file is suited for FILE IN in Class
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname      ! Calling routine name
      type(gildas),     intent(in)    :: hin        !
      logical,          intent(in)    :: velofirst  ! Should the 1st dim be freq/velo?
      logical,          intent(inout) :: error      !
    end subroutine class_file_check_gdfhead
  end interface
  !
  interface
    subroutine index_fromgdf(h,entry_num,ind,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use image_def
      use classic_api
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get the index from the header of the input GDF file
      !---------------------------------------------------------------------
      type(gildas),               intent(in)    :: h          !
      integer(kind=entry_length), intent(in)    :: entry_num  ! Entry number
      type(indx_t),               intent(out)   :: ind        !
      logical,                    intent(inout) :: error      ! Logical error flag
    end subroutine index_fromgdf
  end interface
  !
  interface
    subroutine rgen_gdf(h,obs,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! "Read" (in this case, mimic) the GENeral section from the GDF
      ! header
      !---------------------------------------------------------------------
      type(gildas),      intent(in)    :: h       ! GDF header
      type(observation), intent(inout) :: obs     ! Header
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine rgen_gdf
  end interface
  !
  interface
    subroutine rpos_gdf(h,obs,error)
      use gbl_constant
      use image_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! "Read" (in this case, mimic) the POSition section from the GDF
      ! header
      !---------------------------------------------------------------------
      type(gildas),      intent(in)    :: h      ! GDF header
      type(observation), intent(inout) :: obs    ! Header
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine rpos_gdf
  end interface
  !
  interface
    subroutine rspec_gdf(h,obs,error)
      use gbl_message
      use image_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! "Read" (in this case, mimic) the SPECtroscopic section from the GDF
      ! header
      !---------------------------------------------------------------------
      type(gildas),      intent(in)    :: h      ! GDF header
      type(observation), intent(inout) :: obs    ! Header
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine rspec_gdf
  end interface
  !
  interface
    subroutine rres_gdf(h,obs,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! "Read" (in this case, mimic) the RESolution section from the GDF
      ! header
      !---------------------------------------------------------------------
      type(gildas),      intent(in)    :: h      ! GDF header
      type(observation), intent(inout) :: obs    ! Header
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine rres_gdf
  end interface
  !
  interface
    subroutine rdata_sub_vlm(entry_num,first,last,nv,values,error)
      use classic_api
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !  Read a (subset of) a spectrum from an entry of a GDF file
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: entry_num   !
      integer(kind=data_length),  intent(in)    :: first       ! First data word to read
      integer(kind=data_length),  intent(in)    :: last        ! Last data word to read
      integer(kind=data_length),  intent(inout) :: nv          ! Input and actual number of values read
      real(kind=4),               intent(out)   :: values(nv)  ! Data array
      logical,                    intent(out)   :: error       ! Logical error flag
    end subroutine rdata_sub_vlm
  end interface
  !
  interface
    subroutine gdf2class_spectro(hgdf,hclass,error)
      use gbl_constant
      use image_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert a GDF header to a Class spectroscopic section +
      ! port the measurement frame to the rest frame.
      !---------------------------------------------------------------------
      type(gildas), intent(in)    :: hgdf
      type(header), intent(inout) :: hclass
      logical,      intent(inout) :: error
    end subroutine gdf2class_spectro
  end interface
  !
  interface
    subroutine class2gdf_spectro(hclass,faxi,hgdf,error)
      use gbl_constant
      use image_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert a Class spectroscopic section to (part of) a GDF header
      !---------------------------------------------------------------------
      type(header),    intent(in)    :: hclass
      integer(kind=4), intent(in)    :: faxi
      type(gildas),    intent(inout) :: hgdf
      logical,         intent(inout) :: error
    end subroutine class2gdf_spectro
  end interface
  !
  interface
    subroutine class_iostat(mkind,procname,ier)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Output system message corresponding to IO error code IER, and
      ! using the MESSAGE routine
      !---------------------------------------------------------------------
      integer,          intent(in) :: mkind     ! Message severity
      character(len=*), intent(in) :: procname  ! Calling routine name
      integer,          intent(in) :: ier       ! IO error number
    end subroutine class_iostat
  end interface
  !
  interface
    subroutine fill_noise(set,obs,wmin,wmax,nw,sigma,dointer,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command:
      !   FILL /NOISE [sigma]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(observation),   intent(inout) :: obs       ! Observation to be filled
      integer(kind=4),     intent(in)    :: nw        ! Number of windows
      real(kind=8),        intent(in)    :: wmin(nw)  ! Lower bounds of velo windows
      real(kind=8),        intent(in)    :: wmax(nw)  ! Upper bounds of velo windows
      real(kind=4),        intent(inout) :: sigma     ! RMS for Gaussian noise
      logical,             intent(in)    :: dointer   ! Add the noise to previous interpolation
      logical,             intent(inout) :: error     ! Logical error flag
    end subroutine fill_noise
  end interface
  !
  interface
    subroutine fill_blank(set,obs,wmin,wmax,nw,blank)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine for command FILL /BLANK [bval]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(observation),   intent(inout) :: obs       ! Observation to be filled
      integer(kind=4),     intent(in)    :: nw        ! Number of windows
      real(kind=8),        intent(in)    :: wmin(nw)  ! Lower bounds of velo windows
      real(kind=8),        intent(in)    :: wmax(nw)  ! Upper bounds of velo windows
      real(kind=4),        intent(inout) :: blank     ! Blanking value
    end subroutine fill_blank
  end interface
  !
  interface
    subroutine fill_inter(set,obs,wmin,wmax,nw)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine for command FILL /NOISE [sigma]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(observation),   intent(inout) :: obs       ! Observation to be filled
      integer(kind=4),     intent(in)    :: nw        ! Number of windows
      real(kind=8),        intent(in)    :: wmin(nw)  ! Lower bounds of velo windows
      real(kind=8),        intent(in)    :: wmax(nw)  ! Upper bounds of velo windows
    end subroutine fill_inter
  end interface
  !
  interface
    subroutine coffse(set,rname,value,unit,offset,error)
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Converts the string value in current units (LAS\SET ANGLE) or
      ! specified unit to internal value (radians).
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set     !
      character(len=*),    intent(in)    :: rname   ! Caller name
      character(len=*),    intent(in)    :: value   ! String containing the angle value
      character(len=*),    intent(in)    :: unit    ! String containing the angle unit
      real(kind=4),        intent(out)   :: offset  ! Output angle in radians
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine coffse
  end interface
  !
  interface
    subroutine offsec(set,offset,line)
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Converts an offset value from radian to a formatted string in
      ! current angle units (LAS\SET ANGLE)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set     !
      real(kind=4),        intent(in)  :: offset  ! angle in radian
      character(len=*),    intent(out) :: line    ! formatted angle
    end subroutine offsec
  end interface
  !
  interface
    subroutine consistency_defaults(set,cons)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set   !
      type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
    end subroutine consistency_defaults
  end interface
  !
  interface
    subroutine consistency_check_selection(set,line,iopt,cons,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Command line
      integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine consistency_check_selection
  end interface
  !
  interface
    subroutine consistency_check_gen(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'general' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_gen
  end interface
  !
  interface
    subroutine consistency_check_sou(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'source' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_sou
  end interface
  !
  interface
    subroutine consistency_check_pos(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'position' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_pos
  end interface
  !
  interface
    subroutine consistency_check_off(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'offset' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_off
  end interface
  !
  interface
    subroutine consistency_check_lin(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'line' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_lin
  end interface
  !
  interface
    subroutine consistency_check_spe(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'spectroscopy' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_spe
  end interface
  !
  interface
    subroutine consistency_check_cal(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'calibration' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_cal
  end interface
  !
  interface
    subroutine consistency_check_swi(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'switching' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_swi
  end interface
  !
  interface
    subroutine consistency_check_dri(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check if 'drift' consistency has already been checked
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  !
    end subroutine consistency_check_dri
  end interface
  !
  interface
    subroutine consistency_print(set,ref_head,cons)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine consistency_print
  end interface
  !
  interface
    subroutine consistency_print_gen(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'general' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_gen
  end interface
  !
  interface
    subroutine consistency_print_sou(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'source' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_sou
  end interface
  !
  interface
    subroutine consistency_print_pos(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'position' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_pos
  end interface
  !
  interface
    subroutine consistency_print_off(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'offset' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_off
  end interface
  !
  interface
    subroutine consistency_print_lin(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'line' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_lin
  end interface
  !
  interface
    subroutine consistency_print_spe(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'spectroscopy' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_spe
  end interface
  !
  interface
    subroutine consistency_print_cal(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'calibration' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_cal
  end interface
  !
  interface
    subroutine consistency_print_swi(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'switching' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_swi
  end interface
  !
  interface
    subroutine consistency_print_dri(cons)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print checking status of the 'drift' consistency
      !---------------------------------------------------------------------
      type(consistency_t), intent(in) :: cons  !
    end subroutine consistency_print_dri
  end interface
  !
  interface
    subroutine observation_consistency_check(set,ref_head,obs_head,cons)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(header),        intent(in)    :: obs_head  ! Header to be checked
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine observation_consistency_check
  end interface
  !
  interface
    subroutine observation_consistency_check_gen(kind,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'general' consistency of the input observation header
      !---------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: kind      ! Expected kind of data
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_gen
  end interface
  !
  interface
    subroutine observation_consistency_check_sou(ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'source' consistency of the input observation header
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_sou
  end interface
  !
  interface
    subroutine observation_consistency_check_pos(set,ref_head,obs_head,cons,warned)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'position' consistency of the input observation header
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_pos
  end interface
  !
  interface
    subroutine observation_consistency_check_off(set,ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'offset' consistency of the input observation header
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_off
  end interface
  !
  interface
    subroutine observation_consistency_check_lin(ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'line' consistency of the input observation header
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_lin
  end interface
  !
  interface
    subroutine observation_consistency_check_spe(ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'spectroscopy' consistency of the input observation header
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_spe
  end interface
  !
  interface
    subroutine observation_consistency_check_cal(set,ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'calibration' consistency of the input observation header
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_cal
  end interface
  !
  interface
    subroutine observation_consistency_check_swi(ref_head,obs_head,cons,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'switching' consistency of the input observation header
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_swi
  end interface
  !
  interface
    subroutine observation_consistency_check_dri(set,ref_head,obs_head,cons,warned)
      use phys_const
      use gbl_message
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the 'drift' consistency of the input observation header
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  !
      type(header),        intent(in)    :: obs_head  !
      type(consistency_t), intent(inout) :: cons      !
      logical,             intent(inout) :: warned    ! Warning flag
    end subroutine observation_consistency_check_dri
  end interface
  !
  interface
    subroutine observation_consistency_warn(obs_head,warned)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      ! Warn user about inconsistant spectrum, if not yet done
      !---------------------------------------------------------------------
      type(header), intent(in)    :: obs_head  !
      logical,      intent(inout) :: warned    !
    end subroutine observation_consistency_warn
  end interface
  !
  interface
    subroutine consistency_tole(ref_head,cons)
      use phys_const
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine consistency_tole
  end interface
  !
  interface
    subroutine index_consistency_analysis(set,cons,rname)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      character(len=*),    intent(in)    :: rname  ! Calling routine name
    end subroutine index_consistency_analysis
  end interface
  !
  interface
    subroutine consistency_defaults_spec(cons)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For spectroscopic data
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
    end subroutine consistency_defaults_spec
  end interface
  !
  interface
    subroutine consistency_check_selection_spec(set,line,iopt,cons,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For spectroscopic data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Command line
      integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine consistency_check_selection_spec
  end interface
  !
  interface
    subroutine consistency_print_spec(ref_head,cons)
      use gbl_constant
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For spectroscopic data
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine consistency_print_spec
  end interface
  !
  interface
    subroutine spectrum_consistency_check(set,ref_head,spe_head,cons)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For spectroscopic data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(header),        intent(in)    :: spe_head  ! Header to be checked
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine spectrum_consistency_check
  end interface
  !
  interface
    subroutine index_consistency_analysis_spec(cons,rname)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For spectroscopic data
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      character(len=*),    intent(in)    :: rname  ! Calling routine name
    end subroutine index_consistency_analysis_spec
  end interface
  !
  interface
    subroutine consistency_defaults_cont(cons)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For continuum data
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
    end subroutine consistency_defaults_cont
  end interface
  !
  interface
    subroutine consistency_check_selection_cont(set,line,iopt,cons,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Command line
      integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine consistency_check_selection_cont
  end interface
  !
  interface
    subroutine consistency_print_cont(ref_head,cons)
      use gbl_constant
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For continuum data
      !---------------------------------------------------------------------
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine consistency_print_cont
  end interface
  !
  interface
    subroutine continuum_consistency_check(set,ref_head,dri_head,cons)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set       !
      type(header),        intent(in)    :: ref_head  ! Reference header
      type(header),        intent(in)    :: dri_head  ! Header to be checked
      type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
    end subroutine continuum_consistency_check
  end interface
  !
  interface
    subroutine index_consistency_analysis_cont(cons,rname)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! For continuum data
      !---------------------------------------------------------------------
      type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
      character(len=*),    intent(in)    :: rname  ! Calling routine name
    end subroutine index_consistency_analysis_cont
  end interface
  !
  interface
    subroutine consistency_check_do(set,rname,idx,error,user_function)
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Generic for spectroscopic or continuum data
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      character(len=*),    intent(in)    :: rname
      type(optimize),      intent(inout) :: idx
      logical,             intent(inout) :: error
      logical,             external      :: user_function
    end subroutine consistency_check_do
  end interface
  !
  interface
    subroutine class_controlc(com,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Interruption by ^C: behavior depends on keybord input
      ! - blank: continue execution
      ! - carriage return: continue execution
      ! - q: abort execution
      ! _ any other character: ask for input
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: com    ! calling command
      logical,          intent(out) :: error  ! logical flag
    end subroutine class_controlc
  end interface
  !
  interface
    subroutine crsec(set,obs,scode,error)
      use gbl_message
      use class_common
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Read the appropriate section into the input observation from the
      ! associated entry in the input file, taking care of conversion of
      ! the section data from System data type to File data type.
      !  OBS%DESC: input
      !  OBS%HEAD: updated
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Header
      integer(kind=4),     intent(in)    :: scode  ! Section code
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine crsec
  end interface
  !
  interface
    subroutine rgen_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the GENeral section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rgen_classic
  end interface
  !
  interface
    subroutine rpos_classic(obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the POSition section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rpos_classic
  end interface
  !
  interface
    subroutine rspec_classic(set,obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the SPECtroscopic section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(out)   :: error
    end subroutine rspec_classic
  end interface
  !
  interface
    subroutine rspec_classic_foffpatch(spe,foff)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Apply patch for suppressing a frequency offset on the spectroscopic
      ! axis
      !---------------------------------------------------------------------
      type(class_spectro_t), intent(inout) :: spe   ! The spectroscopic section to update
      real(kind=4),          intent(in)    :: foff  ! The frequency offset to apply
    end subroutine rspec_classic_foffpatch
  end interface
  !
  interface
    subroutine rbas_classic(obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the BASe section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rbas_classic
  end interface
  !
  interface
    subroutine rplo_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Plotting section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rplo_classic
  end interface
  !
  interface
    subroutine rswi_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Switching section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rswi_classic
  end interface
  !
  interface
    subroutine rgau_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Gauss fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rgau_classic
  end interface
  !
  interface
    subroutine rshe_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Shell fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rshe_classic
  end interface
  !
  interface
    subroutine rhfs_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the HFS fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rhfs_classic
  end interface
  !
  interface
    subroutine rabs_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Absorption fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rabs_classic
  end interface
  !
  interface
    subroutine rcal_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Calibration section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rcal_classic
  end interface
  !
  interface
    subroutine rdri_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Drift Continuum section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rdri_classic
  end interface
  !
  interface
    subroutine rpoi_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the Pointing fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rpoi_classic
  end interface
  !
  interface
    subroutine rbea_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the BEAm-switching section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rbea_classic
  end interface
  !
  interface
    subroutine rres_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the RESolution section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rres_classic
  end interface
  !
  interface
    subroutine ruser_classic(obs,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_buffer
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Convert User Section from File data type to System data type.
      ! Read the User Section from buffer 'uwork'.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Observation
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine ruser_classic
  end interface
  !
  interface
    subroutine rassoc_classic(obs,error)
      use gbl_format
      use gbl_message
      use classic_api
      use class_common
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Read the ASSOCiated array section
      !----------------------------------------------------------------------
      type(observation), intent(inout) :: obs    !
      logical,           intent(inout) :: error  !
    end subroutine rassoc_classic
  end interface
  !
  interface
    subroutine rherschel_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !  Read the HERSCHEL section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine rherschel_classic
  end interface
  !
  interface
    subroutine crsec_classic(obs,scode,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use classic_api
      use class_common
      use class_types
      use class_buffer
      !---------------------------------------------------------------------
      ! @ private
      !   Read the appropriate section into the input observation from the
      ! associated entry in the input file, taking care of conversion of
      ! the section data from System data type to File data type.
      !  OBS%DESC: input
      !  OBS%HEAD: updated
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Header
      integer(kind=4),   intent(in)    :: scode  ! Section code
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine crsec_classic
  end interface
  !
  interface
    subroutine crsec_xcoo(set,obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use classic_api
      use class_common
      use class_types
      use class_buffer
      !---------------------------------------------------------------------
      ! @ private
      ! Convert X_coord section from File data type to System data type
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Observation
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine crsec_xcoo
  end interface
  !
#if defined(OBSOLETE)
  interface
    subroutine compute_doppler_compare(obs,telescope,error)
      use gildas_def
      use class_types
      use gbl_message
      use gbl_constant
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      ! Debugging routine used to compare the SLOW and FAST
      ! version of COMPUTE_DOPPLER
      !---------------------------------------------------------------------
      type(header),     intent(inout) :: obs        ! Current header
      character(len=*), intent(in)    :: telescope  ! Observatory
      logical,          intent(out)   :: error      ! flag
    end subroutine compute_doppler_compare
  end interface
  !
  interface
    subroutine compute_doppler_slow(obs,telescope,error)
      use gildas_def
      use phys_const
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Compute the Doppler correction, calling ASTRO routine, according to:
      ! * observatory location
      ! * reference frame (LSR, Helio...)
      ! Radio convention is used
      !---------------------------------------------------------------------
      type(header),     intent(inout) :: obs        ! Current header
      character(len=*), intent(in)    :: telescope  ! Observatory
      logical,          intent(out)   :: error      ! flag
    end subroutine compute_doppler_slow
  end interface
  !
#endif
  interface
    subroutine compute_doppler(set,obs,use_ref,error)
      use gildas_def
      use phys_const
      use gbl_constant
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Compute the Doppler correction, calling ASTRO routine, according to:
      ! * observatory location
      ! * reference frame (LSR, Helio...)
      ! CLASS convention is used (Doppler factor = -V / c)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set      !
      type(header),        intent(inout) :: obs      ! Current header
      logical,             intent(in)    :: use_ref  ! Compute at reference position?
      logical,             intent(inout) :: error    ! Logical error flag
    end subroutine compute_doppler
  end interface
  !
  interface
    subroutine cwsec(set,obs,scode,error)
      use gbl_message
      use class_common
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Write the appropriate section from the input observation to the
      ! associated entry in the output file, taking care of conversion of
      ! the section data from System data type to File data type.
      !  OBS%DESC: updated
      !  OBS%HEAD: input
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Header
      integer(kind=4),     intent(in)    :: scode  ! Section code
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine cwsec
  end interface
  !
  interface
    subroutine wgen_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the GENeral section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wgen_classic
  end interface
  !
  interface
    subroutine wres_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the RESolution section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wres_classic
  end interface
  !
  interface
    subroutine wpos_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the POSition section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wpos_classic
  end interface
  !
  interface
    subroutine wspec_classic(obs,error)
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the SPECtroscopic Section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wspec_classic
  end interface
  !
  interface
    subroutine wbas_classic(obs,error)
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the BASe Section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wbas_classic
  end interface
  !
  interface
    subroutine wplo_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Plotting section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wplo_classic
  end interface
  !
  interface
    subroutine wswi_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Switching section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wswi_classic
  end interface
  !
  interface
    subroutine wgau_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Gauss fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wgau_classic
  end interface
  !
  interface
    subroutine wshe_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Shell fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wshe_classic
  end interface
  !
  interface
    subroutine whfs_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the HFS fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine whfs_classic
  end interface
  !
  interface
    subroutine wabs_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Absorption fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wabs_classic
  end interface
  !
  interface
    subroutine wcal_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the calibration section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wcal_classic
  end interface
  !
  interface
    subroutine wdri_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the Drift Continuum section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wdri_classic
  end interface
  !
  interface
    subroutine wpoi_classic(obs,error)
      use gildas_def
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write Pointing fit section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wpoi_classic
  end interface
  !
  interface
    subroutine wbea_classic(obs,error)
      use gildas_def
      use gbl_message
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the BEAm-switching section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wbea_classic
  end interface
  !
  interface
    subroutine wuser_classic(obs,error)
      use gbl_message
      use classic_api
      use class_buffer
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Transfer the User Section to buffer 'uwork'
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    !
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine wuser_classic
  end interface
  !
  interface
    subroutine wassoc_classic(obs,error)
      use gbl_format
      use gbl_message
      use classic_api
      use class_common
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write the ASSOCiated array section
      !----------------------------------------------------------------------
      type(observation), intent(inout), target :: obs    ! Inout: obs%desc is updated
      logical,           intent(inout)         :: error  !
    end subroutine wassoc_classic
  end interface
  !
  interface
    subroutine wherschel_classic(obs,error)
      use class_common
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the HERSCHEL Section
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine wherschel_classic
  end interface
  !
  interface
    subroutine cwsec_classic(obs,scode,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use classic_api
      use class_types
      use class_buffer
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !   Write the appropriate section from the input observation to the
      ! associated entry in the output file, taking care of conversion of
      ! the section data from System data type to File data type.
      !  OBS%DESC: updated
      !  OBS%HEAD: input
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Header to be written
      integer(kind=4),   intent(in)    :: scode  ! Code of header section
      logical,           intent(out)   :: error  ! Logical error flag
    end subroutine cwsec_classic
  end interface
  !
  interface
    subroutine cwsec_xcoo(set,obs,error)
      use gildas_def
      use gbl_constant
      use classic_api
      use class_types
      use class_buffer
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !  Convert section from System data type to File data type
      ! Note that the external functions do not allow data conversion
      ! => call directly r8tor4 !! This WAS A BUG... MUST CALL THROUGH AN
      !  INTERMEDIATE ARRAY
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    !
      logical,             intent(out)   :: error  ! Logical error flag
    end subroutine cwsec_xcoo
  end interface
  !
  interface
    subroutine deconv_allocate(key,error)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Check memory allocation for SSB, DSB, ALL arrays
      ! * Allocate non-allocated arrays
      ! * Check size of allocated arrays
      !-------------------------------------------------------------------
      character(len=*), intent(in)  :: key   ! SSB, DSB or ALL
      logical,          intent(out) :: error ! Output flag
    end subroutine deconv_allocate
  end interface
  !
  interface
    subroutine deconv_dealloc(error)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Free allocated memory
      !-------------------------------------------------------------------
      logical, intent(out) :: error ! Output flag
    end subroutine deconv_dealloc
  end interface
  !
  interface
    subroutine deconvolve(ftol,itmax,error)
      use gildas_def
      use phys_const
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! This subroutine prepares the deconvolution process by initializing variables.
      ! deconvolve() gives frprmn() the parameters it needs to really calculate the
      ! deconvolution. frprmn() is supposed to return a SSB spectrum which minimizes
      ! the chisquare() function.
      !
      ! Convergence criterium: If the chisquare() evolution between two iterations of
      ! frprmn() is lower than ftol,frprmn() considers it has
      ! achieved convergence. If iter > IT_MAX (as defined in frprmn()),
      ! it means that frprmn() had not finised its convergence.
      !
      ! The information printed on screen at the end is not fundamental,but can be
      ! of any interest. It prints:
      ! - the value found for chisquare() (named min_chi);
      ! - the number of iteration frprmn() required to achieve it (named iter);
      ! - the LSB and USB gains found for each of the dsb_counter DSB scans (gain).
      ! After the deconvolution performed by frprmn(), ssb_spectrum stays in memory
      ! and can be transfered into CLASS.
      !-------------------------------------------------------------------
      real(kind=8),    intent(in)  :: ftol  ! Tolerance on chisqare evolution
      integer(kind=4), intent(in)  :: itmax ! Maximum iteration for frprmn
      logical,         intent(out) :: error ! Error flag
    end subroutine deconvolve
  end interface
  !
  interface
    subroutine deconv_makessb(set,r,error,user_function)
      use gildas_def
      use phys_const
      use gbl_constant
      use gbl_message
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! This subroutine copies the deconvolved SSB spectrum ssb_spectrum
      ! into the CLASS R-memory.
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: r              !
      logical,             intent(inout) :: error          ! Error flag
      logical,             external      :: user_function  !
    end subroutine deconv_makessb
  end interface
  !
  interface
    subroutine frprmn(p,n,ftol,itmax,iter,fret,error)
      use gildas_def
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Fletcher-Reeves-Polak-Ribiere minimization (Numerical Recipes)
      ! Requires the calculation of derivatives for the function.
      !-------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n     ! Size of p
      real(kind=8),    intent(in)    :: ftol  ! Tolerance on MEM deconvolution
      integer(kind=4), intent(in)    :: itmax ! Maximal number of iteration before returing
      integer(kind=4), intent(out)   :: iter  ! Iterations counter
      real(kind=8),    intent(out)   :: fret  ! X^2 - lambda1 * Sspectrum - lambda2 * Sgain
      logical,         intent(out)   :: error ! Logical error flag
      real(kind=8),    intent(inout) :: p(n)  ! Vector to deconvolve
    end subroutine frprmn
  end interface
  !
  interface
    subroutine mem_linmin(xp,xi,n,fret,use_deriv,error)
      !-------------------------------------------------------------------
      ! @ private
      ! Finds the minimum of a N-dimensional function along vector xi from
      ! a specific point P, both defined in N-space. 'linmin' does the
      ! bookkeeping required to treat the function as a function of
      ! position along this line, and minimizes the function with
      ! conventional 1-D minimization routine.
      !-------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n         ! Size of p and xi.
      real(kind=8),    intent(out)   :: fret      !
      real(kind=8),    intent(inout) :: xp(n)     !
      real(kind=8),    intent(inout) :: xi(n)     !
      logical,         intent(in)    :: use_deriv !
      logical,         intent(out)   :: error     ! Logical error flag
    end subroutine mem_linmin
  end interface
  !
  interface
    subroutine mem_mnbrak(ax,bx,cx,fa,fb,fc,func,error)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Search a given function for a minimum. Given two values 'ax' and
      ! 'bx' of abscissa, searches in the downward direction until it can
      ! find 3 new valies 'ax', 'bx,' and 'cx' that bracket a
      ! minimum. 'fa', 'fb', 'fc' are the values of the function at these
      ! points.
      !-------------------------------------------------------------------
      real(kind=8), intent(inout) :: ax
      real(kind=8), intent(inout) :: bx
      real(kind=8), intent(out)   :: cx
      real(kind=8), intent(out)   :: fa
      real(kind=8), intent(out)   :: fb
      real(kind=8), intent(out)   :: fc
      real(kind=8), external      :: func
      logical,      intent(out)   :: error
    end subroutine mem_mnbrak
  end interface
  !
  interface
    function mem_brent(ax,bx,cx,func,tol,xmin)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      !
      !-------------------------------------------------------------------
      real(kind=8) :: mem_brent  ! Function value on return
      real(kind=8), intent(in) :: ax
      real(kind=8), intent(in) :: bx
      real(kind=8), intent(in) :: cx
      real(kind=8), external   :: func
      real(kind=8), intent(in) :: tol
    ! real(kind=8), intent(in) :: xmin
      real(kind=8)             :: xmin
    end function mem_brent
  end interface
  !
  interface
    function mem_dbrent(ax,bx,cx,func,df,tol,xmin)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! --> Uses first derivative
      ! From Numerical Recipes
      !
      !-------------------------------------------------------------------
      real(kind=8) :: mem_dbrent  ! Function value on return
      real(kind=8), intent(in) :: ax    !
      real(kind=8), intent(in) :: bx    !
      real(kind=8), intent(in) :: cx    !
      real(kind=8), external   :: func  !
      real(kind=8), external   :: df    !
      real(kind=8), intent(in) :: tol   !
    ! real(kind=8), intent(in) :: xmin  !
      real(kind=8)             :: xmin  !
    end function mem_dbrent
  end interface
  !
  interface
    function mem_f1dim(xx)
      !-------------------------------------------------------------------
      ! @ private
      ! Make the N-dimensional function effectively a 1-D function along a
      ! given line in N-space.
      !-------------------------------------------------------------------
      real(kind=8) :: mem_f1dim  ! Function value on return
      real(kind=8), intent(in) :: xx
    end function mem_f1dim
  end interface
  !
  interface
    function mem_df1dim(xx)
      !-------------------------------------------------------------------
      ! @ private
      ! Make the N-dimensional function effectively a 1-D function along a
      ! given line in N-space.
      !-------------------------------------------------------------------
      real(kind=8) :: mem_df1dim  ! Function value on return
      real(kind=8), intent(in) :: xx
    end function mem_df1dim
  end interface
  !
  interface
    function chisquare(vect,vect_size)
      use gildas_def
      !-------------------------------------------------------------------
      ! @ private
      ! Calculates the value we want to minimize as a criterium for
      ! a good deconvolution
      ! vect: ssb(ssb_size)+gain(2*dsb_counter)
      !-------------------------------------------------------------------
      real(kind=8) :: chisquare  ! Function value on return
      integer(kind=4), intent(in)    :: vect_size        ! The logical size of vect
      real(kind=8),    intent(inout) :: vect(vect_size)  ! The vector you want to compute the chisquare
    end function chisquare
  end interface
  !
  interface
    function entropy(x,M,n)
      use gildas_def
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Calculate the entropy of a set of data and model of size n.
      ! The formula is:
      ! entropy = - Sum_{i=1,n} (xi/xtot) * log(xi/xtot/Mi)
      ! where xtot = sum(x). It is therefore assumed that Mi = mi / mtot.
      ! If no model is used then Mi = 1. (See init_mem.f.)
      !
      ! Add a continuum offset to x to avoid a negative argument in the
      ! log. Since the offset is the same during all the deconvolution
      ! process, we still can try to maximize the entropy. The model m
      ! must be shifted up by the same cont_offset. It is taken into
      ! account when M is calculated in init_mem():
      ! Mi = (mi+cont_offset) / sum(mi + cont_offset).
      ! -------------------------------------------------------------------
      real(kind=8) :: entropy  ! Function value on return
      integer(kind=4), intent(in)    :: n    ! The number of elements of x and M
      real(kind=8),    intent(in)    :: M(n) ! A normalized model (M = m / sum(m))
      real(kind=8),    intent(inout) :: x(n) ! The vector we want to compute the entropy
    end function entropy
  end interface
  !
  interface
    function entropythreshold(x,M,n)
      use gildas_def
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! Calculate the entropy of a set of data and model of size n.
      ! The formula is: entropy = -sum ( (xi/xtot) * log( (xi/xtot) / Mi),
      ! where xtot = sum(x). It is therefore assumed that Mi = mi / mtot.
      ! If no model is used then Mi = 1. (See init_mem.f.)
      ! Same as entropy(), but if a channel of vect is lower than epsilon, it is set
      ! to epsilon.
      !
      ! Add a continuum offset to x to avoid a negative argument in the
      ! log. Since the offset is the same during all the deconvolution
      ! process, we still can try to maximize the entropy. The model m
      ! must be shifted up by the same cont_offset. It is taken into
      ! account when M is calculated in init_mem():
      ! Mi = (mi+cont_offset) / sum(mi+cont_offset).
      !-------------------------------------------------------------------
      real(kind=8) :: entropythreshold  ! Function value on return
      integer(kind=4), intent(in)    :: n ! The number of elements of x and M
      real(kind=8),    intent(in)    :: M(n) ! A normalized model (M = m / sum(m))
      real(kind=8),    intent(inout) :: x(n) ! The vector we want to compute the entropy
    end function entropythreshold
  end interface
  !
  interface
    subroutine delta_chi(vect,delta_chisquare,vect_size)
      use gildas_def
      use phys_const
      !-------------------------------------------------------------------
      ! @ private
      ! vect contains (in this order) :
      ! - lssb    : Single side band spectrum only:                        size = ssb_size.
      ! - lgain   : Contains the signal band gain and the image band gain: size = 2 * dsb_counter.
      ! - lAsw_bm : Amplitude of the standing waves before mixing:         size = (dsb_counter, n_sw_bm).
      ! - lpsw_bm : Pulsation of the standing waves before mixing:         size = (dsb_counter, n_sw_bm).
      ! - lphsw_bm: Phase of the standing waves before mixing:             size = (dsb_counter, n_sw_bm).
      !-------------------------------------------------------------------
      integer(kind=4), intent(in)    :: vect_size        ! size of vect
      real(kind=8),    intent(inout) :: vect(vect_size)  ! The vector you want to compute the chisquare
      real(kind=8),    intent(out)   :: delta_chisquare(vect_size)
    end subroutine delta_chi
  end interface
  !
  interface
    subroutine derentrop(px,pm,pn,pds)
      !-------------------------------------------------------------------
      ! @ private
      ! Calculate the entropy derivative of a set of data x and model m of size n.
      ! The formula is: entropy = S = sum ((xi/X) * log((xi/X) / Mi)).
      ! Where X = sum(xi). It is therefore assumed that Mi = mi / M. M = sum(mi).
      ! If no model is used then Mi = 1. (see init_mem()).
      ! The derivative of the entropy is:
      ! dS_dvect(i) = 1. / X * (log(xi / X / Mi) - S)
      !
      ! ??????????????? PHB: is it definitive ?
      ! Presently (10/02/05), wherever the model is used, its values are
      ! divided by sum(ssb_model). In order to spare CPU, we (PH and BD)
      ! have decided to divide it once for all. The sum must be kept in
      ! memory because makemodel() should be able to restore ssb_model's
      ! original value. The division is made in put_model() or init_mem()
      ! and need not to be done once again just before calling derentrop().
      !-------------------------------------------------------------------
      integer(kind=4), intent(in)    :: pn      ! logical size of px and pm.
      real(kind=8),    intent(inout) :: px(pn)  ! x
      real(kind=8),    intent(in)    :: pm(pn)  ! m
      real(kind=8),    intent(out)   :: pds(pn)
    end subroutine derentrop
  end interface
  !
  interface
    subroutine class_diff_head(a,b,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_head
  end interface
  !
  interface
    subroutine class_diff_gen(a,b,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations (section GENERAL)
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_gen
  end interface
  !
  interface
    subroutine class_diff_pos(a,b,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations (section POSITION)
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_pos
  end interface
  !
  interface
    subroutine class_diff_spe(a,b,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations (section SPECTROSCOPY)
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_spe
  end interface
  !
  interface
    subroutine class_diff_cal(a,b,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations (section CALIBRATION)
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_cal
  end interface
  !
  interface
    subroutine class_diff_swi(a,b,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Print the differences between 2 observations (section SWITCHING)
      !---------------------------------------------------------------------
      type(header), intent(in)    :: a,b
      logical,      intent(inout) :: error
    end subroutine class_diff_swi
  end interface
  !
  interface
    function class_diff_presec(secid,secname,a,b)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Return .true. if the section is absent from 1 or from the 2 headers
      !---------------------------------------------------------------------
      logical :: class_diff_presec
      integer(kind=4),  intent(in) :: secid    ! Section code
      character(len=*), intent(in) :: secname  !
      type(header),     intent(in) :: a,b      !
    end function class_diff_presec
  end interface
  !
  interface
    subroutine class_draw_sub(set,line,r,error)
      use gildas_def
      use gbl_constant
      use phys_const
      use gbl_message
      use class_setup_new
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   DRAW [FILL     Ichan]
      !   DRAW [KILL     Ichan]
      !   DRAW [LOWER    Xpos String [Angle]]
      !   DRAW [UPPER    Xpos String [Angle]]
      !   DRAW [MASK     [Ylev]]
      !   DRAW [TEXT     Xpos Ypos Text [Centering]]
      !   DRAW [WINDOW   [Yup] [Ylow]]
      !   DRAW MOLECULE  Xpos "Texte" [Angle]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(inout) :: line   ! Command line
      type(observation),   intent(inout) :: r      !
      logical,             intent(inout) :: error  ! Flag
    end subroutine class_draw_sub
  end interface
  !
  interface
    subroutine class_draw_molecule(line,r,error)
      use phys_const
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command:
      !  DRAW MOLECULE Frequency Name [Angle]
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: line   ! Input command line
      type(observation), intent(in)    :: r      !
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine class_draw_molecule
  end interface
  !
  interface
    subroutine class_draw_uplow(set,line,r,interactive,axis,xxp,xf0,xi0,xc,xv,error)
      use phys_const
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   ANA\DRAW UPPER|LOWER Xpos String
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set          !
      character(len=*),    intent(inout) :: line         ! Command line
      type(observation),   intent(in)    :: r            !
      logical,             intent(in)    :: interactive  ! Command line or cursor?
      integer(kind=4),     intent(in)    :: axis         ! 1 = lower, 2 = upper
      real(kind=4),        intent(inout) :: xxp          ! X position from cursor (Paper)
      real(kind=8),        intent(in)    :: xf0          ! X position from cursor (Signal)
      real(kind=8),        intent(in)    :: xi0          ! X position from cursor (Image)
      real(kind=4),        intent(in)    :: xc           ! X position from cursor (Channel)
      real(kind=4),        intent(in)    :: xv           ! X position from cursor (Velocity)
      logical,             intent(inout) :: error        ! Logical error flag
    end subroutine class_draw_uplow
  end interface
  !
  interface
    subroutine class_draw_mask(set,line,error)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !    DRAW MASK [Ylev]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine class_draw_mask
  end interface
  !
  interface
    subroutine class_draw_window(set,line,r,error)
      use gbl_message
      use class_types
      use class_index
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !    DRAW WINDOW [Ymin [Ymax]]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      type(observation),   intent(in)    :: r      !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine class_draw_window
  end interface
  !
  interface
    subroutine eix_newdata(first_new,last_new,error)
      use gbl_constant
      use gbl_message
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Action to be performed when new data has actually been found in the
      ! input file
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(out)   :: first_new  ! First new index entry
      integer(kind=entry_length), intent(out)   :: last_new   ! Last new index entry
      logical,                    intent(inout) :: error      ! Logical error flag
    end subroutine eix_newdata
  end interface
  !
  interface
    subroutine do_extract_units(obs,extr,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute extraction channel range from range values
      ! Must have been set before:
      ! - extr%rname
      ! - extr%xa
      ! - extr%xb
      ! - extr%unit
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! Observation before extraction
      type(extract_t),   intent(inout) :: extr   ! Extraction descriptor
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine do_extract_units
  end interface
  !
  interface
    subroutine do_extract(obs,extr,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Extract a subset of an observation
      ! Must have been set before:
      ! - extr%rname
      ! - extr%c1
      ! - extr%c2
      ! - extr%nc
      !  For efficiency purpose, assume that extr%c1 and extr%c2 are already
      ! sorted.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Observation before and after extraction
      type(extract_t),   intent(in)    :: extr   ! Extraction descriptor
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine do_extract
  end interface
  !
  interface do_extract_data
    subroutine do_extract_data_r4(in,inchan,out,onchan,bad,extr,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic do_extract_data
      !  Extract a subset of a data array according the extraction
      ! descriptor.
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: inchan       ! Input nchan
      real(kind=4),    intent(in)    :: in(inchan)   !
      integer(kind=4), intent(in)    :: onchan       ! Output nchan
      real(kind=4),    intent(out)   :: out(onchan)  !
      real(kind=4),    intent(in)    :: bad          ! Blank value
      type(extract_t), intent(in)    :: extr         ! Extraction descriptor
      logical,         intent(inout) :: error        ! Logical error flag
    end subroutine do_extract_data_r4
    subroutine do_extract_data_i4(in,inchan,out,onchan,bad,extr,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic do_extract_data
      !  Extract a subset of a data array according the extraction
      ! descriptor.
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: inchan       ! Input nchan
      integer(kind=4), intent(in)    :: in(inchan)   !
      integer(kind=4), intent(in)    :: onchan       ! Output nchan
      integer(kind=4), intent(out)   :: out(onchan)  !
      integer(kind=4), intent(in)    :: bad          ! Blank value
      type(extract_t), intent(in)    :: extr         ! Extraction descriptor
      logical,         intent(inout) :: error        ! Logical error flag
    end subroutine do_extract_data_i4
  end interface do_extract_data
  !
  interface
    subroutine class_filter_do(obs,store,error)
      use gildas_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! See http://en.wikipedia.org/wiki/Median_absolute_deviation
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    !
      logical,           intent(in)    :: store  ! Store result in the observation header
      logical,           intent(inout) :: error  !
    end subroutine class_filter_do
  end interface
  !
  interface
    subroutine find_setup(set,line,error)
      use gbl_constant
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Parse the command line and setup the smin%, smax% and flg%
      ! structures for later use by subroutine FIX.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   !
      logical,             intent(inout) :: error  !
    end subroutine find_setup
  end interface
  !
  interface
    subroutine index_ranges(windex,error)
      use class_parameter
      use class_types
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Computes ranges of LAMBDA BETA SCAN DOBS (DRED)
      !---------------------------------------------------------------------
      type(optimize), intent(inout) :: windex  !
      logical,        intent(out)   :: error   !
    end subroutine index_ranges
  end interface
  !
  interface
    subroutine find_by_entry(set,line,indmin,indmax,error)
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !    FIND /ENTRY
      !  Parse the command line for the FIND /ENTRY arguments
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set
      character(len=*),           intent(in)    :: line
      integer(kind=entry_length), intent(out)   :: indmin
      integer(kind=entry_length), intent(out)   :: indmax
      logical,                    intent(inout) :: error
    end subroutine find_by_entry
  end interface
  !
  interface
    subroutine find_setup_section(line,error)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command FIND /SECTION FOO
      ! If required, turn on the FIND flags for a by-section search.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_section
  end interface
  !
  interface
    subroutine find_setup_mask(line,error)
      use gbl_message
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command FIND /MASK Name
      ! If required, turn on the FIND flags for a mask search
      ! Name is assumed a file name
      ! We could also support variables in the future
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_mask
  end interface
  !
  interface
    subroutine find_setup_position(line,error)
      use gbl_constant
      use gbl_message
      use phys_const
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    FIND /POSITION A0 D0 System [Equinox]
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_position
  end interface
  !
  interface
    subroutine find_setup_switching(line,error)
      use gbl_constant
      use gbl_message
      use phys_const
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    FIND /SWITCHING Key
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_switching
  end interface
  !
  interface
    subroutine find_setup_drift(line,error)
      use phys_const
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    FIND /DRIFT Angle
      ! Find continuum drifts with position angle "Angle" module 180 degrees
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_drift
  end interface
  !
  interface
    subroutine find_setup_direction(line,error)
      use phys_const
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    FIND /DIRECTION Angle
      ! Find continuum drifts with position angle "Angle" module 360 degrees
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine find_setup_direction
  end interface
  !
  interface
    subroutine sort_index(set,key,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Sort the index using the quicksort algorithm.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set    !
      character(len=1),    intent(in)  :: key    ! Index: I, O, Current (default)
      logical,             intent(out) :: error  ! Error status
    end subroutine sort_index
  end interface
  !
  interface
    subroutine sort_cx(set,error)
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Sort the index using the quicksort algorithm.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      logical,             intent(inout) :: error  ! Error status
    end subroutine sort_cx
  end interface
  !
  interface
    subroutine sort_ix(set,error)
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Sort the input file index using the quicksort algorithm.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      logical,             intent(inout) :: error  ! Error status
    end subroutine sort_ix
  end interface
  !
  interface
    subroutine fits_class_read(set,line,r,user_function,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS FITS Support routine for command FITS READ
      ! Read current FITS file
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      character(len=*),    intent(in)    :: line           ! Command line
      type(observation),   intent(inout) :: r              !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Error status
    end subroutine fits_class_read
  end interface
  !
  interface
    subroutine fits_class_write(set,line,r,user_function,error)
      use gbl_message
      use class_fits
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS
      ! Support routine for command
      !   FITS WRITE File.fits [/BITS Nbits] [/MODE SPECTRUM|INDEX] [/CHECK]
      ! Option sequence
      !   1  /BITS
      !   2  /STYLE
      !   3  /XTENSION
      !   4  /MODE
      !   5  /CHECK
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      character(len=*),    intent(in)    :: line           ! Command line
      type(observation),   intent(inout) :: r              !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Error status
    end subroutine fits_class_write
  end interface
  !
  interface
    subroutine fits_select (line,error)
      use gbl_message
      use class_fits
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command SELECT.
      !     SET FITS BITS Nbits
      !     SET FITS MODE Spectrum|Index|None
      !		Define optional parameters for writing
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: line   ! Command line
      logical,          intent(out) :: error  ! Error status
    end subroutine fits_select
  end interface
  !
  interface
    subroutine zeros_to_spaces(String)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(inout) :: String  !
    end subroutine zeros_to_spaces
  end interface
  !
  interface
    subroutine fits_put_keyword(pCardImage,pKeyWord,pValue,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=80), intent(out) :: pCardImage  !
      character(len=*),  intent(in)  :: pKeyWord    !
      logical,           intent(in)  :: pValue      !
      logical,           intent(out) :: pError      !
    end subroutine fits_put_keyword
  end interface
  !
  interface
    subroutine fits_put_comment(pCardImage,pComment,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=80), intent(inout) :: pCardImage  !
      character(len=*),  intent(in)    :: pComment    !
      logical,           intent(out)   :: pError      !
    end subroutine fits_put_comment
  end interface
  !
  interface
    subroutine fits_put_logi(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      logical,          intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_logi
  end interface
  !
  interface
    subroutine fits_put_inte(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      integer(kind=4),  intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_inte
  end interface
  !
  interface
    subroutine fits_put_long(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      integer(kind=8),  intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_long
  end interface
  !
  interface
    subroutine fits_put_dble(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      real(kind=8),     intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_dble
  end interface
  !
  interface
    subroutine fits_put_simple(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      real(kind=4),     intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_simple
  end interface
  !
  interface
    subroutine fits_put_string(pKeyWord,pValue,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      character(len=*), intent(in)  :: pValue    !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_string
  end interface
  !
  interface
    subroutine fits_put_novalue(pKeyWord,pComment,pCheck,pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: pKeyWord  !
      character(len=*), intent(in)  :: pComment  !
      logical,          intent(in)  :: pCheck    !
      logical,          intent(out) :: pError    !
    end subroutine fits_put_novalue
  end interface
  !
  interface
    subroutine fits_write_primary_header(pCheck,pError)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! LAS
      ! Primary header and data
      !---------------------------------------------------------------------
      logical, intent(in)  :: pCheck    !
      logical, intent(out) :: pError    !
    end subroutine fits_write_primary_header
  end interface
  !
  interface
    subroutine fits_write_primary_data(pError)
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      logical, intent(out) :: pError    !
    end subroutine fits_write_primary_data
  end interface
  !
  interface
    subroutine fits_write_primary(pCheck,pError)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      logical, intent(in)  :: pCheck    !
      logical, intent(out) :: pError    !
    end subroutine fits_write_primary
  end interface
  !
  interface
    subroutine fits_put_column(iCol,sName,iNbElem,sFormat,sUnit,pCheck,pError)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Binary tables
      !---------------------------------------------------------------------
      integer,          intent(in)  :: iCol     !
      character(len=*), intent(in)  :: sName    !
      integer,          intent(in)  :: iNbElem  !
      character(len=*), intent(in)  :: sFormat  !
      character(len=*), intent(in)  :: sUnit    !
      logical,          intent(in)  :: pCheck   !
      logical,          intent(out) :: pError   !
    end subroutine fits_put_column
  end interface
  !
  interface
    subroutine fits_write_binheader(set,pCheck,user_function,pError)
      use gbl_constant     ! vel_lsr
      use gbl_message
      use phys_const
      use class_types      ! type (observation)
      use class_index      ! cx
      use class_fits       ! i_* columns
      !---------------------------------------------------------------------
      ! @ private
      ! LAS
      ! Binary tables
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(in)  :: pCheck         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: pError         !
    end subroutine fits_write_binheader
  end interface
  !
  interface
    subroutine fits_write_bindata(set,pCheck,user_function,pError)
      use gbl_constant ! vel_lsr
      use gbl_format   ! fmt_i4...
      use phys_const
      use gbl_message
      use class_types
      use class_index  ! cx
      use class_fits   ! i_* columns, nrows...
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(in)  :: pCheck         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: pError         !
    end subroutine fits_write_bindata
  end interface
  !
  interface
    subroutine fits_write_bintables(set,pCheck,user_function,pError)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(in)  :: pCheck         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: pError         !
    end subroutine fits_write_bintables
  end interface
  !
  interface
    subroutine fits_analyse_index(set,nomore,user_function,pError)
      use gbl_message
      use class_types
      use class_index
      use class_fits
      !---------------------------------------------------------------------
      ! @ private
      ! Read entries in the INDEX
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(out) :: nomore         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: pError         !
    end subroutine fits_analyse_index
  end interface
  !
  interface
    subroutine fits_write_index(set,pCheck,user_function,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Used to write the current index in INDEX mode
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(in)  :: pCheck         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: error          !
    end subroutine fits_write_index
  end interface
  !
  interface
    subroutine fits_save_index(set,pcheck,user_function,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! LAS
      ! Check the current INDEX
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set            !
      logical,             intent(in)  :: pcheck         !
      logical,             external    :: user_function  !
      logical,             intent(out) :: error          !
    end subroutine fits_save_index
  end interface
  !
  interface
    subroutine fix(set,idx,lx,nfound,error,erange,more)
      use phys_const
      use gbl_message
      use gkernel_types
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Search in the input index for entries matching the parameters in
      ! flg% and smin%/smax%. Selected entries are appended to the output
      ! index (it is the responsibility of the caller to check for
      ! duplicates between old and new entries).
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)           :: set        !
      type(optimize),             intent(in)           :: idx        ! The index to search in
      type(optimize),             intent(inout)        :: lx         ! The optimize'd index to be updated
      integer(kind=entry_length), intent(out)          :: nfound     ! Number of observations actually found
      logical,                    intent(inout)        :: error      ! Error status
      integer(kind=entry_length), intent(in), optional :: erange(2)  ! Entry range to search in (default all)
      integer(kind=entry_length), intent(in), optional :: more       ! Size of allocation extension
    end subroutine fix
  end interface
  !
  interface
    function fix_by_freq(obs,fmin,fmax,fsig)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !  Return .true. if the input range intersects the frequency range
      ! of the input observation.
      !---------------------------------------------------------------------
      logical                       :: fix_by_freq  ! Function value on return
      type(observation), intent(in) :: obs          ! Input observation
      real(kind=8),      intent(in) :: fmin         ! Frequency range (min)
      real(kind=8),      intent(in) :: fmax         ! Frequency range (max)
      logical,           intent(in) :: fsig         ! Signal or image frequencies?
    end function fix_by_freq
  end interface
  !
  interface
    function fix_by_switch(obs,swmode)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if the observation matches the given switching mode
      !---------------------------------------------------------------------
      logical                       :: fix_by_switch ! Function value on return
      type(observation), intent(in) :: obs           ! Input observation
      integer(kind=4),   intent(in) :: swmode        ! Switching mode code
    end function fix_by_switch
  end interface
  !
  interface
    function fix_by_drift(obs,driang,modu)
      use phys_const
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if the drift matches the required angle modulo some
      ! angle
      !---------------------------------------------------------------------
      logical                       :: fix_by_drift  ! Function value on return
      type(observation), intent(in) :: obs           ! Input observation
      real(kind=4),      intent(in) :: driang        ! [rad] Drift angle
      real(kind=4),      intent(in) :: modu          ! [rad] Modulo angle
    end function fix_by_drift
  end interface
  !
  interface
    function fix_by_posi(obs,reflam,refbet,refsys,refequ,tole)
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !  Return .true. if the observation position matches the reference
      ! position with the given tolerance
      !---------------------------------------------------------------------
      logical                          :: fix_by_posi  ! Function value on return
      type(observation), intent(inout) :: obs          ! Input observation
      real(kind=8),      intent(in)    :: reflam       ! [rad]  Reference lambda position
      real(kind=8),      intent(in)    :: refbet       ! [rad]  Reference beta position
      integer(kind=4),   intent(in)    :: refsys       ! [code] Reference system of coordinates
      real(kind=4),      intent(in)    :: refequ       ! [year] Reference equinox (if relevant)
      real(kind=4),      intent(in)    :: tole         ! [rad]  Tolerance
    end function fix_by_posi
  end interface
  !
  interface
    function fix_by_mask(lamof,betof,mask)
      use image_def
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if the observation is selected by the input
      ! position-position mask.
      !  Note there is no consistency checking with the center of
      ! projection, kind of projection, and projection angle. This is the
      ! same feature as FIND /RANGE
      !---------------------------------------------------------------------
      logical :: fix_by_mask  ! Function value on return
      real(kind=4), intent(in) :: lamof,betof  ! Offsets
      type(gildas), intent(in) :: mask         ! The GDF 2D mask
    end function fix_by_mask
  end interface
  !
  interface
    subroutine ox_sort_reset(set,error)
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Recompute the sorting arrays of the Output indeX
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      logical,             intent(inout) :: error
    end subroutine ox_sort_reset
  end interface
  !
  interface
    subroutine ox_sort_add(set,obs,dupl,error)
      use gbl_message
      use class_common
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Add a new observation in the sorting arrays of the Output indeX
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(in)    :: obs
      logical,             intent(out)   :: dupl
      logical,             intent(inout) :: error
    end subroutine ox_sort_add
  end interface
  !
  interface
    subroutine fox(anum,ifound)
      use gbl_message
      use class_parameter
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Search for observation number Anum (last version) in the sorted
      ! index.
      !----------------------------------------------------------------------
      integer(kind=obsnum_length), intent(in)  :: anum    ! Obs number being searched for
      integer(kind=entry_length),  intent(out) :: ifound  ! Corresponding Entry Number (0 if none)
    end subroutine fox
  end interface
  !
  interface
    subroutine fox_reset
      use gbl_message
      use classic_api
      use class_parameter
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Build up the Sorted Entry/Number list when opening an output file
      ! The Sorted list will then be kept up-to-date at each writing.
      !----------------------------------------------------------------------
      ! Local
    end subroutine fox_reset
  end interface
  !
  interface
    subroutine fox_next(anum)
      use gbl_message
      use class_parameter
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! RW  Returns next available ObsNumber Anum (last version)
      !---------------------------------------------------------------------
      integer(kind=obsnum_length), intent(out) :: anum  !
    end subroutine fox_next
  end interface
  !
  interface
    subroutine fox_add (anum, entry)
      use gbl_message
      use classic_api
      use class_parameter
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! RW  Search for ObsNumber Anum (last version)
      !---------------------------------------------------------------------
      integer(kind=obsnum_length), intent(in) :: anum   ! Obs number being searched for
      integer(kind=entry_length),  intent(in) :: entry  ! Corresponding Entry Number (0 if none)
    end subroutine fox_add
  end interface
  !
  interface
    subroutine locplus (x,np,xlim,nlim,mlim)
      use classic_api
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Find NLIM and MLIM such as
      !      X(NLIM) < XLIM < X(MLIM)
      !  for input data ordered increasingly
      !  Use a dichotomic search for that
      !---------------------------------------------------------------------
      integer(kind=entry_length),  intent(in)  :: np     !
      integer(kind=obsnum_length), intent(in)  :: x(np)  !
      integer(kind=obsnum_length), intent(in)  :: xlim   !
      integer(kind=entry_length),  intent(out) :: nlim   !
      integer(kind=entry_length),  intent(out) :: mlim   !
    end subroutine locplus
  end interface
  !
  interface
    subroutine optimize_sort_set_dtt(in,error)
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Compute the date-time-telescope sorting list of the given index
      !---------------------------------------------------------------------
      type(optimize), intent(inout) :: in     !
      logical,        intent(inout) :: error  !
    end subroutine optimize_sort_set_dtt
  end interface
  !
  interface
    subroutine optimize_sort_add_dtt(optx,obs,dupl,error)
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Add a new observation to the Date-Time-Telescope sorting list.
      ! Raise an error if this new observation is duplicate of a previous
      ! one.
      !---------------------------------------------------------------------
      type(optimize),    intent(inout) :: optx   ! Index to search in
      type(observation), intent(in)    :: obs    ! Observation to be added
      logical,           intent(out)   :: dupl   ! Observation is a duplicate?
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine optimize_sort_add_dtt
  end interface
  !
  interface
    subroutine class_fft_do(set,obs,doindex,docurs,doremove,nkill,fkill,  &
      wmin,wmax,error,user_function)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set             !
      type(observation),   intent(inout) :: obs             !
      logical,             intent(in)    :: doindex         ! Index or obs mode?
      logical,             intent(in)    :: docurs          ! Get parameters from cursor
      logical,             intent(in)    :: doremove        ! Remove option
      integer(kind=4),     intent(in)    :: nkill           ! Number of FFT windows to kill
      real(kind=8),        intent(in)    :: fkill(2,nkill)  ! FFT window values
      real(kind=4),        intent(in)    :: wmin            ! Lower bound for window removal
      real(kind=4),        intent(in)    :: wmax            ! Upper bound for window removal
      logical,             intent(inout) :: error           ! Error status
      logical,             external      :: user_function   !
    end subroutine class_fft_do
  end interface
  !
  interface
    subroutine sub_fourier(set,obs,nx,ny,user_function,nkill,fkill,wmin,wmax,  &
      doindex,docurs,doremove,error)
      use gildas_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command
      !    FFT [Wave1 Wave2 [Wave3 ...]]
      !  Display and possibly edit the Fourier Transform of the spectrum.
      !  Interpolation is done in Amplitude and Phase, but only the Power
      !  Spectrum is displayed
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set             !
      type(observation),   intent(inout) :: obs             ! Input observation
      integer(kind=4),     intent(in)    :: nx              ! X-size
      integer(kind=4),     intent(in)    :: ny              ! Y-size
      logical,             external      :: user_function   !
      integer(kind=4),     intent(in)    :: nkill           ! Number of FFT windows to kill
      real(kind=8),        intent(in)    :: fkill(2,nkill)  ! FFT window values
      real(kind=4),        intent(in)    :: wmin            ! Lower bound for window removal
      real(kind=4),        intent(in)    :: wmax            ! Upper bound for window removal
      logical,             intent(in)    :: doindex         ! Observation or index mode?
      logical,             intent(in)    :: docurs          ! Get parameters from cursor
      logical,             intent(in)    :: doremove        ! Remove option
      logical,             intent(inout) :: error           ! Error status
    end subroutine sub_fourier
  end interface
  !
  interface
    subroutine class_fft_remove(set,obs,cdata,v1,v2,docurs,user_function,error)
      use gbl_message
      use gkernel_types
      use class_parameter
      use class_index
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Support routine for command:
      !     FFT /REMOVE
      !   Remove fitted lines or interval
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(in)    :: obs            ! Input observation
      complex(kind=4),     intent(inout) :: cdata(obs%fft%nx,obs%fft%ny)
      real(kind=4),        intent(in)    :: v1             ! Interval lower bound
      real(kind=4),        intent(in)    :: v2             ! Interval upper bound
      logical,             intent(in)    :: docurs         ! Get values from cursor ?
      logical,             external      :: user_function  !
      logical,             intent(out)   :: error          ! Logical error flag
    end subroutine class_fft_remove
  end interface
  !
  interface
    subroutine class_fft_kill(obs,cdata,fkill,nkill,fill,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command:
      !   FFT /KILL
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs             ! Input observation
      complex(kind=4),   intent(inout) :: cdata(obs%fft%nx,obs%fft%ny)
      integer(kind=4),   intent(in)    :: nkill           ! Number of FFT windows to kill
      real(kind=8),      intent(in)    :: fkill(2,nkill)  ! FFT window values
      logical,           intent(out)   :: fill            !
      logical,           intent(inout) :: error           ! Logical error flag
    end subroutine class_fft_kill
  end interface
  !
  interface
    subroutine class_fft_compute(obs,cdata,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute obs%fft%datay(:,:) and obs%fft%datax(:), and associated X
      ! Fourier axis description.
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    !
      complex(kind=4),   intent(inout) :: cdata(obs%fft%nx,obs%fft%ny)
      logical,           intent(inout) :: error  !
    end subroutine class_fft_compute
  end interface
  !
  interface
    subroutine reallocate_fft(fft,new_nx,new_ny,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_observation_fft_t), intent(inout) :: fft
      integer(kind=4),               intent(in)    :: new_nx
      integer(kind=4),               intent(in)    :: new_ny
      logical,                       intent(inout) :: error
    end subroutine reallocate_fft
  end interface
  !
  interface
    subroutine class_fft_plot(set,obs,cbad,ebad,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Plot power spectrum
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      type(observation),   intent(in)    :: obs    !
      real(kind=4),        intent(in)    :: cbad   !
      real(kind=4),        intent(in)    :: ebad   !
      logical,             intent(inout) :: error  !
    end subroutine class_fft_plot
  end interface
  !
  interface
    subroutine class_fft_kill_fill(set,obs,cdata,fkill,nkill,doindex,removed,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command:
      !   FFT /KILL
      !   1: kill the desired window(s)
      !   2: replace (fill) these windows
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set             !
      type(observation),   intent(inout) :: obs             !
      complex(kind=4),     intent(inout) :: cdata(obs%fft%nx,obs%fft%ny)
      integer(kind=4),     intent(in)    :: nkill           ! Number of FFT windows to kill
      real(kind=8),        intent(in)    :: fkill(2,nkill)  ! FFT window values
      logical,             intent(in)    :: doindex         !
      real(kind=4),        intent(in)    :: removed(obs%fft%nx,obs%fft%ny)
      logical,             intent(inout) :: error           ! Logical error flag
    end subroutine class_fft_kill_fill
  end interface
  !
  interface
    subroutine class_fft_kill_getwindows(docurs,fkill,mkill,nkill,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Get the "inverse frequency" window(s) to be killed from cursor
      !---------------------------------------------------------------------
      logical,          intent(in)    :: docurs          !
      integer(kind=4),  intent(in)    :: mkill           ! Max number of windows
      real(kind=8),     intent(out)   :: fkill(2,mkill)  ! Kill windows
      integer(kind=4),  intent(out)   :: nkill           ! Actual number of windows
      logical,          intent(inout) :: error           ! Logical error flag
    end subroutine class_fft_kill_getwindows
  end interface
  !
  interface
    complex function cfillin(cr,ival,imin,imax,bad)
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate bad channel (if possible)
      ! ---
      !  Complex*4 version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)  ::  imax      ! Last pixel in array
      complex(kind=4), intent(in)  ::  cr(imax)  ! Array to be interpolated
      integer(kind=4), intent(in)  ::  ival      ! Pixel to be interpolated
      integer(kind=4), intent(in)  ::  imin      ! First pixel in array
      real(kind=4),    intent(in)  ::  bad       ! Blanking value
    end function cfillin
  end interface
  !
  interface
    subroutine getcur(xc,xv,xf,xi,ya,xo,yo,ch)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Sends back cursor position in all user units
      !---------------------------------------------------------------------
      real(kind=4),     intent(out) :: xc  ! Channel number
      real(kind=4),     intent(out) :: xv  ! Velocity
      real(kind=4),     intent(out) :: xf  ! Frequency offset
      real(kind=4),     intent(out) :: xi  ! Image offset
      real(kind=4),     intent(out) :: ya  ! Intensity
      real(kind=4),     intent(out) :: xo  ! Cursor X-offset
      real(kind=4),     intent(out) :: yo  ! Cursor Y-offset
      character(len=*), intent(out) :: ch  ! Character struck
    end subroutine getcur
  end interface
  !
  interface
    subroutine setcur(xa,ya,unit)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Set cursor at (XA,YA) in UNIT coordinate system
      !---------------------------------------------------------------------
      real(kind=4),     intent(in) ::  xa   ! X position
      real(kind=4),     intent(in) ::  ya   ! Intensity
      character(len=*), intent(in) :: unit  ! X unit
    end subroutine setcur
  end interface
  !
  interface
    subroutine cursor(r,par,jcode,error)
      use gildas_def
      use gbl_message
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Compute initial values for gauss fit using cursor
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: r       !
      real(kind=4),      intent(out)   :: par(3)  ! Parameters array
      integer(kind=4),   intent(in)    :: jcode   ! Code to tell what to compute
      logical,           intent(inout) :: error   ! Error flag
    end subroutine cursor
  end interface
  !
  interface
    subroutine get_first(set,obs,user_function,error)
      use gildas_def
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get the first index entry
      ! An index must exist
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: obs            ! Current observation
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Error flag
    end subroutine get_first
  end interface
  !
  interface
    subroutine get_next(set,obs,endof,user_function,error)
      use gildas_def
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get next index entry
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: obs            ! Current observation
      logical,             intent(out)   :: endof          ! End of index
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Error flag
    end subroutine get_next
  end interface
  !
  interface
    subroutine get_last(set,obs,user_function,error)
      use gildas_def
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get the last index entry
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: obs            ! Current observation
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Error flag
    end subroutine get_last
  end interface
  !
  interface
    subroutine get_num(set,obs,nnn,mmm,user_function,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Get VERSION mmm of ENTRY nnn
      ! First look for in the Current Index
      ! If not in Current Index, search in File
      !---------------------------------------------------------------------
      type(class_setup_t),         intent(in)    :: set            !
      type(observation),           intent(inout) :: obs            ! Current observation
      integer(kind=obsnum_length), intent(in)    :: nnn            ! Entry number
      integer(kind=4),             intent(in)    :: mmm            ! Version number
      logical,                     external      :: user_function  !
      logical,                     intent(out)   :: error          ! Error flag
    end subroutine get_num
  end interface
  !
  interface
    subroutine get_num_cx(num,ver,found,kx,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_parameter
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Get VERSION ver of ENTRY num. Look in Current Index
      !---------------------------------------------------------------------
      integer(kind=obsnum_length), intent(in)    :: num    ! Observation number
      integer(kind=4),             intent(in)    :: ver    ! Version number
      logical,                     intent(out)   :: found  !
      integer(kind=entry_length),  intent(out)   :: kx     ! Entry number
      logical,                     intent(inout) :: error  ! Error flag
    end subroutine get_num_cx
  end interface
  !
  interface
    subroutine get_num_ix(set,num,ver,found,kx,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_index
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get VERSION ver of ENTRY num. Search in the Input File Index
      !---------------------------------------------------------------------
      type(class_setup_t),         intent(in)    :: set    !
      integer(kind=obsnum_length), intent(in)    :: num    ! Observation number
      integer(kind=4),             intent(in)    :: ver    ! Version number
      logical,                     intent(out)   :: found  !
      integer(kind=entry_length),  intent(out)   :: kx     ! Entry number
      logical,                     intent(inout) :: error  ! Error flag
    end subroutine get_num_ix
  end interface
  !
  interface
    subroutine get_it(set,obs,kx,user_function,error)
      use gildas_def
      use gbl_message
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get observation (header+data) number KX into observation structure OBS
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set            !
      type(observation),          intent(inout) :: obs            ! Observation structure
      integer(kind=entry_length), intent(in)    :: kx             ! Entry number
      logical,                    external      :: user_function  ! intent(in)
      logical,                    intent(out)   :: error          ! Error flag
    end subroutine get_it
  end interface
  !
  interface
    subroutine get_it_subset(set,obs,kx,extr,user_function,error)
      use gbl_message
      use gbl_constant
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! *** (Much) simplified duplicate of 'get_it', combined with ***
      ! *** partial duplicate of 'do_extract'                      ***
      ! - Get observation (header + SUBSET of data) number KX, FROM FILE
      ! (always), into observation structure OBS.
      ! - No support for OTF data, no use of the virtual buffers, no
      ! annoying message, no DROP support
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set            !
      type(observation),          intent(inout) :: obs            ! Observation structure
      integer(kind=entry_length), intent(in)    :: kx             ! Entry number
      type(extract_t),            intent(inout) :: extr           ! Extraction description
      logical,                    external      :: user_function  !
      logical,                    intent(inout) :: error          ! Error flag
    end subroutine get_it_subset
  end interface
  !
  interface
    subroutine get_rec(obs,ir,error)
      use gildas_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy record IR into OBS structure
      ! The content of DAPS in CLASS old OTF format
      !     type      number      content
      !     Real*4    1           RAZ           Azimuth in radians
      !     Real*4    1           REL           Elevation in radians
      !     Real*4    1           R4ST          LST       in radians
      !     Real*4    1           R4UT          UT        in radians
      !     Real*4    1           RLAMOF        Lambda offset in radians
      !     Real*4    1           RBETOF        Beta   offset in radians
      !     Integer*4 1           RFEED         feed number of array rec.
      !---------------------------------------------------------------------
      type (observation), intent(inout) :: obs    ! Current observation
      integer,            intent(in)    :: ir     ! Record number
      logical,            intent(out)   :: error  ! Error flag
    end subroutine get_rec
  end interface
  !
  interface
    subroutine extract_otf(raw,ndat,dap,datotf,nchan,nrec)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Separate spectral intensities from DAPS for an old OTF format scan
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)  :: ndat                ! nchan+ndaps
      integer(kind=4), intent(in)  :: nrec                ! Nb of records
      real(kind=4),    intent(in)  :: raw(ndat,nrec)      ! Complete data array
      type (dapotf),   intent(out) :: dap(nrec)           ! DAPs array
      integer(kind=4), intent(in)  :: nchan               ! Nb of channels
      real(kind=4),    intent(out) :: datotf(nchan,nrec)  ! Spectral data array
    end subroutine extract_otf
  end interface
  !
  interface
    subroutine copy_header(in,out)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      ! Copy the header of IN into OUT
      !---------------------------------------------------------------------
      type(header), intent(in)  :: in   !
      type(header), intent(out) :: out  !
    end subroutine copy_header
  end interface
  !
  interface
    subroutine index_frombuf_v1(data,indl,conv,error)
      use gildas_def
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transfer the data(*) buffer from V1 to the last version of the
      ! index
      !---------------------------------------------------------------------
      integer(kind=4),          intent(in)    :: data(*)  !
      type(indx_t),             intent(out)   :: indl     !
      type(classic_fileconv_t), intent(in)    :: conv     !
      logical,                  intent(inout) :: error    !
    end subroutine index_frombuf_v1
  end interface
  !
  interface
    subroutine index_v1tovl(ind1,indl,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transform the index V1 into an index last version
      !---------------------------------------------------------------------
      type(indx_v1_t), intent(in)    :: ind1   !
      type(indx_t),    intent(out)   :: indl   !
      logical,         intent(inout) :: error  !
    end subroutine index_v1tovl
  end interface
  !
  interface
    subroutine index_frombuf_v2orv3(data,isv3,indl,conv,error)
      use gildas_def
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transfer the data(*) buffer from V2 or V3 to the last version of
      ! the index
      !---------------------------------------------------------------------
      integer(kind=4),          intent(in)    :: data(*)  !
      logical,                  intent(in)    :: isv3     !
      type(indx_t),             intent(out)   :: indl     !
      type(classic_fileconv_t), intent(in)    :: conv     !
      logical,                  intent(inout) :: error    !
    end subroutine index_frombuf_v2orv3
  end interface
  !
  interface
    subroutine index_tobuf_v1(indl,data,conv,error)
      use gildas_def
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transfer last version of the index to the data(*) buffer V1
      !---------------------------------------------------------------------
      type(indx_t),             intent(in)    :: indl     !
      integer(kind=4),          intent(out)   :: data(*)  !
      type(classic_fileconv_t), intent(in)    :: conv     !
      logical,                  intent(inout) :: error    !
    end subroutine index_tobuf_v1
  end interface
  !
  interface
    subroutine index_vltov1(indl,ind1,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transform the index last version into an index V1
      !---------------------------------------------------------------------
      type(indx_t),    intent(in)    :: indl   !
      type(indx_v1_t), intent(out)   :: ind1   !
      logical,         intent(inout) :: error  !
    end subroutine index_vltov1
  end interface
  !
  interface
    subroutine index_tobuf_v2orv3(indl,isv3,data,conv,error)
      use gildas_def
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Transfer last version of the index to the data(*) buffer V2 or V3
      !---------------------------------------------------------------------
      type(indx_t),             intent(in)    :: indl     !
      logical,                  intent(in)    :: isv3     !
      integer(kind=4),          intent(out)   :: data(*)  !
      type(classic_fileconv_t), intent(in)    :: conv     !
      logical,                  intent(inout) :: error    !
    end subroutine index_tobuf_v2orv3
  end interface
  !
  interface
    subroutine index_fromobs(head,ind,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set the output Index from the input Observation Header
      !---------------------------------------------------------------------
      type(header), intent(in)    :: head   ! Observation header
      type(indx_t), intent(out)   :: ind    ! Computed Index
      logical,      intent(inout) :: error  !
    end subroutine index_fromobs
  end interface
  !
  interface
    subroutine index_toobs(ind,head,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Copy the Index to the in/out Observation Header
      !---------------------------------------------------------------------
      type(indx_t), intent(in)    :: ind    ! Computed Index
      type(header), intent(inout) :: head   ! Observation header
      logical,      intent(inout) :: error  !
    end subroutine index_toobs
  end interface
  !
  interface
    subroutine index_tooptimize(ind,iind,long,iopt,optx,error)
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Copy the input Index to the input 'optimize' object (collection
      ! of all the Indexes of the Observations in the file). The code
      ! assumes that the arrays are correctly allocated (enough space).
      ! This is done with reallocate_optimize.
      !  'long' index: all arrays are allocated
      !  'short' index: only ind(:), bloc(:), num(:), ver(:)
      !---------------------------------------------------------------------
      type(indx_t),               intent(in)    :: ind    ! Index
      integer(kind=entry_length), intent(in)    :: iind   ! Index number
      logical,                    intent(in)    :: long   ! Long index?
      integer(kind=entry_length), intent(in)    :: iopt   ! Position in optimized index
      type(optimize),             intent(inout) :: optx   ! Optimized index of file
      logical,                    intent(inout) :: error  !
    end subroutine index_tooptimize
  end interface
  !
  interface
    subroutine index_fromoptimize(optx,i,ind,error)
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Fill the given Index from the input 'optimize' object
      ! (collection of Indexes)
      !---------------------------------------------------------------------
      type(optimize),             intent(in)    :: optx   ! Optimized index of file
      integer(kind=entry_length), intent(in)    :: i      ! Index number
      type(indx_t),               intent(out)   :: ind    ! Current spectrum index
      logical,                    intent(inout) :: error  !
    end subroutine index_fromoptimize
  end interface
  !
  interface
    subroutine optimize_tooptimize(in,i,ou,o,long,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy 1 element of optimize'd index IN into OU
      !---------------------------------------------------------------------
      type(optimize),             intent(in)    :: in     ! Input index
      integer(kind=entry_length), intent(in)    :: i      ! Element to be copied
      type(optimize),             intent(inout) :: ou     ! Output index
      integer(kind=entry_length), intent(in)    :: o      ! Destination
      logical,                    intent(in)    :: long   ! Long index?
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine optimize_tooptimize
  end interface
  !
  interface
    subroutine optimize_old_format(optx,name,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check whether the index contains old format observations, and act
      ! accordingly.
      !---------------------------------------------------------------------
      type(optimize),   intent(inout) :: optx   !
      character(len=*), intent(in)    :: name   ! Index name
      logical,          intent(inout) :: error  !
    end subroutine optimize_old_format
  end interface
  !
  interface
    subroutine rix_to_ix(entry_num,error)
      use classic_api
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      !  Read the Entry Index for given entry in FILE IN, and store it into
      ! IX. Assume IX has already been (re)allocated to a sufficient size!
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: entry_num  !
      logical,                    intent(inout) :: error      ! Logical error flag
    end subroutine rix_to_ix
  end interface
  !
  interface
    subroutine rox_to_ox(entry_num,error)
      use classic_api
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      !  Read the Entry Index for given entry in FILE OUT, and store it into
      ! OX. Assume OX has already been (re)allocated to a sufficient size!
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: entry_num  !
      logical,                    intent(inout) :: error      ! Logical error flag
    end subroutine rox_to_ox
  end interface
  !
  interface
    subroutine ix_update(error)
      use gbl_message
      use gbl_format
      use gbl_constant
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Check if input file has new entries, and save them in IX if yes
      !---------------------------------------------------------------------
      logical, intent(out) :: error  ! Error status
    end subroutine ix_update
  end interface
  !
  interface
    subroutine classcore_filein_open(spec,nspec,error)
      use gildas_def
      use gbl_format
      use gbl_convert
      use gbl_message
      use gkernel_types
      use classic_api
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      !   Close any input file, set the file specification for input, open
      ! this file.
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: spec   ! File name including extension
      integer(kind=4),  intent(in)  :: nspec  ! Length of filename
      logical,          intent(out) :: error  ! Logical error flag
    end subroutine classcore_filein_open
  end interface
  !
  interface
    subroutine class_file_check_classic(rname,file,error)
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Check if the input Classic file is supported
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: rname  ! Calling routine name
      type(classic_file_t), intent(in)    :: file   !
      logical,              intent(inout) :: error  ! Logical error flag
    end subroutine class_file_check_classic
  end interface
  !
  interface
    subroutine classcore_fileout_flush(error)
      use gbl_format
      use gbl_message
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      ! Flush the output file to the disk
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine classcore_fileout_flush
  end interface
  !
  interface
    subroutine classcore_filein_close(error)
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !  Close the input file without closing the output file if they are
      ! the same
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Error status
    end subroutine classcore_filein_close
  end interface
  !
  interface
    subroutine class_files_info
      use gildas_def
      use gbl_format
      use gbl_convert
      use gbl_message
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !  Prints input and output file names
      !---------------------------------------------------------------------
      ! Local
    end subroutine class_files_info
  end interface
  !
  interface
    subroutine class_luns_get(error)
      use gbl_message
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      ! Allocate 2 luns for filein and fileout support
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine class_luns_get
  end interface
  !
  interface
    function filein_opened(rname,error)
      use gbl_message
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if an input file is opened, or error with message
      ! otherwise
      !---------------------------------------------------------------------
      logical :: filein_opened  ! Function value on return
      character(len=*), intent(in)    :: rname  ! Calling routine name
      logical,          intent(inout) :: error  ! Logical error flag
    end function filein_opened
  end interface
  !
  interface
    function fileout_opened(rname,error)
      use gbl_message
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if an output file is opened, or error with message
      ! otherwise
      !---------------------------------------------------------------------
      logical :: fileout_opened  ! Function value on return
      character(len=*), intent(in)    :: rname  ! Calling routine name
      logical,          intent(inout) :: error  ! Logical error flag
    end function fileout_opened
  end interface
  !
  interface
    subroutine lfit(x,y,weight,ndata,a,ma,covar,ncvm,chisq,funcs,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Given a set of NDATA points X(I),Y(I) with individual weights WEIGHT(I),
      ! use Chi2 minimization to determine the MA coefficients A
      ! of a function that depends linearly on A.
      !---------------------------------------------------------------------
      integer,                    intent(in)  :: ndata   ! Size of data arrays
      real, dimension(ndata),     intent(in)  :: x       ! Abscissa of input values
      real, dimension(ndata),     intent(in)  :: y       ! Ordinates of input values
      real, dimension(ndata),     intent(in)  :: weight  ! Weights
      integer,                    intent(in)  :: ma      ! Approx. polynom number
      real, dimension(ma),        intent(out) :: a       ! Output coefficients
      integer,                    intent(in)  :: ncvm    ! Size of covariance matrix
      real, dimension(ncvm,ncvm), intent(out) :: covar   ! Covariance matrix (pivot)
      real,                       intent(out) :: chisq   ! Chi2 value
      external                                :: funcs   ! Approx. function
      logical,                    intent(out) :: error   ! Error flag
    end subroutine lfit
  end interface
  !
  interface
    subroutine gaussj(a,n,np,b,m,mp)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Gauss Jordan elimination with full pivoting
      ! Solve A.X = B by computing inv(A) : X = inv(A).B
      !---------------------------------------------------------------------
      integer, intent(in)    ::  np        ! Size
      real,    intent(inout) ::  a(np,np)  ! On input A ; on output inv(A)
      integer, intent(in)    ::  n         ! Size of X vectors
      integer, intent(in)    ::  mp        ! Size
      real,    intent(inout) ::  b(np,mp)  ! On input, RHS ; on output, X vectors
      integer, intent(in)    ::  m         ! Number of X vectors
    end subroutine gaussj
  end interface
  !
  interface
    subroutine class_list_defbrieflong(set,optx,roptx,mode,error)
      use gbl_constant
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !   LIST [IN|OUT]  (default mode)
      !   LIST [IN|OUT]  /BRIEF
      !   LIST [IN|OUT]  /LONG
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(optimize),      intent(in)    :: optx   ! Index to be listed
      interface
        subroutine roptx(entry_num,ind,error)  ! Index reading routine
        use classic_api
        use class_types
        integer(kind=entry_length), intent(in)  :: entry_num
        type(indx_t),               intent(out) :: ind
        logical,                    intent(out) :: error
        end subroutine roptx
      end interface
      integer(kind=4),     intent(in)    :: mode   ! List mode (0=def,1=brief,2=long)
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine class_list_defbrieflong
  end interface
  !
  interface
    subroutine list_numver_format(optx,forma,leng)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return the "best" (minimum and sufficient) format to display the
      ! any number and version as "N;V"
      !---------------------------------------------------------------------
      type(optimize),   intent(in)  :: optx   !
      character(len=*), intent(out) :: forma  ! Computed format
      integer(kind=4),  intent(out) :: leng   ! Length when format will be applied
    end subroutine list_numver_format
  end interface
  !
  interface
    subroutine list_scansub_format(optx,forma,leng,title)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return the "best" (minimum and sufficient) format to display any
      ! scan and subscan as "Scan Subscan"
      !---------------------------------------------------------------------
      type(optimize),   intent(in)  :: optx   !
      character(len=*), intent(out) :: forma  ! Computed format
      integer(kind=4),  intent(out) :: leng   ! Length when format will be applied
      character(len=*), intent(out) :: title  !
    end subroutine list_scansub_format
  end interface
  !
  interface
    subroutine class_list_default(set,ind,forma)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Print the current indx with the default LIST format
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)           :: set
      type(indx_t),        intent(in)           :: ind
      character(len=*),    intent(in), optional :: forma
    end subroutine class_list_default
  end interface
  !
  interface
    subroutine out0(gtype,x,y,error)
      use output_header
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Output on terminal or graphic device
      !	'G',x,y   : for graphic device in x,y coordinates
      !	'T',0.,0. : write on terminal
      !	'F',0.,0. : write in file
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: gtype  ! Type of output (G,T,F)
      real,             intent(in)  :: x,y    ! Coordinates
      logical,          intent(out) :: error  ! Logical error flag
    end subroutine out0
  end interface
  !
  interface
    subroutine outlin(cin,lin)
      use gbl_message
      use output_header
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Writes string cin(1:lin) on screen or file
      !---------------------------------------------------------------------
      character(len=*), intent(in) :: cin  !
      integer,          intent(in) :: lin  !
    end subroutine outlin
  end interface
  !
  interface
    subroutine out1(error)
      use output_header
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Close output device
      !---------------------------------------------------------------------
      logical, intent(in) :: error      !
    end subroutine out1
  end interface
  !
  interface
    subroutine list_scan(set,key,brief,error)
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command
      !   LIST /SCAN
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=1),    intent(in)    :: key    ! I(n) or O(ut). Default is Current index
      logical,             intent(in)    :: brief  ! BRIEF or NORMAL
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine list_scan
  end interface
  !
  interface
    subroutine list_scan_brief(idx,kmax0,error)
      use classic_api
      use class_parameter
      use class_index
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)  :: kmax0       !
      integer(kind=entry_length), intent(in)  :: idx(kmax0)  !
      logical,                    intent(out) :: error       !
    end subroutine list_scan_brief
  end interface
  !
  interface
    subroutine list_scan_long(set,idx,kmax0,error)
      use gbl_message
      use classic_api
      use class_parameter
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(inout) :: set         !
      integer(kind=entry_length), intent(in)    :: kmax0       ! Number of entries
      integer(kind=entry_length), intent(in)    :: idx(kmax0)  ! Scan-sorted Index array (IX, OX, CX)
      logical,                    intent(inout) :: error       ! Logical error flag
    end subroutine list_scan_long
  end interface
  !
  interface
    subroutine out_scan(set,ind,xoff1,xoff2,yoff1,yoff2,snum,nspec)
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t),         intent(in) :: set    !
      type(indx_t),                intent(in) :: ind    !
      real(kind=4),                intent(in) :: xoff1  ! Min lam offset
      real(kind=4),                intent(in) :: xoff2  ! Max lam offset
      real(kind=4),                intent(in) :: yoff1  ! Min bet offset
      real(kind=4),                intent(in) :: yoff2  ! Max bet offset
      integer(kind=obsnum_length), intent(in) :: snum   ! Scan number
      integer(kind=4),             intent(in) :: nspec  ! Number of spectra
    end subroutine out_scan
  end interface
  !
  interface
    subroutine exp_medians(obs,width,sampling,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       !
      real(kind=8),      intent(in)    :: width     ! [MHz]
      real(kind=8),      intent(in)    :: sampling  ! [MHz]
      logical,           intent(inout) :: error     !
    end subroutine exp_medians
  end interface
  !
  interface
    subroutine exp_median(obs,data,width,sampling,aaname,factor,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Compute the median of the input 'data', save the result in an
      ! associated array
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       !
      real(kind=4),      intent(in)    :: data(*)   !
      real(kind=8),      intent(in)    :: width     ! [MHz]
      real(kind=8),      intent(in)    :: sampling  ! [MHz]
      character(len=*),  intent(in)    :: aaname    !
      real(kind=8),      intent(in)    :: factor    ! Extra factor to be used
      logical,           intent(inout) :: error     !
    end subroutine exp_median
  end interface
  !
  interface
    subroutine memorize_free(imem)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !  Cleanly free the imem-th MEMORY slot
      !---------------------------------------------------------------------
      integer(kind=4), intent(in) :: imem  ! Slot number
    end subroutine memorize_free
  end interface
  !
  interface
    subroutine midsinus(obs,fit,ifatal,liter)
      use gildas_def
      use sinus_parameter
      use class_data
      use fit_minuit
      !-------------------------------------------------------------------
      ! @ private
      ! Start a BASE SINUS fit by building the par array and internal
      ! variable used by minuit
      ! IFATAL basically not used
      !-------------------------------------------------------------------
      type(observation) , intent(in)    :: obs    !
      type(fit_minuit_t), intent(inout) :: fit    ! Fitting variables
      logical,            intent(in)    :: liter  ! Iterate a fit
      integer(kind=4),    intent(out)   :: ifatal ! Number of fatal errors
    end subroutine midsinus
  end interface
  !
  interface class_minmax
    subroutine class_minmax_r4_1d(rmin,rmax,a,na,rbad)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic class_minmax
      ! Compute MIN and MAX from a (section of) given array taking into
      ! account blanking values and NaN
      ! ---
      ! R*4 1D version
      !---------------------------------------------------------------------
      real(kind=4),    intent(out) :: rmin   ! Min value plus lower margin
      real(kind=4),    intent(out) :: rmax   ! Max value plus upper margin
      integer(kind=4), intent(in)  :: na     ! Number of values
      real(kind=4),    intent(in)  :: a(na)  ! Input array
      real(kind=4),    intent(in)  :: rbad   ! Bad channel value
    end subroutine class_minmax_r4_1d
    subroutine class_minmax_i4_1d(rmin,rmax,a,na,ibad)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic class_minmax
      ! Compute MIN and MAX from a (section of) given array taking into
      ! account blanking values
      ! ---
      ! I*4 1D version
      !---------------------------------------------------------------------
      real(kind=4),    intent(out) :: rmin   ! Min value plus lower margin
      real(kind=4),    intent(out) :: rmax   ! Max value plus upper margin
      integer(kind=4), intent(in)  :: na     ! Number of values
      integer(kind=4), intent(in)  :: a(na)  ! Input array
      integer(kind=4), intent(in)  :: ibad   ! Bad channel value
    end subroutine class_minmax_i4_1d
    subroutine class_minmax_r4_2d(rmin,rmax,a,n1,n2,rbad)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic class_minmax
      ! Compute MIN and MAX from a (section of) given array taking into
      ! account blanking values and NaN
      ! ---
      ! R*4 2D version
      !---------------------------------------------------------------------
      real(kind=4),    intent(out) :: rmin      ! Min value plus lower margin
      real(kind=4),    intent(out) :: rmax      ! Max value plus upper margin
      integer(kind=4), intent(in)  :: n1,n2     ! Number of values
      real(kind=4),    intent(in)  :: a(n1,n2)  ! Input array
      real(kind=4),    intent(in)  :: rbad      ! Bad channel value
    end subroutine class_minmax_r4_2d
  end interface class_minmax
  !
  interface
    subroutine minsinus(npar,g,f,x,iflag,obs)
      use gildas_def
      use phys_const
      use class_types
      use sinus_parameter
      !----------------------------------------------------------------------
      ! @ private-mandatory
      !  Function to be minimized in the SINUS fit.
      !  Basic parameters are Intensity, Period and Phase.
      !----------------------------------------------------------------------
      integer(kind=4),   intent(in)  :: npar     ! Number of parameters
      real(kind=8),      intent(out) :: g(npar)  ! Array of derivatives
      real(kind=8),      intent(out) :: f        ! Function values
      real(kind=8),      intent(in)  :: x(npar)  ! Input parameter values
      integer(kind=4),   intent(in)  :: iflag    ! Code operation
      type(observation), intent(in)  :: obs      !
    end subroutine minsinus
  end interface
  !
  interface
    subroutine model_header_default(set,obs,error)
      use gbl_constant
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the needed part of the header, if not defined yet
      ! Should use RZERO to nullify section by section
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    !
      logical,             intent(inout) :: error  !
    end subroutine model_header_default
  end interface
  !
  interface
    subroutine model_Y_from_var(yname,incay,error)
      use gildas_def
      use gbl_format
      use gbl_message
      use gkernel_types
      !---------------------------------------------------------------------
      ! @ private
      ! Incarnate Y variable given its name.
      !---------------------------------------------------------------------
      character(len=*),       intent(in)    :: yname  ! Name of Y variable
      type(sic_descriptor_t), intent(out)   :: incay  ! Y variable incarnation
      logical,                intent(inout) :: error  ! Error flag
    end subroutine model_Y_from_var
  end interface
  !
  interface
    subroutine model_X_from_var(xname,r,error)
      use gildas_def
      use gbl_format
      use phys_const
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Read X axis from variable 'xname', and store it in r%datav. Set also
      ! r%head. In case of irregular sampling, X values are stored in datav.
      ! datax in then filled appropriately by newdat.
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: xname  ! Name of X variable
      type(observation), intent(inout) :: r      !
      logical,           intent(inout) :: error  ! Error flag
    end subroutine model_X_from_var
  end interface
  !
  interface
    function model_X_isregular(datax,nx,tol)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Check if the input array is regularly spaced or not. Tolerance is
      ! given as a fraction of the first interval. Positive or negative
      ! increments are accepted.
      !  Single precision version.
      !---------------------------------------------------------------------
      logical :: model_X_isregular  ! Function value on return
      integer(kind=4),       intent(in) :: nx         ! Number of values
      real(kind=xdata_kind), intent(in) :: datax(nx)  ! Values
      real(kind=4),          intent(in) :: tol        ! Tolerance
    end function model_X_isregular
  end interface
  !
  interface
    function model_obs_fillgaps(obs,tol)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Insert 'bad' channels in obs%datav and obs%data1 so that obs%datav
      ! is regularly sampled. This is suited for obs%datav(:) being a
      ! regular grid except some missing channels (gaps).
      !  Axes less regular than tolerance are assumed completely irregular
      ! and the function will fail. Use a resampling in this case.
      !---------------------------------------------------------------------
      logical :: model_obs_fillgaps  ! success = .true. on return
      type(observation), intent(inout) :: obs    !
      real(kind=8),      intent(in)    :: tol    ! Tolerance (channel fraction)
    end function model_obs_fillgaps
  end interface
  !
  interface
    subroutine model_Y_to_R(addr_y,r)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy values in Y variable into R buffer
      !---------------------------------------------------------------------
      integer(kind=address_length), intent(in)    :: addr_y  ! Y variable address
      type(observation),            intent(inout) :: r      !
    end subroutine model_Y_to_R
  end interface
  !
  interface
    subroutine modify_frequency(obs,new_restf,error)
      use phys_const
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Modify velocity scale according to new rest frequency [MHz]
      ! The axes are assumed to be linear in Frequency.
      ! It will also work properly for the RADIO definition of the velocity,
      ! but not for the others
      ! See IRAM Memo "Description of the frequency/velocity axes in CLASS"
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs        !
      real(kind=8),      intent(in)    :: new_restf  !
      logical,           intent(inout) :: error      !
    end subroutine modify_frequency
  end interface
  !
  interface
    subroutine modify_velocity(obs,velo_new,error)
      use gbl_message
      use class_types
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   MODIFY VELOCITY
      ! See IRAM Memo "Description of the frequency/velocity axes in CLASS"
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs       !
      real(kind=8),      intent(in)    :: velo_new  !
      logical,           intent(inout) :: error     !
    end subroutine modify_velocity
  end interface
  !
  interface
    subroutine modify_resolution(obs,old_freq,new_freq,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Recompute the resolution according to the new frequency at
      ! reference channel (= rest frequency)
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      real(kind=8),      intent(in)    :: old_freq
      real(kind=8),      intent(in)    :: new_freq
      logical,           intent(inout) :: error
    end subroutine modify_resolution
  end interface
  !
  interface
    subroutine modify_beeff(set,line,r,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   MODIFY BEAM_EFF Beeff
      !   MODIFY BEAM_EFF /RUZE [B0 Sigma]
      ! The spectrum is rescaled according to the new value only if the beam
      ! efficiency previously was non zero valued
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      type(observation),   intent(inout) :: r      !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine modify_beeff
  end interface
  !
  interface
    subroutine modify_blanking_head(obs,newbad)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Modify the blank value in a header
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      real(kind=4),      intent(in)    :: newbad
    end subroutine modify_blanking_head
  end interface
  !
  interface
    subroutine modify_scale(obs,tocode,verbose,error)
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Modify the Y scale unit
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs      !
      integer(kind=4),   intent(in)    :: tocode   ! Class internal code for new Y unit
      logical,           intent(in)    :: verbose  ! Verbose warnings and infos?
      logical,           intent(inout) :: error    !
    end subroutine modify_scale
  end interface
  !
  interface
    subroutine modify_doppler(set,code,head,error)
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command:
      !  MODIFY DOPPLER [SIGN|*|Value]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: code   !
      type(header),        intent(inout) :: head   ! head%pos%doppler modified in return
      logical,             intent(inout) :: error  !
    end subroutine modify_doppler
  end interface
  !
  interface
    subroutine modify_elevationgain(obs,error)
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Apply elevation gain correction for 30M data (see Juan Penalver memo
      ! 16-Apr-2012).
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine modify_elevationgain
  end interface
  !
  interface
    subroutine modify_parang(obs,error)
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Recompute the parallactic angle from latitude + azimuth + elevation
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine modify_parang
  end interface
  !
  interface modify_blanking
    subroutine modify_blanking_obs(obs,newbad)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic modify_blanking
      !  Modify blank values (bad and NaN) from the spectrum, and update
      ! the header accordingly
      ! ---
      ! This version for a type(observation) as argument
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      real(kind=4),      intent(in)    :: newbad
    end subroutine modify_blanking_obs
    subroutine modify_blanking_nv4(val,nv4,oldbad,newbad)
      !---------------------------------------------------------------------
      ! @ private-generic modify_blanking
      ! Modify blank values (bad and NaN) from the spectrum
      ! ---
      ! This version for I*4 number of values
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: nv4
      real(kind=4),    intent(inout) :: val(nv4)
      real(kind=4),    intent(in)    :: oldbad
      real(kind=4),    intent(in)    :: newbad
    end subroutine modify_blanking_nv4
    subroutine modify_blanking_nv8(val,nv8,oldbad,newbad)
      !---------------------------------------------------------------------
      ! @ private-generic modify_blanking
      ! Modify blank values (bad and NaN) from the spectrum
      ! ---
      ! This version for I*8 number of values
      !---------------------------------------------------------------------
      integer(kind=8), intent(in)    :: nv8
      real(kind=4),    intent(inout) :: val(nv8)
      real(kind=4),    intent(in)    :: oldbad
      real(kind=4),    intent(in)    :: newbad
    end subroutine modify_blanking_nv8
  end interface modify_blanking
  !
  interface modify_projection
    subroutine modify_projection_charval(set,head,newproj_c,newa0_c,newd0_c,  &
      newang_c,newaunit_c,error)
      use gbl_constant
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic modify_projection
      !   Modify the kind of projection (RADIO, AZIMUTHAL, etc), the
      ! projection center, and the projection angle
      ! ---
      !  Entry point with char*(*) proj, A0, and D0. If head%pos%system is
      ! Equatorial or ICRS, A0 is assumed an hour angle. Arguments with
      ! value '=' mean unchanged.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set         !
      type(header),        intent(inout) :: head        ! Header to be modified
      character(len=*),    intent(in)    :: newproj_c   ! New projection name
      character(len=*),    intent(in)    :: newa0_c     ! New proj. center A0 (sexagesimal)
      character(len=*),    intent(in)    :: newd0_c     ! New proj. center D0 (sexagesimal)
      character(len=*),    intent(in)    :: newang_c    ! New projection angle
      character(len=*),    intent(in)    :: newaunit_c  ! Projection angle unit
      logical,             intent(inout) :: error       ! Logical error flag
    end subroutine modify_projection_charval
    subroutine modify_projection_numval(set,head,newproj,newa0,newd0,newang,error)
      use gbl_constant
      use gbl_message
      use gkernel_types
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic modify_projection
      !   Modify the kind of projection (RADIO, AZIMUTHAL, etc), the
      ! projection center, and the projection angle
      ! ---
      !  Entry point with integer code for proj, and real*8 a0, d0, pang
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set      !
      type(header),        intent(inout) :: head     !
      integer(kind=4),     intent(in)    :: newproj  ! [code] New proj. code
      real(kind=8),        intent(in)    :: newa0    ! [rad ] New proj. center A0
      real(kind=8),        intent(in)    :: newd0    ! [rad ] New proj. center D0
      real(kind=8),        intent(in)    :: newang   ! [rad ] New proj. angle
      logical,             intent(inout) :: error    !
    end subroutine modify_projection_numval
  end interface modify_projection
  !
  interface
    subroutine rescale_data(r,r5)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: r
      real(kind=4),      intent(in)    :: r5  ! Scale factor
    end subroutine rescale_data
  end interface
  !
  interface
    subroutine rescale_header(r,r5)
      use gildas_def
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Apply a scaling factor to current header parameters.
      !----------------------------------------------------------------------
      type(header), intent(inout) :: r
      real(kind=4), intent(in)    :: r5  ! Scale factor
    end subroutine rescale_header
  end interface
  !
  interface
    subroutine abscissa(set,obs,error)
      use gildas_def
      use gbl_message
      use gbl_constant
      use phys_const
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Recompute the observation arrays DATAV, DATAS and DATAI, and
      ! set the observation array DATAX according to the current SET
      ! UNIT value.
      !  Use of DATA arrays:
      !  -------------------------
      !   Regul | SPEC  |  CONT
      !   DATAV |  V    |   A
      !   DATAS |  F    |   T
      !   DATAI |  I    |   -
      !   DATAC |  C    |   C    (NB: computed on the fly)
      !   DATAX | VFIC  |  ATC   (NB: copied from above arrays)
      !  -------------------------
      !   Irreg | SPEC  |  CONT
      !   DATAV | VFI   |   AT
      !   DATAS |  -    |   -
      !   DATAI |  -    |   -
      !   DATAC |  C    |   C    (NB: computed on the fly)
      !   DATAX | VFIC  |  ATC   (NB: copied from above arrays)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)     :: set    !
      type(observation),   intent(inout)  :: obs    ! Current observation
      logical,             intent(out)    :: error  ! Error status
    end subroutine abscissa
  end interface
  !
  interface
    subroutine newlim(set,obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Current observation
      logical,             intent(out)   :: error  ! Error flag
    end subroutine newlim
  end interface
  !
  interface
    subroutine newlimx(set,obs,error)
      use gildas_def
      use gbl_message
      use gbl_constant
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Set X plotting limits according to selected mode.
      ! It is called only by NEWDAT, and calls SELIMX and GELIMX.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Current observation
      logical,             intent(out)   :: error  ! Error flag
    end subroutine newlimx
  end interface
  !
  interface
    subroutine newlimx_spec_irreg(set,obs,xc1,xc2,xv1,xv2,xf1,xf2,xfo,xi1,xi2,xio)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Compute the X limits for the 4 supported units for spectroscopic
      ! data irregularly sampled
      !---------------------------------------------------------------------
      type(class_setup_t),    intent(in)  :: set      !
      type(observation),      intent(in)  :: obs      !
      real(kind=plot_length), intent(out) :: xc1,xc2  !
      real(kind=plot_length), intent(out) :: xv1,xv2  !
      real(kind=plot_length), intent(out) :: xf1,xf2  !
      real(kind=8),           intent(out) :: xfo      !
      real(kind=plot_length), intent(out) :: xi1,xi2  !
      real(kind=8),           intent(out) :: xio      !
    end subroutine newlimx_spec_irreg
  end interface
  !
  interface
    subroutine newlimx_cont_irreg(set,obs,xc1,xc2,xv1,xv2,xf1,xf2,xfo)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Compute the X limits for the 3 supported units for continuum
      ! data irregularly sampled
      !---------------------------------------------------------------------
      type(class_setup_t),    intent(in)  :: set      !
      type(observation),      intent(in)  :: obs      !
      real(kind=plot_length), intent(out) :: xc1,xc2  !
      real(kind=plot_length), intent(out) :: xv1,xv2  !
      real(kind=plot_length), intent(out) :: xf1,xf2  !
      real(kind=8),           intent(out) :: xfo      !
    end subroutine newlimx_cont_irreg
  end interface
  !
  interface
    subroutine newlimx_spec_regul(set,obs,xc1,xc2,xv1,xv2,xf1,xf2,xfo,xi1,xi2,xio)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Compute the X limits for the 4 supported units for spectroscopic
      ! data regularly sampled
      !---------------------------------------------------------------------
      type(class_setup_t),    intent(in)  :: set      !
      type(observation),      intent(in)  :: obs      !
      real(kind=plot_length), intent(out) :: xc1,xc2  !
      real(kind=plot_length), intent(out) :: xv1,xv2  !
      real(kind=plot_length), intent(out) :: xf1,xf2  !
      real(kind=8),           intent(out) :: xfo      !
      real(kind=plot_length), intent(out) :: xi1,xi2  !
      real(kind=8),           intent(out) :: xio      !
    end subroutine newlimx_spec_regul
  end interface
  !
  interface
    subroutine newlimx_cont_regul(set,obs,xc1,xc2,xv1,xv2,xf1,xf2,xfo)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Compute the X limits for the 3 supported units for continuum
      ! data regularly sampled
      !---------------------------------------------------------------------
      type(class_setup_t),    intent(in)  :: set      !
      type(observation),      intent(in)  :: obs      !
      real(kind=plot_length), intent(out) :: xc1,xc2  !
      real(kind=plot_length), intent(out) :: xv1,xv2  !
      real(kind=plot_length), intent(out) :: xf1,xf2  !
      real(kind=8),           intent(out) :: xfo      !
    end subroutine newlimx_cont_regul
  end interface
  !
  interface
    subroutine newlimy(set,obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Set Y plotting limits according to selected mode.
      ! It is called only by NEWDAT, and calls SELIMY.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Current observation
      logical,             intent(out)   :: error  ! Error flag
    end subroutine newlimy
  end interface
  !
  interface
    subroutine newlimz(set,obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Used only in the case of 2D plots
      ! Set Z plotting limits according to selected mode in Z
      ! It is called when getting a multirecord scan.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set    !
      type(observation),   intent(in)  :: obs    ! Current observation
      logical,             intent(out) :: error  ! Error flag
    end subroutine newlimz
  end interface
  !
  interface
    subroutine set_angle(set,head)
      use gildas_def
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! Compute true offsets taking into account position angle
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(header),        intent(inout) :: head
    end subroutine set_angle
  end interface
  !
  interface
    subroutine ichan_from_value(obs,v1,v2,i1,i2)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert velocity interval into corresponding channel interval
      !   obs%datax(i1).ge.min(v1,v2)
      !   obs%datax(i2).le.max(v1,v2)
      !---------------------------------------------------------------------
      type(observation),      intent(in)  :: obs  !
      real(kind=plot_length), intent(in)  :: v1   ! Velocity interval
      real(kind=plot_length), intent(in)  :: v2   ! Velocity interval
      real(kind=plot_length), intent(out) :: i1   ! First channel
      real(kind=plot_length), intent(out) :: i2   ! Last channel
    end subroutine ichan_from_value
  end interface
  !
  interface
    subroutine class_noise_guess(rname,obs,sigma,error)
      use gbl_message
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Try to guess the noise (RMS) value from header values
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: rname  ! Calling routine name
      type(observation), intent(in)    :: obs    !
      real(kind=4),      intent(out)   :: sigma  ! Computed RMS
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine class_noise_guess
  end interface
  !
  interface
    subroutine conne1(x,y,nxy,func)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Internal routine
      !  Connect a set of points.
      !---------------------------------------------------------------------
      integer, intent(in) :: nxy     ! Number of points
      real,    intent(in) :: x(nxy)  ! X values
      real,    intent(in) :: y(nxy)  ! Y values
      external            :: func    ! Plotting function
    end subroutine conne1
  end interface
  !
  interface
    subroutine conne2(xval,xref,xinc,y,nxy,func)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Internal routine
      !  Connect a set of points regularly spaced along the X axis.
      !---------------------------------------------------------------------
      real,    intent(in) :: xval    ! X value at reference
      real,    intent(in) :: xref    ! X reference pixel
      real,    intent(in) :: xinc    ! X increment
      integer, intent(in) :: nxy     ! Number of points
      real,    intent(in) :: y(nxy)  ! Y values
      external            :: func    ! Plotting function
    end subroutine conne2
  end interface
  !
  interface
    subroutine conne3(x,y,nxy,func,rbad)
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS  Internal routine
      !   Connect a set of points with blanking.
      !----------------------------------------------------------------------
      integer, intent(in) :: nxy     ! Number of points
      real,    intent(in) :: x(nxy)  ! X values
      real,    intent(in) :: y(nxy)  ! Y values
      real,    intent(in) :: rbad    ! Blanking value
      external            :: func    ! Plotting function
    end subroutine conne3
  end interface
  !
  interface
    subroutine conne4(xval,xref,xinc,y,nxy,func,rbad)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Internal routine
      !  Connect a set of points regularly spaced along the X axis with
      ! blanking
      !---------------------------------------------------------------------
      integer, intent(in) :: nxy     ! Number of points
      real,    intent(in) :: xref    ! X reference pixel
      real,    intent(in) :: xval    ! X value
      real,    intent(in) :: xinc    ! X increment
      real,    intent(in) :: y(nxy)  ! Y values
      external            :: func    ! Plotting function
      real,    intent(in) :: rbad    ! Blanking value
    end subroutine conne4
  end interface
  !
  interface
    subroutine histo2(xval,xref,xinc,y,nxy,func)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !   Trace d'Histogramme a partir de donnees X regulierement espacees
      ! et du tableau Y
      !---------------------------------------------------------------------
      integer, intent(in) :: nxy     ! Number of points
      real,    intent(in) :: xref    ! X reference pixel
      real,    intent(in) :: xval    ! X value
      real,    intent(in) :: xinc    ! X increment
      real,    intent(in) :: y(nxy)  ! Y values
      external            :: func    ! Plotting function
    end subroutine histo2
  end interface
  !
  interface
    subroutine plot_index(set,error)
      use gbl_message
      use class_data
      use class_index
      use class_popup
      use class_types
      use plot_formula
      !-----------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command
      !     PLOT /INDEX
      ! Plot the currently loaded 2-D array as an image
      !-----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine plot_index
  end interface
  !
  interface
    subroutine polyno_obs(set,obs,last,cont,flux,z,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private (?)
      ! Support routine for command BASE.
      ! This version for a single observation.
      ! Computes and remove a polynomial baseline. This version uses
      ! singular value decomposition, with fall back to Gauss Jordan if not
      ! possible.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! The input observation to work on
      logical,             intent(inout) :: last   ! Use last baseline determination
      logical,             intent(in)    :: cont   ! Divide rather than subtract baseline
      real(kind=4),        intent(inout) :: flux   ! Flux value (if 0, average of base channels)
      real(kind=4),        intent(inout) :: z(*)   ! Working array
      logical,             intent(out)   :: error  ! Logical error flag
    end subroutine polyno_obs
  end interface
  !
  interface
    subroutine polyno_obs_arrays_spec(obs,last,x,y,weight,w1,np,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Fill the X, Y, WEIGHT arrays with the valid points to be used for
      ! baselining. A valid point is not in a signal window and is not
      ! bad. The number of valid points is set in NP.
      !  Also fill the W1 array with 0 (in a signal window) or 1 (out a
      ! signal window), i.e. W1 is the representation of the signal windows
      ! as an array of channels.
      !  X, Y, WEIGHT and W1 must have been preallocated to the size
      ! obs%cnchan (i.e. the number of channels currently covered by SET
      ! MODE X), even if they are not entirely used in return.
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs        !
      logical,           intent(in)    :: last       ! Do we reuse the last fitting results?
      real(kind=4),      intent(out)   :: x(:)       ! X positions, in current DATAX units
      real(kind=4),      intent(out)   :: y(:)       ! Y intensities
      real(kind=4),      intent(out)   :: weight(:)  !
      integer(kind=4),   intent(out)   :: w1(:)      ! In or out the signal windows
      integer(kind=4),   intent(out)   :: np         !
      logical,           intent(inout) :: error      !
    end subroutine polyno_obs_arrays_spec
  end interface
  !
  interface
    subroutine polyno_obs_arrays_cont(obs,x,y,weight,w1,np,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Handle the special case of continuum on/off
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs        !
      real(kind=4),      intent(out)   :: x(:)       ! X positions, in current DATAX units
      real(kind=4),      intent(out)   :: y(:)       ! Y intensities
      real(kind=4),      intent(out)   :: weight(:)  !
      integer(kind=4),   intent(out)   :: w1(:)      ! In or out the signal windows
      integer(kind=4),   intent(out)   :: np         !
      logical,           intent(inout) :: error      !
    end subroutine polyno_obs_arrays_cont
  end interface
  !
  interface
    subroutine mindeg(a,n)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Internal routine
      !    Warn if the polynomial degree is too high
      !---------------------------------------------------------------------
      integer, intent(in) :: n     ! Polynom degree + 1
      real,    intent(in) :: a(n)  ! RMS for each degree
    end subroutine mindeg
  end interface
  !
  interface
    subroutine popup_full(set,this_one,user_function,error)
      use gildas_def
      use gbl_constant
      use class_types
      use plot_formula
      !----------------------------------------------------------------------
      ! @ private
      !  Plot one observation in the <POPUP window
      !----------------------------------------------------------------------
      type(class_setup_t),         intent(in)    :: set            !
      integer(kind=obsnum_length), intent(in)    :: this_one       ! Obs. number
      logical,                     external      :: user_function  !
      logical,                     intent(inout) :: error          ! Logical error flag
    end subroutine popup_full
  end interface
  !
  interface
    subroutine convert_vtype(set,obs,error)
      use gbl_constant
      use gbl_message
      use phys_const
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Convert the velocity information to the current default type,
      ! according to SET VELO
      !
      ! Conversion is done only between LSRK and HELIO
      !
      ! Parameters of the solar motion relative to the LSR: apex
      ! and velocity. Right ascension and declination of the apex
      ! are referred to equinox 1900.0 (Lang, Astrophysical Formulae)
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(header),        intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine convert_vtype
  end interface
  !
  interface
    subroutine convert_pos(set,obs,error)
      use gbl_constant
      use gbl_message
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !   Convert positions to current coordinate system and equinox,
      ! according to SET SYSTEM
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(header),        intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine convert_pos
  end interface
  !
  interface
    subroutine convert_drop(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Drop off data edges, according to SET DROP
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine convert_drop
  end interface
  !
  interface
    subroutine convert_scale(set,obs,verbose,error)
      use class_parameter
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Rescale RY to new Y scale unit if needed, according to SET SCALE
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set      !
      type(observation),   intent(inout) :: obs
      logical,             intent(in)    :: verbose  ! Verbose warnings and infos?
      logical,             intent(inout) :: error
    end subroutine convert_scale
  end interface
  !
  interface
    subroutine getmom(obs,v1,v2,aire,vit,del)
      use gildas_def
      use gbl_constant
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Computes moment of the data between V1 and V2
      ! Caution: V1 and V2 are rounded to the nearest channel
      !----------------------------------------------------------------------
      type(observation), intent(in)  :: obs   !
      real(kind=4),      intent(in)  :: v1    ! Lower bound
      real(kind=4),      intent(in)  :: v2    ! Upper bound
      real(kind=4),      intent(out) :: aire  ! Integrated area
      real(kind=4),      intent(out) :: vit   ! Central velocity
      real(kind=4),      intent(out) :: del   ! Line width
    end subroutine getmom
  end interface
  !
  interface
    subroutine prigauss(set,jtmp)
      use gbl_constant
      use class_setup_new
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Print the results of gaussfit to a listing file
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set   !
      integer(kind=4),     intent(in) :: jtmp  ! Logical unit number
    end subroutine prigauss
  end interface
  !
  interface
    subroutine priabs(set,jtmp)
      use class_setup_new
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Print the ABS fit results in a format suitable for GREG
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
      integer(kind=4),     intent(in) :: jtmp
    end subroutine priabs
  end interface
  !
  interface
    subroutine prishell(set,jtmp)
      use phys_const
      use class_setup_new
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Print the SHELL fit results in a format suitable for GREG
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set   !
      integer(kind=4),     intent(in) :: jtmp  ! Logical Unit number for message
    end subroutine prishell
  end interface
  !
  interface
    subroutine prinh3(set,jtmp)
      use class_setup_new
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Print the NH3 fit results in a format suitable for GREG
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
      integer(kind=4),     intent(in) :: jtmp
    end subroutine prinh3
  end interface
  !
  interface
    subroutine pricont(set,jtmp)
      use phys_const
      use class_setup_new
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Print the results of gaussfit to a listing file, for continuum data
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set   !
      integer(kind=4),     intent(in) :: jtmp  ! Logical unit number
    end subroutine pricont
  end interface
  !
  interface
    subroutine pripoint(set,jtmp)
      use phys_const
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Print the results of gaussfit to a listing file, for pointing data
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
      integer(kind=4),     intent(in) :: jtmp   ! Logical unit number
    end subroutine pripoint
  end interface
  !
  interface
    subroutine priflux(set,jtmp)
      use phys_const
      use class_index
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Print the results of gaussfit to a listing file, for FLUX data
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
      integer(kind=4),     intent(in) :: jtmp   ! Logical unit number
    end subroutine priflux
  end interface
  !
  interface
    subroutine cido00 (num,off1,off2,aire,sigma,n,tab,nl,nc)
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! obsolete
      !----------------------------------------------------------------------
      integer, intent(in) :: num
      integer, intent(in) :: n
      integer, intent(in) :: nl
      integer, intent(in) :: nc
      real,    intent(in) :: off1
      real,    intent(in) :: off2
      real,    intent(in) :: aire
      real,    intent(in) :: sigma
      real,    intent(inout) :: tab(nl,nc)
    end subroutine cido00
  end interface
  !
  interface
    subroutine cido03 (num,off1,off2,nv,value,n,tab,nl,nc)
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! obsolete
      !----------------------------------------------------------------------
      integer num,n,nl,nc,nv,i
      real off1,off2,value(nv),tab(nl,nc)
    end subroutine cido03
  end interface
  !
  interface
    subroutine cido04 (num,off1,off2,nv,val1,val2,val3,n,tab,nl,nc)
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      ! obsolete
      !----------------------------------------------------------------------
      integer num,n,nl,nc,nv,i
      real off1,off2,val1(nv),val2(nv),val3(nv),tab(nl,nc)
    end subroutine cido04
  end interface
  !
  interface
    subroutine fits_convert(inbuf,fmtin,outbuf,fmtout,ndat,error)
      use gildas_def
      use gbl_format
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! FITS        Internal routine.
      !     Conversion between compatible local data types.
      !---------------------------------------------------------------------
      integer(kind=1), intent(in)  :: inbuf(*)   ! Input buffer
      integer,         intent(in)  :: fmtin      ! Format of data in buffer
      integer(kind=1), intent(out) :: outbuf(*)  ! Output buffer
      integer,         intent(in)  :: fmtout     ! Format for requested information
      integer,         intent(in)  :: ndat       ! Size of buffer
      logical,         intent(out) :: error      ! Error status
    end subroutine fits_convert
  end interface
  !
  interface
    subroutine vararrayread(ioffset,vbuffer,isize,ierror)
      use gildas_def
      use class_fits
      !---------------------------------------------------------------------
      ! @ private
      ! FITS        Internal routine.
      !---------------------------------------------------------------------
      integer,                   intent(in)  :: ioffset         !
      integer(kind=size_length), intent(in)  :: isize           !
      integer(kind=1),           intent(out) :: vbuffer(isize)  !
      logical,                   intent(out) :: ierror          !
    end subroutine vararrayread
  end interface
  !
  interface
    subroutine rgen(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -2 General
      !  Caution: part of the GEN section is actually copied from the
      ! index, and not read here
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rgen
  end interface
  !
  interface
    subroutine rpos(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -3 Position
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rpos
  end interface
  !
  interface
    subroutine rspec(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -4 Spectroscopy
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rspec
  end interface
  !
  interface
    subroutine rres(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -21 Resolution description
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rres
  end interface
  !
  interface
    subroutine rbase(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -5 Baseline
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rbase
  end interface
  !
  interface
    subroutine rorig(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -6 Origin
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rorig
  end interface
  !
  interface
    subroutine rplot(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -7 Plotting parameters
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rplot
  end interface
  !
  interface
    subroutine rswi(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -8 Switching description
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rswi
  end interface
  !
  interface
    subroutine rgaus(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -9 Gauss fit
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rgaus
  end interface
  !
  interface
    subroutine rcont(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -10 Drift continuum
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rcont
  end interface
  !
  interface
    subroutine rbeam(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -11 Beam Switch
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rbeam
  end interface
  !
  interface
    subroutine rshel(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -12 SHELL fit
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rshel
  end interface
  !
  interface
    subroutine rnh3(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -13 NH3 fit
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rnh3
  end interface
  !
  interface
    subroutine rabs(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -18 ABS fit
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rabs
  end interface
  !
  interface
    subroutine rcal(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -14 Calibration
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rcal
  end interface
  !
  interface
    subroutine rpoint(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -15 Pointing fit
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rpoint
  end interface
  !
  interface
    subroutine rsky(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -16 Skydip
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rsky
  end interface
  !
  interface
    subroutine rxcoo(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -17 X coordinates (irregularly spaced data).
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rxcoo
  end interface
  !
  interface
    subroutine rdescr(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -30 Data Section descriptor
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rdescr
  end interface
  !
  interface
    subroutine rcom(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! -1  Comment section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rcom
  end interface
  !
  interface
    subroutine ruser(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write the USER defined section description
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine ruser
  end interface
  !
  interface
    subroutine rassoc(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! -19 ASSOCiated arrays section
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rassoc
  end interface
  !
  interface
    subroutine rherschel(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! HERSCHEL section
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine rherschel
  end interface
  !
  interface
    subroutine rdata(set,obs,nv4,values,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_types
      use class_common
      !----------------------------------------------------------------------
      ! @ private
      ! Read the whole data section
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set          !
      type(observation),   intent(in)    :: obs          ! Observation
      integer(kind=4),     intent(inout) :: nv4          ! Number of data words
      real(kind=4),        intent(out)   :: values(nv4)  ! Data array
      logical,             intent(inout) :: error        !
    end subroutine rdata
  end interface
  !
  interface
    subroutine rdata_sub(set,obs,first,last,nv,values,error)
      use classic_api
      use class_common
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Read a subset of the data section.
      ! No support for OTF data
      !----------------------------------------------------------------------
      type(class_setup_t),       intent(in)    :: set         !
      type(observation),         intent(in)    :: obs         ! Observation
      integer(kind=data_length), intent(in)    :: first       ! First data word to read
      integer(kind=data_length), intent(in)    :: last        ! Last data word to read
      integer(kind=data_length), intent(inout) :: nv          ! Input and actual number of values read
      real(kind=4),              intent(out)   :: values(nv)  ! Data array
      logical,                   intent(inout) :: error       ! Logical error flag
    end subroutine rdata_sub
  end interface
  !
  interface
    subroutine rdata_sub_classic(obs,first,last,nv,values,error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read a (subset of) the data array from an entry of a Classic file
      !---------------------------------------------------------------------
      type(observation),         intent(in)      :: obs         ! Observation
      integer(kind=data_length), intent(in)      :: first       ! First data word to read
      integer(kind=data_length), intent(in)      :: last        ! Last data word to read
      integer(kind=data_length), intent(inout)   :: nv          ! Input and actual number of values read
      real(kind=4),              intent(out)     :: values(nv)  ! Data array
      logical,                   intent(inout)   :: error       ! Logical error flag
    end subroutine rdata_sub_classic
  end interface
  !
  interface
    subroutine convert_dh (iwin,nw,conv)
      use gbl_convert
      use classic_api
      !---------------------------------------------------------------------
      ! @ private
      !  Convert data header IWIN using conversion code CONVE, assuming NW
      ! is the length of the data header.
      !---------------------------------------------------------------------
      real(kind=4),             intent(inout) :: iwin(*)  ! Array containing data header to be converted
      integer(kind=4),          intent(in)    :: nw       ! Size of IWIN
      type(classic_fileconv_t), intent(in)    :: conv     ! Conversion structure
    end subroutine convert_dh
  end interface
  !
  interface
    subroutine rdump(obs,key,error)
      use gildas_def
      use gbl_constant
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    !
      character(len=*),  intent(in)    :: key    !
      logical,           intent(inout) :: error  !
    end subroutine rdump
  end interface
  !
  interface
    subroutine adump(r,t,error)
      use gildas_def
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Dump addresses
      !----------------------------------------------------------------------
      type(observation), intent(in)    :: r,t
      logical,           intent(inout) :: error
    end subroutine adump
  end interface
  !
  interface
    subroutine aadump(chain,r)
      use gildas_def
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Dump addresses
      !----------------------------------------------------------------------
      character(len=*), intent(in) :: chain
      type (OBSERVATION), intent(in) :: r
    end subroutine aadump
  end interface
  !
  interface
    subroutine odump(r,error)
      use gildas_def
      use class_types
      use gbl_constant
      !----------------------------------------------------------------------
      ! @ private
      ! Dump OTF
      !----------------------------------------------------------------------
      type (OBSERVATION), intent(in) :: r
      logical, intent(out) :: error
    end subroutine odump
  end interface
  !
  interface
    subroutine ddump(r,error)
      use gildas_def
      use class_types
      use gbl_constant
      !----------------------------------------------------------------------
      ! @ private
      ! Dump data
      !----------------------------------------------------------------------
      type (OBSERVATION), intent(in) :: r
      logical, intent(out) :: error
    end subroutine ddump
  end interface
  !
  interface
    subroutine idump(error)
      use classic_api
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Dump INDEX
      !----------------------------------------------------------------------
      logical, intent(out) :: error
    end subroutine idump
  end interface
  !
  interface
    subroutine filedump(line,error)
      use class_common
      !----------------------------------------------------------------------
      ! @ private
      ! Dump FILE [IN|OUT]
      !----------------------------------------------------------------------
      character(len=*), intent(in)    :: line   !
      logical,          intent(inout) :: error  !
    end subroutine filedump
  end interface
  !
  interface
    subroutine filedump_one(file,name,error)
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file   !
      character(len=*),     intent(in)    :: name   ! The File name (some prefix)
      logical,              intent(inout) :: error  !
    end subroutine filedump_one
  end interface
  !
  interface
    subroutine pdump(error)
      use plot_formula
      !----------------------------------------------------------------------
      ! @ private
      ! Dump PLOT
      !----------------------------------------------------------------------
      logical, intent(out) :: error
    end subroutine pdump
  end interface
  !
  interface
    subroutine mdump(error)
      use gbl_message
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Display the memory usage of the various Class buffers. For
      ! debugging purpose
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine mdump
  end interface
  !
  interface
    subroutine redsky(line,r,error)
      use gbl_message
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !   Reduce a skydip. Compute the starting atmospheric model.
      !----------------------------------------------------------------------
      character(len=*),  intent(in)    :: line  ! Input command line
      type(observation), intent(inout) :: r     !
      logical,           intent(inout) :: error ! Error flag
    end subroutine redsky
  end interface
  !
  interface
    subroutine fitsky(fcn,liter,ier,meancho)
      use gbl_message
      use fit_minuit
      !----------------------------------------------------------------------
      ! @ private
      !  Setup and starts a SKYDIP fit minimisation using MINUIT
      !----------------------------------------------------------------------
      external             :: fcn      ! Function to be mininized
      logical, intent(in)  :: liter    ! Logical of iterate fit
      integer, intent(out) :: ier      ! Error flag
      real,    intent(in)  :: meancho  !
    end subroutine fitsky
  end interface
  !
  interface
    subroutine midsky(fit,ier,liter)
      use gbl_message
      use fit_minuit
      !----------------------------------------------------------------------
      ! @ private
      ! RED Internal routine
      !   Start a SKYDIP fit by building the PAR array and internal
      !    variable used by Minuit.
      !   Parameters are
      !    PAR(1) = RFOEFF Forward efficiency
      !     or      RTREC  Receiver temperature
      !    PAR(2) = RH2OMM Water vapor amount (mm)
      !----------------------------------------------------------------------
      type(fit_minuit_t), intent(inout) :: fit    ! Fitting variables
      integer,            intent(out)   :: ier    ! Error code
      logical,            intent(in)    :: liter  ! Iterate a fit
    end subroutine midsky
  end interface
  !
  interface
    subroutine minsky(npar,grad,sqsum,x,iflag)
      !----------------------------------------------------------------------
      ! @ private-mandatory
      ! RED Internal routine
      !   Function to be minimized in the SKYDIP.
      !----------------------------------------------------------------------
      integer, intent(in)  :: npar        ! Number of parameters
      real(8), intent(out) :: grad(npar)  ! Array of derivatives
      real(8), intent(out) :: sqsum       ! Sum of the square distances to the data points
      real(8), intent(in)  :: x(npar)     ! Parameter values
      integer, intent(in)  :: iflag       ! Code operation
    end subroutine minsky
  end interface
  !
  interface
    subroutine fsky(eleva,npar,params,dograd,airmass,yy,dyy)
      use phys_const
      !----------------------------------------------------------------------
      ! @ private
      ! RED Internal routine
      !   Compute sky emission
      !----------------------------------------------------------------------
      real,    intent(in)  :: eleva         ! Elevation in degrees
      integer, intent(in)  :: npar          ! Number of parameters (forward_eff, wh2o,...)
      real(8), intent(in)  :: params(npar)  ! Values of parameters
      logical, intent(in)  :: dograd        ! Compute the gradient
      real,    intent(out) :: airmass       ! Number of airmasses
      real(8), intent(out) :: yy            ! Emissivity (Kelvins)
      real(8), intent(out) :: dyy(npar)     ! Derivate value according to each parameter
    end subroutine fsky
  end interface
  !
  interface
    subroutine classcore_fold_obs_sub(set,data1,data2,inchan,bad,nphase,throw,  &
      weight,keepblank,odata1,odataw,onchan,omin,omax,shift,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Two main use cases:
      ! 1) 1 data spectrum to be folded for N phases,
      ! 2) N data spectra  to be folded for N phases
      ! Ideally we should receive a 'data(Nchan,Nspec)' array, and compare
      ! Nspec to Nphase. However this is not programmer friendly as long
      ! as we can not avoid duplicating the data in the case 1, i.e. we can
      ! not write before entering here:
      !   data(:,1) => obs%spectre
      ! This is pointer reshape and this is not supported by gfortran 4.4
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)         :: set             !
      integer(kind=4),     intent(in)         :: inchan          ! Input number of channels
      real(kind=4),        intent(in), target :: data1(inchan)   ! Input data (phase1)
      real(kind=4),        intent(in), target :: data2(inchan)   ! Input data (phase2)
      real(kind=4),        intent(in)         :: bad             ! Blanking value
      integer(kind=4),     intent(in)         :: nphase          ! Number of phases
      real(kind=4),        intent(in)         :: throw(nphase)   ! [chan] Can be non-int, can be negative
      real(kind=4),        intent(in)         :: weight(nphase)  ! Phase weight
      logical,             intent(in)         :: keepblank       ! Keep blank channels at boundaries?
      integer(kind=4),     intent(in)         :: onchan          ! Size of output arrays
      real(kind=4),        intent(out)        :: odata1(onchan)  ! Output data
      real(kind=4),        intent(out)        :: odataw(onchan)  ! Output weight
      integer(kind=4),     intent(out)        :: omin,omax       ! Useful part of odata1(:) in return
      integer(kind=4),     intent(out)        :: shift           ! By how many channels the idata and odata axes are shifted?
      logical,             intent(inout)      :: error           ! Logical error flag
    end subroutine classcore_fold_obs_sub
  end interface
  !
  interface
    subroutine resample_parse_command(line,iopt,rname,ref,new,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Parse resample parameters from command line
      !
      !  If frequency resampling, take care that the new resolution is
      ! returned in the current (usually observatory) frame of the reference
      ! header. BUT if the user invokes the command with an explicit value
      ! (i.e. something different from * or =), it is assumed to be given in
      ! the rest frame, and will be converted to the current frame. The idea
      ! behind this is that RESAMPLE does not modify the spectrum frame, but
      ! the user can RESAMPLE a serie of spectra to the same REST frequency
      ! resolution.
      !
      ! Default channel shapes and widths for 30-m (AOS unaccounted for)
      ! Shape is TPAR for telescopes other than the 30m
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Command line
      integer(kind=4),  intent(in)    :: iopt   ! Number of the RESAMPLE option
      character(len=*), intent(in)    :: rname  ! Calling routine name
      type(header),     intent(in)    :: ref    ! Reference header
      type(resampling), intent(out)   :: new    ! New definition of X-axis sampling
      logical,          intent(inout) :: error  ! Error flag
    end subroutine resample_parse_command
  end interface
  !
  interface
    subroutine resample_parse_like(rname,line,iopt,new,error)
      use gbl_message
      use image_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Parse /LIKE GDFFile option and setup a resampling structure
      ! according to the GDF header (can be an LMV cube or a UVT)
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname  ! Calling routine name
      character(len=*), intent(in)    :: line   ! Command line
      integer(kind=4),  intent(in)    :: iopt   ! Option number
      type(resampling), intent(out)   :: new    ! New definition of X-axis sampling
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine resample_parse_like
  end interface
  !
  interface
    function channel_shape(teles)
      !---------------------------------------------------------------------
      ! @ private
      ! Return the channel shape given the telescope name.
      ! Test is not very robust as PI often temper with the telescope name
      ! to get other information like the used backend, the OTF scanning
      ! direction...
      !---------------------------------------------------------------------
      character(len=4) :: channel_shape  ! Function value on return
      character(len=*), intent(in) :: teles  ! Telescope name
    end function channel_shape
  end interface
  !
  interface
    subroutine do_resample(set,obs,new_in,dofft,error)
      use gildas_def
      use phys_const
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Resample the observation
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set     !
      type(observation),   intent(inout) :: obs     ! Observation before and after resampling
      type(resampling),    intent(in)    :: new_in  ! New definition of X-axis sampling
      logical,             intent(in)    :: dofft   ! In frequency or time domain (the default)
      logical,             intent(out)   :: error   ! Error flag
    end subroutine do_resample
  end interface
  !
  interface
    subroutine do_resample_sub(set,obs,old,new,dofft,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    !
      type(resampling),    intent(in)    :: old    ! Old X-axis sampling
      type(resampling),    intent(inout) :: new    ! New X-axis sampling (increment can be updated)
      logical,             intent(in)    :: dofft  ! In frequency or time domain (the default)
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine do_resample_sub
  end interface
  !
  interface
    subroutine do_resample_generic(set,idatax,idatay,odatay,odataw,bad,isirreg,  &
      old,new,dofft,error)
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Resample any kind of array
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set        !
      real(kind=xdata_kind), intent(in)    :: idatax(:)  !
      real(kind=4),          intent(in)    :: idatay(:)  !
      real(kind=4),          intent(out)   :: odatay(:)  !
      real(kind=4),          intent(out)   :: odataw(:)  !
      real(kind=4),          intent(in)    :: bad        !
      logical,               intent(inout) :: isirreg    ! Is X axis regularly sampled?
      type(resampling),      intent(in)    :: old        ! Old X-axis sampling
      type(resampling),      intent(inout) :: new        ! New X-axis sampling
      logical,               intent(in)    :: dofft      !
      logical,               intent(inout) :: error      ! Logical error flag
    end subroutine do_resample_generic
  end interface
  !
  interface
    subroutine do_resample_fft(idatay,odatay,bad,isirreg,irmin,irmax,  &
      old_in,new_in,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! FFT resampling on a regularly spaced axis
      !---------------------------------------------------------------------
      real(kind=4),         intent(in)    :: idatay(:)  ! Size old%nchan
      real(kind=4), target, intent(out)   :: odatay(:)  ! Size new%nchan
      real(kind=4),         intent(in)    :: bad        !
      logical,              intent(in)    :: isirreg    !
      integer(kind=4),      intent(in)    :: irmin      ! First input channel to be used
      integer(kind=4),      intent(in)    :: irmax      ! Last input channel to be used
      type(resampling),     intent(in)    :: old_in     ! Old X-axis sampling
      type(resampling),     intent(inout) :: new_in     ! New X-axis sampling
      logical,              intent(inout) :: error      ! Logical error flag
    end subroutine do_resample_fft
  end interface
  !
  interface
    subroutine do_resample_direct(set,idatax,idatay,odatay,odataw,bad,  &
      isirreg,old,new,error)
      use gbl_message
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Direct interpolation
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set        !
      real(kind=xdata_kind), intent(in)    :: idatax(:)  ! Size old%nchan
      real(kind=4),          intent(in)    :: idatay(:)  ! Size old%nchan
      real(kind=4),          intent(out)   :: odatay(:)  ! Size new%nchan
      real(kind=4),          intent(out)   :: odataw(:)  ! Size new%nchan
      real(kind=4),          intent(in)    :: bad        !
      logical,               intent(inout) :: isirreg    ! Is X axis regularly sampled?
      type(resampling),      intent(in)    :: old        ! Old X-axis sampling
      type(resampling),      intent(in)    :: new        ! New X-axis sampling
      logical,               intent(inout) :: error      ! Logical error flag
    end subroutine do_resample_direct
  end interface
  !
  interface
    subroutine do_resample_nointersecterror_regul(old,new)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(resampling), intent(in) :: old  ! Old X-axis sampling
      type(resampling), intent(in) :: new  ! New X-axis sampling
    end subroutine do_resample_nointersecterror_regul
  end interface
  !
  interface
    subroutine do_resample_nointersecterror_irreg(rdatax,rnchan,new)
      use gbl_message
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      real(xdata_kind), intent(in) :: rdatax(:)  ! Old irregular X-axis
      integer(kind=4),  intent(in) :: rnchan     ! Number of channels
      type(resampling), intent(in) :: new        ! New X-axis sampling
    end subroutine do_resample_nointersecterror_irreg
  end interface
  !
  interface
    subroutine fft_interpolate(y,old,x,new,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Performs the interpolation/integration, using FFT.
      ! SHAPE: Channel shape in TBox, TParabola, FBox or Ftriangle
      !  TBox means a box in delay space          (unsmoothed correlator, w=1)
      !  Ppar means a parabola in delay space     (smoothed correlator, w=1)
      !  FBox means a box in frequency space      (square filter, w=0.5)
      !  FTri means a triangle in frequency space (Hanning smoothed square filter, w=1)
      !---------------------------------------------------------------------
      real(kind=4),     intent(in)    :: y(:)     ! Input spectrum
      type(resampling), intent(in)    :: old      ! Old axis description
      real(kind=4),     intent(out)   :: x(:)     ! Output spectrum
      type(resampling), intent(inout) :: new      ! New axis description (increment can be rounded)
      logical,          intent(inout) :: error    ! Logical error flag
    end subroutine fft_interpolate
  end interface
  !
  interface
    subroutine fft_offset(x,nc,z)
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      ! Offset by x channels
      !---------------------------------------------------------------------
      real,    intent(in)    :: x     ! offset by x channels
      integer, intent(in)    :: nc    ! Dimension of input array
      complex, intent(inout) :: z(nc) ! Input array
    end subroutine fft_offset
  end interface
  !
  interface
    subroutine fft_normalize(n,z)
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer, intent(in)    :: n    ! Dimension of input array
      complex, intent(inout) :: z(n) ! Input array
    end subroutine fft_normalize
  end interface
  !
  interface
    subroutine fft_reconv(n,y,w,shape)
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer,          intent(in)    :: n     ! Dimension of input array
      complex,          intent(inout) :: y(n)  ! Input array
      real,             intent(in)    :: w     ! width (in terms of channel separation)
      character(len=*), intent(in)    :: shape ! Convolution function
    end subroutine fft_reconv
  end interface
  !
  interface
    subroutine fft_deconv(n,y,w,shape)
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer,          intent(in)    :: n     ! Dimension of input array
      complex,          intent(inout) :: y(n)  ! Input array
      real,             intent(in)    :: w     ! width (in terms of channel separation)
      character(len=*), intent(in)    :: shape ! Convolution function
    end subroutine fft_deconv
  end interface
  !
  interface
    subroutine reverse(n,r)
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer, intent(in)    :: n
      complex, intent(inout) :: r(n)
    end subroutine reverse
  end interface
  !
  interface
    subroutine fft_extend(c,n,m)
      !---------------------------------------------------------------------
      ! @ private
      ! complete FFT with zeroes in high frequencies
      !   c[1:n/2]       : not touched
      !   c[n/2+1:m-n/2] = 0.
      !   c[m-n/2+1:m]   = c[n/2+1:n]
      !---------------------------------------------------------------------
      integer, intent(in)    :: n    ! Former dimension
      integer, intent(in)    :: m    ! New dimension
      complex, intent(inout) :: c(m) ! New array
    end subroutine fft_extend
  end interface
  !
  interface
    subroutine fft_cutoff(c,m,n)
      !---------------------------------------------------------------------
      ! @ private
      ! Cutoff FFT in high frequencies
      !---------------------------------------------------------------------
      integer, intent(in)    :: n    ! Former dimension
      integer, intent(in)    :: m    ! New dimension
      complex, intent(inout) :: c(m) ! New array
    end subroutine fft_cutoff
  end interface
  !
  interface
    subroutine resample_interpolate_range(old,new,edges,ismin,ismax,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the range of channels to be updated in the output spectrum
      !---------------------------------------------------------------------
      type(resampling), intent(in)    :: old     ! Old X axis description
      type(resampling), intent(in)    :: new     ! New X axis description
      logical,          intent(in)    :: edges   ! Should we consider the edges?
      integer(kind=4),  intent(out)   :: ismin   ! Output channel range (min)
      integer(kind=4),  intent(out)   :: ismax   ! Output channel range (max)
      logical,          intent(inout) :: error   ! Logical error flag
    end subroutine resample_interpolate_range
  end interface
  !
  interface
    subroutine resample_interpolate_regul(set,                     &
                                          rdata1,rdataw,rbad,old,  &
                                          sdata1,sdataw,sbad,new,  &
                                          ismin,ismax,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Main entry point for over- or under-sampling of a regularly
      ! spaced spectrum.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(in)    :: rdata1(:)  ! Input spectrum
      real(kind=4),        intent(in)    :: rdataw(:)  ! Input weights
      real(kind=4),        intent(in)    :: rbad       ! Input bad value
      type(resampling),    intent(in)    :: old        ! Old axis description
      real(kind=4),        intent(out)   :: sdata1(:)  ! Output spectrum
      real(kind=4),        intent(out)   :: sdataw(:)  ! Output weights
      real(kind=4),        intent(in)    :: sbad       ! Output bad value
      type(resampling),    intent(in)    :: new        ! New axis description
      integer(kind=4),     intent(out)   :: ismin      ! Range of channels updated in...
      integer(kind=4),     intent(out)   :: ismax      ! ... the output spectrum.
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate_regul
  end interface
  !
  interface
    subroutine resample_interpolate3_under(set,                     &
                                           rdata1,rdataw,rbad,old,  &
                                           sdata1,sdataw,sbad,new,  &
                                           ismin,ismax,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  3 points undersampling routine.
      !  Performs the linear interpolation/integration.
      !  This routine integrates in a square output channel passband (width
      ! sinc) the piecewise linear interpolation of the original data.
      !   As a result the integration is always on 3 points (hence the name)
      ! and the effective resolution is degraded if the input spectrum was
      ! undersampled.
      !
      ! This is what is needed e.g. for square channel responses in the
      ! frequency domain (fbox) i.e. approximation of filter channels of
      ! separation equal to their width.
      ! * There is no restriction on the output range compared to the input
      !   range (i.e. output can be too large, overlap, or be off limits).
      !   For efficiency purpose, only the intersection is updated, and the
      !   channel range which is updated is returned in 2 variables. It is
      !   up to the caller to do something (or not) out of this range.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(in)    :: rdata1(:)  ! Input spectrum
      real(kind=4),        intent(in)    :: rdataw(:)  ! Input weights
      real(kind=4),        intent(in)    :: rbad       ! Input bad value
      type(resampling),    intent(in)    :: old        ! Old axis description
      real(kind=4),        intent(out)   :: sdata1(:)  ! Output spectrum
      real(kind=4),        intent(out)   :: sdataw(:)  ! Output weights
      real(kind=4),        intent(in)    :: sbad       ! Output bad value
      type(resampling),    intent(in)    :: new        ! New axis description
      integer(kind=4),     intent(out)   :: ismin      ! Range of channels updated in...
      integer(kind=4),     intent(out)   :: ismax      ! ... the output spectrum.
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate3_under
  end interface
  !
  interface
    subroutine resample_interpolate3_over(set,                     &
                                          rdata1,rdataw,rbad,old,  &
                                          sdata1,sdataw,sbad,new,  &
                                          ismin,ismax,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  3 points oversampling routine.
      !  Performs the linear interpolation/integration.
      !  This routine integrates in a square output channel passband (width
      ! sinc) the piecewise linear interpolation of the original data.
      !   As a result the integration is always on 3 points (hence the name)
      ! and the effective resolution is degraded if the input spectrum was
      ! undersampled.
      !
      ! This is what is needed e.g. for square channel responses in the
      ! frequency domain (fbox) i.e. approximation of filter channels of
      ! separation equal to their width.
      ! * There is no restriction on the output range compared to the input
      !   range (i.e. output can be too large, overlap, or be off limits).
      !   For efficiency purpose, only the intersection is updated, and the
      !   channel range which is updated is returned in 2 variables. It is
      !   up to the caller to do something (or not) out of this range.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(in)    :: rdata1(:)  ! Input spectrum
      real(kind=4),        intent(in)    :: rdataw(:)  ! Input weights
      real(kind=4),        intent(in)    :: rbad       ! Input bad value
      type(resampling),    intent(in)    :: old        ! Old axis description
      real(kind=4),        intent(out)   :: sdata1(:)  ! Output spectrum
      real(kind=4),        intent(out)   :: sdataw(:)  ! Output weights
      real(kind=4),        intent(in)    :: sbad       ! Output bad value
      type(resampling),    intent(in)    :: new        ! New axis description
      integer(kind=4),     intent(out)   :: ismin      ! Range of channels updated in...
      integer(kind=4),     intent(out)   :: ismax      ! ... the output spectrum.
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate3_over
  end interface
  !
  interface
    subroutine resample_interpolate2_under(set,                     &
                                           rdata1,rdataw,rbad,old,  &
                                           sdata1,sdataw,sbad,new,  &
                                           ismin,ismax,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   2 points undersampling routine (i.e. reso(out) >= reso(in)).
      ! * This resampling engine is generic enough to work without
      !   knowing the X unit. This means in particular that the input
      !   resolutions must be in same units and same referential, e.g.
      !   if unit is frequency the Doppler must be identical OR the
      !   resolution must be provided in the LSR frame. Also if unit is
      !   offset frequency, take care that the 2 axes must have the same
      !   rest frequencies.
      ! * The engine assumes a linear representation of the axis, i.e. it
      !   can be described with:
      !     X(ichan) = (ichan-Xref)*Xinc+Xval
      ! * No global variables here (i.e. multithreading is possible)
      ! * Input weights must have been computed *before* resampling, since
      !   resampling also affect the output weights.
      ! * Blanked channels propagates or not in output sum according to SET
      !   BAD.
      ! * Output channels with 0 weights are *not* yet blanked: it is up to
      !   the caller to blank them or not depending on what it does with
      !   such channels. This is because 'no data' is not the same as 'bad
      !   data'.
      ! * There is no restriction on the output range compared to the input
      !   range (i.e. output can be too large, overlap, or be off limits).
      !   For efficiency purpose, only the intersection is updated, and the
      !   channel range which is updated is returned in 2 variables. It is
      !   up to the caller to do something (or not) out of this range.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(in)    :: rdata1(:)  ! Input values
      real(kind=4),        intent(in)    :: rdataw(:)  ! Input weights
      real(kind=4),        intent(in)    :: rbad       ! Input bad value
      type(resampling),    intent(in)    :: old        ! Old axis description
      real(kind=4),        intent(out)   :: sdata1(:)  ! Output values
      real(kind=4),        intent(out)   :: sdataw(:)  ! Output weights
      real(kind=4),        intent(in)    :: sbad       ! Output bad value
      type(resampling),    intent(in)    :: new        ! New axis description
      integer(kind=4),     intent(out)   :: ismin      ! Range of channels updated in...
      integer(kind=4),     intent(out)   :: ismax      ! ... the output spectrum.
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate2_under
  end interface
  !
  interface
    subroutine resample_interpolate2_over(set,                     &
                                          rdata1,rdataw,rbad,old,  &
                                          sdata1,sdataw,sbad,new,  &
                                          ismin,ismax,error)
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   2 points oversampling routine (i.e. reso(out) >= reso(in)).
      ! * This resampling engine is generic enough to work without
      !   knowing the X unit. This means in particular that the input
      !   resolutions must be in same units and same referential, e.g.
      !   if unit is frequency the Doppler must be identical OR the
      !   resolution must be provided in the LSR frame. Also if unit is
      !   offset frequency, take care that the 2 axes must have the same
      !   rest frequencies.
      ! * The engine assumes a linear representation of the axis, i.e. it
      !   can be described with:
      !     X(ichan) = (ichan-Xref)*Xinc+Xval
      ! * No global variables here (i.e. multithreading is possible)
      ! * Input weights must have been computed *before* resampling, since
      !   resampling also affect the output weights.
      ! * Blanked channels propagates or not in output sum according to SET
      !   BAD.
      ! * Output channels with 0 weights are *not* yet blanked: it is up to
      !   the caller to blank them or not depending on what it does with
      !   such channels. This is because 'no data' is not the same as 'bad
      !   data'.
      ! * There is no restriction on the output range compared to the input
      !   range (i.e. output can be too large, overlap, or be off limits).
      !   For efficiency purpose, only the intersection is updated, and the
      !   channel range which is updated is returned in 2 variables. It is
      !   up to the caller to do something (or not) out of this range.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(in)    :: rdata1(:)  ! Input values
      real(kind=4),        intent(in)    :: rdataw(:)  ! Input weights
      real(kind=4),        intent(in)    :: rbad       ! Input bad value
      type(resampling),    intent(in)    :: old        ! Old axis description
      real(kind=4),        intent(out)   :: sdata1(:)  ! Output values
      real(kind=4),        intent(out)   :: sdataw(:)  ! Output weights
      real(kind=4),        intent(in)    :: sbad       ! Input bad value
      type(resampling),    intent(in)    :: new        ! New axis description
      integer(kind=4),     intent(out)   :: ismin      ! Range of channels updated in...
      integer(kind=4),     intent(out)   :: ismax      ! ... the output spectrum.
      logical,             intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate2_over
  end interface
  !
  interface
    subroutine resample_interpolate_irreg(set,                        &
                                          rdatax,rdata1,rbad,rnchan,  &
                                          sdata1,sdataw,sbad,new,     &
                                          error)
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Performs the linear interpolation/integration to resample on a
      ! Regular Grid. Edge handling should be improved one day
      ! * There is no restriction on the output range compared to the input
      !   range (i.e. output can be too large, overlap, or be off limits).
      !   For efficiency purpose, only the intersection is updated, and the
      !   channel range which is updated is returned in 2 variables. It is
      !   up to the caller to do something (or not) out of this range.
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set        !
      real(kind=xdata_kind), intent(in)    :: rdatax(:)  ! Input abscissa
      real(kind=4),          intent(in)    :: rdata1(:)  ! Input spectrum
      real(kind=4),          intent(in)    :: rbad       ! Input bad value
      integer(kind=4),       intent(in)    :: rnchan     ! Input spectrum size
      real(kind=4),          intent(out)   :: sdata1(:)  ! Output spectrum
      real(kind=4),          intent(out)   :: sdataw(:)  ! Output weight
      real(kind=4),          intent(in)    :: sbad       ! Output bad value
      type(resampling),      intent(in)    :: new        ! Output axis
      logical,               intent(inout) :: error      ! Logical error flag
    end subroutine resample_interpolate_irreg
  end interface
  !
  interface
    subroutine pfactor(n,p)
      !---------------------------------------------------------------------
      ! @ private
      ! Returns in p the largest prime factor in n
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)  :: n
      integer(kind=4), intent(out) :: p
    end subroutine pfactor
  end interface
  !
  interface
    function prime(n,p)
      !---------------------------------------------------------------------
      ! @ private
      ! Find if n is prime, returns the smallest integer divisor p.
      !---------------------------------------------------------------------
      logical :: prime  ! Function value on return
      integer(kind=4), intent(in)  :: n  !
      integer(kind=4), intent(out) :: p  !
    end function prime
  end interface
  !
  interface
    subroutine rheader(set,obs,entry_num,user_function,error,readsec_in)
      use gbl_message
      use gbl_constant
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Reset the observation and read all present header sections by
      ! default, or read a subset if optional argument is present.
      !----------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set                    !
      type(observation),          intent(inout) :: obs                    !
      integer(kind=entry_length), intent(in)    :: entry_num              !
      logical,                    intent(out)   :: error                  !
      logical,                    external      :: user_function          !
      logical, optional,          intent(in)    :: readsec_in(-mx_sec:0)  !
    end subroutine rheader
  end interface
  !
  interface
    subroutine rheader_sub(set,obs,readsec_in,error)
      use gbl_constant
      use gbl_message
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !  Read only the requested sections (if they exist)
      ! FixMe:
      !   - rename this subroutine!
      !   - use a specific type instead of "readsec_in(-mx_sec:0)"
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set                    !
      type(observation),   intent(inout) :: obs                    !
      logical,             intent(in)    :: readsec_in(-mx_sec:0)  !
      logical,             intent(inout) :: error                  ! Logical error flag
    end subroutine rheader_sub
  end interface
  !
  interface
    subroutine rix(entry_num,ind,error)
      use gbl_message
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      ! Read an Entry Index in the input file
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)  :: entry_num  ! Entry number
      type(indx_t),               intent(out) :: ind        !
      logical,                    intent(out) :: error      ! Logical error flag
    end subroutine rix
  end interface
  !
  interface
    subroutine rox(entry_num,ind,error)
      use gbl_message
      use class_common
      use class_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      ! Read an Entry Index in the output file
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)  :: entry_num  ! Entry number
      type(indx_t),               intent(out) :: ind        !
      logical,                    intent(out) :: error      ! Logical errror flag
    end subroutine rox
  end interface
  !
  interface
    subroutine wox(ind,error)
      use gbl_message
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Write a new Entry Index in the output file
      !---------------------------------------------------------------------
      type(indx_t), intent(in)    :: ind    !
      logical,      intent(inout) :: error  !
    end subroutine wox
  end interface
  !
  interface
    subroutine mox(entry_num,ind,error)
      use gbl_message
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! Modify an old Entry Index in the output file
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: entry_num  !
      type(indx_t),               intent(in)    :: ind        !
      logical,                    intent(inout) :: error      !
    end subroutine mox
  end interface
  !
  interface
    subroutine cox(error)
      use gbl_convert
      use class_common
      !---------------------------------------------------------------------
      ! @ private
      ! Close an observation in the output file index
      !---------------------------------------------------------------------
      logical, intent(out) :: error
    end subroutine cox
  end interface
  !
  interface
    subroutine robs(obs,entry_num,error)
      use class_common
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Read file header into internal buffer. Then fill into the
      ! observation header the presec section and part of the general
      ! sections, namely the elements coming from the Entry Index:
      !     obs%head%gen%num
      !     obs%head%gen%ver
      !     obs%head%pos%sourc
      !     obs%head%spe%line/obs%head%sky%line
      !     obs%head%gen%teles
      !     obs%head%gen%dobs
      !     obs%head%gen%dred
      !     obs%head%pos%lamof
      !     obs%head%pos%betof
      !     obs%head%pos%system
      !     obs%head%gen%kind
      !     obs%head%gen%qual
      !     obs%head%gen%scan
      !     obs%head%dri%apos
      !     obs%head%gen%subscan
      !----------------------------------------------------------------------
      type(observation),          intent(inout) :: obs        ! Observation header
      integer(kind=entry_length), intent(in)    :: entry_num  ! Index number of observation
      logical,                    intent(out)   :: error      !
    end subroutine robs
  end interface
  !
  interface
    subroutine class_entrydesc_read(rname,file,idx,entry_num,ed,bufobs,error)
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read the entry descriptor. Class overlay to the Classic subroutine
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: rname      ! Calling routine name
      type(classic_file_t),       intent(in)    :: file       ! Class file
      type(optimize),             intent(in)    :: idx        ! Associated index
      integer(kind=entry_length), intent(in)    :: entry_num  ! Entry number
      type(classic_entrydesc_t),  intent(out)   :: ed         ! Entry descriptor
      type(classic_recordbuf_t),  intent(inout) :: bufobs     ! Working buffer
      logical,                    intent(inout) :: error      ! Logical error flag
    end subroutine class_entrydesc_read
  end interface
  !
  interface
    subroutine mobs(obs,error)
      use gbl_message
      use class_types
      use class_common
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      !  Open an observation of the output file to modify it. The length of
      ! each section modified must be smaller than the length of the
      ! corresponding section already present.
      !  Find the latest version of this obs. in this file
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs    ! Observation header
      logical,           intent(out)   :: error  ! Logical error flag
    end subroutine mobs
  end interface
  !
  interface
    subroutine cobs(set,obs,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_common
      use class_index
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Ends the writing of the output observation.
      !  Find the latest version of this observation in the file and
      ! decrease its version number by 32768
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! Observation header
      logical,             intent(out)   :: error  ! Logical error flag
    end subroutine cobs
  end interface
  !
  interface
    subroutine rsec(ed,ksec,lsec,sec,error)
      use gbl_message
      use classic_api
      use class_common
      !----------------------------------------------------------------------
      ! @ private
      !  Read a section in the input observation
      !----------------------------------------------------------------------
      type(classic_entrydesc_t), intent(in)    :: ed      ! Entry Descriptor
      integer(kind=4),           intent(in)    :: ksec    ! Section number
      integer(kind=8),           intent(inout) :: lsec    ! Maximum and actual length of section
      integer(kind=4),           intent(out)   :: sec(*)  ! Section buffer
      logical,                   intent(out)   :: error   ! Error flag
    end subroutine rsec
  end interface
  !
  interface
    subroutine wsec(ed,ksec,lsec,sec,error)
      use gbl_message
      use classic_api
      use class_common
      !----------------------------------------------------------------------
      ! @ private
      !  Write a section to the output file
      !----------------------------------------------------------------------
      type(classic_entrydesc_t), intent(inout) :: ed      ! Entry Descriptor
      integer(kind=4),           intent(in)    :: ksec    ! Section number
      integer(kind=8),           intent(in)    :: lsec    ! Maximum and actual length of section
      integer(kind=4),           intent(in)    :: sec(*)  ! Section buffer
      logical,                   intent(out)   :: error   ! Error flag
    end subroutine wsec
  end interface
  !
  interface
    subroutine init_obs(obs)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! Initialize an observation
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
    end subroutine init_obs
  end interface
  !
  interface
    subroutine free_obs(obs)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      ! Free an Observation
      ! Must not touch the Header, which may have been previously defined
      !-------------------------------------------------------------------
      type(observation), intent(inout) :: obs
    end subroutine free_obs
  end interface
  !
  interface
    subroutine rzero(obs,code,user_function)
      use gbl_constant
      use gbl_message
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Reset an observation to default values
      !----------------------------------------------------------------------
      type(observation), intent(inout) :: obs            !
      character(len=*),  intent(in)    :: code           ! KEEP or FREE or NULL
      logical,           external      :: user_function  !
    end subroutine rzero
  end interface
  !
  interface
    function obs_firstgood(data,nc,bad)
      !---------------------------------------------------------------------
      ! @ private
      !  Return the first non-bad channel
      !---------------------------------------------------------------------
      integer(kind=4) :: obs_firstgood  ! Function value on return
      real(kind=4),    intent(in) :: data(*)  ! Data array
      integer(kind=4), intent(in) :: nc       ! Size of data
      real(kind=4),    intent(in) :: bad      ! Bad value
    end function obs_firstgood
  end interface
  !
  interface
    function obs_lastgood(data,nc,bad)
      !---------------------------------------------------------------------
      ! @ private
      !  Return the last non-bad channel
      !---------------------------------------------------------------------
      integer(kind=4) :: obs_lastgood  ! Function value on return
      real(kind=4),    intent(in) :: data(*)  ! Data array
      integer(kind=4), intent(in) :: nc       ! Size of data
      real(kind=4),    intent(in) :: bad      ! Bad value
    end function obs_lastgood
  end interface
  !
  interface
    function obs_fillin(r,ival,imin,imax,bad)
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate bad channel (if possible)
      !---------------------------------------------------------------------
      real(kind=4) :: obs_fillin  ! Function value on return
      integer(kind=4), intent(in) :: ival    ! Channel number
      integer(kind=4), intent(in) :: imin    ! First Channel number
      integer(kind=4), intent(in) :: imax    ! Last Channel number
      real(kind=4),    intent(in) :: r(imax) !
      real(kind=4),    intent(in) :: bad     !
    end function obs_fillin
  end interface
  !
  interface
    function obs_system(itype)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      !  Return the Type of Coordinates as a character*2 string
      !---------------------------------------------------------------------
      character(len=4) :: obs_system
      integer(kind=4), intent(in) :: itype
    end function obs_system
  end interface
  !
  interface
    function obs_typev(itype)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      !  Return the Type of Velocity as a character*4 string
      !---------------------------------------------------------------------
      character(len=4) :: obs_typev
      integer(kind=4), intent(in) :: itype
    end function obs_typev
  end interface
  !
  interface
    function obs_projection(iproj)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      !  Return the Type of Projection as a character*4 string
      !---------------------------------------------------------------------
      character(len=4) :: obs_projection
      integer(kind=4), intent(in) :: iproj
    end function obs_projection
  end interface
  !
  interface
    function obs_swmod(swmod)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      !  Return the switching mode as a character*17 string
      !---------------------------------------------------------------------
      character(len=17) :: obs_swmod
      integer(kind=4), intent(in) :: swmod
    end function obs_swmod
  end interface
  !
  interface
    subroutine obs_weight_sigma(rname,obs,w,error,verbose)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Compute the spectrum weight from sigma (baseline rms), with the
      ! appropriate sanity checks
      !  Note the 1e-6 extra factor which is added to match the [s.MHz/K^2]
      ! units of the time weight. obs%head%bas%sigfi is the RY RMS, i.e.
      ! same unit as RY (usually K), and 1 MHz is 1e6 s^-1.
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: rname    ! Calling routine name
      type(observation), intent(in)    :: obs      !
      real(kind=4),      intent(out)   :: w        ! [1-e6/K^2]
      logical,           intent(inout) :: error    !
      logical, optional, intent(in)    :: verbose  ! Default true
    end subroutine obs_weight_sigma
  end interface
  !
  interface
    subroutine obs_tsys_time(rname,obs,w,error,verbose)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Compute the spectrum Tsys from time, fres, and input weight, with
      ! the appropriate sanity checks.
      ! ---
      !  This is the obs_weight_time inverse function.
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: rname    ! Calling routine name
      type(observation), intent(inout) :: obs      ! Tsys changed inplace
      real(kind=8),      intent(in)    :: w        ! [s.MHz/K^2]
      logical,           intent(inout) :: error    ! Logical error flag
      logical, optional, intent(in)    :: verbose  ! Default true
    end subroutine obs_tsys_time
  end interface
  !
  interface obs_yunit
    function obs_yunit_tostr(code)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private-generic obs_yunit
      !  Convert a Y unit code to a human readable string
      !---------------------------------------------------------------------
      character(len=8) :: obs_yunit_tostr  ! Function value on return
      integer(kind=4), intent(in) :: code
    end function obs_yunit_tostr
    function obs_yunit_fromstr(string)
      use gbl_message
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private-generic obs_yunit
      !  Convert a Y unit string to Class internal code
      !---------------------------------------------------------------------
      integer(kind=4) :: obs_yunit_fromstr  ! Function value on return
      character(len=*), intent(in) :: string
    end function obs_yunit_fromstr
  end interface obs_yunit
  !
  interface
    subroutine sas_save(set,lun,error)
      use gbl_constant
      use class_setup_new
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command:
      !    SAVE
      ! Save the current CLASS parameters on a file opend on a Logical Unit
      ! Number
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      integer(kind=4),     intent(in)    :: lun    ! Fortran Logical Unit Number to use
      logical,             intent(inout) :: error  !
    end subroutine sas_save
  end interface
  !
  interface
    subroutine selimx(obs,xc1,xc2,xv1,xv2,xf1,xf2,xfo,xi1,xi2,xio)
      use gildas_def
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Defines the four coordinates systems
      !---------------------------------------------------------------------
      type (observation),     intent(inout) :: obs      !
      real(kind=plot_length), intent(in)    :: xc1,xc2  ! Channel limits
      real(kind=plot_length), intent(in)    :: xv1,xv2  ! Velocity limits
      real(kind=plot_length), intent(in)    :: xf1,xf2  ! Rest frequency limits
      real(kind=8),           intent(in)    :: xfo      ! Rest frequency offset
      real(kind=plot_length), intent(in)    :: xi1,xi2  ! Image frequency limits
      real(kind=8),           intent(in)    :: xio      ! Image frequency offset
    end subroutine selimx
  end interface
  !
  interface
    subroutine obs_limits(obs)
      use gildas_def
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Defines the Min Max range of the channels to be plotted. Note that
      ! this range is also used for BASElining, be careful...
      !---------------------------------------------------------------------
      type (observation), intent(inout) :: obs
    end subroutine obs_limits
  end interface
  !
  interface
    subroutine seunitx(set,r,unit_low,unit_up,error)
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Change the current unit and modifies all parameters accordingly.
      ! If no R buffer is loaded, no error is raised.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set       !
      type(observation),   intent(inout) :: r         !
      character(len=*),    intent(in)    :: unit_low  ! Lower axis unit
      character(len=*),    intent(in)    :: unit_up   ! Upper axis unit
      logical,             intent(inout) :: error     ! Logical error flag
    end subroutine seunitx
  end interface
  !
  interface
    subroutine seunitx_wind_mask(set,r,old,new,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Update the SET WINDOW and SET MASK values according to the old and
      ! new units. Take Doppler factor correctly into account, i.e. use
      ! 'abscissa' subroutines.
      ! NB: if you plan to support irregularly spaced data, you should merge
      ! with abscissa_any2chan()
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      type(observation),   intent(inout) :: r      !
      character(len=*),    intent(in)    :: old    ! Old unit for values
      character(len=*),    intent(in)    :: new    ! New unit for values
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine seunitx_wind_mask
  end interface
  !
  interface
    subroutine gelimx(x0,x1,x2,dx,unit)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Return current limits and conversion factor in given X unit
      !---------------------------------------------------------------------
      real(kind=8),           intent(out) :: x0     ! Offset, if any
      real(kind=plot_length), intent(out) :: x1,x2  ! Range
      real(kind=plot_length), intent(out) :: dx     ! Conversion factors
      character(len=*),       intent(in)  :: unit   ! X unit
    end subroutine gelimx
  end interface
  !
  interface
    subroutine geunit(set,head,unit,unit_up)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return the current units
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set      !
      type(header),        intent(in)  :: head     !
      character(len=*),    intent(out) :: unit     ! X unit
      character(len=*),    intent(out) :: unit_up  ! X unit
    end subroutine geunit
  end interface
  !
  interface
    subroutine gulimx(x1,x2,dx)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Return the current limits in current unit
      !---------------------------------------------------------------------
      real(kind=plot_length), intent(out) ::  x1,x2  ! Conversion factors
      real(kind=plot_length), intent(out) ::  dx     ! Conversion factors
    end subroutine gulimx
  end interface
  !
  interface
    subroutine get_box(ax1,ax2,ay1,ay2)
      use gbl_message
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      ! Get box position from GreG
      !---------------------------------------------------------------------
      real(kind=plot_length), intent(out) :: ax1,ax2  !
      real(kind=plot_length), intent(out) :: ay1,ay2  !
    end subroutine get_box
  end interface
  !
  interface
    subroutine selimy(y1,y2)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Set Y limits to Y1 Y2
      !---------------------------------------------------------------------
      real(kind=plot_length), intent(in) :: y1,y2  !
    end subroutine selimy
  end interface
  !
  interface
    subroutine gelimy(y1,y2,dy)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Returns current limits in Y and conversion factor
      ! Arguments :
      !	Y1,Y2	R*4	Limits 			Output
      !	DY	R*4	Conversion factor	Output
      !---------------------------------------------------------------------
      real(kind=plot_length), intent(out) :: y1,y2  !
      real(kind=plot_length), intent(out) :: dy     !
    end subroutine gelimy
  end interface
  !
  interface
    subroutine selimy2d(y1,y2)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Set Y limits to Y1 Y2
      !---------------------------------------------------------------------
      real(kind=4), intent(in) :: y1,y2  !
    end subroutine selimy2d
  end interface
  !
  interface
    subroutine selimz(z1,z2)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Set Z limits to Z1 Z2
      !---------------------------------------------------------------------
      real(kind=plot_length), intent(in) :: z1,z2  !
    end subroutine selimz
  end interface
  !
  interface
    subroutine gelimz(z1,z2,dz)
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS	Internal routine
      !	Returns current limits in Z and conversion factor
      !---------------------------------------------------------------------
      real(kind=4), intent(out) :: z1,z2  !
      real(kind=4), intent(out) :: dz     !
    end subroutine gelimz
  end interface
  !
  interface
    subroutine las_setdef(set,error)
      use gildas_def
      use gbl_constant
      use phys_const
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !  Setup default parameters
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      logical,             intent(inout) :: error  ! Error flag
    end subroutine las_setdef
  end interface
  !
  interface
    subroutine setmod(set,line,r,error)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_setup_new
      use class_types
      use class_popup
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command
      !   SET MODE X | Y | Z | ALL [ AUTO | TOTAL | CURRENT | [Min Max] ]
      !   Computes limits and initialise plot parameters
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(inout) :: line   ! Input command line (modified on return)
      type(observation),   intent(inout) :: r      !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine setmod
  end interface
  !
  interface
    subroutine setwindow_polygon(set,line,error)
      use gildas_def
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !  SET WINDOW /POLYGON [N] [filename1...filenameN]
      ! Define the windows from 1 or several polygons.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine setwindow_polygon
  end interface
  !
  interface
    subroutine polygon2window(set,file,nfile,error)
      use gildas_def
      use gbl_message
      use gbl_constant
      use gbl_format
      use class_data
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set          !
      integer(kind=4),     intent(in)    :: nfile        ! Number of polygon files
      character(len=*),    intent(in)    :: file(nfile)  ! Polygon files
      logical,             intent(inout) :: error        !
    end subroutine polygon2window
  end interface
  !
  interface
    subroutine polygon2mask(file,nfile,m2d,poly_lim,nx,ny,error)
      use gbl_message
      use gkernel_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      !   Defines a logical mask from a list of polygon files
      !---------------------------------------------------------------------
      integer(kind=4),  intent(in)    :: nfile        ! Number of polygon files
      character(len=*), intent(in)    :: file(nfile)  ! Polygon files
      integer(kind=4),  intent(in)    :: nx,ny        ! Dimensions of 2D array
      logical,          intent(out)   :: m2d(nx,ny)   ! Resulting logical mask
      integer(kind=4),  intent(out)   :: poly_lim(4)  ! Polygon limit (for fast search)
      logical,          intent(inout) :: error        ! Logical error flag
    end subroutine polygon2mask
  end interface
  !
  interface
    subroutine setbox(set,error)
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! LAS support routine for command
      ! SET BOX L[andscape] P[ortrait]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      logical,             intent(inout) :: error  ! Error flag
    end subroutine setbox
  end interface
  !
  interface
    subroutine setregion(set,line,mw,nw,w1,w2,wtype,error)
      use gildas_def
      use gbl_constant
      use gbl_format
      use gbl_message
      use gkernel_types
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for SET WINDOW|MASK [/VARIABLE]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set     !
      character(len=*),    intent(inout) :: line    ! Command line
      integer(kind=4),     intent(in)    :: mw      ! Maximum number of regions
      integer(kind=4),     intent(out)   :: nw      ! Actual number of regions
      real(kind=4),        intent(out)   :: w1(mw)  ! Lower bounds of regions
      real(kind=4),        intent(out)   :: w2(mw)  ! Upper bounds of regions
      character(len=*),    intent(in)    :: wtype   ! Type of regions (Window or Mask)
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine setregion
  end interface
  !
  interface
    subroutine setfrequency(rname,line,optnum,argnum,freqmin,freqmax,freqsig,error)
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for commands:
      !   SET FREQUENCY Freq1 [Freq2] [SIGNAL|IMAGE]
      ! and
      !   FIND /FREQUENCY Freq1 [Freq2] [SIGNAL|IMAGE]
      !   Parse the command line to set the frequency values which will be
      ! used for the later FIND selection.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname    ! Calling routine name
      character(len=*), intent(in)    :: line     ! Command line
      integer,          intent(in)    :: optnum   ! Option number for command line parsing
      integer,          intent(in)    :: argnum   ! First argument number in the option
      real(kind=8),     intent(out)   :: freqmin  ! Minimum value found
      real(kind=8),     intent(out)   :: freqmax  ! Maximum value found
      logical,          intent(out)   :: freqsig  ! Signal or image frequency?
      logical,          intent(inout) :: error    ! Logical error flag
    end subroutine setfrequency
  end interface
  !
  interface
    subroutine setfor(set,line,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS support routine for command
      ! SET FORMAT
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(in)    :: line   !
      logical,             intent(inout) :: error  !
    end subroutine setfor
  end interface
  !
  interface
    subroutine setcheck(set,line,check,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !   SET  [NO]CHECK  [SOURCE|POSITION|OFFSET|LINE|SPECTROSCOPY|CALIBRATION|SWITCHING]
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(in)    :: line   !
      logical,             intent(in)    :: check  !
      logical,             intent(inout) :: error  !
    end subroutine setcheck
  end interface
  !
  interface
    subroutine setweight(rname,line,iopt,iarg,weight,error)
      !---------------------------------------------------------------------
      ! @ private
      !  Parse command line for TIME|SIGMA|EQUAL, and return value in a
      ! 1-character string.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname   ! Calling routine name
      character(len=*), intent(in)    :: line    ! Command line
      integer(kind=4),  intent(in)    :: iopt    ! Option number (0=command)
      integer(kind=4),  intent(in)    :: iarg    ! Argument number
      character(len=*), intent(inout) :: weight  ! Value, unchanged in case of error
      logical,          intent(inout) :: error   ! Logical error flag
    end subroutine setweight
  end interface
  !
  interface
    subroutine set_angle_factor(rname,argum,angle,fangle,error)
      use phys_const
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the angle conversion factor between 'unit' and radians.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: rname   ! Caller name
      character(len=*), intent(in)    :: argum   ! Argument to be resolved
      character(len=*), intent(inout) :: angle   ! Resolved angle
      real(kind=8),     intent(inout) :: fangle  ! Conversion factor
      logical,          intent(inout) :: error   !
    end subroutine set_angle_factor
  end interface
  !
  interface
    subroutine las_setvar(set,line,r,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !  SET VARIABLE Section_name [READ|WRITE|OFF]
      ! This commands has 2 purposes:
      !  - change the RO/RW status of the R%HEAD%Section,
      !  - create/remove aliases to this section
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(in)    :: line   !
      type(observation),   intent(inout) :: r      !
      logical,             intent(inout) :: error  !
    end subroutine las_setvar
  end interface
  !
  interface
    subroutine las_setvar_R(set,r,keywor,mode,error)
      use gildas_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Instantiate the requested section in Sic structure R%HEAD
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set     !
      type(observation),   intent(inout) :: r       !
      character(len=*),    intent(in)    :: keywor  !
      integer(kind=4),     intent(in)    :: mode    ! setvar_off/read/write
      logical,             intent(inout) :: error   !
    end subroutine las_setvar_R
  end interface
  !
  interface
    subroutine las_setvar_R_alias(code,delete,error)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Delete and/or (re)create aliases to the section elements.
      !  NB: aliases inherit the RW/RO status of their targets
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: code    ! Section code
      logical,         intent(in)    :: delete  ! Delete or create aliases?
      logical,         intent(inout) :: error   ! Logical error flag
    end subroutine las_setvar_R_alias
  end interface
  !
  interface
    subroutine class_variable_index_reset(error)
      !---------------------------------------------------------------------
      ! @ private
      !  Reset the IDX% structure in Sic, probably because something has
      ! changed in CX.
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine class_variable_index_reset
  end interface
  !
  interface
    subroutine class_variable_index_cx(error)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      !  Create the IDX% Sic structure mapping the CX arrays (always
      ! available)
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Error status
    end subroutine class_variable_index_cx
  end interface
  !
  interface
    subroutine class_variable_index(set,presec,readsec,mode,error,user_function)
      use gbl_message
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Create a section in the IDX%HEAD% Sic structure
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set                 !
      logical,             intent(in)    :: presec              ! Enable the 'present sections' array?
      logical,             intent(in)    :: readsec(-mx_sec:0)  ! Which section are to be added
      integer(kind=4),     intent(in)    :: mode                ! setvar_off/read/write
      logical,             intent(inout) :: error               !
      logical,             external      :: user_function       !
    end subroutine class_variable_index
  end interface
  !
  interface
    subroutine class_variable_index_delvar(presec,readsec,error)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Delete variables (structures) in IDX%HEAD%
      !---------------------------------------------------------------------
      logical, intent(in)    :: presec              ! Enable the 'present sections' array?
      logical, intent(in)    :: readsec(-mx_sec:0)  ! Which section are to be added
      logical, intent(inout) :: error               !
    end subroutine class_variable_index_delvar
  end interface
  !
  interface
    subroutine class_variable_index_fill(set,presec,readsec,error,user_function)
      use gbl_message
      use gkernel_types
      use class_index
      use class_parameter
      use class_sicidx
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Fill the section arrays for the IDX%HEAD% Sic structure
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set                 !
      logical,             intent(in)    :: presec              ! Enable the 'present sections' array?
      logical,             intent(in)    :: readsec(-mx_sec:0)  ! Which section are to be added
      logical,             intent(inout) :: error               !
      logical,             external      :: user_function       !
    end subroutine class_variable_index_fill
  end interface
  !
  interface
    subroutine class_variable_index_defvar(presec,readsec,error)
      use class_index
      use class_parameter
      use class_sicidx
      !---------------------------------------------------------------------
      ! @ private
      !  Create the sections in the IDX%HEAD% Sic structure
      !---------------------------------------------------------------------
      logical, intent(in)    :: presec              ! Enable the 'present sections' array?
      logical, intent(in)    :: readsec(-mx_sec:0)  ! Which section are to be added
      logical, intent(inout) :: error               !
    end subroutine class_variable_index_defvar
  end interface
  !
  interface
    subroutine class_variable_index_reallocate(presec,readsec,nent,error)
      use class_parameter
      use class_sicidx
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Reallocate (if needed) the IDX support arrays, section by section.
      !  nent <= 0 means deallocate only.
      !---------------------------------------------------------------------
      logical,         intent(in)    :: presec              ! Enable the 'present sections' array?
      logical,         intent(in)    :: readsec(-mx_sec:0)  ! Which section are to be reallocated
      integer(kind=8), intent(in)    :: nent                ! Size of reallocation
      logical,         intent(inout) :: error               ! Logical error flag
    end subroutine class_variable_index_reallocate
  end interface
  !
  interface
    subroutine class_show(set,ikey,r,error)
      use phys_const
      use gbl_constant
      use gbl_message
      use class_setup_new
      use class_fits
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS  Support routine for command
      !   SHOW ALL  | Arg1 ... ArgN
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      integer(kind=4),     intent(in)    :: ikey
      type(observation),   intent(in)    :: r
      logical,             intent(inout) :: error
    end subroutine class_show
  end interface
  !
  interface
    subroutine svdfit(x,y,weight,ndata,a,ma,u,v,w,mp,np,chisq,funcs,error)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Singular value decomposition
      ! Given a set of NDATA points X(I), Y(I) with individual weights
      ! WEIGHT(I), use Chi2 minimization to determine the MA coefficients A of the
      ! fitting function. Here we solve the fitting
      ! equations using singular value decomposition of the NDATA by MA matrix.
      ! Arrays U,V,W provide workspace on input. On output they define the singular
      ! value decomposition and can be used to obtain the covariance matrix. MP, NP
      ! are the physical dimensions of the matrices U, V, W, as indicated below. It
      ! is necessary that MP>=NDATA, NP>=MA. The programs returns values for the MA
      ! fit parameters and Chi2, CHISQ. The user supplies a subroutine
      ! FUNCS(X,AFUNC,MA) that returns the MA basis functions evaluated at x=X in the
      ! array AFUNC.
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: ndata          !
      real(kind=4),    intent(in)    :: x(ndata)       !
      real(kind=4),    intent(in)    :: y(ndata)       !
      real(kind=4),    intent(in)    :: weight(ndata)  !
      integer(kind=4), intent(in)    :: ma             !
      real(kind=4),    intent(out)   :: a(ma)          !
      integer(kind=4), intent(in)    :: mp             !
      integer(kind=4), intent(in)    :: np             !
      real(kind=4),    intent(inout) :: u(mp,np)       !
      real(kind=4),    intent(inout) :: v(np,np)       !
      real(kind=4),    intent(inout) :: w(np)          !
      real(kind=4),    intent(out)   :: chisq          ! Chi^2
      external                       :: funcs          !
      logical,         intent(out)  :: error           !
    end subroutine svdfit
  end interface
  !
  interface
    subroutine svdcmp(a,m,n,mp,np,w,v,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Singular value decomposition
      ! Given a matrix A with logical dimensions M by N and physical dimensions MP
      ! by NP, this routine computes its singular value decomposition
      !	A = U.W.Vt
      ! The matrix U replaces A on output. The diagonal matrix of singular values W
      ! is a output as a vector W. The matrix V (not the transpose Vt) is output as
      ! V. M must be greater or equal to N. If it is smaller, then A should be filled
      ! up to square with zero rows.
      ! Typed from "numerical recipes".  TF
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: mp        !
      integer(kind=4), intent(in)    :: np        !
      real(kind=4),    intent(inout) :: a(mp,np)  !
      integer(kind=4), intent(in)    :: m         !
      integer(kind=4), intent(in)    :: n         !
      real(kind=4),    intent(out)   :: w(np)     !
      real(kind=4),    intent(out)   :: v(np,np)  !
      logical,         intent(out)   :: error     !
    end subroutine svdcmp
  end interface
  !
  interface
    subroutine svbksb(u,w,v,m,n,mp,np,b,x,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Singular value decomposition
      ! Solves A.X = B for a vector X, where A is specified by the arrays U,W,V as
      ! returned by SVDCMP. M and N are the logical dimensions of A, and will be
      ! equal for square matrices. MP and NP are the physical dimensions of A. B
      ! is the input right hand side. X is the output soolution vector. No input
      ! quantities are destroyed, so the routine may be called sequentially with
      ! different B's.
      ! Typed from "numerical recipes".  TF
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)  :: mp        !
      integer(kind=4), intent(in)  :: np        !
      real(kind=4),    intent(in)  :: u(mp,np)  !
      real(kind=4),    intent(in)  :: w(np)     !
      real(kind=4),    intent(in)  :: v(np,np)  !
      integer(kind=4), intent(in)  :: m         !
      integer(kind=4), intent(in)  :: n         !
      real(kind=4),    intent(in)  :: b(mp)     !
      real(kind=4),    intent(out) :: x(np)     !
      logical,         intent(out) :: error     !
    end subroutine svbksb
  end interface
  !
  interface
    subroutine fpoly(x,p,np)
      !---------------------------------------------------------------------
      ! @ private
      ! Fitting routine for a polynomial of degree NP-1.
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)  :: x      ! Variable value
      integer(kind=4), intent(in)  :: np     ! Polynom degree
      real(kind=4),    intent(out) :: p(np)  ! NP values of Chebychev polynoms
    end subroutine fpoly
  end interface
  !
  interface
    subroutine fcheb(x,p,np)
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the first NP-1 Chebychev polynom of first kind at x
      !    T_n(x), n=0...np-1
      ! Recurrence relation : T_(n+1)(x) - 2xT_(n)(x) + T_(n-1)(x) = 0
      ! Initialization      : T_0 = 1
      !                     : T_1 = x
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)  :: x      ! Variable value
      integer(kind=4), intent(in)  :: np     ! Polynom degree
      real(kind=4),    intent(out) :: p(np)  ! NP values of Chebychev polynoms
    end subroutine fcheb
  end interface
  !
  interface
    subroutine sinus_obs(set,obs,sinuspar,last,work,error)
      use gildas_def
      use phys_const
      use class_types
      use sinus_parameter
      !---------------------------------------------------------------------
      ! @ private
      ! This version for a single observation.
      ! Subtract a sinusoidal baseline to the input observation
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set          !
      type(observation),   intent(inout) :: obs          ! The observation to work on
      real(kind=4),        intent(in)    :: sinuspar(3)  ! Amplitude Period Phase
      logical,             intent(in)    :: last         ! Subtract last fitted baseline
      real(kind=4),        intent(inout) :: work(*)      ! Working array
      logical,             intent(inout) :: error        ! Error flag
    end subroutine sinus_obs
  end interface
  !
  interface
    subroutine fitsinus(set,obs,fcn,liter,error)
      use gildas_def
      use gbl_message
      use fit_minuit
      use class_types
      use sinus_parameter
      !---------------------------------------------------------------------
      ! @ private
      ! Setup and starts a gauss fit minimisation using minuit
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set  !
      type(observation),   intent(in) :: obs  ! The observation to work on
      interface
        subroutine fcn(npar,g,f,x,iflag,obs)  ! Function to be mininized
        use class_types
        integer(kind=4),   intent(in)  :: npar
        real(kind=8),      intent(out) :: g(npar)
        real(kind=8),      intent(out) :: f
        real(kind=8),      intent(in)  :: x(npar)
        integer(kind=4),   intent(in)  :: iflag
        type(observation), intent(in)  :: obs
        end subroutine fcn
      end interface
      logical,           intent(in)  :: liter  ! Iterate fit
      logical,           intent(out) :: error  ! Logical error flag
    end subroutine fitsinus
  end interface
  !
  interface
    subroutine init_sinus(set,obs)
      use gildas_def
      use sinus_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initializes parameters for 1st order polynom component of sine fit
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set  !
      type(observation),   intent(in) :: obs  ! The observation to work on
    end subroutine init_sinus
  end interface
  !
  interface
    subroutine sinus_obs_new(set,obs,dosinus,sinuspar,work,error)
      use gbl_message
      use phys_const
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! This version for a single observation.
      ! Subtract a sinusoidal baseline to the input observation, knowing
      ! its period.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set          !
      type(observation),   intent(inout) :: obs          ! The observation to work on
      logical,             intent(in)    :: dosinus(3)   ! Which parameters are to be fitted?
      real(kind=4),        intent(in)    :: sinuspar(3)  ! Ampli Period Phase
      real(kind=4),        intent(inout) :: work(*)      ! The fitted model
      logical,             intent(inout) :: error        ! Error flag
    end subroutine sinus_obs_new
  end interface
  !
  interface
    subroutine smnois(yin,yout,ny,nx,seuil,bad)
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS
      !	Noise cheating smoothing routine
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)  :: ny        ! Number of pixels
      real(kind=4),    intent(in)  :: yin(ny)   ! Input spectrum
      real(kind=4),    intent(out) :: yout(ny)  ! Output spectrum
      integer(kind=4), intent(in)  :: nx        ! Maximum number of pixels smoothed
      real(kind=4),    intent(in)  :: seuil     ! Smoothing threshold
      real(kind=4),    intent(in)  :: bad       ! Blanking value
    end subroutine smnois
  end interface
  !
  interface
    subroutine smhann_default(ty,ry,cnchan,cbad,error)
      use gildas_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   SMOOTH HANNING (no arguments)
      ! Makes a Hanning smoothing of the input data with a window width of
      ! 4 channels.
      !---------------------------------------------------------------------
      integer(kind=4), intent(inout) :: cnchan      ! Updated in return
      real(kind=4),    intent(in)    :: ty(cnchan)  !
      real(kind=4),    intent(out)   :: ry(cnchan)  !
      real(kind=4),    intent(in)    :: cbad        !
      logical,         intent(inout) :: error       !
    end subroutine smhann_default
  end interface
  !
  interface
    subroutine smhann(ty,ry,cnchan,cbad,width,space,ushift,error)
      use phys_const
      use gildas_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   SMOOTH HANNING
      ! Makes a Hanning smoothing of the input data
      !---------------------------------------------------------------------
      integer(kind=4), intent(inout) :: cnchan      ! Updated in return
      real(kind=4),    intent(in)    :: ty(cnchan)  !
      real(kind=4),    intent(out)   :: ry(cnchan)  !
      real(kind=4),    intent(in)    :: cbad        !
      real(kind=4),    intent(in)    :: width       ! [channels] Hann window width
      real(kind=4),    intent(in)    :: space       ! [channels] Output channel spacing
      real(kind=4),    intent(in)    :: ushift      ! [channels] User custom shift
      logical,         intent(inout) :: error       !
    end subroutine smhann
  end interface
  !
  interface
    subroutine smgauss(ty,ry,cnchan,cbad,ax,error)
      use gildas_def
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   SMOOTH GAUSS Width
      ! Makes a Gaussian smoothing of the input data
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: cnchan      !
      real(kind=4),    intent(in)    :: ty(cnchan)  !
      real(kind=4),    intent(out)   :: ry(cnchan)  !
      real(kind=4),    intent(in)    :: cbad        !
      real(kind=4),    intent(in)    :: ax          ! [channels] Input FWHM of Gaussian
      logical,         intent(inout) :: error       !
    end subroutine smgauss
  end interface
  !
  interface
    subroutine smbox(ty,ry,cnchan,cbad,nbox,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !   SMOOTH BOX Nchan
      !---------------------------------------------------------------------
      integer(kind=4), intent(inout) :: cnchan      ! Updated in return
      real(kind=4),    intent(in)    :: ty(cnchan)  !
      real(kind=4),    intent(out)   :: ry(cnchan)  !
      real(kind=4),    intent(in)    :: cbad        !
      integer(kind=4), intent(in)    :: nbox        ! Number of channels averaged
      logical,         intent(inout) :: error       !
    end subroutine smbox
  end interface
  !
  interface
    subroutine set_sort(set,line,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! SET SORT NONE
      ! SET SORT Para1
      !---------------------------------------------------------------------
      type(class_setup_t), intent(inout) :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      logical,             intent(inout) :: error  ! Error flag
    end subroutine set_sort
  end interface
  !
  interface
    subroutine quicksort(set,x,n,gtt,gte,error)
      use gbl_message
      use classic_api
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Sorting program that uses a quicksort algorithm. Apply for an input
      ! array of integer values, which are SORTED
      !---------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set    !
      integer(kind=entry_length), intent(in)    :: n      ! Length of array
      integer(kind=entry_length), intent(inout) :: x(n)   ! Index array to be sorted
      logical,                    external      :: gtt    ! Greater than
      logical,                    external      :: gte    ! Greater than or equal
      logical,                    intent(out)   :: error  ! Error status
    end subroutine quicksort
  end interface
  !
  interface
    logical function ix_csour_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_csour_gt
  end interface
  !
  interface
    logical function ix_cline_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_cline_gt
  end interface
  !
  interface
    logical function ix_ctele_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ctele_gt
  end interface
  !
  interface
    logical function ix_bloc_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_bloc_gt
  end interface
  !
  interface
    logical function ix_num_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_num_gt
  end interface
  !
  interface
    logical function ix_ver_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ver_gt
  end interface
  !
  interface
    logical function ix_dobs_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! Sorting arrays (by precedence order):
      !    %dobs
      !    %scan
      !    %num
      !    %ver
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_dobs_gt
  end interface
  !
  interface
    logical function ix_off1_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off1_gt
  end interface
  !
  interface
    logical function ix_off2_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off2_gt
  end interface
  !
  interface
    logical function ix_scan_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_scan_gt
  end interface
  !
  interface
    logical function ix_subscan_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_subscan_gt
  end interface
  !
  interface
    logical function ix_kind_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_kind_gt
  end interface
  !
  interface
    logical function ix_qual_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_qual_gt
  end interface
  !
  interface
    logical function ix_toc_default_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_toc_default_gt
  end interface
  !
  interface
    logical function ix_csour_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_csour_ge
  end interface
  !
  interface
    logical function ix_cline_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_cline_ge
  end interface
  !
  interface
    logical function ix_ctele_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ctele_ge
  end interface
  !
  interface
    logical function ix_bloc_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_bloc_ge
  end interface
  !
  interface
    logical function ix_num_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_num_ge
  end interface
  !
  interface
    logical function ix_ver_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ver_ge
  end interface
  !
  interface
    logical function ix_dobs_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! Sorting arrays (by precedence order):
      !    %dobs
      !    %scan
      !    %num
      !    %ver
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_dobs_ge
  end interface
  !
  interface
    logical function ix_off1_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off1_ge
  end interface
  !
  interface
    logical function ix_off2_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off2_ge
  end interface
  !
  interface
    logical function ix_scan_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_scan_ge
  end interface
  !
  interface
    logical function ix_subscan_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_subscan_ge
  end interface
  !
  interface
    logical function ix_kind_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_kind_ge
  end interface
  !
  interface
    logical function ix_qual_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_qual_ge
  end interface
  !
  interface
    logical function ix_toc_default_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_toc_default_ge
  end interface
  !
  interface
    logical function ix_csour_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_csour_eq
  end interface
  !
  interface
    logical function ix_cline_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_cline_eq
  end interface
  !
  interface
    logical function ix_ctele_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ctele_eq
  end interface
  !
  interface
    logical function ix_bloc_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_bloc_eq
  end interface
  !
  interface
    logical function ix_num_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_num_eq
  end interface
  !
  interface
    logical function ix_ver_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_ver_eq
  end interface
  !
  interface
    logical function ix_dobs_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_dobs_eq
  end interface
  !
  interface
    logical function ix_off1_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off1_eq
  end interface
  !
  interface
    logical function ix_off2_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_off2_eq
  end interface
  !
  interface
    logical function ix_scan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_scan_eq
  end interface
  !
  interface
    logical function ix_subscan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_subscan_eq
  end interface
  !
  interface
    logical function ix_kind_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_kind_eq
  end interface
  !
  interface
    logical function ix_qual_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_qual_eq
  end interface
  !
  interface
    logical function ix_toc_default_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_toc_default_eq
  end interface
  !
  interface
    logical function ix_toc_date_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_toc_date_eq
  end interface
  !
  interface
    logical function ix_toc_scan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function ix_toc_scan_eq
  end interface
  !
  interface
    logical function cx_csour_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_csour_gt
  end interface
  !
  interface
    logical function cx_cline_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_cline_gt
  end interface
  !
  interface
    logical function cx_ctele_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ctele_gt
  end interface
  !
  interface
    logical function cx_bloc_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_bloc_gt
  end interface
  !
  interface
    logical function cx_num_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_num_gt
  end interface
  !
  interface
    logical function cx_ver_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ver_gt
  end interface
  !
  interface
    logical function cx_dobs_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_dobs_gt
  end interface
  !
  interface
    logical function cx_off1_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off1_gt
  end interface
  !
  interface
    logical function cx_off2_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off2_gt
  end interface
  !
  interface
    logical function cx_scan_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_scan_gt
  end interface
  !
  interface
    logical function cx_subscan_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_subscan_gt
  end interface
  !
  interface
    logical function cx_kind_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_kind_gt
  end interface
  !
  interface
    logical function cx_qual_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_qual_gt
  end interface
  !
  interface
    logical function cx_toc_default_gt(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_toc_default_gt
  end interface
  !
  interface
    logical function cx_csour_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_csour_ge
  end interface
  !
  interface
    logical function cx_cline_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_cline_ge
  end interface
  !
  interface
    logical function cx_ctele_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ctele_ge
  end interface
  !
  interface
    logical function cx_bloc_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_bloc_ge
  end interface
  !
  interface
    logical function cx_num_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_num_ge
  end interface
  !
  interface
    logical function cx_ver_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ver_ge
  end interface
  !
  interface
    logical function cx_dobs_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_dobs_ge
  end interface
  !
  interface
    logical function cx_off1_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off1_ge
  end interface
  !
  interface
    logical function cx_off2_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off2_ge
  end interface
  !
  interface
    logical function cx_scan_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_scan_ge
  end interface
  !
  interface
    logical function cx_subscan_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_subscan_ge
  end interface
  !
  interface
    logical function cx_kind_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_kind_ge
  end interface
  !
  interface
    logical function cx_qual_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_qual_ge
  end interface
  !
  interface
    logical function cx_toc_default_ge(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_toc_default_ge
  end interface
  !
  interface
    logical function cx_csour_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_csour_eq
  end interface
  !
  interface
    logical function cx_cline_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_cline_eq
  end interface
  !
  interface
    logical function cx_ctele_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      ! TRUE if observation m is greater than observation l
      ! Comparison is done according to one keyword
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ctele_eq
  end interface
  !
  interface
    logical function cx_bloc_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_bloc_eq
  end interface
  !
  interface
    logical function cx_num_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_num_eq
  end interface
  !
  interface
    logical function cx_ver_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_ver_eq
  end interface
  !
  interface
    logical function cx_dobs_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_dobs_eq
  end interface
  !
  interface
    logical function cx_off1_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off1_eq
  end interface
  !
  interface
    logical function cx_off2_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_off2_eq
  end interface
  !
  interface
    logical function cx_scan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_scan_eq
  end interface
  !
  interface
    logical function cx_subscan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_subscan_eq
  end interface
  !
  interface
    logical function cx_kind_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_kind_eq
  end interface
  !
  interface
    logical function cx_qual_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_qual_eq
  end interface
  !
  interface
    logical function cx_toc_default_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_toc_default_eq
  end interface
  !
  interface
    logical function cx_toc_date_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_toc_date_eq
  end interface
  !
  interface
    logical function cx_toc_scan_eq(m,l)
      use class_index
      !---------------------------------------------------------------------
      ! @ private
      ! LAS internal routine
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in) :: m  ! Observation number
      integer(kind=entry_length), intent(in) :: l  ! Observation number
    end function cx_toc_scan_eq
  end interface
  !
  interface
    subroutine spectr1d(caller,set,obs,error,offset,aaname)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_types
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! Plot the spectrum (RY), with an optional Y offset.
      ! If an Associated Array name is given, plot this array instead.
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: caller  ! Calling routine name
      type(class_setup_t),        intent(in)    :: set     !
      type(observation),          intent(in)    :: obs     ! Observation to be plotted
      logical,                    intent(inout) :: error   ! Logical error flag
      real(kind=4),     optional, intent(in)    :: offset  ! Y offset value
      character(len=*), optional, intent(in)    :: aaname  ! Associated Array name
    end subroutine spectr1d
  end interface
  !
  interface
    subroutine spectr1d_draw_histo1chan(set,obs,y)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Ad hoc subroutine which draws a single-channel histogram. This can
      ! not be done with gr4_histo/gr8_histo as they guess the width from
      ! 2 contiguous channels.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
      type(observation),   intent(in) :: obs
      real(kind=8),        intent(in) :: y
    end subroutine spectr1d_draw_histo1chan
  end interface
  !
  interface
    subroutine spectr2d(obs,error)
      use gildas_def
      use gbl_message
      use class_data
      use plot_formula
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !
      ! Plot the INDEX as a 2D image.
      !---------------------------------------------------------------------
      type(observation), intent(in)  :: obs    ! Observation to be plotted
      logical,           intent(out) :: error  ! Logical error flag
    end subroutine spectr2d
  end interface
  !
  interface spectr1d_draw
    subroutine spectr1d_draw_r4(set,obs,y,bad,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic spectr1d_draw
      ! Draw the input Y array according to the current SET PLOT rule.
      ! X in found in obs%datax(:), plot is done according to the current
      ! SET MODE X range.
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(in)    :: obs    !
      real(kind=4),        intent(in)    :: y(:)   !
      real(kind=4),        intent(in)    :: bad    ! Blanking value
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine spectr1d_draw_r4
    subroutine spectr1d_draw_r8(set,obs,y,bad,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic spectr1d_draw
      ! Draw the input Y array according to the current SET PLOT rule.
      ! X in found in obs%datax(:), plot is done according to the current
      ! SET MODE X range.
      ! ---
      !  R*8 version
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(in)    :: obs    !
      real(kind=8),        intent(in)    :: y(:)   !
      real(kind=8),        intent(in)    :: bad    ! Blanking value
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine spectr1d_draw_r8
    subroutine spectr1d_draw_i4(set,obs,y,bad,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private-generic spectr1d_draw
      ! Draw the input Y array according to the current SET PLOT rule.
      ! X in found in obs%datax(:), plot is done according to the current
      ! SET MODE X range.
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(in)    :: obs    !
      integer(kind=4),     intent(in)    :: y(:)   !
      integer(kind=4),     intent(in)    :: bad    ! Blanking value
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine spectr1d_draw_i4
  end interface spectr1d_draw
  !
  interface
    subroutine strip_map(set,name,error,user_function)
      use gildas_def
      use image_def
      use gbl_constant
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support for command
      !   ANA\STRIP FileName
      ! Generic version. Make a strip map, i.e. a Velocity-Position plot.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      character(len=*),    intent(in)    :: name           ! File name
      logical,             intent(inout) :: error          !
      logical,             external      :: user_function  !
    end subroutine strip_map
  end interface
  !
  interface
    subroutine strip_map_offsets(set,cx_off,offmin,offmax,dis,beta,error)
      use gbl_message
      use class_index
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Store offsets, check if they define a slice
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set        !
      real(kind=4),        intent(out)   :: cx_off(:)  ! Offset array
      real(kind=4),        intent(out)   :: offmin     !
      real(kind=4),        intent(out)   :: offmax     !
      real(kind=4),        intent(out)   :: dis        !
      logical,             intent(out)   :: beta       ! Beta fixed or not?
      logical,             intent(inout) :: error      !
    end subroutine strip_map_offsets
  end interface
  !
  interface
    subroutine strip_map_header(set,str,name,offmin,offmax,dis,beta,user_function,error)
      use image_def
      use gbl_message
      use class_index
      use class_parameter
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the GDF image header
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(gildas),        intent(inout) :: str            ! GDF image
      character(len=*),    intent(in)    :: name           ! File name
      real(kind=4),        intent(in)    :: offmin         ! Minimal offset
      real(kind=4),        intent(in)    :: offmax         ! Maximal offset
      real(kind=4),        intent(in)    :: dis            !
      logical,             intent(in)    :: beta           !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Logical error flag
    end subroutine strip_map_header
  end interface
  !
  interface
    subroutine strip_map_data_spec(set,str,cx_off,offmin,dis,error,user_function)
      use gbl_constant
      use phys_const
      use image_def
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Fill the GDF image data (for spectroscopic observations)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(gildas),        intent(inout) :: str            ! The GDF image
      real(kind=4),        intent(in)    :: cx_off(:)      ! The offsets
      real(kind=4),        intent(in)    :: offmin         !
      real(kind=4),        intent(in)    :: dis            !
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  !
    end subroutine strip_map_data_spec
  end interface
  !
  interface
    subroutine strip_map_data_cont(set,str,cx_off,offmin,dis,error,user_function)
      use gbl_constant
      use phys_const
      use image_def
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Fill the GDF image data (for continuum observations)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(gildas),        intent(inout) :: str            ! The GDF image
      real(kind=4),        intent(in)    :: cx_off(:)      ! The offsets
      real(kind=4),        intent(in)    :: offmin         !
      real(kind=4),        intent(in)    :: dis            !
      logical,             intent(inout) :: error          ! Logical error flag
      logical,             external      :: user_function  !
    end subroutine strip_map_data_cont
  end interface
  !
  interface
    subroutine reallocate_optimize(optx,mobs,long,keep,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Allocate the 'optimize' type arrays.
      !  'long' allocation: all arrays are allocated
      !  'short' allocation: only ind(:), num(:), bloc(:), word(:), ver(:),
      !                      ut(:)
      !---------------------------------------------------------------------
      type(optimize),             intent(inout) :: optx   !
      integer(kind=entry_length), intent(in)    :: mobs   ! Requested size
      logical,                    intent(in)    :: long   ! Long allocation?
      logical,                    intent(in)    :: keep   ! Keep previous data?
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine reallocate_optimize
  end interface
  !
  interface
    subroutine deallocate_optimize(optx,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Deallocate the 'optimize' type arrays.
      !---------------------------------------------------------------------
      type(optimize),  intent(inout) :: optx   !
      logical,         intent(inout) :: error  ! Logical error flag
    end subroutine deallocate_optimize
  end interface
  !
  interface
    subroutine reallocate_pq(new_nchan,new_nobs,error)
      use class_data
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      !   (Re)allocate pointers and targets for P and Q buffers
      !   The headers are not modified at all
      !---------------------------------------------------------------------
      integer(kind=4),            intent(in)  :: new_nchan  ! Size of new P & Q arrays
      integer(kind=entry_length), intent(in)  :: new_nobs   ! Size of new P & Q arrays
      logical,                    intent(out) :: error      ! Error flag
    end subroutine reallocate_pq
  end interface
  !
  interface
    subroutine class_subtract_header(h1,h2,ho,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the header of the difference from the input header
      ! NOT IMPLEMENTED! Use 1st header instead!
      !---------------------------------------------------------------------
      type(header), intent(in)    :: h1     ! Header of 1st obs
      type(header), intent(in)    :: h2     ! Header of 2nd obs
      type(header), intent(inout) :: ho     ! Output header
      logical,      intent(inout) :: error  ! Logical error flag
    end subroutine class_subtract_header
  end interface
  !
  interface
    subroutine class_table_parse(set,line,filename,append,math,nexp,expression,  &
      lexp,fft,faxis,range,frequency,new_line,new_restf,weighting,donasmyth,  &
      cons,error,user_function)
      use gildas_def
      use gbl_constant
      use gbl_message
      use class_index
      use class_averaging
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Parse the input command line and make first checks
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set
      character(len=*),      intent(in)    :: line
      character(len=*),      intent(inout) :: filename
      logical,               intent(out)   :: append
      logical,               intent(out)   :: math
      integer(kind=4),       intent(out)   :: nexp  ! Number of /MATH expressions
      character(len=*),      intent(out)   :: expression(:)
      integer(kind=4),       intent(out)   :: lexp(:)
      logical,               intent(out)   :: fft
      type(resampling),      intent(out)   :: faxis
      type(average_range_t), intent(out)   :: range
      logical,               intent(out)   :: frequency
      character(len=*),      intent(out)   :: new_line
      real(kind=8),          intent(out)   :: new_restf
      character(len=*),      intent(out)   :: weighting
      logical,               intent(out)   :: donasmyth
      type(consistency_t),   intent(out)   :: cons
      logical,               intent(inout) :: error
      logical,               external      :: user_function
    end subroutine class_table_parse
  end interface
  !
  interface
    subroutine class_table_header(set,filename,ref_head,htable,append,frequency,  &
       new_line,new_restf,weighting,faxis,range,math,nexp,expression,lexp,cons,     &
       resample,nchanmax,error,user_function)
      use image_def
      use class_types
      use class_averaging
      !----------------------------------------------------------------------
      ! @ private
      !   * In NEW mode, ref_head is set to first obs and then table header
      !     is filled from ref_head
      !   * In APPEND mode, ref_header is filled from table header
      !   * Finally ensure that the new quantities (rest frequency and x-axis
      !     definition) are defined in all cases
      !----------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set            !
      character(len=*),      intent(in)    :: filename       ! Table filename
      type(header),          intent(out)   :: ref_head       ! Reference header for resampling and consistency checks
      type(gildas),          intent(out)   :: htable         ! Table header
      logical,               intent(in)    :: append         ! Append to the table?
      logical,               intent(in)    :: frequency      !
      character(len=*),      intent(inout) :: new_line       !
      real(kind=8),          intent(inout) :: new_restf      !
      character(len=*),      intent(in)    :: weighting      ! Weighting type
      type(resampling),      intent(inout) :: faxis          ! New x-axis definition
      type(average_range_t), intent(in)    :: range          ! Range requested
      logical,               intent(inout) :: math           ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),       intent(inout) :: nexp           ! Number of /MATH expressions
      character(len=*),      intent(inout) :: expression(:)  ! String containing the mathematical expressions
      integer,               intent(inout) :: lexp(:)        ! Length of expression strings
      type(consistency_t),   intent(inout) :: cons           !
      logical,               intent(out)   :: resample       !
      integer(kind=4),       intent(out)   :: nchanmax       ! Largest spectrum size in index
      logical,               intent(out)   :: error          ! Error flag
      logical,               external      :: user_function  !
    end subroutine class_table_header
  end interface
  !
  interface
    subroutine class_table_header_old(set,htable,ref_head,math,nexp,expression,  &
      lexp,faxis,cons,resample,nchanmax,error,user_function)
      use image_def
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set the header when reusing an OLD table (append mode)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(gildas),        intent(inout) :: htable         ! Table header
      type(header),        intent(out)   :: ref_head       ! Reference header for resampling and consistency checks
      logical,             intent(out)   :: math           ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),     intent(out)   :: nexp           ! Number of /MATH expressions
      character(len=*),    intent(out)   :: expression(:)  ! String containing the mathematical expressions
      integer(kind=4),     intent(out)   :: lexp(:)        ! Length of expression strings
      type(resampling),    intent(out)   :: faxis          ! Resampling axis
      type(consistency_t), intent(inout) :: cons           !
      logical,             intent(out)   :: resample       !
      integer(kind=4),     intent(out)   :: nchanmax       ! Largest spectrum size in index
      logical,             intent(inout) :: error          ! Error flag
      logical,             external      :: user_function  !
    end subroutine class_table_header_old
  end interface
  !
  interface
    subroutine class_table2class_spectro(htable,hclass,error)
      use gbl_constant
      use image_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set the spectro section of a class header from a table header
      !---------------------------------------------------------------------
      type(gildas), intent(in)    :: htable
      type(header), intent(inout) :: hclass
      logical,      intent(inout) :: error
    end subroutine class_table2class_spectro
  end interface
  !
  interface
    subroutine class_class2table_spectro(htable,math,nexp,expression1,hclass,error)
      use gbl_constant
      use image_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set the spectro section of a table header from a class header
      !---------------------------------------------------------------------
      type(header),     intent(in)    :: hclass       !
      logical,          intent(in)    :: math         ! /MATH mode?
      integer(kind=4),  intent(in)    :: nexp         ! Number of math expressions
      character(len=*), intent(in)    :: expression1  ! First math expression
      type(gildas),     intent(inout) :: htable       !
      logical,          intent(inout) :: error        !
    end subroutine class_class2table_spectro
  end interface
  !
  interface
    subroutine class_table_header_to_ref(htable,ref_head,math,nexp,expression,  &
      lexp,error)
      use gbl_constant
      use image_def
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the Class observation header from the Gildas table header
      !---------------------------------------------------------------------
      type(gildas),     intent(in)    :: htable         ! Table header
      type(header),     intent(out)   :: ref_head       ! Reference header for resampling and consistency checks
      logical,          intent(out)   :: math           ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),  intent(out)   :: nexp           ! Number of /MATH expressions
      character(len=*), intent(out)   :: expression(:)  ! String containing the mathematical expression
      integer(kind=4),  intent(out)   :: lexp(:)        ! Length of expression string
      logical,          intent(inout) :: error          ! Error flag
    end subroutine class_table_header_to_ref
  end interface
  !
  interface
    subroutine class_table_header_new(set,ref_head,htable,frequency,new_line,  &
      new_restf,weighting,faxis,range,math,nexp,expression,lexp,cons,resample,   &
      nchanmax,error,user_function)
      use gbl_constant
      use image_def
      use gbl_message
      use class_averaging
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set the header of a new table
      !---------------------------------------------------------------------
      type(class_setup_t),   intent(in)    :: set               !
      type(header),          intent(out)   :: ref_head          ! Reference header for resampling and consistency checks
      type(gildas),          intent(inout) :: htable            ! Table header
      logical,               intent(in)    :: frequency         ! /FREQUENCY was used?
      character(len=*),      intent(in)    :: new_line          ! /FREQUENCY Line
      real(kind=8),          intent(in)    :: new_restf         ! /FREQUENCY Restf
      character(len=*),      intent(in)    :: weighting         ! Weighting type
      type(resampling),      intent(inout) :: faxis             ! New x-axis definition, if any
      type(average_range_t), intent(in)    :: range             ! Requested range
      logical,               intent(in)    :: math              ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),       intent(in)    :: nexp              ! Number of /MATH expressions
      character(len=*),      intent(in)    :: expression(nexp)  ! String containing the mathematical expressions
      integer,               intent(in)    :: lexp(nexp)        ! Length of expression strings
      type(consistency_t),   intent(inout) :: cons              !
      logical,               intent(out)   :: resample          !
      integer(kind=4),       intent(out)   :: nchanmax          ! Largest spectrum size in index
      logical,               intent(inout) :: error             ! Error flag
      logical,               external      :: user_function     !
    end subroutine class_table_header_new
  end interface
  !
  interface
    subroutine class_table_header_from_ref(ref_head,math,nexp,expression,lexp,  &
      htable,error)
      use phys_const
      use image_def
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the Gildas table header from the Class observation header
      !---------------------------------------------------------------------
      type(header),     intent(in)    :: ref_head          ! Reference header
      logical,          intent(in)    :: math              ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),  intent(in)    :: nexp              ! Number of /MATH expressions
      character(len=*), intent(in)    :: expression(nexp)  ! String containing the mathematical expression
      integer,          intent(in)    :: lexp(nexp)        ! Length of expression string
      type(gildas),     intent(inout) :: htable            ! Table header
      logical,          intent(inout) :: error             !
    end subroutine class_table_header_from_ref
  end interface
  !
  interface
    subroutine class_table_first_changes(set,fst,new_line,new_restf,  &
      resample_index,faxis,fft,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !  Modify rest frequency and resample if needed
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set             !
      type(observation),   intent(inout) :: fst             ! First index spectrum
      character(len=*),    intent(inout) :: new_line        !
      real(kind=8),        intent(inout) :: new_restf       !
      logical,             intent(in)    :: resample_index  ! Enforce resampling of the whole index?
      logical,             intent(in)    :: fft             !
      type(resampling),    intent(in)    :: faxis           ! New x-axis definition
      logical,             intent(inout) :: error           ! Error flag
    end subroutine class_table_first_changes
  end interface
  !
  interface
    subroutine class_table_first_math(math,nexp,expression,lexp,error)
      use gbl_message
      !----------------------------------------------------------------------
      ! @ private
      !    Check validity of math expression on the R buffer
      !----------------------------------------------------------------------
      logical,          intent(in)    :: math              ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),  intent(in)    :: nexp              ! Number of /MATH expressions
      character(len=*), intent(in)    :: expression(nexp)  ! String containing the mathematical expression
      integer(kind=4),  intent(in)    :: lexp(nexp)        ! Length of expression string
      logical,          intent(inout) :: error             ! Error flag
    end subroutine class_table_first_math
  end interface
  !
  interface
    subroutine class_table_fill(set,htable,append,obs,ref_head,resample,fft,faxis,  &
      new_restf,math,nexp,expression,lexp,weighting,donasmyth,user_function,error)
      use gildas_def
      use image_def
      use gbl_message
      use gkernel_types
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      !  Fill the table from the index. To do this, it performs:
      !    * Consistency checks against reference header
      !    * Resampling on reference header
      !    * Mathematical computation
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set               !
      type(gildas),        intent(inout) :: htable            ! Table header
      logical,             intent(in)    :: append            ! Append to the table?
      type(observation),   intent(inout) :: obs               ! Working buffer (special trick for math mode)
      type(header),        intent(in)    :: ref_head          ! Reference header
      logical,             intent(in)    :: resample          ! Enforce resampling of the whole index?
      logical,             intent(in)    :: fft               ! Use FFT for resampling?
      type(resampling),    intent(in)    :: faxis             ! New x-axis definition
      real(kind=8),        intent(in)    :: new_restf         !
      logical,             intent(in)    :: math              ! Output a mathematical formula instead of the spectrum?
      integer(kind=4),     intent(in)    :: nexp              ! Number of /MATH expressions
      character(len=*),    intent(in)    :: expression(nexp)  ! String containing the mathematical expressions
      integer(kind=4),     intent(in)    :: lexp(nexp)        ! Length of expression strings
      character(len=*),    intent(in)    :: weighting         ! Weighting type
      logical,             intent(in)    :: donasmyth         ! Nasmyth offsets?
      logical,             intent(out)   :: error             ! Error flag
      logical,             external      :: user_function     !
    end subroutine class_table_fill
  end interface
  !
  interface
    subroutine class_table_nasmyth_offsets(obs,lamof,betof,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the observation offsets in Nasmyth plane coordinates
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs
      real(kind=4),      intent(out)   :: lamof,betof
      logical,           intent(inout) :: error
    end subroutine class_table_nasmyth_offsets
  end interface
  !
  interface
    subroutine class_table_size(htable,error)
      use gbl_message
      use image_def
      !---------------------------------------------------------------------
      ! @ private
      !  Should be removed and replaced by a simple assignment when
      ! loca%size will have an automatic length (kind=axis_length or
      ! index_length)
      !---------------------------------------------------------------------
      type(gildas), intent(in)    :: htable  ! Table header
      logical,      intent(inout) :: error   ! Logical error flag
    end subroutine class_table_size
  end interface
  !
  interface
    subroutine class_table_line(nchan,intensities,line,offx,offy,weight,bad,blank)
      !----------------------------------------------------------------------
      ! @ private
      !  Fill a line of one table line taking blanking into account
      !----------------------------------------------------------------------
      integer(kind=4), intent(in)    :: nchan              ! Number of spectrum channels
      real(kind=4),    intent(in)    :: intensities(nchan) ! Spectrum intensities
      real(kind=4),    intent(inout) :: line(-2:nchan)     ! Table line to be filled
      real(kind=4),    intent(in)    :: offx,offy          ! Spectrum x and y offsets
      real(kind=4),    intent(in)    :: weight             ! Spectrum weight
      real(kind=4),    intent(in)    :: bad,blank          ! Spectrum and table blanking values
    end subroutine class_table_line
  end interface
  !
  interface
    subroutine my_get_teles(caller,telescope,mustfind,name,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Translate a Class obs%head%gen%teles into a telescope name
      ! gwcs_observatory and astro_observatory can understand. Symmetric
      ! to my_set_teles
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: caller     !
      character(len=*), intent(in)    :: telescope  !
      logical,          intent(in)    :: mustfind   !
      character(len=*), intent(out)   :: name       !
      logical,          intent(inout) :: error      !
    end subroutine my_get_teles
  end interface
  !
  interface
    subroutine my_set_teles(caller,name,mustfind,telescope,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Translate a telescope name into a Class obs%head%gen%teles.
      ! Symmetric to my_get_teles.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: caller     !
      character(len=*), intent(in)    :: name       !
      logical,          intent(in)    :: mustfind   !
      character(len=*), intent(out)   :: telescope  !
      logical,          intent(inout) :: error      !
    end subroutine my_set_teles
  end interface
  !
  interface
    subroutine titout(set,head,key1,key2)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write a title
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set   !
      type(header),        intent(in) :: head  ! Observation header
      character(len=1),    intent(in) :: key1  ! Output Format type (Brief, Long, Full)
      character(len=1),    intent(in) :: key2  ! Output Format kind (INDEX or OBS)
    end subroutine titout
  end interface
  !
  interface
    subroutine titout_index(set,head,brief)
      use gbl_constant
      use phys_const
      use class_types
      use class_index
      !----------------------------------------------------------------------
      ! @ private
      ! Write a title
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set    !
      type(header),        intent(in) :: head   ! Observation header
      logical,             intent(in) :: brief  ! Brief or long?
    end subroutine titout_index
  end interface
  !
  interface
    subroutine titout_observation(set,head,long,full)
      use gbl_constant
      use phys_const
      use class_setup_new
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write a title
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set   !
      type(header),        intent(in) :: head  ! Observation header
      logical,             intent(in) :: long  !
      logical,             intent(in) :: full  !
    end subroutine titout_observation
  end interface
  !
  interface
    subroutine class_list_toc_comm(set,line,idx,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS support routine for command
      !   LIST [IN|CURRENT] /TOC [Key1] ... [KeyN]  [/VARIABLE VarName]
      ! Main entry point
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      character(len=*),    intent(in)    :: line   ! Input command line
      type(optimize),      intent(in)    :: idx    !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine class_list_toc_comm
  end interface
  !
  interface
    subroutine class_toc_init(toc,error)
      use toc_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command LIST /TOC
      ! Initialization routine
      !---------------------------------------------------------------------
      type(toc_t), intent(inout) :: toc    !
      logical,     intent(inout) :: error  !
    end subroutine class_toc_init
  end interface
  !
  interface
    function class_toc_eq_drift(ptr,l,m)
      use phys_const
      use classic_params
      use toc_types
      !-------------------------------------------------------------------
      ! @ private
      ! Compute the "equality" of drifts.
      ! The "drift value" is not directly available in the index. It is an
      ! information derived from r%head%dri%apos (the main "detail" is the
      ! modulo pi). Hence the specific equality routine.
      !-------------------------------------------------------------------
      logical :: class_toc_eq_drift
      class(pointer_typer4_t),    intent(in) :: ptr
      integer(kind=entry_length), intent(in) :: m,l
    end function class_toc_eq_drift
  end interface
  !
  interface
    function class_toc_eq_direction(ptr,l,m)
      use phys_const
      use classic_params
      use toc_types
      !-------------------------------------------------------------------
      ! @ private
      ! Compute the "equality" of drift directions.
      ! Need some machine error, hence the specific equality routine.
      !-------------------------------------------------------------------
      logical :: class_toc_eq_direction
      class(pointer_typer4_t),    intent(in) :: ptr
      integer(kind=entry_length), intent(in) :: m,l
    end function class_toc_eq_direction
  end interface
  !
  interface
    function class_toc_eq_fesb(ptr,l,m)
      use classic_params
      use toc_types
      !-------------------------------------------------------------------
      ! @ private
      ! Compute the "equality" of frontend-sideband.
      ! The "frontend-backend" value is not directly available in the
      ! index. It is an information derived from r%head%gen%teles. Hence
      ! the specific equality routine.
      !    30ME0HLS-B01 and
      !    30ME0VLS-B03 are equal (same frontend, same sideband, not the
      ! same polarizarion), and
      !    30ME0HUS-B02 and
      !    30ME0VUS-B04 are a different class.
      !-------------------------------------------------------------------
      logical :: class_toc_eq_fesb
      class(pointer_typec12_t),   intent(in) :: ptr
      integer(kind=entry_length), intent(in) :: m,l
    end function class_toc_eq_fesb
  end interface
  !
  interface
    function class_toc_eq_frontend(ptr,l,m)
      use classic_params
      use toc_types
      !-------------------------------------------------------------------
      ! @ private
      ! Compute the "equality" of frontends.
      ! The "frontend" value is not directly available in the index. It is
      ! an information derived from r%head%gen%teles. Hence the specific
      ! equality routine.
      !    30ME0HLS-B01 and
      !    30ME0HUS-B02 and
      !    30ME0VLS-B03 and
      !    30ME0VUS-B04 are all equal.
      !-------------------------------------------------------------------
      logical :: class_toc_eq_frontend
      class(pointer_typec12_t),   intent(in) :: ptr
      integer(kind=entry_length), intent(in) :: m,l
    end function class_toc_eq_frontend
  end interface
  !
  interface
    subroutine class_list_toc(set,idx,keywords,tocname,error)
      use gbl_message
      use class_types
      use output_header
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Support routine for command LIST /TOC
      ! Processing routine
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set          !
      type(optimize),      intent(in)    :: idx          ! The idx whose TOC is desired
      integer(kind=4),     intent(in)    :: keywords(:)  ! Selection (key identifiers)
      character(len=*),    intent(in)    :: tocname      ! Structure name
      logical,             intent(inout) :: error        ! Logical error flag
    end subroutine class_list_toc
  end interface
  !
  interface
    subroutine class_toc_datasetup(toc,idx)
      use class_types
      use toc_types
      !---------------------------------------------------------------------
      ! @ private
      ! Associate the TOC data pointers to the index whose TOC is desired
      !---------------------------------------------------------------------
      type(toc_t),    intent(inout) :: toc
      type(optimize), intent(in)    :: idx
    end subroutine class_toc_datasetup
  end interface
  !
  interface
    subroutine toclass(set,r,check,user_function,error)
      use gildas_def
      use gbl_format
      use gbl_constant
      use gbl_message
      use class_types
      use class_fits
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS-FITS Internal routine
      !
      ! Read a FITS file from tape or disk and conwvert it to CLASS format
      ! in virtual memory.
      ! From the header, we have NX*NY integer pixel values of NBITS
      ! each to read. The blocksize is 2880 Bytes.
      ! The conversion to REAL*4 is done using BSCAL and BZERO
      !
      ! Supports Binary Tables, and Continuum data
      !
      ! Still missing:
      ! * Coordinate Description matrix
      !   RADECSYS, MJD-OBS (the offset between Julian day numbers and
      !   internal code is 2460549.5d0).
      ! * Support for all projections
      !
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: r              !
      logical,             intent(in)    :: check          !
      logical,             intent(inout) :: error          ! Error status
      logical,             external      :: user_function  !
    end subroutine toclass
  end interface
  !
  interface
    subroutine fits_next_hdu(fits,nomore,error)
      use gildas_def
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Move the gio library to the beginning of next header
      !---------------------------------------------------------------------
      type(classfits_t), intent(in)    :: fits    !
      logical,           intent(out)   :: nomore  !
      logical,           intent(inout) :: error   !
    end subroutine fits_next_hdu
  end interface
  !
  interface
    subroutine fits_read_hdu(set,fits,r,check,doexit,user_function,error)
      use class_types
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           ! Reading buffer
      type(observation),   intent(inout) :: r              !
      logical,             intent(in)    :: check          !
      logical,             intent(out)   :: doexit         ! No more to be done
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_read_hdu
  end interface
  !
  interface
    subroutine fits_convert_basicnodata(fits,check,error,user_function)
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Skip the no-data Primary HDU
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits           !
      logical,           intent(in)    :: check          !
      logical,           intent(inout) :: error          !
      logical,           external      :: user_function  !
    end subroutine fits_convert_basicnodata
  end interface
  !
  interface
    subroutine fits_convert_basic(set,fits,obs,check,error,user_function)
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read FITS header into work arrays and CLASS observation
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           !
      type(observation),   intent(inout) :: obs            !
      logical,             intent(in)    :: check          !
      logical,             intent(inout) :: error          !
      logical,             external      :: user_function  !
    end subroutine fits_convert_basic
  end interface
  !
  interface
    subroutine fits_convert_bintable(set,check,invalid,user_function,error)
      use gbl_message
      use class_fits
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      logical,             intent(in)    :: check          !
      logical,             intent(out)   :: invalid        ! Invalid bintable to be skipped?
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_convert_bintable
  end interface
  !
  interface
    subroutine fits_convert_bintable_byrow(set,fits,row_buffer,obs,  &
      user_function,error)
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Extract 1 or more spectra found in each row, iterate on all rows
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=1),     intent(inout) :: row_buffer(:)  !
      type(observation),   intent(inout) :: obs            ! Observation buffer
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_convert_bintable_byrow
  end interface
  !
  interface
    subroutine fits_convert_bintable_matrix(set,fits,row_buffer,obs,user_function,error)
      use gbl_format
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read data from MATRIX or SPECTRUM or SERIES or DATA column,
      ! and write it as a Class spectrum
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=1),     intent(in)    :: row_buffer(:)  !
      type(observation),   intent(inout) :: obs            !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_convert_bintable_matrix
  end interface
  !
  interface
    subroutine fits_read_bintable_wave(row_buffer,ndata,cols,obs,error)
      use gbl_constant
      use gbl_format
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read X irregular axis from WAVE column
      !---------------------------------------------------------------------
      integer(kind=1),           intent(in)    :: row_buffer(:)  !
      integer(kind=4),           intent(in)    :: ndata          !
      type(classfits_columns_t), intent(in)    :: cols           ! Columns description
      type(observation),         intent(inout) :: obs            !
      logical,                   intent(inout) :: error          !
    end subroutine fits_read_bintable_wave
  end interface
  !
  interface
    subroutine fits_reset_column_positions(pos)
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      !   Reset the pointers to the bintable columns. 0 means 'I don't know
      ! this column (yet).'
      !----------------------------------------------------------------------
      type(classfits_column_positions_t), intent(inout) :: pos
    end subroutine fits_reset_column_positions
  end interface
  !
  interface
    subroutine fits_reset_column_desc(desc)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(classfits_column_desc_t), intent(inout) :: desc
    end subroutine fits_reset_column_desc
  end interface
  !
  interface
    subroutine fits_reset(fits)
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      !  Resets everything before reading a new file (or a new binary table
      ! extension)
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits
    end subroutine fits_reset
  end interface
  !
  interface
    subroutine fits_read_basicdata(fits,obs,error)
      use gildas_def
      use classfits_types
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Read all the data
      !----------------------------------------------------------------------
      type(classfits_t), intent(in)    :: fits   !
      type(observation), intent(inout) :: obs    !
      logical,           intent(inout) :: error  ! Error status
    end subroutine fits_read_basicdata
  end interface
  !
  interface
    subroutine fits_check_head(obs,error)
      use gbl_constant
      use phys_const
      use gbl_message
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS-FITS Internal routine
      !
      ! Check that no fundamental information is missing, and provide
      ! defaults otherwise.
      !----------------------------------------------------------------------
      type(observation), intent(inout) :: obs    !
      logical,           intent(out)   :: error  !
    end subroutine fits_check_head
  end interface
  !
  interface
    subroutine fits_head2obs(set,fits,obs,error)
      use gbl_constant
      use class_types
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      ! Try to translate the FITS header into sensible CLASS parameters.
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(classfits_t),   intent(inout) :: fits   !
      type(observation),   intent(inout) :: obs    !
      logical,             intent(inout) :: error  !
    end subroutine fits_head2obs
  end interface
  !
  interface
    subroutine fits_head2obs_class(set,fits,obs,error)
      use gbl_constant
      use phys_const
      use gbl_message
      use class_setup_new
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  FITS header to observation header conversion
      !  Specific to the CLASS FITS format
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(classfits_t),   intent(inout) :: fits   ! Unit header
      type(observation),   intent(inout) :: obs    !
      logical,             intent(inout) :: error  !
    end subroutine fits_head2obs_class
  end interface
  !
  interface
    subroutine fits_read_header(fits,check,error)
      use gbl_message
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      ! Read header information into FITS work arrays
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits   !
      logical,           intent(in)    :: check  ! Echo card images on terminal?
      logical,           intent(inout) :: error  !
    end subroutine fits_read_header
  end interface
  !
  interface
    subroutine fits_convert_header(fits,obs,error,user_function)
      use gbl_message
      use classfits_types
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      !   Read header information into CLASS variables
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits           !
      type(observation), intent(inout) :: obs            !
      logical,           intent(inout) :: error          !
      logical,           external      :: user_function  !
    end subroutine fits_convert_header
  end interface
  !
  interface
    subroutine fits_read_header_card(comm,argu,fits,inerror,error)
      use phys_const
      use gbl_constant
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Decode the card (name+value) into the fits header structure
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: comm     !
      character(len=*),  intent(in)    :: argu     !
      type(classfits_t), intent(inout) :: fits     ! FITS header
      integer(kind=4),   intent(inout) :: inerror  ! Minor errors to be counted
      logical,           intent(inout) :: error    ! Logical error flag
    end subroutine fits_read_header_card
  end interface
  !
  interface
    subroutine fits_convert_header_card(comm,argu,obs,inerror,error)
      use phys_const
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Decode the card (name+value) into the obs structure
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: comm     !
      character(len=*),  intent(in)    :: argu     !
      type(observation), intent(inout) :: obs      !
      integer(kind=4),   intent(inout) :: inerror  ! Minor errors to be counted
      logical,           intent(inout) :: error    ! Logical error flag
    end subroutine fits_convert_header_card
  end interface
  !
  interface
    subroutine werror(comm,count,warn)
      use gbl_message
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS internal routine
      ! Print an error message and increment error counter
      !-------------------------------------------------------------------
      character(len=*), intent(in)    :: comm
      integer,          intent(inout) :: count
      logical,          intent(in)    :: warn
    end subroutine werror
  end interface
  !
  interface
    subroutine fits_read_header_desc(fits,check,invalid,error)
      use gbl_message
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      ! Retrieve really essential information from a header:
      !   data size, and type of FITS format (basic FITS, or binary table).
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits     !
      logical,           intent(in)    :: check    ! Echo card images on terminal.
      logical,           intent(out)   :: invalid  ! Validity status.
      logical,           intent(inout) :: error    ! Error status.
    end subroutine fits_read_header_desc
  end interface
  !
  interface
    subroutine fits_read_bintable_header(fits,error)
      use gildas_def
      use gbl_format
      use gbl_message
      use classfits_types
      !----------------------------------------------------------------------
      ! @ private
      ! Try to decode the column description (for binary  tables). Decode
      ! FITS format of each column into a column width, a repeat count and
      ! a SIC format code.
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits
      logical,           intent(inout) :: error
    end subroutine fits_read_bintable_header
  end interface
  !
  interface
    subroutine class_fits_decode_colpos(stype_in,icol,hifi,colpos,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set column position in the input structure
      !---------------------------------------------------------------------
      character(len=*),                   intent(in)    :: stype_in  ! Column TTYPE string
      integer(kind=4),                    intent(in)    :: icol      ! Associated column number
      logical,                            intent(in)    :: hifi      ! Search also for HIFI columns?
      type(classfits_column_positions_t), intent(inout) :: colpos    ! Updated column positions list
      logical,                            intent(inout) :: error     ! Logical error flag
    end subroutine class_fits_decode_colpos
  end interface
  !
  interface
    subroutine check_axis(axis,naxis,ndata,main,error)
      use gbl_message
      !----------------------------------------------------------------------
      ! @ private
      ! CLASS-FITS Internal routine
      !
      ! Try to decode the column description (for binary  tables).
      ! recall: naxis=0 for binary table
      !----------------------------------------------------------------------
      integer, intent(in)  :: naxis       ! Number of axes.
      integer, intent(in)  :: axis(naxis) ! Axes dimensions.
      integer, intent(out) :: ndata       ! Number of data points.
      integer, intent(out) :: main        ! Main axis number.
      logical, intent(out) :: error       ! Logical error flag.
    end subroutine check_axis
  end interface
  !
  interface
    subroutine fits_chopbuf_1header(fits,row,lr,obs,error)
      use gildas_def
      use gbl_message
      use gbl_format
      use gbl_constant
      use phys_const
      use classfits_types
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Chop the row buffer into individual header elements.
      ! Granularity is at the header level.
      !----------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits     !
      integer(kind=4),   intent(in)    :: lr       ! Row buffer length
      integer(kind=1),   intent(in)    :: row(lr)  ! Row buffer
      type(observation), intent(inout) :: obs      !
      logical,           intent(out)   :: error    ! Logical error flag
    end subroutine fits_chopbuf_1header
  end interface
  !
  interface
    subroutine fits_decode_specsys(specsys,vtype)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      ! Decode SPECSYS value as velocity type.
      ! Note: values are not modified if information is missing (might be
      ! read from another keyword).
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: specsys
      integer(kind=4),  intent(inout) :: vtype
    end subroutine fits_decode_specsys
  end interface
  !
  interface
    subroutine fits_decode_velref(velref,vconv,vtype)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ private
      ! Decode VELREF value as velocity convention + velocity type.
      ! Note: values are not modified if information is missing (might be
      ! read from another keyword).
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: velref
      integer(kind=4), intent(inout) :: vconv
      integer(kind=4), intent(inout) :: vtype
    end subroutine fits_decode_velref
  end interface
  !
  interface
    subroutine fits_convert_bintable_hifi(set,fits,row_buffer,obs,invalid,  &
        user_function,error)
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=1),     intent(inout) :: row_buffer(:)  !
      type(observation),   intent(inout) :: obs            !
      logical,             intent(inout) :: invalid        !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          ! Logical error flag
    end subroutine fits_convert_bintable_hifi
  end interface
  !
  interface
    subroutine fits_parse_ishcss_hifi(fits,ishcss,error)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Parse the HCSS vs CLASS-FITS format
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits    ! inout because of fits_get_header_card
      logical,           intent(out)   :: ishcss  !
      logical,           intent(inout) :: error   !
    end subroutine fits_parse_ishcss_hifi
  end interface
  !
  interface
    subroutine fits_parse_version_hifi(fits,version,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Parse the FITS version from CREATOR card
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits  ! inout because of fits_get_header_card
      character(len=*),  intent(out)   :: version
      logical,           intent(inout) :: error
    end subroutine fits_parse_version_hifi
  end interface
  !
  interface
    subroutine fits_check_version_hifi(fits,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Check if the FITS version is supported
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits
      logical,           intent(inout) :: error
    end subroutine fits_check_version_hifi
  end interface
  !
  interface
    subroutine fits_convert_bintable_bycolumn_hifi(set,fits,row_buffer,obs,  &
      user_function,error)
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Extract the 'flux' column as a single spectrum
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=1),     intent(inout) :: row_buffer(:)  !
      type(observation),   intent(inout) :: obs            ! Observation buffer
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_convert_bintable_bycolumn_hifi
  end interface
  !
  interface
    subroutine fits_convert_bintable_byrow_hifi(set,row_buffer,fits,isub,obs,  &
      user_function,error)
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Read data from a HIFI FLUX_i columns and write it as a Class
      ! spectrum
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      integer(kind=1),     intent(in)    :: row_buffer(:)  !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=4),     intent(in)    :: isub           !
      type(observation),   intent(inout) :: obs            !
      logical,             external      :: user_function  !
      logical,             intent(inout) :: error          !
    end subroutine fits_convert_bintable_byrow_hifi
  end interface
  !
  interface
    subroutine fits_read_bintable_byrow_hifi(set,row_buffer,fits,isub,obs,  &
      obsdone,error)
      use gbl_constant
      use gbl_format
      use gbl_message
      use phys_const
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Read FITS binary table into Class parameters (HIFI-specific table)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      integer(kind=1),     intent(in)    :: row_buffer(:)  !
      type(classfits_t),   intent(inout) :: fits           !
      integer(kind=4),     intent(in)    :: isub           !
      type(observation),   intent(inout) :: obs            !
      logical,             intent(out)   :: obsdone        !
      logical,             intent(inout) :: error          !
    end subroutine fits_read_bintable_byrow_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_gen_hifi(fits,buffer,subband,obs,error)
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the General section
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits       !
      integer(kind=1),   intent(in)    :: buffer(:)  !
      integer(kind=4),   intent(in)    :: subband    ! Subband number
      type(observation), intent(inout) :: obs        !
      logical,           intent(inout) :: error      ! Logical error flag
    end subroutine fits_convert_header_gen_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_pos_hifi(set,fits,lam,bet,obs,error)
      use gbl_constant
      use gbl_message
      use phys_const
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the position section
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(classfits_t),   intent(inout) :: fits   !
      real(kind=8),        intent(in)    :: lam    ! [deg] Actual position (RA)
      real(kind=8),        intent(in)    :: bet    ! [deg] Actual position (DEC)
      type(observation),   intent(inout) :: obs    ! Position section
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine fits_convert_header_pos_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_spe_hifi(fits,buffer,colnum,nchan,obs,error)
      use phys_const
      use gbl_constant
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set up the spectroscopic section from obs%datav(:)
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits       !
      integer(kind=1),   intent(in)    :: buffer(:)  !
      integer(kind=4),   intent(in)    :: colnum     !
      integer(kind=4),   intent(in)    :: nchan      ! Number of channels
      type(observation), intent(inout) :: obs        !
      logical,           intent(inout) :: error      ! Logical error flag
    end subroutine fits_convert_header_spe_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_lofreq_hifi(fits,buffer,lofreq,error)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get the LO frequency from FITS header (zero-sized buffer) or from
      ! binary columns (non-zero buffer)
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits       !
      integer(kind=1),   intent(in)    :: buffer(:)  !
      real(kind=8),      intent(out)   :: lofreq     !
      logical,           intent(inout) :: error      !
    end subroutine fits_convert_header_lofreq_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_line_hifi(fits,lofrequency,line,error)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !   Set up the LINE name. 2 possibilities:
      ! - according to the input LO frequency, of the form: "1234.567_XSB"
      ! - or "DECON_SSB" for a deconvolved spectrum
      !   HIFI specific.
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits         ! Unit header
      real(kind=8),      intent(in)    :: lofrequency  ! [GHz]
      character(len=*),  intent(inout) :: line         !
      logical,           intent(inout) :: error        ! Logical error flag
    end subroutine fits_convert_header_line_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_swi_hifi(fits,buffer,obs,error)
      use gbl_constant
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the Frequency SWitch section
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits       !
      integer(kind=1),   intent(in)    :: buffer(:)  !
      type(observation), intent(inout) :: obs        !
      logical,           intent(inout) :: error      ! Logical error flag
    end subroutine fits_convert_header_swi_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_cal_hifi(fits,hotcold,obs,error)
      use gbl_constant
      use gbl_message
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the Calibration section
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits        !
      real(kind=8),      intent(in)    :: hotcold(2)  ! [K]
      type(observation), intent(inout) :: obs         !
      logical,           intent(inout) :: error       ! Logical error flag
    end subroutine fits_convert_header_cal_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_her_hifi(fits,buffer,obs,error)
      use gbl_message
      use phys_const
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the Herschel section
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits       !
      integer(kind=1),   intent(in)    :: buffer(:)  !
      type(observation), intent(inout) :: obs        !
      logical,           intent(inout) :: error      ! Logical error flag
    end subroutine fits_convert_header_her_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_vzinfo_hifi(fits,vinfo,zinfo,error)
      use gbl_constant
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set up the elements R%HEAD%HER%VINFO (informative source velocity
      ! in LSR) and R%HEAD%HER%ZINFO (Informative target redshift)
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits
      real(kind=4),      intent(out)   :: vinfo
      real(kind=4),      intent(out)   :: zinfo
      logical,           intent(inout) :: error
    end subroutine fits_convert_header_vzinfo_hifi
  end interface
  !
  interface
    subroutine fits_convert_header_assoc_hifi(fits,buffer,nchan,obs,aablank,aaline,error)
      use classfits_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set up the Associated Arrays section
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits        !
      integer(kind=1),   intent(in)    :: buffer(:)   !
      integer(kind=4),   intent(in)    :: nchan       !
      type(observation), intent(inout) :: obs         !
      integer(kind=4),   pointer       :: aablank(:)  ! Pointer to Associated Array set in return
      integer(kind=4),   pointer       :: aaline(:)   ! Pointer to Associated Array set in return
      logical,           intent(inout) :: error       ! Logical error flag
    end subroutine fits_convert_header_assoc_hifi
  end interface
  !
  interface
    subroutine fits_warning_hifi(fits,error)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Add the HIFI-specific warning
      !---------------------------------------------------------------------
      type(classfits_t), intent(inout) :: fits
      logical,           intent(inout) :: error
    end subroutine fits_warning_hifi
  end interface
  !
  interface
    subroutine fits_chopbuf_1chan_hifi(fits,row,lr,ifreq,iflux,iflag,obs,aablank,  &
      aaline,ichan,error)
      use gbl_format
      use classfits_types
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Chop the row buffer into individual channel elements.
      ! Granularity is at the channel level.
      !  HIFI-specific
      !----------------------------------------------------------------------
      type(classfits_t), intent(in)    :: fits        !
      integer(kind=4),   intent(in)    :: lr          ! Row buffer length
      integer(kind=1),   intent(in)    :: row(lr)     ! Row buffer
      integer(kind=4),   intent(in)    :: ifreq       ! Frequency column
      integer(kind=4),   intent(in)    :: iflux       ! Flux column
      integer(kind=4),   intent(in)    :: iflag       ! Flag column
      type(observation), intent(inout) :: obs         !
      integer(kind=4),   intent(inout) :: aablank(:)  ! BLANKED array
      integer(kind=4),   intent(inout) :: aaline(:)   ! LINE array
      integer(kind=4),   intent(in)    :: ichan       ! Channel to be updated
      logical,           intent(inout) :: error       ! Logical error flag
    end subroutine fits_chopbuf_1chan_hifi
  end interface
  !
  interface
    function fits_convert_flag_hifi(ikind,okind,flag)
      !---------------------------------------------------------------------
      ! @ private
      !  Convert a:
      !   ikind=1: row flag
      !   ikind=2: channel flag
      ! into a:
      !   okind=1: blank flag
      !   okind=2: window flag
      !  HIFI specific
      !---------------------------------------------------------------------
      integer(kind=4) :: fits_convert_flag_hifi  ! Function value on return
      integer(kind=4), intent(in) :: ikind  ! Input kind of flag
      integer(kind=4), intent(in) :: okind  ! Output kind of flag
      integer(kind=4), intent(in) :: flag   ! The flag value
    end function fits_convert_flag_hifi
  end interface
  !
  interface
    subroutine fits_get_header_val2key(head,val,key,found)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Find the key corresponding to input value. Key must start with
      ! "key." to avoid false positives. This prefix is stripped off on
      ! return. Search is case sensitive. For example
      !    HIERARCH  key.META_20='bbtype'
      ! returns "META_20".
      !---------------------------------------------------------------------
      type(classfits_header_t), intent(in)  :: head   ! Unit header
      character(len=*),         intent(in)  :: val    ! Desired value name
      character(len=*),         intent(out) :: key    ! Corresponding key name
      logical,                  intent(out) :: found  !
    end subroutine fits_get_header_val2key
  end interface
  !
  interface
    subroutine fits_get_header_key2val(head,key,val,found)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Find the (string) value corresponding to input key
      !---------------------------------------------------------------------
      type(classfits_header_t), intent(in)  :: head   ! Unit header
      character(len=*),         intent(in)  :: key    ! Key name
      character(len=*),         intent(out) :: val    ! Value found
      logical,                  intent(out) :: found  !
    end subroutine fits_get_header_key2val
  end interface
  !
  interface
    subroutine fits_get_bintable_key2column(cols,key,icol,found)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      ! Find the column number whose TTYPE is 'key'
      ! Case-sensitive search
      !---------------------------------------------------------------------
      type(classfits_columns_t), intent(in)  :: cols   ! Columns description
      character(len=*),          intent(in)  :: key    ! Key name
      integer(kind=4),           intent(out) :: icol   ! Column number, if found
      logical,                   intent(out) :: found  !
    end subroutine fits_get_bintable_key2column
  end interface
  !
  interface
    subroutine fits_warning_add(warn,mess,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Add a new warning to the warning list. Duplicates are not added
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn
      character(len=*),           intent(in)    :: mess
      logical,                    intent(inout) :: error
    end subroutine fits_warning_add
  end interface
  !
  interface
    subroutine fits_warning_dump(warn,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Displays the warnings in the structure input structure.
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn
      logical,                    intent(inout) :: error
    end subroutine fits_warning_dump
  end interface
  !
  interface fits_get_header_card
    subroutine fits_get_header_card_i4(fits,iname,i4,found,error,target)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      integer(kind=4),            intent(inout) :: i4      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_i4
    subroutine fits_get_header_card_i8(fits,iname,i8,found,error,target)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  I*8 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      integer(kind=8),            intent(inout) :: i8      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_i8
    subroutine fits_get_header_card_r4(fits,iname,r4,found,error,target)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      real(kind=4),               intent(inout) :: r4      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_r4
    subroutine fits_get_header_card_r8(fits,iname,r8,found,error,target)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  R*8 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      real(kind=8),               intent(inout) :: r8      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_r8
    subroutine fits_get_header_card_l(fits,iname,l,found,error,target)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  Logical version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      logical,                    intent(inout) :: l       ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_l
    subroutine fits_get_header_card_cc(fits,iname,value,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_card
      !  Translate a card to its associated value
      ! ---
      !  Character*(*) version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      character(len=*),           intent(inout) :: value   ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_card_cc
  end interface fits_get_header_card
  !
  interface fits_get_header_metacard
    subroutine fits_get_header_metacard_i4(fits,iname,i4,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      integer(kind=4),            intent(inout) :: i4      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_i4
    subroutine fits_get_header_metacard_i8(fits,iname,i8,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  I*8 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      integer(kind=8),            intent(inout) :: i8      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_i8
    subroutine fits_get_header_metacard_r4(fits,iname,r4,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      real(kind=4),               intent(inout) :: r4      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_r4
    subroutine fits_get_header_metacard_r8(fits,iname,r8,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  R*8 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      real(kind=8),               intent(inout) :: r8      ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_r8
    subroutine fits_get_header_metacard_l(fits,iname,l,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  Logical version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      logical,                    intent(inout) :: l       ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_l
    subroutine fits_get_header_metacard_cc(fits,iname,value,found,error,target)
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_header_metacard
      !  Translate meta-cards to their associated value, i.e. follow the
      ! indirection due to hierarch cards. For example:
      !  HIERARCH  key.META_20='bbtype'
      !  META_20 =                 6031 / [] Building Block Type
      ! The parsing here is probably very HIFI-specific
      ! ---
      !  Character*(*) version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits    !
      character(len=*),           intent(in)    :: iname   ! Card name
      character(len=*),           intent(inout) :: value   ! inout: if not found, input is preserved
      logical,                    intent(out)   :: found   !
      logical,                    intent(inout) :: error   ! Logical error flag
      character(len=*), optional, intent(in)    :: target  ! Target name
    end subroutine fits_get_header_metacard_cc
  end interface fits_get_header_metacard
  !
  interface fits_get_metacard_or_column
    subroutine fits_get_metacard_or_column_i4(fits,buffer,name,i4,found,error,target)
      use gbl_format
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_metacard_or_column
      !  If buffer(:) is zero-sized, read the metacard 'name' from the
      ! FITS header
      !  If not, read the single-valued column 'name' from the bintable
      !  NB: zero-sized arrays are legitimate objects in Fortran
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits       !
      integer(kind=1),            intent(in)    :: buffer(:)  !
      character(len=*),           intent(in)    :: name       ! Element name (case-sensitive)
      integer(kind=4),            intent(inout) :: i4         ! Previous value preserved if not found
      logical,                    intent(out)   :: found      !
      logical,                    intent(inout) :: error      !
      character(len=*), optional, intent(in)    :: target     ! Target name
    end subroutine fits_get_metacard_or_column_i4
    subroutine fits_get_metacard_or_column_r4(fits,buffer,name,r4,found,error,target)
      use gbl_format
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_metacard_or_column
      !  If buffer(:) is zero-sized, read the metacard 'name' from the
      ! FITS header
      !  If not, read the single-valued column 'name' from the bintable
      !  NB: zero-sized arrays are legitimate objects in Fortran
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits       !
      integer(kind=1),            intent(in)    :: buffer(:)  !
      character(len=*),           intent(in)    :: name       ! Element name (case-sensitive)
      real(kind=4),               intent(inout) :: r4         ! Target value (preserved if not found)
      logical,                    intent(out)   :: found      !
      logical,                    intent(inout) :: error      !
      character(len=*), optional, intent(in)    :: target     ! Target name
    end subroutine fits_get_metacard_or_column_r4
    subroutine fits_get_metacard_or_column_r8(fits,buffer,name,r8,found,error,target)
      use gbl_format
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_get_metacard_or_column
      !  If buffer(:) is zero-sized, read the metacard 'name' from the
      ! FITS header
      !  If not, read the single-valued column 'name' from the bintable
      !  NB: zero-sized arrays are legitimate objects in Fortran
      ! ---
      !  Scalar R*8 version
      !---------------------------------------------------------------------
      type(classfits_t),          intent(inout) :: fits       !
      integer(kind=1),            intent(in)    :: buffer(:)  !
      character(len=*),           intent(in)    :: name       ! Element name (case-sensitive)
      real(kind=8),               intent(inout) :: r8         ! Previous value preserved if not found
      logical,                    intent(out)   :: found      !
      logical,                    intent(inout) :: error      !
      character(len=*), optional, intent(in)    :: target     ! Target name
    end subroutine fits_get_metacard_or_column_r8
  end interface fits_get_metacard_or_column
  !
  interface fits_warn_missing
    subroutine fits_warn_missing_i4(warn,ftype,fname,tname,tvalue,found,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_warn_missing
      !  If not found, add a warning to the warning list
      ! ---
      !  I*4 version
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn    !
      character(len=*),           intent(in)    :: ftype   ! FITS element type
      character(len=*),           intent(in)    :: fname   ! FITS element name
      character(len=*),           intent(in)    :: tname   ! Target name
      integer(kind=4),            intent(in)    :: tvalue  ! Target value
      logical,                    intent(in)    :: found   ! Was it found or not?
      logical,                    intent(inout) :: error   !
    end subroutine fits_warn_missing_i4
    subroutine fits_warn_missing_i8(warn,ftype,fname,tname,tvalue,found,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_warn_missing
      !  If not found, add a warning to the warning list
      ! ---
      !  I*8 version
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn    !
      character(len=*),           intent(in)    :: ftype   ! FITS element type
      character(len=*),           intent(in)    :: fname   ! FITS element name
      character(len=*),           intent(in)    :: tname   ! Target name
      integer(kind=8),            intent(in)    :: tvalue  ! Target value
      logical,                    intent(in)    :: found   ! Was it found or not?
      logical,                    intent(inout) :: error   !
    end subroutine fits_warn_missing_i8
    subroutine fits_warn_missing_r4(warn,ftype,fname,tname,tvalue,found,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_warn_missing
      !  If not found, add a warning to the warning list
      ! ---
      !  R*4 version
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn    !
      character(len=*),           intent(in)    :: ftype   ! FITS element type
      character(len=*),           intent(in)    :: fname   ! FITS element name
      character(len=*),           intent(in)    :: tname   ! Target name
      real(kind=4),               intent(in)    :: tvalue  ! Target value
      logical,                    intent(in)    :: found   ! Was it found or not?
      logical,                    intent(inout) :: error   !
    end subroutine fits_warn_missing_r4
    subroutine fits_warn_missing_r8(warn,ftype,fname,tname,tvalue,found,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_warn_missing
      !  If not found, add a warning to the warning list
      ! ---
      !  R*8 version
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn    !
      character(len=*),           intent(in)    :: ftype   ! FITS element type
      character(len=*),           intent(in)    :: fname   ! FITS element name
      character(len=*),           intent(in)    :: tname   ! Target name
      real(kind=8),               intent(in)    :: tvalue  ! Target value
      logical,                    intent(in)    :: found   ! Was it found or not?
      logical,                    intent(inout) :: error   !
    end subroutine fits_warn_missing_r8
    subroutine fits_warn_missing_cc(warn,ftype,fname,tname,tvalue,found,error)
      use gbl_message
      use classfits_types
      !---------------------------------------------------------------------
      ! @ private-generic fits_warn_missing
      !  If not found, add a warning to the warning list
      ! ---
      !  C*(*) version
      !---------------------------------------------------------------------
      type(classfits_warnings_t), intent(inout) :: warn    !
      character(len=*),           intent(in)    :: ftype   ! FITS element type
      character(len=*),           intent(in)    :: fname   ! FITS element name
      character(len=*),           intent(in)    :: tname   ! Target name
      character(len=*),           intent(in)    :: tvalue  ! Target value
      logical,                    intent(in)    :: found   ! Was it found or not?
      logical,                    intent(inout) :: error   !
    end subroutine fits_warn_missing_cc
  end interface fits_warn_missing
  !
  interface
    subroutine las_tofits(set,obs,check,error)
      use gildas_def
      use phys_const
      use gbl_constant
      use gbl_message
      use class_fits
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Class private routine
      ! Write a single spectrum (the current one) in a FITS file
      ! Current limitations:
      !  - Horizontal offsets incorrectly handled.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      type(observation),   intent(inout) :: obs    ! The input observation
      logical,             intent(in)    :: check  ! Echo card images on terminal
      logical,             intent(inout) :: error  !
    end subroutine las_tofits
  end interface
  !
  interface
    function fitput(line,check)
      !---------------------------------------------------------------------
      ! @ private
      !  Write a FITS line of the header
      !---------------------------------------------------------------------
      logical :: fitput                     ! Function return value
      character(len=*), intent(in) :: line  ! Line to be written in FITS
      logical, intent(in) :: check          ! Echo line on terminal
    end function fitput
  end interface
  !
  interface
    subroutine tofits_radesys(set,head,radesys,equinox,ra,dec,error)
      use phys_const
      use gbl_constant
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Convert the current position section to:
      !  - RADESYS is relevant
      !  - EQUINOX if relevant
      !  - alternate RA, DEC if relevant (i.e. if starting from galactic)
      ! suited for FITS.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(header),        intent(in)    :: head
      character(len=*),    intent(out)   :: radesys
      real(kind=4),        intent(out)   :: equinox  ! [yr]
      real(kind=8),        intent(out)   :: ra,dec   ! [deg]
      logical,             intent(inout) :: error
    end subroutine tofits_radesys
  end interface
  !
  interface
    subroutine tofits_specsys(head,velkey,velref,specsys,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the following FITS keywords for the given observation:
      !   VELO*
      !   VELREF
      !   SPECSYS
      !---------------------------------------------------------------------
      type(header),     intent(in)    :: head
      character(len=*), intent(out)   :: velkey
      integer(kind=4),  intent(out)   :: velref
      character(len=*), intent(out)   :: specsys
      logical,          intent(inout) :: error
    end subroutine tofits_specsys
  end interface
  !
  interface
    subroutine unblank_reject(tabin,tabou,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Copy input table into output table, but reject all spectra which
      ! contain one or more blank values
      !---------------------------------------------------------------------
      type(gildas), intent(in)    :: tabin  !
      type(gildas), intent(inout) :: tabou  !
      logical,      intent(inout) :: error  !
    end subroutine unblank_reject
  end interface
  !
  interface
    subroutine unblank_patch(tabou,mode,val,error)
      use image_def
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Copy input table into output table, but replace blanking values
      ! by a value, noise, or interpolation
      !---------------------------------------------------------------------
      type(gildas),    intent(inout) :: tabou  ! Pre-filled with all tabin values
      integer(kind=4), intent(in)    :: mode   ! Replacement mode 1|2|3
      real(kind=4),    intent(in)    :: val    ! Custom value (mode 1)
      logical,         intent(inout) :: error  !
    end subroutine unblank_patch
  end interface
  !
  interface
    subroutine uplot(x,y,imode)
      use plot_formula
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	User unit entry.
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine uplot
  end interface
  !
  interface
    subroutine cplot(x,y,imode)
      use plot_formula
      !-------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	Channel units entry
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine cplot
  end interface
  !
  interface
    subroutine vplot(x,y,imode)
      use plot_formula
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	Velocity units entry
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine vplot
  end interface
  !
  interface
    subroutine fplot(x,y,imode)
      use plot_formula
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	Frequency units entry
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine fplot
  end interface
  !
  interface
    subroutine iplot(x,y,imode)
      use plot_formula
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	Image units entry
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine iplot
  end interface
  !
  interface
    subroutine gplot(x,y,imode)
      !-------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine
      !	Draw a line from current pen position to specified (X,Y) position.
      !	Several entries are available, and correspond  to different units
      !	for the coordinates. IMODE=3 corresponds to a pen up move.
      !	Paper units entry
      !-------------------------------------------------------------------
      real(kind=4), intent(in) :: x ! X coordinate
      real(kind=4), intent(in) :: y ! Y coordinate
      integer, intent(in) :: imode  ! Pen down (#3) or up (=3) mode
    end subroutine gplot
  end interface
  !
  interface
    function user_sec_match(subsection)
      use class_user
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Return .true. if the input User Subsection matches the hooks
      ! known by Class
      !---------------------------------------------------------------------
      logical :: user_sec_match  ! Function value on return
      type(class_user_sub_t), intent(in) :: subsection  !
    end function user_sec_match
  end interface
  !
  interface
    subroutine user_sec_owner(subsection,iowner,error)
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Loop in the list of known hooks to find the one matching the input
      ! User Subsection
      !---------------------------------------------------------------------
      type(class_user_sub_t), intent(in)    :: subsection  !
      integer(kind=4),        intent(out)   :: iowner      !
      logical,                intent(inout) :: error       !
    end subroutine user_sec_owner
  end interface
  !
  interface
    subroutine reallocate_user(user,nuser,keep,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Allocates or reallocates the section user depending on the
      ! 'nuser' value. In case of reallocation, previous data is preserved.
      !---------------------------------------------------------------------
      type(class_user_t), intent(inout) :: user   !
      integer(kind=4),    intent(in)    :: nuser  ! Number of User Subsections needed
      logical,            intent(in)    :: keep   ! Keep the previous data when enlarging?
      logical,            intent(inout) :: error  ! Logical error flag
    end subroutine reallocate_user
  end interface
  !
  interface
    subroutine reallocate_user_sub(sub,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  Reallocate sub%data according to sub%ndata
      !---------------------------------------------------------------------
      type(class_user_sub_t), intent(inout) :: sub
      logical,                intent(inout) :: error
    end subroutine reallocate_user_sub
  end interface
  !
  interface
    subroutine rzero_user(obs)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Reset the User Section to default value
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs  !
    end subroutine rzero_user
  end interface
  !
  interface
    subroutine copy_user(inuser,outuser,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Copy the User Section from the input observation to the output one.
      ! User Section is enlarged if needed.
      !---------------------------------------------------------------------
      type(class_user_t), intent(in)    :: inuser   ! Input user section
      type(class_user_t), intent(inout) :: outuser  ! Output user section
      logical,            intent(inout) :: error    ! Logical error flag
    end subroutine copy_user
  end interface
  !
  interface
    subroutine user_sec_dump(obs,error)
      use gbl_message
      use class_buffer
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !   Dump all the User Sections from the input observation. Data is
      ! not displayed if there is no hook provided by the user.
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! Observation
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_dump
  end interface
  !
  interface
    subroutine user_sec_setvar(set,obs,delete,error)
      use gbl_message
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Support subroutine for
      !   SET VARIABLE USER
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set     !
      type(observation),   intent(in)    :: obs     ! Observation
      logical,             intent(in)    :: delete  ! Delete structure only?
      logical,             intent(inout) :: error   ! Logical error flag
    end subroutine user_sec_setvar
  end interface
  !
  interface
    subroutine user_sec_fix(obs,found,error)
      use gbl_message
      use class_buffer
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !   Select or not the input observation according to its user section
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: obs    ! Observation
      logical,           intent(out)   :: found  !
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_fix
  end interface
  !
  interface
    subroutine user_sec_find(line,error)
      use gbl_message
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Command line parsing for option FIND /USER
      !---------------------------------------------------------------------
      character(len=*), intent(in) :: line  !
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_find
  end interface
  !
  interface
    subroutine user_sec_varidx_fill(obs,ient,error)
      use gildas_def
      use gbl_message
      use class_buffer
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Fill the VARIABLE /INDEX support array(s) for user section
      !---------------------------------------------------------------------
      type(observation),          intent(in)    :: obs    ! Observation
      integer(kind=entry_length), intent(in)    :: ient   ! Entry number in index
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_varidx_fill
  end interface
  !
  interface
    subroutine user_sec_varidx_defvar(error)
      use gildas_def
      use gbl_message
      use classic_api
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Define the VARIABLE /INDEX sic arrays for user section
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_varidx_defvar
  end interface
  !
  interface
    subroutine user_sec_varidx_realloc(nent,error)
      use gildas_def
      use classic_api
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Re/Deallocate the VARIABLE /INDEX support arrays for user section
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: nent   ! Size of arrays
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine user_sec_varidx_realloc
  end interface
  !
  interface
    subroutine class_user_reset(set)
      use class_types
      use class_user
      !---------------------------------------------------------------------
      ! @ private
      !  Reset the User Subsection hooks, i.e. forget how to handle a
      ! specific User Subsection
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in) :: set
    end subroutine class_user_reset
  end interface
  !
  interface
    subroutine reallocate_uwork(newlen,twice,error)
      use class_buffer
      !---------------------------------------------------------------------
      ! @ private
      !  Reallocate the 'uwork' working buffer
      !---------------------------------------------------------------------
      integer(kind=data_length), intent(in)    :: newlen  !
      logical,                   intent(in)    :: twice   ! Strict reallocation or twice more?
      logical,                   intent(inout) :: error   !
    end subroutine reallocate_uwork
  end interface
  !
  interface
    subroutine class_uvzero_new(set,line,error,user_function)
      use phys_const
      use image_def
      use gbl_message
      use class_index
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   UV_ZERO file.uvt /NEW
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      character(len=*),    intent(in)    :: line
      logical,             intent(inout) :: error
      logical,             external      :: user_function
    end subroutine class_uvzero_new
  end interface
  !
  interface
    subroutine mosaic_getfields(visi,np,nv,ixoff,iyoff,nf,doff)
      use gkernel_types
      !----------------------------------------------------------------------
      ! @ private
      !  Count number of fields and get their coordinates
      !----------------------------------------------------------------------
      integer(kind=4), intent(in)    :: np                    ! Size of a visibility
      integer(kind=4), intent(in)    :: nv                    ! Number of visibilities
      real(kind=4),    intent(in)    :: visi(np,nv)           ! Input visibilities
      integer(kind=4), intent(in)    :: ixoff                 ! X pointer
      integer(kind=4), intent(in)    :: iyoff                 ! Y pointer
      integer(kind=4), intent(out)   :: nf                    ! Number of fields
      real(kind=4),    intent(out), allocatable :: doff(:,:)  ! Field offsets
    end subroutine mosaic_getfields
  end interface
  !
  interface
    function mosaic_getfields_offset_eq(x1,x2,y1,y2)
      use phys_const
      !---------------------------------------------------------------------
      ! @ private
      ! Equality routine between two pairs of offset (real*8) with a
      ! tolerance.
      ! ---
      ! This subroutine should be kept in 'mosaic_getfields' under a
      ! contains statement, but gfortran 4.4 is not able to compile this...
      !---------------------------------------------------------------------
      logical :: mosaic_getfields_offset_eq
      real(kind=8), intent(in) :: x1,x2  ! [rad]
      real(kind=8), intent(in) :: y1,y2  ! [rad]
    end function mosaic_getfields_offset_eq
  end interface
  !
  interface
    subroutine class_set_structure(set,error)
      use gildas_def
      use class_setup_new
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !   Define the SIC variables which map the internal set% values.
      ! Currently only map a few values, mostly those which are scalar,
      ! i.e. unique in the SET calling sequence (e.g. SET TYPE SPECTRO).
      ! Will have to think twice for the variable name when multiple
      ! arguments are provided in the SET calling sequence (e.g. SET ALIGN
      ! VELO INTER)
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set    !
      logical,             intent(inout) :: error  ! Logical error flag
    end subroutine class_set_structure
  end interface
  !
  interface
    subroutine las_variables_rgen(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rgen
  end interface
  !
  interface
    subroutine las_variables_rpos(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rpos
  end interface
  !
  interface
    subroutine las_variables_rspe(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rspe
  end interface
  !
  interface
    subroutine las_variables_rres(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rres
  end interface
  !
  interface
    subroutine las_variables_rbas(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rbas
  end interface
  !
  interface
    subroutine las_variables_rhis(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rhis
  end interface
  !
  interface
    subroutine las_variables_rplo(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rplo
  end interface
  !
  interface
    subroutine las_variables_rswi(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rswi
  end interface
  !
  interface
    subroutine las_variables_rcal(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rcal
  end interface
  !
  interface
    subroutine las_variables_rsky(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rsky
  end interface
  !
  interface
    subroutine las_variables_rgau(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rgau
  end interface
  !
  interface
    subroutine las_variables_rshe(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rshe
  end interface
  !
  interface
    subroutine las_variables_rhfs(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rhfs
  end interface
  !
  interface
    subroutine las_variables_rabs(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rabs
  end interface
  !
  interface
    subroutine las_variables_rdri(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rdri
  end interface
  !
  interface
    subroutine las_variables_rbea(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rbea
  end interface
  !
  interface
    subroutine las_variables_rpoi(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rpoi
  end interface
  !
  interface
    subroutine las_variables_rher(struct,obs,ro,error)
      use gildas_def
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: struct  ! Structure to be filled
      type(observation), intent(in)    :: obs     ! Observation to be mapped
      logical,           intent(in)    :: ro      ! Should the variables be RO?
      logical,           intent(inout) :: error   ! Logical error flag
    end subroutine las_variables_rher
  end interface
  !
  interface
    subroutine las_variables_r_old(r,error)
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !  (Re)define the set of old R-related variables which are always
      ! present in Class.
      !  NB: There are yet other sets of old R-related variables, section
      ! per section, defined by the command SET VARIABLE <section>. The
      ! associated names may be different again e.g. NCHAN vs CHANNELS
      !---------------------------------------------------------------------
      type(observation), intent(in)    :: r      !
      logical,           intent(inout) :: error  ! Logical error flag
    end subroutine las_variables_r_old
  end interface
  !
  interface
    subroutine las_codes(error)
      !---------------------------------------------------------------------
      ! @ private
      !  Define SIC variables providing the various codes used by the Class
      ! Data Format
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine las_codes
  end interface
  !
  interface
    subroutine las_codes_sections(parent,error)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Define SIC variables providing the Section codes
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: parent  ! Parent structure name
      logical,          intent(inout) :: error   ! Logical error flag
    end subroutine las_codes_sections
  end interface
  !
  interface
    subroutine las_codes_qual(parent,error)
      use class_parameter
      !---------------------------------------------------------------------
      ! @ private
      !  Define SIC variables providing the Quality codes
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: parent  ! Parent structure name
      logical,          intent(inout) :: error   ! Logical error flag
    end subroutine las_codes_qual
  end interface
  !
  interface
    subroutine las_codes_calmode(parent,error)
      use class_calibr
      !---------------------------------------------------------------------
      ! @ private
      !  Define SIC variables providing the Calibration mode codes
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: parent  ! Parent structure name
      logical,          intent(inout) :: error   ! Logical error flag
    end subroutine las_codes_calmode
  end interface
  !
  interface
    subroutine wgen(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the GENeral Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wgen
  end interface
  !
  interface
    subroutine wres(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the RESolution section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wres
  end interface
  !
  interface
    subroutine wbase(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the BASE Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wbase
  end interface
  !
  interface
    subroutine wcom(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the COMment Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wcom
  end interface
  !
  interface
    subroutine wcal(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the CALibration Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wcal
  end interface
  !
  interface
    subroutine wcont(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the CONTinuum Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wcont
  end interface
  !
  interface
    subroutine wbeam(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the BEAM Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wbeam
  end interface
  !
  interface
    subroutine wswi(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the SWitching Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wswi
  end interface
  !
  interface
    subroutine wgaus(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the GAUSs Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wgaus
  end interface
  !
  interface
    subroutine wnh3(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the NH3 Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wnh3
  end interface
  !
  interface
    subroutine wabs(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the ABSorption Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wabs
  end interface
  !
  interface
    subroutine wshel(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the SHELl Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wshel
  end interface
  !
  interface
    subroutine worig(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the ORIGin Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine worig
  end interface
  !
  interface
    subroutine wplot(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the PLOT Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wplot
  end interface
  !
  interface
    subroutine wpos(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the POSition Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wpos
  end interface
  !
  interface
    subroutine wspec(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the SPECtroscopic Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wspec
  end interface
  !
  interface
    subroutine wpoint(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the POINTing Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wpoint
  end interface
  !
  interface
    subroutine wsky(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the SKYdip Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wsky
  end interface
  !
  interface
    subroutine wxcoo(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the X COOrdinates Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wxcoo
  end interface
  !
  interface
    subroutine wdescr(set,obs,error)
      use class_types
      !-------------------------------------------------------------------
      ! @ private
      !   Write the DESCRiptor Section
      !-------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wdescr
  end interface
  !
  interface
    subroutine wuser(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write the USER defined section description
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wuser
  end interface
  !
  interface
    subroutine wherschel(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write the HERSCHEL defined section description
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wherschel
  end interface
  !
  interface
    subroutine wassoc(set,obs,error)
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Write the ASSOCiated Arrays section
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set
      type(observation),   intent(inout) :: obs
      logical,             intent(inout) :: error
    end subroutine wassoc
  end interface
  !
  interface
    subroutine wdata(obs,ndata,array,error)
      use gbl_message
      use classic_api
      use class_types
      use class_common
      !----------------------------------------------------------------------
      ! @ private
      ! Write or update the data section
      !----------------------------------------------------------------------
      type(observation), intent(inout) :: obs           ! Observation to be written
      integer(kind=4),   intent(in)    :: ndata         ! Length in 32_bit words of data
      real(kind=4),      intent(in)    :: array(ndata)  ! Data itself
      logical,           intent(inout) :: error         ! Error flag
    end subroutine wdata
  end interface
  !
  interface
    subroutine wavelet_obs(obs,iorder,doplot,plotpen,error)
      use gildas_def
      use class_types
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Compute and modify inplace the wavelets for input observation
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      integer(kind=4),   intent(in)    :: iorder   ! /BASE order?
      logical,           intent(in)    :: doplot   !
      integer(kind=4),   intent(in)    :: plotpen  !
      logical,           intent(inout) :: error    !
    end subroutine wavelet_obs
  end interface
  !
  interface
    subroutine wincur(set,mw,nw,w1,w2,wtype)
      use gbl_constant
      use gbl_message
      use class_setup_new
      use class_types
      use plot_formula
      !----------------------------------------------------------------------
      ! @ private
      !  Use the cursor to setup a list of windows, or masks
      !----------------------------------------------------------------------
      type(class_setup_t), intent(in)  :: set     !
      integer(kind=4),     intent(in)  :: mw      ! Maximum number of regions
      integer(kind=4),     intent(out) :: nw      ! Actual number of regions
      real(kind=4),        intent(out) :: w1(mw)  ! Lower bounds of regions
      real(kind=4),        intent(out) :: w2(mw)  ! Upper bounds of regions
      character(len=*),    intent(in)  :: wtype   ! Type of regions (Window or Mask)
    end subroutine wincur
  end interface
  !
  interface
    subroutine class_update(set,rname,obs,error,user_function)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS Internal routine for commands
      !   UPDATE
      !   WRITE
      !  Update the input observation in the output file. Output file is not
      ! flushed, it must be done (or not for efficiency purpose) by the
      ! calling routine.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      character(len=*),    intent(in)    :: rname          ! Caller name
      type(observation),   intent(inout) :: obs            !
      logical,             intent(inout) :: error          ! Return error code
      logical,             external      :: user_function  ! Handling of user defined sections
    end subroutine class_update
  end interface
  !
  interface
    subroutine class_write_open(set,obs,maxsec,entry_num,error)
      use gbl_message
      use class_common
      use class_types
      !----------------------------------------------------------------------
      ! @ private
      ! Starts the writing of a new observation.
      !----------------------------------------------------------------------
      type(class_setup_t),        intent(in)    :: set        !
      type(observation),          intent(inout) :: obs        !
      integer(kind=4),            intent(in)    :: maxsec     ! Max num of sections to be written (in addition of the data)
      integer(kind=entry_length), intent(out)   :: entry_num  ! Entry number of the observation in the output file
      logical,                    intent(inout) :: error      ! Error flag
    end subroutine class_write_open
  end interface
  !
  interface
    subroutine class_write_transfer(set,obs,error,user_function)
      use gildas_def
      use gbl_format
      use gbl_constant
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! CLASS External routine (available to other programs)
      !  Perform all the necessary operations to transfer the observation
      ! once it has been defined in 'obs' and opened in the output file.
      !---------------------------------------------------------------------
      type(class_setup_t), intent(in)    :: set            !
      type(observation),   intent(inout) :: obs            ! or intent(in) only?
      logical,             intent(inout) :: error          ! Return error code
      logical,             external      :: user_function  ! Handling of user defined sections
    end subroutine class_write_transfer
  end interface
  !
end module classcore_interfaces_private
