module mrtcal_interfaces_private
  interface
    subroutine reallocate_chunk(nchan,chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (Re)allocate a chunk so that it can describe n channels.
      !-------------------------------------------------------------------
      integer(kind=4),  intent(in)    :: nchan
      type(chunk_t),    intent(inout) :: chunk
      logical,          intent(inout) :: error
    end subroutine reallocate_chunk
  end interface
  !
  interface
    subroutine reallocate_chunkset(n,chunkset,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (Re)allocate a chunkset so that it can store n chunks.
      !
      ! Nothing is done for the chunks in the chunkset. The caller is free
      ! to allocate them or associate them depending on its need.
      !-------------------------------------------------------------------
      integer(kind=4),  intent(in)    :: n
      type(chunkset_t), intent(inout) :: chunkset
      logical,          intent(inout) :: error
    end subroutine reallocate_chunkset
  end interface
  !
  interface
    subroutine reallocate_chunkset_2d(nset,npix,ou2d,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate a 2D array of chunksets of same dimension as another
      ! 2D array of chunksets
      !
      ! Nothing is done for the chunksets and for the chunks in the
      ! chunksets. The caller is free to allocate them or associate them
      ! depending on its need.
      !-------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: nset
      integer(kind=4),     intent(in)    :: npix
      type(chunkset_2d_t), intent(inout) :: ou2d
      logical,             intent(inout) :: error
    end subroutine reallocate_chunkset_2d
  end interface
  !
  interface
    subroutine reallocate_chunkset_3d(nset,npix,ntime,ck3d,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate a 3D array of chunksets.
      !
      ! Nothing is done for the chunksets and for the chunks in the
      ! chunksets. The caller is free to allocate them or associate them
      ! depending on its need.
      !-------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: nset
      integer(kind=4),     intent(in)    :: npix
      integer(kind=4),     intent(in)    :: ntime
      type(chunkset_3d_t), intent(inout) :: ck3d
      logical,             intent(inout) :: error
    end subroutine reallocate_chunkset_3d
  end interface
  !
  interface
    subroutine reallocate_chopperset(chunkset_2d,chopperset,error)
      use gbl_message
      use chopper_definitions
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate chopperset with a size deduced from chunkset
      !-------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: chunkset_2d
      type(chopper_t),     pointer       :: chopperset(:,:) ! inout
      logical,             intent(inout) :: error
    end subroutine reallocate_chopperset
  end interface
  !
  interface
    subroutine reallocate_calib_scan(n,calarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate calibration arrays
      !-------------------------------------------------------------------
      integer(kind=4),    intent(in)    :: n
      type(calib_scan_t), intent(inout) :: calarray
      logical,            intent(inout) :: error
    end subroutine reallocate_calib_scan
  end interface
  !
  interface
    subroutine reallocate_science_scan(n,sciarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate science arrays
      !-------------------------------------------------------------------
      integer(kind=4),              intent(in)    :: n
      type(science_scan_t), target, intent(inout) :: sciarray
      logical,                      intent(inout) :: error
    end subroutine reallocate_science_scan
  end interface
  !
  interface
    subroutine reallocate_backend_list(n,backarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate backend list arrays
      !-------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: n
      type(backend_list_t), intent(inout) :: backarray
      logical,              intent(inout) :: error
    end subroutine reallocate_backend_list
  end interface
  !
  interface
    subroutine reallocate_subscan_list(n,list,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate subscan list arrays
      !-------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: n
      type(subscan_list_t), intent(inout) :: list
      logical,              intent(inout) :: error
    end subroutine reallocate_subscan_list
  end interface
  !
  interface
    subroutine reallocate_switch_desc(noffset,nfront,desc,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate switch desc arrays
      !-------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: noffset
      integer(kind=4),     intent(in)    :: nfront
      type(switch_desc_t), intent(inout) :: desc
      logical,             intent(inout) :: error
    end subroutine reallocate_switch_desc
  end interface
  !
  interface
    subroutine reallocate_switch_cycle(ndump,npha,nfront,cycle,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! (re)allocate cycle arrays
      !-------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: ndump
      integer(kind=4),      intent(in)    :: npha
      integer(kind=4),      intent(in)    :: nfront
      type(switch_cycle_t), intent(inout) :: cycle
      logical,              intent(inout) :: error
    end subroutine reallocate_switch_cycle
  end interface
  !
  interface
    subroutine free_chunk(chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! Free a chunk
      !-------------------------------------------------------------------
      type(chunk_t), intent(inout) :: chunk
      logical,       intent(inout) :: error
    end subroutine free_chunk
  end interface
  !
  interface
    subroutine free_chunkset(chunkset,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! Free a chunkset
      !-------------------------------------------------------------------
      type(chunkset_t), intent(inout) :: chunkset
      logical,          intent(inout) :: error
    end subroutine free_chunkset
  end interface
  !
  interface
    subroutine free_chunkset_2d(ck2d,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !  Free a chunkset_2d type:
      !   1) free all the elements in its 2D array of chunksets,
      !   2) free the array itself
      !-------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: ck2d
      logical,             intent(inout) :: error
    end subroutine free_chunkset_2d
  end interface
  !
  interface
    subroutine free_chunkset_3d(ck3d,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !  Free a chunkset_3d type:
      !   1) free all the elements in its 3D array of chunksets,
      !   2) free the array itself
      !-------------------------------------------------------------------
      type(chunkset_3d_t), intent(inout) :: ck3d
      logical,             intent(inout) :: error
    end subroutine free_chunkset_3d
  end interface
  !
  interface
    subroutine free_chopperset(chopperset,error)
      use gbl_message
      use chopper_definitions
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      ! Free a 2D array of chopper type
      !-------------------------------------------------------------------
      type(chopper_t), pointer       :: chopperset(:,:)
      logical,         intent(inout) :: error
    end subroutine free_chopperset
  end interface
  !
  interface
    subroutine free_calib_scan(calarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(calib_scan_t), intent(inout) :: calarray
      logical,            intent(inout) :: error
    end subroutine free_calib_scan
  end interface
  !
  interface
    subroutine free_calib_backend(backcal,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t), intent(inout) :: backcal  !
      logical,               intent(inout) :: error    !
    end subroutine free_calib_backend
  end interface
  !
  interface
    subroutine free_science_scan(sciarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(science_scan_t), intent(inout) :: sciarray
      logical,              intent(inout) :: error
    end subroutine free_science_scan
  end interface
  !
  interface
    subroutine free_science_backend(backsci,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine free_science_backend
  end interface
  !
  interface
    subroutine free_on_stack(on,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(on_stack_t), intent(inout) :: on
      logical,          intent(inout) :: error
    end subroutine free_on_stack
  end interface
  !
  interface
    subroutine free_off_stack(off,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(off_stack_t), intent(inout) :: off
      logical,           intent(inout) :: error
    end subroutine free_off_stack
  end interface
  !
  interface
    subroutine free_backend_list(backarray,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(backend_list_t), intent(inout) :: backarray
      logical,              intent(inout) :: error
    end subroutine free_backend_list
  end interface
  !
  interface
    subroutine free_subscan_list(list,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(subscan_list_t), intent(inout) :: list
      logical,              intent(inout) :: error
    end subroutine free_subscan_list
  end interface
  !
  interface
    subroutine free_switch_desc(desc,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(switch_desc_t), intent(inout) :: desc
      logical,             intent(inout) :: error
    end subroutine free_switch_desc
  end interface
  !
  interface
    subroutine free_switch_cycle(cycle,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(switch_cycle_t), intent(inout) :: cycle
      logical,              intent(inout) :: error
    end subroutine free_switch_cycle
  end interface
  !
  interface
    subroutine reallocate_dble_1d(r8,newndata,keep,error)
      !---------------------------------------------------------------------
      ! @ private
      ! Reallocate a simple 1D REAL*8 pointer
      !---------------------------------------------------------------------
      real(kind=8),    pointer       :: r8(:)     !
      integer(kind=4), intent(in)    :: newndata  !
      logical,         intent(in)    :: keep      !
      logical,         intent(inout) :: error     !
    end subroutine reallocate_dble_1d
  end interface
  !
  interface
    subroutine reassociate_chunkset(in,ou,error,ichunk)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Associate a chunkset onto another one.
      !  If 'ichunk' is present, associate only onto this single element
      ! (pointer to subset).
      !---------------------------------------------------------------------
      type(chunkset_t),          intent(in)    :: in
      type(chunkset_t),          intent(inout) :: ou
      logical,                   intent(inout) :: error
      integer(kind=4), optional, intent(in)    :: ichunk
    end subroutine reassociate_chunkset
  end interface
  !
  interface
    subroutine nullify_chunk(chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(chunk_t), intent(inout) :: chunk
      logical,       intent(inout) :: error
    end subroutine nullify_chunk
  end interface
  !
  interface
    subroutine nullify_chunkset(chunkset,error)
      use gbl_message
      use mrtcal_calib_types
      !-------------------------------------------------------------------
      ! @ private
      !-------------------------------------------------------------------
      type(chunkset_t), intent(inout) :: chunkset
      logical,          intent(inout) :: error
    end subroutine nullify_chunkset
  end interface
  !
  interface
    subroutine nullify_chunkset_2d(ck2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Nullify a chunkset_2d type.
      !  Nullify only the array. Its components are owned by the target,
      ! this is its responsibility, not ours here.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: ck2d
      logical,             intent(inout) :: error
    end subroutine nullify_chunkset_2d
  end interface
  !
  interface reassociate_chunk
    subroutine reassociate_chunk_on_data(dataval,datawei,fchan,nchan,chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic reassociate_chunk
      !---------------------------------------------------------------------
      real(kind=4), target, intent(in)    :: dataval(:)  ! DATA target
      real(kind=4), target, intent(in)    :: datawei(:)  ! WEIGHT target
      integer(kind=4),      intent(in)    :: fchan       ! First channel
      integer(kind=4),      intent(in)    :: nchan       ! Number of channels
      type(chunk_t),        intent(inout) :: chunk       !
      logical,              intent(inout) :: error       ! Logical error flag
    end subroutine reassociate_chunk_on_data
    subroutine reassociate_chunk_on_chunk(in,ou,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic reassociate_chunk
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: in
      type(chunk_t), intent(inout) :: ou
      logical,       intent(inout) :: error
    end subroutine reassociate_chunk_on_chunk
  end interface reassociate_chunk
  !
  interface reassociate_chunkset_2d
    subroutine reassociate_chunkset_2d_on_2d(in2d,ou2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic reassociate_chunkset_2d
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: in2d
      type(chunkset_2d_t), intent(inout) :: ou2d
      logical,             intent(inout) :: error
    end subroutine reassociate_chunkset_2d_on_2d
    subroutine reassociate_chunkset_2d_on_3d(itime,in3d,ou2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic reassociate_chunkset_2d
      !---------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: itime  ! Position in in3d
      type(chunkset_3d_t), intent(in)    :: in3d   !
      type(chunkset_2d_t), intent(inout) :: ou2d   !
      logical,             intent(inout) :: error  !
    end subroutine reassociate_chunkset_2d_on_3d
  end interface reassociate_chunkset_2d
  !
  interface reassociate_chunkset_3d
    subroutine reassociate_chunkset_3d_on_2d(itime,in2d,ou3d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic reassociate_chunkset_3d
      ! Associate a subset of a chunkset_3d onto a chunkset_2d. Note that
      ! this is kind of reverse operation done by
      ! reassociate_chunkset_2d_on_3d.
      !
      !   Note also that:
      !   - this is a problem of "arrays of pointers", which, in Fortran
      !     is not possible
      !   - chunkset_3d are always allocated, never associated
      ! which means we can not associate a chunkset_3d onto several
      ! chunkset_2d. But this is what we want to do!
      !   Knowing that:
      !   - chunkset are always allocated, never associated
      !   - chunks can be allocated or associated
      ! The solution is to allocate the chunkset_3d, plus its chunksets,
      ! but associate its chunks to the desired target at very low level...
      !---------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: itime   ! Position in ou3d
      type(chunkset_2d_t), intent(in)    :: in2d   !
      type(chunkset_3d_t), intent(inout) :: ou3d   !
      logical,             intent(inout) :: error  !
    end subroutine reassociate_chunkset_3d_on_2d
  end interface reassociate_chunkset_3d
  !
  interface
    subroutine mrtcal_bookkeeping_init_time(bufsize,subs,time,error)
      use gbl_message
      use ram_sizes
      use imbfits_types
      use mrtcal_bookkeeping_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize a time loop
      !---------------------------------------------------------------------
      integer(kind=8),         intent(in)    :: bufsize
      type(imbfits_subscan_t), intent(in)    :: subs
      type(book_t),            intent(inout) :: time
      logical,                 intent(inout) :: error
    end subroutine mrtcal_bookkeeping_init_time
  end interface
  !
  interface
    subroutine mrtcal_bookkeeping_iterate(time,subs,first,last,needupdate,error)
      use imbfits_types
      use mrtcal_bookkeeping_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !  Fill the time%cur% structure suited for reading at least dumps
      ! 'first' to 'last'. They are the first and last dumps the caller
      ! wants to be present AT LEAST in the buffer. 'first' and 'last' are
      ! absolute positions in the compressed backdata columns.
      !---------------------------------------------------------------------
      type(book_t),            intent(inout) :: time
      type(imbfits_subscan_t), intent(in)    :: subs
      integer(kind=4),         intent(in)    :: first
      integer(kind=4),         intent(in)    :: last
      logical,                 intent(out)   :: needupdate
      logical,                 intent(inout) :: error
    end subroutine mrtcal_bookkeeping_iterate
  end interface
  !
  interface
    subroutine mrtcal_bookkeeping_compr2uncompr(compr,backpoin,uncompr,error)
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      !   Convert a "compressed" range_t (i.e. providing indices in the
      ! compressed columns to an "uncompressed" range_t.
      !   "compressed" columns are present in the BackendData e.g. if SET
      ! CALIB BAD is NO
      !---------------------------------------------------------------------
      type(range_t),   intent(in)    :: compr        !
      integer(kind=4), intent(in)    :: backpoin(:)  ! Back-pointer array
      type(range_t),   intent(out)   :: uncompr      !
      logical,         intent(inout) :: error        !
    end subroutine mrtcal_bookkeeping_compr2uncompr
  end interface
  !
  interface
    subroutine mrtcal_init_scan_cal(backsci,imbf,error)
      use gbl_message
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_t),         intent(inout) :: imbf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_init_scan_cal
  end interface
  !
  interface
    subroutine mrtcal_accumulate_cycle(backsci,dowei,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Accumulate last dump after (re)initialization of the accumulation when
      ! requested
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(in)    :: dowei
      logical,                 intent(inout) :: error
    end subroutine mrtcal_accumulate_cycle
  end interface
  !
  interface
    subroutine mrtcal_init_accumulate_or_write(obstype,swmode,iset,oset,error)
      use gbl_message
      use mrtindex_parameters
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set up the accumulation mode according to user's MSET OUTPUT
      ! INTEGRATION choice, and to observing mode in case of automatic
      ! choice.
      !---------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: obstype  ! [code] Observing type
      integer(kind=4),      intent(in)    :: swmode   ! [code] Switching mode
      type(mrtcal_setup_t), intent(in)    :: iset     ! Setup (user choices)
      type(mrtcal_setup_t), intent(inout) :: oset     ! Setup (resolved)
      logical,              intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_init_accumulate_or_write
  end interface
  !
  interface
    subroutine mrtcal_write_cycle(setout,backsci,error)
      use gbl_message
      use mrtcal_setup_types
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_output_t), intent(in)    :: setout
      type(science_backend_t),     intent(inout) :: backsci
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_cycle
  end interface
  !
  interface
    subroutine mrtcal_write_subscan(setout,backsci,error)
      use gbl_message
      use mrtcal_setup_types
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_output_t), intent(in)    :: setout
      type(science_backend_t),     intent(inout) :: backsci
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_subscan
  end interface
  !
  interface
    subroutine mrtcal_write_scan(setout,backsci,error)
      use gbl_message
      use mrtcal_setup_types
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_output_t), intent(in)    :: setout
      type(science_backend_t),     intent(inout) :: backsci
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_scan
  end interface
  !
  interface
    subroutine mrtcal_accumulate_or_write(level_code,mrtset,backsci,error)
      use gbl_message
      use mrtcal_level_codes
      use mrtcal_setup_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer(kind=4),         intent(in)    :: level_code
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_accumulate_or_write
  end interface
  !
  interface
    subroutine mrtcal_init_refloop(backsci,nref,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize the loop on REF subscans, i.e., number of REF.
      ! Enforce initialization of the cumulated chunkset_2d structure if and when needed
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      integer(kind=4),         intent(out)   :: nref
      logical,                 intent(inout) :: error
    end subroutine mrtcal_init_refloop
  end interface
  !
  interface
    subroutine mrtcal_get_nextref(backsci,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Update the REF number
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_nextref
  end interface
  !
  interface
    subroutine mrtcal_init_onloop(backsci,non,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize the loop on ON subscans, i.e., number of ON, current on and
      ! OFF subscan numbers
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      integer(kind=4),         intent(out)   :: non
      logical,                 intent(inout) :: error
    end subroutine mrtcal_init_onloop
  end interface
  !
  interface
    subroutine mrtcal_get_nexton(backsci,error)
      use gkernel_types
      use imbfits_types
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Get in the current list of subscans the number of next ON subscan
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_nexton
  end interface
  !
  interface
    subroutine mrtcal_sanity_check(backsci,error)
      use mrtcal_calib_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Check whether ON and OFF subscans are red and give user feedback
      ! about the next processing step
      !---------------------------------------------------------------------
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_sanity_check
  end interface
  !
  interface
    subroutine mrtcal_init_dumpcycle_loop(name,mrtset,filebuf,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*),        intent(in)    :: name
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_init_dumpcycle_loop
  end interface
  !
  interface
    subroutine mrtcal_init_dumpcycle_book(time,switch,error)
      use gbl_message
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(book_t),   intent(in)    :: time
      type(switch_t), intent(inout) :: switch
      logical,        intent(inout) :: error
    end subroutine mrtcal_init_dumpcycle_book
  end interface
  !
  interface
    subroutine mrtcal_get_next_dumpcycle(mrtset,filebuf,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Search for and then read next cycle
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_next_dumpcycle
  end interface
  !
  interface
    subroutine mrtcal_find_next_dumpcycle(backdata,book,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Search for cycle phases in increasing order and return when found.
      ! If the cycle is incomplete, try to find the next cycle.
      ! Return with found = .false. when it tries to read past the last dump
      ! of the subscan.
      ! Caution: Modifying this code can lead to infinite loops...
      !---------------------------------------------------------------------
      type(imbfits_backdata_t), intent(in)    :: backdata
      type(switch_book_t),      intent(inout) :: book
      logical,                  intent(inout) :: error
    end subroutine mrtcal_find_next_dumpcycle
  end interface
  !
  interface
    subroutine mrtcal_read_next_dumpcycle(setup,imbf,subshead,databuf,switch,error)
      use gbl_message
      use imbfits_types
      use mrtcal_setup_types
      use mrtcal_buffer_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: setup
      type(imbfits_t),         intent(in)    :: imbf
      type(imbfits_subscan_t), intent(in)    :: subshead
      type(data_buffer_t),     intent(inout) :: databuf
      type(switch_t),          intent(inout) :: switch
      logical,                 intent(inout) :: error
    end subroutine mrtcal_read_next_dumpcycle
  end interface
  !
  interface
    subroutine mrtcal_update_databuf(setup,imbf,subshead,book,databuf,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Update (only IF NEEDED) the DATA buffer currently in memory
      ! according to the switching cycle described in 'switch'. As output
      ! the subroutine guarantees that (at least) this cycle is entirely in
      ! the DATA buffer.
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: setup
      type(imbfits_t),         intent(in)    :: imbf
      type(imbfits_subscan_t), intent(in)    :: subshead
      type(switch_book_t),     intent(in)    :: book
      type(data_buffer_t),     intent(inout) :: databuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_update_databuf
  end interface
  !
  interface
    subroutine mrtcal_fill_dumpphase(iphase,subshead,databuf,book,dump,error)
      use gbl_message
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer(kind=4),         intent(in)    :: iphase
      type(imbfits_subscan_t), intent(in)    :: subshead
      type(data_buffer_t),     intent(in)    :: databuf
      type(switch_book_t),     intent(in)    :: book
      type(chunkset_2d_t),     intent(inout) :: dump
      logical,                 intent(inout) :: error
    end subroutine mrtcal_fill_dumpphase
  end interface
  !
  interface
    subroutine mrtcal_calib_calibration(mrtset,filebuf,backcal,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !
      !  1. Read the calsky, calambient, calcold subscan in the order they
      !     appear in the IMBFITS and compute the mean counts over the channels.
      !  2. Fill the chopper structure, compute the Tamt, Trec, Tsys, and Tcal,
      !     and fill the chunkset structure with these results.
      !  3. List results on screen and write results in the output CLASS file.
      !
      !  When the calsky is the only missing subscan, we can still compute an
      !  approximated receiver temperature (i.e., assuming 100% coupling to the
      !  hot and cold loads). To do this, we create a blanked calsky so that we
      !  can use exactly the same steps/pieces of code. It's only in the
      !  chopper code that we'll catch the fact we can only compute the Trec.  
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),   intent(in)    :: mrtset
      type(imbfits_buffer_t), intent(inout) :: filebuf
      type(calib_backend_t),  intent(inout) :: backcal
      logical,                intent(inout) :: error
    end subroutine mrtcal_calib_calibration
  end interface
  !
  interface
    subroutine mrtcal_calibrate_toclass(mrtset,backcal,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),  intent(in)    :: mrtset
      type(calib_backend_t), intent(inout) :: backcal
      logical,               intent(inout) :: error
    end subroutine mrtcal_calibrate_toclass
  end interface
  !
  interface
    subroutine mrtcal_calibrate_user_feedback(backcal,setout,error)
      use gbl_message
      use mrtcal_buffers
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Some direct allocations and deallocations here. It should maybe be 
      ! changed *** JP
      !---------------------------------------------------------------------
      type(calib_backend_t),       intent(in)    :: backcal
      type(mrtcal_setup_output_t), intent(in)    :: setout
      logical,                     intent(inout) :: error
    end subroutine mrtcal_calibrate_user_feedback
  end interface
  !
  interface
    subroutine mrtcal_calibrate_compute_chopperset(backcal,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t), intent(inout) :: backcal
      logical,               intent(inout) :: error
    end subroutine mrtcal_calibrate_compute_chopperset
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chunkset2chopperset(backcal,mrtset,error)
      use gbl_message
      use phys_const
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t), intent(inout) :: backcal
      type(mrtcal_setup_t),  intent(in)    :: mrtset
      logical,               intent(inout) :: error
    end subroutine mrtcal_calibrate_chunkset2chopperset
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset2chunkset(backcal,error)
      use gbl_message
      use chopper_definitions
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t), target, intent(inout) :: backcal
      logical,                       intent(inout) :: error
    end subroutine mrtcal_calibrate_chopperset2chunkset
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset_cross(hh,vv,hv,vh,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chopper_t),  intent(in)    :: hh
      type(chopper_t),  intent(in)    :: vv
      type(chopper_t),  intent(inout) :: hv
      type(chopper_t),  intent(inout) :: vh
      logical,          intent(inout) :: error
    end subroutine mrtcal_calibrate_chopperset_cross
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset2loadheader(chopperset,chunkset,error)
      use gbl_message
      use phys_const
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chopper_t),  intent(in)    :: chopperset
      type(chunkset_t), intent(inout) :: chunkset
      logical,          intent(inout) :: error
    end subroutine mrtcal_calibrate_chopperset2loadheader
  end interface
  !
  interface
    subroutine mrtcal_calibrate_patch_atsysheader(chopperset,chunkset,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Ad-hoc patch to replace gen%tsys in the chunk header as the
      ! attenuated Tsys from chopper type.
      !---------------------------------------------------------------------
      type(chopper_t),  intent(in)    :: chopperset
      type(chunkset_t), intent(inout) :: chunkset
      logical,          intent(inout) :: error
    end subroutine mrtcal_calibrate_patch_atsysheader
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset2calarray(chopperset,ref,trec,tcal,  &
      atsys,tsys,water,ztau,flag,error)
      use gbl_message
      use phys_const
      use mrtcal_calib_types
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chopper_t),  intent(in)    :: chopperset
      type(chunkset_t), intent(in)    :: ref
      type(chunkset_t), intent(inout) :: trec
      type(chunkset_t), intent(inout) :: tcal
      type(chunkset_t), intent(inout) :: atsys
      type(chunkset_t), intent(inout) :: tsys
      type(chunkset_t), intent(inout) :: water
      type(chunkset_t), intent(inout) :: ztau
      type(chunkset_t), intent(inout) :: flag
      logical,          intent(inout) :: error
    end subroutine mrtcal_calibrate_chopperset2calarray
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset_interpolate(chopperset,nchunk,mrtset,  &
      trec,tcal,atsys,tsys,water,ztau,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate the calibration products (Trec, Tcal, Tsys, Water,
      ! Ztau) per chunk and per channels, according to the desired
      ! interpolation mode.
      !---------------------------------------------------------------------
      type(chopper_t),      intent(in)    :: chopperset  !
      integer(kind=4),      intent(in)    :: nchunk      ! Number of chunks
      type(mrtcal_setup_t), intent(in)    :: mrtset      !
      type(chunkset_t),     intent(inout) :: trec        !
      type(chunkset_t),     intent(inout) :: tcal        !
      type(chunkset_t),     intent(inout) :: atsys       !
      type(chunkset_t),     intent(inout) :: tsys        !
      type(chunkset_t),     intent(inout) :: water       !
      type(chunkset_t),     intent(inout) :: ztau        !
      logical,              intent(inout) :: error       !
    end subroutine mrtcal_calibrate_chopperset_interpolate
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset_interpolate_nearest(chopperset,nchunk,  &
      trec,tcal,atsys,tsys,water,ztau,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate the calibration products (Trec, Tcal, Tsys, Water,
      ! Ztau) per chunk and per channels, using nearest value.
      !---------------------------------------------------------------------
      type(chopper_t),      intent(in)    :: chopperset  !
      integer(kind=4),      intent(in)    :: nchunk      ! Number of chunks
      type(chunkset_t),     intent(inout) :: trec        !
      type(chunkset_t),     intent(inout) :: tcal        !
      type(chunkset_t),     intent(inout) :: atsys       !
      type(chunkset_t),     intent(inout) :: tsys        !
      type(chunkset_t),     intent(inout) :: water       !
      type(chunkset_t),     intent(inout) :: ztau        !
      logical,              intent(inout) :: error       !
    end subroutine mrtcal_calibrate_chopperset_interpolate_nearest
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset_interpolate_linear(chopperset,nchunk,  &
      trec,tcal,atsys,tsys,water,ztau,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate the calibration products (Trec, Tcal, Tsys, Water,
      ! Ztau) per chunk and per channels, using linear interpolation.
      !---------------------------------------------------------------------
      type(chopper_t),      intent(in)    :: chopperset  !
      integer(kind=4),      intent(in)    :: nchunk      ! Number of chunks
      type(chunkset_t),     intent(inout) :: trec        !
      type(chunkset_t),     intent(inout) :: tcal        !
      type(chunkset_t),     intent(inout) :: atsys       !
      type(chunkset_t),     intent(inout) :: tsys        !
      type(chunkset_t),     intent(inout) :: water       !
      type(chunkset_t),     intent(inout) :: ztau        !
      logical,              intent(inout) :: error       !
    end subroutine mrtcal_calibrate_chopperset_interpolate_linear
  end interface
  !
  interface
    subroutine mrtcal_calibrate_chopperset_interpolate_spline(chopperset,nchunk,  &
      trec,tcal,atsys,tsys,water,ztau,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate the calibration products (Trec, Tcal, Tsys, Water,
      ! Ztau) per chunk and per channels, using cubic spline interpolation.
      !---------------------------------------------------------------------
      type(chopper_t),      intent(in)    :: chopperset  !
      integer(kind=4),      intent(in)    :: nchunk      ! Number of chunks
      type(chunkset_t),     intent(inout) :: trec        !
      type(chunkset_t),     intent(inout) :: tcal        !
      type(chunkset_t),     intent(inout) :: atsys       !
      type(chunkset_t),     intent(inout) :: tsys        !
      type(chunkset_t),     intent(inout) :: water       !
      type(chunkset_t),     intent(inout) :: ztau        !
      logical,              intent(inout) :: error       !
    end subroutine mrtcal_calibrate_chopperset_interpolate_spline
  end interface
  !
  interface
    subroutine mrtcal_calibrate_average_load(mrtset,name,imbf,subscanbuf,load,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),   intent(in)    :: mrtset
      character(len=*),       intent(in)    :: name
      type(imbfits_t),        intent(in)    :: imbf
      type(subscan_buffer_t), intent(inout) :: subscanbuf
      type(chunkset_2d_t),    intent(inout) :: load
      logical,                intent(inout) :: error
    end subroutine mrtcal_calibrate_average_load
  end interface
  !
  interface
    subroutine mrtcal_calibrate_grid(mrtset,imbf,subscanbuf,backcal,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),   intent(in)    :: mrtset
      type(imbfits_t),        intent(in)    :: imbf
      type(subscan_buffer_t), intent(inout) :: subscanbuf
      type(calib_backend_t),  intent(inout) :: backcal
      logical,                intent(inout) :: error
    end subroutine mrtcal_calibrate_grid
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_calgrid(chunksetlist,grid_2d,amppha_2d,sincos_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(in)    :: chunksetlist
      type(chunkset_2d_t), target, intent(in)    :: grid_2d
      type(chunkset_2d_t), target, intent(inout) :: amppha_2d
      type(chunkset_2d_t), target, intent(inout) :: sincos_2d
      logical,                     intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_calgrid
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_cross(chunksetlist,operation,chunkset_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(in)    :: chunksetlist
      type(chunkset_2d_t), target, intent(inout) :: chunkset_2d
      logical,                     intent(inout) :: error
      external :: operation
    end subroutine mrtcal_chunkset_2d_cross
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_modify_source(source,chunkset_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: source
      type(chunkset_2d_t), intent(inout) :: chunkset_2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_modify_source
  end interface
  !
  interface
    subroutine mrtcal_gr8_median(data,ndata,bval,eval,median,error)
      use gildas_def
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! *** JP Trick because gr8_median does not return the blanking
      ! *** JP value when there is no valid data
      !---------------------------------------------------------------------
      integer(kind=size_length), intent(in)    :: ndata        ! Array size
      real(kind=8),              intent(in)    :: data(ndata)  ! Data
      real(kind=8),              intent(in)    :: bval         ! Blanking value
      real(kind=8),              intent(in)    :: eval         ! Tolerance
      real(kind=8),              intent(inout) :: median       ! Median of input array
      logical,                   intent(inout) :: error        ! Logical error flag
    end subroutine mrtcal_gr8_median
  end interface
  !
  interface
    subroutine mrtcal_check_substype(ith,name,subheader,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer(kind=4),         intent(in)    :: ith
      character(len=*),        intent(in)    :: name
      type(imbfits_subscan_t), intent(in)    :: subheader
      logical,                 intent(inout) :: error
    end subroutine mrtcal_check_substype
  end interface
  !
  interface
    subroutine mrtcal_average_times(mrtset,iscal,ith,name,imbf,subscanbuf,averaged,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! We read the imbfits data in a limited size buffer. To do this, we
      ! read it by part. Thus, there is no reason to keep it in the main
      ! structure. We keep only the product, i.e. the time average...
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),   intent(in)    :: mrtset
      logical,                intent(in)    :: iscal
      integer(kind=4),        intent(in)    :: ith
      character(len=*),       intent(in)    :: name
      type(imbfits_t),        intent(in)    :: imbf
      type(subscan_buffer_t), intent(inout) :: subscanbuf
      type(chunkset_2d_t),    intent(inout) :: averaged
      logical,                intent(inout) :: error
    end subroutine mrtcal_average_times
  end interface
  !
  interface
    subroutine mrtcal_average_time_init(elevation,chunkset_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Initialize the input array of chunksets:
      !  - the data and weights arrays (Npix x Nset) are filled with zeros,
      !---------------------------------------------------------------------
      real(kind=8),        intent(in)    :: elevation    ! Double in contrast with CLASS header
      type(chunkset_2d_t), intent(inout) :: chunkset_2d  !
      logical,             intent(inout) :: error        !
    end subroutine mrtcal_average_time_init
  end interface
  !
  interface
    subroutine mrtcal_average_time_range(chunkset_3d,chunkset_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Average all the chunksets from the input chunkset_3d into the
      ! output chunkset_2d.
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(in)    :: chunkset_3d
      type(chunkset_2d_t), intent(inout) :: chunkset_2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_average_time_range
  end interface
  !
  interface
    subroutine mrtcal_average_channels(chunkset_2d,error)
      use gildas_def
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: chunkset_2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_average_channels
  end interface
  !
  interface
    subroutine mrtcal_compute_opacity_corr(tauzen,current,expatau,error)
      use gbl_message
      use phys_const
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the opacity correction for all the chunks of a chunkset_2d
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: tauzen
      type(chunkset_2d_t), intent(in)    :: current
      type(chunkset_2d_t), intent(inout) :: expatau
      logical,             intent(inout) :: error
    end subroutine mrtcal_compute_opacity_corr
  end interface
  !
  interface
    subroutine mrtcal_compute_opacity_corr_data(bad,nchan,airmass,tauzen,expatau,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the opacity correction, i.e., exp( airmass * tauzen ), as
      ! a function of the frequency
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)    :: bad
      integer(kind=4), intent(in)    :: nchan
      real(kind=4),    intent(in)    :: airmass
      real(kind=4),    intent(in)    :: tauzen(nchan)
      real(kind=4),    intent(out)   :: expatau(nchan)
      logical,         intent(inout) :: error
    end subroutine mrtcal_compute_opacity_corr_data
  end interface
  !
  interface
    subroutine mrtcal_compute_opacity_corr_head(airmass,chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute the opacity correction, i.e., exp( airmass * tauzen )
      ! *** JP it could be some kind of average or median value
      !---------------------------------------------------------------------
      real(kind=4),  intent(in)    :: airmass
      type(chunk_t), intent(inout) :: chunk
      logical,       intent(inout) :: error
    end subroutine mrtcal_compute_opacity_corr_head
  end interface
  !
  interface
    subroutine mrtcal_on_minus_off(isotfmap,isfsw,backsci,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute ON-OFF and update the associated header
      !---------------------------------------------------------------------
      logical,                         intent(in)    :: isotfmap
      logical,                         intent(in)    :: isfsw
      type(science_backend_t), target, intent(inout) :: backsci
      logical,                         intent(inout) :: error
    end subroutine mrtcal_on_minus_off
  end interface
  !
  interface
    subroutine mrtcal_on_minus_off_new(isotfmap,isfsw,backcal,backsci,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute ON-OFF and update the associated header
      !---------------------------------------------------------------------
      logical,                         intent(in)    :: isotfmap
      logical,                         intent(in)    :: isfsw
      type(calib_backend_t),   target, intent(in)    :: backcal
      type(science_backend_t), target, intent(inout) :: backsci
      logical,                         intent(inout) :: error
    end subroutine mrtcal_on_minus_off_new
  end interface
  !
  interface
    subroutine mrtcal_on_minus_off_head(isotfmap,ion,ioff,on,off,diff,error)
      use gbl_message
      use gildas_def
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Update the ON-OFF time and noise
      !---------------------------------------------------------------------
      logical,         intent(in)    :: isotfmap
      integer(kind=4), intent(in)    :: ion
      integer(kind=4), intent(in)    :: ioff
      type(chunk_t),   intent(in)    :: on
      type(chunk_t),   intent(in)    :: off
      type(chunk_t),   intent(inout) :: diff
      logical,         intent(inout) :: error
    end subroutine mrtcal_on_minus_off_head
  end interface
  !
  interface
    subroutine mrtcal_on_minus_off_data_auto(bad,nchan,on,off,diff)
      use gbl_message
      use gildas_def
      !---------------------------------------------------------------------
      ! @ private
      ! Compute:  ON/OFF - 1
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)  :: bad
      integer(kind=4), intent(in)  :: nchan
      real(kind=4),    intent(in)  :: on(nchan)
      real(kind=4),    intent(in)  :: off(nchan)
      real(kind=4),    intent(out) :: diff(nchan)
    end subroutine mrtcal_on_minus_off_data_auto
  end interface
  !
  interface
    subroutine mrtcal_on_minus_off_data_cross(bad,nchan,on,off,auto1,auto2,diff)
      use gbl_message
      use gildas_def
      !---------------------------------------------------------------------
      ! @ private
      ! Compute:  (ON-OFF)/sqrt(AUTO1*AUTO2)
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)  :: bad
      integer(kind=4), intent(in)  :: nchan
      real(kind=4),    intent(in)  :: on(nchan)
      real(kind=4),    intent(in)  :: off(nchan)
      real(kind=4),    intent(in)  :: auto1(nchan)
      real(kind=4),    intent(in)  :: auto2(nchan)
      real(kind=4),    intent(out) :: diff(nchan)
    end subroutine mrtcal_on_minus_off_data_cross
  end interface
  !
  interface
    subroutine mrtcal_tscale_computation(backcal,backsci,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_tscale_computation
  end interface
  !
  interface
    subroutine mrtcal_tscale_application(tscale,inout,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Multiply the data spectra by the tscale spectra
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: tscale
      type(chunkset_3d_t), intent(inout) :: inout
      logical,             intent(inout) :: error
    end subroutine mrtcal_tscale_application
  end interface
  !
  interface
    subroutine mrtcal_fill_switch_section(cycle,error)
      use gbl_message
      use gbl_constant
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(switch_cycle_t), intent(inout) :: cycle
      logical,              intent(inout) :: error
    end subroutine mrtcal_fill_switch_section
  end interface
  !
  interface
    subroutine mrtcal_calib_command(line,error)
      use gbl_message
      use mrtcal_buffers
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      ! CALIBRATE ient
      ! 1. /WITH ical
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_calib_command
  end interface
  !
  interface
    subroutine mrtcal_calib_ix_entry(mrtset,ix,ientuser,icaluser,filebuf,  &
         calib,science,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: mrtset
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(inout) :: ientuser
      integer(kind=entry_length), intent(inout) :: icaluser
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(calib_t),              intent(inout) :: calib
      type(science_t),            intent(inout) :: science
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_ix_entry
  end interface
  !
  interface
    subroutine mrtcal_calib_ix_entry_calib(mrtset,ix,icaluser,filebuf,  &
         calib,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: mrtset
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(inout) :: icaluser
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(calib_t),              intent(inout) :: calib
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_ix_entry_calib
  end interface
  !
  interface
    subroutine mrtcal_calib_get_backid(idx,ient,backid,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Return the backend identifier for the i-th entry in the input index
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      integer(kind=entry_length), intent(in)    :: ient
      integer(kind=4),            intent(out)   :: backid
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_get_backid
  end interface
  !
  interface
    subroutine mrtcal_calib_autofind_matching_cal(idx,backward,mtole,ientuser,  &
      istart,jcalprog,error)
      use phys_const
      use mrtindex_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !   Automatic search of the previous or next matching calibration in
      ! the input index, starting from the istart entry.
      !   The returned scan will be:
      !    - a calibration (obstype)
      !    - with calibration status none or done (reject failed or empty)
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      logical,                    intent(in)    :: backward  ! Backward or forward search?
      real(kind=4),               intent(in)    :: mtole     ! [min] Tolerance
      integer(kind=entry_length), intent(in)    :: ientuser
      integer(kind=entry_length), intent(inout) :: istart
      integer(kind=entry_length), intent(out)   :: jcalprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_autofind_matching_cal
  end interface
  !
  interface
    subroutine mrtcal_calib_autofind_done_cal(mrtset,ix,ientuser,jcalprog,filebuf,calib,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Automatic search of the nearest matching calibration in the input index.
      ! Calibrate it when needed
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: mrtset
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(in)    :: ientuser
      integer(kind=entry_length), intent(out)   :: jcalprog
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(calib_t),              intent(inout) :: calib
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_autofind_done_cal
  end interface
  !
  interface
    subroutine mrtcal_calib_check_consistency(idx,ient,ical,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      integer(kind=entry_length), intent(in)    :: ient
      integer(kind=entry_length), intent(inout) :: ical
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_check_consistency
  end interface
  !
  interface
    subroutine mrtcal_calib_check_obstype_is_cal(idx,ical,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      integer(kind=entry_length), intent(inout) :: ical
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_check_obstype_is_cal
  end interface
  !
  interface
    subroutine mrtcal_calib_check_calstatus(idx,ical,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      integer(kind=entry_length), intent(in)    :: ical
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_check_calstatus
  end interface
  !
  interface
    subroutine mrtcal_calib_check_current(idx,ical,backcal,warn,same,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !  Check if the calibration scan given as argument is the ical-th
      ! entry in the index. Issue warning messages if needed.
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: idx
      integer(kind=entry_length), intent(in)    :: ical
      type(calib_backend_t),      intent(in)    :: backcal
      logical,                    intent(in)    :: warn
      logical,                    intent(out)   :: same
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_check_current
  end interface
  !
  interface
    subroutine mrtcal_calib_reload(mrtset,idx,ient,filebuf,calib,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_calib_types
      use mrtindex_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: mrtset
      type(mrtindex_optimize_t),  intent(inout) :: idx
      integer(kind=entry_length), intent(inout) :: ient
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(calib_t),              intent(inout) :: calib
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_reload
  end interface
  !
  interface
    subroutine mrtcal_calib_feedback(idx,ient,ical,warnlim,error)
      use phys_const
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)           :: idx
      integer(kind=entry_length), intent(in)           :: ient
      integer(kind=entry_length), intent(in), optional :: ical
      real(kind=4),               intent(in), optional :: warnlim
      logical,                    intent(inout)        :: error
    end subroutine mrtcal_calib_feedback
  end interface
  !
  interface
    subroutine mrtcal_calib_init_calib(ix,ientuser,ientprog,error)
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Prepare a new entry for a calibration scan
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(in)    :: ientuser
      integer(kind=entry_length), intent(out)   :: ientprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_init_calib
  end interface
  !
  interface
    subroutine mrtcal_calib_init_science(ix,ientuser,ientprog,error)
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Prepare a new entry for a science scan
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),    intent(inout) :: ix
      integer(kind=entry_length), intent(in)    :: ientuser
      integer(kind=entry_length), intent(out)   :: ientprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_init_science
  end interface
  !
  interface
    subroutine mrtcal_calib_init(ix,iscalib,ientuser,ientprog,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Do not call directly! Call mrtcal_calib_init_calib or
      ! mrtcal_calib_init_science instead.
      ! ---
      ! Copy the ient entry of the input index into a new entry. Then set 
      ! in place its calstatus to calstatus_failed. This status will
      ! be replaced in place by calstatus_done in mrtcal_calib_exit_*
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(inout) :: ix
      logical,                    intent(in)    :: iscalib
      integer(kind=entry_length), intent(in)    :: ientuser
      integer(kind=entry_length), intent(out)   :: ientprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_init
  end interface
  !
  interface
    subroutine mrtcal_calib_exit_calib(cal,ix,ientprog,error)
      use gbl_message
      use mrtindex_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t),      intent(in)    :: cal
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(in)    :: ientprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_exit_calib
  end interface
  !
  interface
    subroutine mrtcal_calib_exit_science(sci,ix,isciprog,icalprog,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(science_backend_t),    intent(in)    :: sci
      type(mrtindex_optimize_t),  intent(inout) :: ix
      integer(kind=entry_length), intent(in)    :: isciprog
      integer(kind=entry_length), intent(in)    :: icalprog
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_exit_science
  end interface
  !
  interface
    subroutine mrtcal_calib_onebackend_calibration(mrtset,scanidx,ient,filebuf,&
         backcal,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: mrtset
      type(mrtindex_optimize_t),  intent(in)    :: scanidx
      integer(kind=entry_length), intent(in)    :: ient
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(calib_backend_t),      intent(inout) :: backcal
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_onebackend_calibration
  end interface
  !
  interface
    subroutine mrtcal_calib_onebackend_science(doset,backcal,scanidx,ient,filebuf,&
         backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),       intent(in)    :: doset    ! Setup (user choices)
      type(calib_backend_t),      intent(in)    :: backcal
      type(mrtindex_optimize_t),  intent(in)    :: scanidx
      integer(kind=entry_length), intent(in)    :: ient
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(science_backend_t),    intent(inout) :: backsci
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_onebackend_science
  end interface
  !
  interface
    subroutine mrtcal_calib_read_backend_header(scanidx,ient,filebuf,head,error)
      use gbl_message
      use classic_api
      use mrtcal_buffer_types
      use mrtcal_buffers
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t),  intent(in)    :: scanidx
      integer(kind=entry_length), intent(in)    :: ient
      type(imbfits_buffer_t),     intent(inout) :: filebuf
      type(mrtindex_header_t),    intent(inout) :: head
      logical,                    intent(inout) :: error
    end subroutine mrtcal_calib_read_backend_header
  end interface
  !
  interface
    subroutine mrtcal_calib_otf_fsw(mrtset,backcal,backsci,filebuf,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_calib_otf_fsw
  end interface
  !
  interface
    subroutine mrtcal_calib_otf_psw(mrtset,backcal,backsci,filebuf,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_calib_otf_psw
  end interface
  !
  interface
    subroutine mrtcal_get_next_otfpsw_cycle(mrtset,filebuf,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! OTF PSW is an hybrid case between tracked PSW that only deals with
      ! subscan cycles and (WSW and FSW) that only deal with dump cycle. In
      ! OTF PSW, the ON is delivered as a dump, but the OFF is typically
      ! interpolated between two OFF subscans.
      !
      ! So here, we first read the current ON dump and put it in the
      ! cycle%data(1) structure, we then compute the OFF "phase" from one or
      ! two OFF subscans and put it in the cycle%data(2) structure. We can then
      ! fill the switching sections based on the cycle%desc structure.
      ! ---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_next_otfpsw_cycle
  end interface
  !
  interface
    subroutine mrtcal_otf_psw_read_surrounding_offs(mrtset,imbf,subscanbuf,backsci,error)
      use gbl_message
      use gkernel_types
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Get in the current list of subscans the number of the previous and 
      ! the next OFF subscans, read them, average them in time, and store 
      ! them into backsci%off
      !
      ! That's a stack. The code must start the previous OFF subscan, because 
      ! it probably is the current next OFF subscan, as the subscans are 
      ! ordered by increasing time. This saves data reading. Setting the 
      ! subscan number to zero means that we did not find either the previous 
      ! or the next off
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),            intent(in)    :: mrtset
      type(imbfits_t),                 intent(in)    :: imbf
      type(subscan_buffer_t),          intent(inout) :: subscanbuf
      type(science_backend_t), target, intent(inout) :: backsci
      logical,                         intent(inout) :: error
    end subroutine mrtcal_otf_psw_read_surrounding_offs
  end interface
  !
  interface
    subroutine mrtcal_otf_psw_interpolate_off_init(off,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! *** JP In output, interp%isub = prev%isub or interp%isub = next%isub
      ! *** JP It would be better to have the averaged value stored as a real
      ! *** JP If this subscan number is used at read time, some additional
      ! *** JP protection would be needed.
      !---------------------------------------------------------------------
      type(off_stack_t), target, intent(inout) :: off
      logical,                   intent(inout) :: error
    end subroutine mrtcal_otf_psw_interpolate_off_init
  end interface
  !
  interface
    subroutine mrtcal_otf_psw_prepare_nextoff(mrtset,filebuf,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Read the OFF subscans surrounding the current ON subscan and prepare
      ! the linear interpolation in time, i.e., compute the segment slope and
      ! constant
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      type(science_backend_t), intent(inout) :: backsci
      logical,                 intent(inout) :: error
    end subroutine mrtcal_otf_psw_prepare_nextoff
  end interface
  !
  interface
    subroutine mrtcal_otf_psw_select_off(mrtset,backsci,error)
      use mrtcal_messaging
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Select the OFF subscan to be used. It can be either a linear
      ! interpolation of the previous and next OFF or the nearest neighbour
      ! in time. That's MRTSET%CAL%INTERPOFF that switches the behavior.
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),            intent(in)    :: mrtset
      type(science_backend_t), target, intent(inout) :: backsci
      logical,                         intent(inout) :: error
    end subroutine mrtcal_otf_psw_select_off
  end interface
  !
  interface
    subroutine mrtcal_calib_tracked_fsw(mrtset,backcal,backsci,filebuf,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      use mrtcal_level_codes
      !---------------------------------------------------------------------
      ! @ private
      ! Gather all needed steps to read, calibrate, and write a 
      ! tracked frequency switched scan for a given backend
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_calib_tracked_fsw
  end interface
  !
  interface
    subroutine mrtcal_calib_tracked_psw(mrtset,backcal,backsci,filebuf,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Gather all needed steps to read, calibrate, and write a 
      ! tracked position switched scan for a given backend
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_calib_tracked_psw
  end interface
  !
  interface
    subroutine mrtcal_calib_tracked_psw_cycle(mrtset,imbf,ifirst,nswitch,  &
      subscanbuf,backcal,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Calibrate a TRACKED PSW cycle of subscans
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)            :: mrtset      !
      type(imbfits_t),         intent(in)            :: imbf        !
      integer(kind=4),         intent(in)            :: ifirst      ! First subscan in cycle
      integer(kind=4),         intent(in)            :: nswitch     ! Number of subscans in cycle
      type(subscan_buffer_t),  intent(inout)         :: subscanbuf  !
      type(calib_backend_t),   intent(in)            :: backcal     !
      type(science_backend_t), intent(inout), target :: backsci     !
      logical,                 intent(inout)         :: error       ! Logical error flag
    end subroutine mrtcal_calib_tracked_psw_cycle
  end interface
  !
  interface
    subroutine mrtcal_calib_tracked_wsw(mrtset,backcal,backsci,filebuf,error)
      use gbl_message
      use mrtcal_level_codes
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Gather all needed steps to read, calibrate, and write a 
      ! tracked wobbler switched scan for a given backend
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset
      type(calib_backend_t),   intent(in)    :: backcal
      type(science_backend_t), intent(inout) :: backsci
      type(imbfits_buffer_t),  intent(inout) :: filebuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_calib_tracked_wsw
  end interface
  !
  interface
    subroutine mrtcal_chunksets_from_data(imbf,subs,databuf,error)
      use gbl_message
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      ! Extract all chunks from DATA.
      !---------------------------------------------------------------------
      type(imbfits_t), target, intent(in)    :: imbf
      type(imbfits_subscan_t), intent(in)    :: subs
      type(data_buffer_t),     intent(inout) :: databuf
      logical,                 intent(inout) :: error
    end subroutine mrtcal_chunksets_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunksets_from_data_1time1pix(imbf,subs,data,weight,  &
         ipix,itime,chunks,set,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Gather the chunks by sets, for 1 time dump and 1 receiver pixel.
      !---------------------------------------------------------------------
      type(imbfits_t),             intent(in)    :: imbf
      type(imbfits_subscan_t),     intent(in)    :: subs
      real(kind=4),                intent(inout) :: data(:)    ! Input data values
      real(kind=4),                intent(in)    :: weight(:)  ! Input data weights
      integer(kind=4),             intent(in)    :: ipix
      integer(kind=4),             intent(in)    :: itime
      type(imbfits_back_chunks_t), intent(in)    :: chunks     ! Chunks description
      type(chunkset_t),            intent(inout) :: set(:)     ! Output chunksets
      logical,                     intent(inout) :: error
    end subroutine mrtcal_chunksets_from_data_1time1pix
  end interface
  !
  interface
    subroutine mrtcal_chunksets_from_data_1time1pix_1chunk(subs,data,weight,  &
      ipix,itime,ichunk,primary,scan,front,back,derot,chunk,error)
      use gbl_message
      use mrtcal_calib_types
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Fill the 'chunk' instance with correct values and data, from given
      ! IMBFITS tables.
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(in)    :: subs
      real(kind=4),            intent(inout) :: data(:)    ! Input data values
      real(kind=4),            intent(in)    :: weight(:)  ! Input data weights
      integer(kind=4),         intent(in)    :: ipix
      integer(kind=4),         intent(in)    :: itime
      integer(kind=4),         intent(in)    :: ichunk     ! Chunk position in the backend table
      type(imbfits_primary_t), intent(in)    :: primary
      type(imbfits_scan_t),    intent(in)    :: scan
      type(imbfits_front_t),   intent(in)    :: front
      type(imbfits_back_t),    intent(in)    :: back
      type(imbfits_derot_t),   intent(in)    :: derot
      type(chunk_t),           intent(inout) :: chunk      ! The chunk to be filled
      logical,                 intent(inout) :: error
    end subroutine mrtcal_chunksets_from_data_1time1pix_1chunk
  end interface
  !
  interface
    subroutine mrtcal_chunk_data_from_data(dataval,datawei,backe,ichunk,  &
         chunk,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Extract one chunk from DATA
      !---------------------------------------------------------------------
      real(kind=4), target, intent(inout) :: dataval(:)  ! inout because of sign flip
      real(kind=4), target, intent(in)    :: datawei(:)
      type(imbfits_back_t), intent(in)    :: backe
      integer(kind=4),      intent(in)    :: ichunk
      type(chunk_t),        intent(inout) :: chunk
      logical,              intent(inout) :: error
    end subroutine mrtcal_chunk_data_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_cal_from_data(scan,front,ifront,cal,error)
      use gbl_message
      use phys_const
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_scan_t),    intent(in)    :: scan
      type(imbfits_front_t),   intent(in)    :: front
      integer(kind=4),         intent(in)    :: ifront
      type(class_calib_t),     intent(out)   :: cal
      logical,                 intent(inout) :: error
    end subroutine mrtcal_chunk_cal_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_spe_from_data(antslow,front,ifront,back,ichunk,spe,error)
      use gbl_message
      use gbl_constant
      use phys_const
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! It is unclear whether at this stage we want the freq/vel axis
      ! to be defined in the source or the observatory frame *** JP
      ! Right now it is defined in the source frame
      !
      ! Order matters here!...
      !
      !---------------------------------------------------------------------
      type(imbfits_antslow_t), intent(in)    :: antslow
      type(imbfits_front_t),   intent(in)    :: front
      integer(kind=4),         intent(in)    :: ifront
      type(imbfits_back_t),    intent(in)    :: back
      integer(kind=4),         intent(in)    :: ichunk
      type(class_spectro_t),   intent(out)   :: spe
      logical,                 intent(inout) :: error
    end subroutine mrtcal_chunk_spe_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_gen_from_data(primary,scan,back,ichunk,backdata,itime,  &
      mjd,azimuth,elevation,lst,frontend,gen,error)
      use gbl_message
      use gbl_constant
      use phys_const
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_primary_t),  intent(in)    :: primary
      type(imbfits_scan_t),     intent(in)    :: scan
      type(imbfits_back_t),     intent(in)    :: back
      integer(kind=4),          intent(in)    :: ichunk
      type(imbfits_backdata_t), intent(in)    :: backdata
      integer(kind=4),          intent(in)    :: itime
      real(kind=8),             intent(in)    :: mjd
      real(kind=4),             intent(in)    :: azimuth
      real(kind=4),             intent(in)    :: elevation
      real(kind=8),             intent(in)    :: lst
      character(len=*),         intent(in)    :: frontend
      type(class_general_t),    intent(out)   :: gen
      logical,                  intent(inout) :: error
    end subroutine mrtcal_chunk_gen_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_pos_from_data(primary,scan,front,derot,ifront,  &
      pixel,subs,mjd,longoff,latoff,pos,error)
      use gbl_message
      use gbl_constant
      use phys_const
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_primary_t), intent(in)    :: primary
      type(imbfits_scan_t),    intent(in)    :: scan
      type(imbfits_front_t),   intent(in)    :: front
      type(imbfits_derot_t),   intent(in)    :: derot
      integer(kind=4),         intent(in)    :: ifront
      integer(kind=4),         intent(in)    :: pixel
      type(imbfits_subscan_t), intent(in)    :: subs
      real(kind=8),            intent(in)    :: mjd
      real(kind=4),            intent(in)    :: longoff  ! [rad] Antenna X offset (interpolated)
      real(kind=4),            intent(in)    :: latoff   ! [rad] Antenna Y offset (interpolated)
      type(class_position_t),  intent(out)   :: pos
      logical,                 intent(inout) :: error
    end subroutine mrtcal_chunk_pos_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_swi_from_data(time,swi,error)
      use gbl_message
      use gbl_constant
      use phys_const
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      real(kind=4),         intent(in)    :: time
      type(class_switch_t), intent(out)   :: swi
      logical,              intent(inout) :: error
    end subroutine mrtcal_chunk_swi_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_res_from_data(teles,restf,res,error)
      use gbl_message
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: teles  !
      real(kind=8),      intent(in)    :: restf  ! [MHz]
      type(class_res_t), intent(out)   :: res    !
      logical,           intent(inout) :: error  !
    end subroutine mrtcal_chunk_res_from_data
  end interface
  !
  interface
    subroutine mrtcal_get_offset_from_scan(scan,projcode,projname,xoffset,yoffset,error)
      use gbl_constant
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Set the observed scan offsets (there can be additional per-subscan
      ! offsets that will be added later on).
      !---------------------------------------------------------------------
      type(imbfits_scan_t), intent(in)    :: scan      !
      integer(kind=4),      intent(out)   :: projcode  ! [code] Projection kind for these offsets
      character(len=*),     intent(out)   :: projname  ! [char] Projection kind for these offsets
      real(kind=4),         intent(out)   :: xoffset   ! [rad]
      real(kind=4),         intent(out)   :: yoffset   ! [rad]
      logical,              intent(inout) :: error     !
    end subroutine mrtcal_get_offset_from_scan
  end interface
  !
  interface
    subroutine mrtcal_pixel_offset(pos,recname,pixel,rotang,error)
      use phys_const
      use gbl_message
      use gkernel_types
      use class_types
      !---------------------------------------------------------------------
      ! @ private
      ! Apply the receiver array offsets (e.g. for HERA). pos%lamof and
      ! pos%betof are modified in return
      !---------------------------------------------------------------------
      type(class_position_t), intent(inout) :: pos      !
      character(len=*),       intent(in)    :: recname  ! Receiver name
      integer(kind=4),        intent(in)    :: pixel    ! Pixel number
      real(kind=8),           intent(in)    :: rotang   ! [deg] Derotator angle
      logical,                intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_pixel_offset
  end interface
  !
  interface
    subroutine mrtcal_chunk_user_from_data(primary,user,error)
      use gbl_message
      use class_types
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_primary_t),  intent(in)    :: primary
      type(mrtcal_classuser_t), intent(out)   :: user
      logical,                  intent(inout) :: error
    end subroutine mrtcal_chunk_user_from_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_show(chunk)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Display a 'chunk' element. For debugging purpose.
      !---------------------------------------------------------------------
      type(chunk_t), intent(in) :: chunk
    end subroutine mrtcal_chunk_show
  end interface
  !
  interface
    subroutine mrtcal_chunk_swi_fill(swmode,swdesc,chunk,error)
      use gbl_message
      use gbl_constant
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! At this point, the phase of the cycle are not yet combined. Hence,
      ! only the part corresponding to each phase is filled in the CLASS 
      ! switching section. Combination will be done during ON-OFF so that
      ! the user can write separately the different phases with consistent
      ! headers...
      !
      ! Moreover the different decal arrays have been set to zero at data read
      ! time. So only the first value is set here according to the switch
      ! mode.
      !---------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: swmode
      type(switch_desc_t), intent(in)    :: swdesc
      type(chunk_t),       intent(inout) :: chunk
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunk_swi_fill
  end interface
  !
  interface
    subroutine mrtcal_chunk_init_data(chunk,v,w,c,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize the chunk data from the input values
      !---------------------------------------------------------------------
      type(chunk_t), intent(inout) :: chunk
      real(kind=4),  intent(in)    :: v      ! Data value (duplicated to all channels)
      real(kind=4),  intent(in)    :: w      ! Weight (duplicated to all channels)
      real(kind=4),  intent(in)    :: c      ! Continuum value
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_init_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_copy_header(in,out,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Section are copied
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: in
      type(chunk_t), intent(inout) :: out
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_copy_header
  end interface
  !
  interface
    subroutine mrtcal_chunk_copy_data(in,out,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Section are copied
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: in
      type(chunk_t), intent(inout) :: out
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_copy_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_self_multiply(gain,inout,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: gain
      type(chunk_t), intent(inout) :: inout
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_self_multiply
  end interface
  !
  interface
    subroutine mrtcal_chunk_self_multiply_head(gain,inout,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: gain
      type(chunk_t), intent(inout) :: inout
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_self_multiply_head
  end interface
  !
  interface
    subroutine mrtcal_chunk_self_multiply_data(bad,nchan,gain,inout,error)
      use gbl_message
      use gildas_def
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      real(kind=4),    intent(in)    :: bad
      integer(kind=4), intent(in)    :: nchan
      real(kind=4),    intent(in)    :: gain(nchan)
      real(kind=4),    intent(inout) :: inout(nchan)
      logical,         intent(inout) :: error
    end subroutine mrtcal_chunk_self_multiply_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_multiply_head(atsys,expatau,tscale,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! This subroutine is NOT a generic multiplication of 2 headers.
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: atsys
      type(chunk_t), intent(in)    :: expatau
      type(chunk_t), intent(inout) :: tscale
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_multiply_head
  end interface
  !
  interface
    subroutine mrtcal_chunk_multiply_data(in1,in2,out,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: in1
      type(chunk_t), intent(in)    :: in2
      type(chunk_t), intent(inout) :: out
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_multiply_data
  end interface
  !
  interface
    subroutine mrtcal_chunk_noise_init(chunk,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize the computation of the theoretical noise of the chunk with
      ! 1.0 / [backeff * sqrt(dnu * tint)]
      !---------------------------------------------------------------------
      type(chunk_t), intent(inout) :: chunk
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_noise_init
  end interface
  !
  interface
    subroutine mrtcal_chunk_interpolate_init(prev,next,slope,offset,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize linear interpolation using the following formula
      !     xoffset = xprev
      !     y(x) = (x-xoffset)*slope + offset
      ! We shift the x axis by xoffset to avoid rounding errors as the
      ! computation are done in single precision while the x axis is MJD...
      !---------------------------------------------------------------------
      type(chunk_t), target, intent(in)    :: prev
      type(chunk_t), target, intent(in)    :: next
      type(chunk_t),         intent(inout) :: slope
      type(chunk_t),         intent(inout) :: offset
      logical,               intent(inout) :: error
    end subroutine mrtcal_chunk_interpolate_init
  end interface
  !
  interface
    subroutine mrtcal_chunk_interpolate_do(mjd,slope,offset,interp,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute linear interpolation from previously computed slope and offset
      ! using the following formula
      !     xoffset = xprev
      !     y(x) = (x-xoffset)*slope + offset
      ! We shift the x axis by xoffset to avoid rounding errors as the
      ! computation are done in single precision while the x axis is MJD...
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)    :: mjd
      type(chunk_t),   intent(in)    :: slope
      type(chunk_t),   intent(in)    :: offset
      type(chunk_t),   intent(inout) :: interp
      logical,         intent(inout) :: error
    end subroutine mrtcal_chunk_interpolate_do
  end interface
  !
  interface
    subroutine mrtcal_chunk_calgrid(real,imag,amp,pha,cos,sin,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunk_t), intent(inout) :: real
      type(chunk_t), intent(inout) :: imag
      type(chunk_t), intent(inout) :: amp
      type(chunk_t), intent(inout) :: pha
      type(chunk_t), intent(inout) :: cos
      type(chunk_t), intent(inout) :: sin
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_calgrid
  end interface
  !
  interface
    subroutine mrtcal_chunk_cross(h,v,hv,vh,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: h
      type(chunk_t), intent(in)    :: v
      type(chunk_t), intent(inout) :: hv
      type(chunk_t), intent(inout) :: vh
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_cross
  end interface
  !
  interface
    subroutine mrtcal_chunk_mean(h,v,hv,vh,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: h
      type(chunk_t), intent(in)    :: v
      type(chunk_t), intent(inout) :: hv
      type(chunk_t), intent(inout) :: vh
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_mean
  end interface
  !
  interface
    subroutine mrtcal_chunk_flag(h,v,hv,vh,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory (because symbol is used elsewhere)
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: h
      type(chunk_t), intent(in)    :: v
      type(chunk_t), intent(inout) :: hv
      type(chunk_t), intent(inout) :: vh
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_flag
  end interface
  !
  interface
    subroutine mrtcal_chunk_unrotate(cos,sin,real,imag,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! The phase is rotated by a given phase with cos = cos(phase) and sin =
      ! sin(phase). This subroutine unrotate the phase. Hence the sign
      ! convention used here in applying a rotation of -phase.
      ! ---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: cos
      type(chunk_t), intent(in)    :: sin
      type(chunk_t), intent(inout) :: real
      type(chunk_t), intent(inout) :: imag
      logical,       intent(inout) :: error
    end subroutine mrtcal_chunk_unrotate
  end interface
  !
  interface
    subroutine mrtcal_chunkset_check(set,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Check the integrity of a set of chunks
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: set
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset_check
  end interface
  !
  interface
    subroutine mrtcal_chunkset_show(chunkset)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Display a set of chunks. For debugging purpose.
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in) :: chunkset
    end subroutine mrtcal_chunkset_show
  end interface
  !
  interface
    subroutine chunkset_consistency(caller,c1,c2,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: caller  ! Calling routine name
      type(chunkset_t), intent(in)    :: c1
      type(chunkset_t), intent(in)    :: c2
      logical,          intent(inout) :: error
    end subroutine chunkset_consistency
  end interface
  !
  interface
    subroutine mrtcal_chunkset_accumulate_setweight(diff,tscale,dowei,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! ZZZ
      ! Quick and dirty subroutine to enforce chunks dataw to something
      ! non-zero (needed by simple_waverage). Currently set to 1.0 i.e.
      ! equal weights. Should probably come early and cleverly e.g.
      ! weight equal, tsys, time, maybe in mrtcal_on_minus_off.
      !---------------------------------------------------------------------
      type(chunkset_t), intent(inout) :: diff
      type(chunkset_t), intent(in)    :: tscale
      logical,          intent(in)    :: dowei   ! Compute real weights or dummy?
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset_accumulate_setweight
  end interface
  !
  interface mrtcal_chunkset_accumulate_do
    subroutine mrtcal_chunkset_accumulate_do(inchunkset,ouchunkset,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_chunkset_accumulate_do
      ! Accumulate the input chunkset into the running output chunkset
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: inchunkset
      type(chunkset_t), intent(inout) :: ouchunkset
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset_accumulate_do
  end interface mrtcal_chunkset_accumulate_do
  !
  interface
    subroutine mrtcal_chunkset_2d_swi_fill(swmode,swdesc,chunkset2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer(kind=4),     intent(in)    :: swmode
      type(switch_desc_t), intent(in)    :: swdesc
      type(chunkset_2d_t), intent(inout) :: chunkset2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_swi_fill
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_copy_data(in,out,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Data are copied
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: in
      type(chunkset_2d_t), intent(inout) :: out
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_copy_data
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_init_data(chunkset_2d,v,w,c,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set data to zero
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: chunkset_2d
      real(kind=4),        intent(in)    :: v      ! Data value (duplicated to all channels)
      real(kind=4),        intent(in)    :: w      ! Weight (duplicated to all channels)
      real(kind=4),        intent(in)    :: c      ! Continuum value
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_init_data
  end interface
  !
  interface
    subroutine mrtcal_chunkset_3d_init_data(chunkset_3d,v,w,c,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Set data to zero
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(inout) :: chunkset_3d
      real(kind=4),        intent(in)    :: v      ! Data value (duplicated to all channels)
      real(kind=4),        intent(in)    :: w      ! Weight (duplicated to all channels)
      real(kind=4),        intent(in)    :: c      ! Continuum value
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_3d_init_data
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_interpolate_init(prev,next,slope,offset,interp,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Initialize linear interpolation
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: prev
      type(chunkset_2d_t), intent(in)    :: next
      type(chunkset_2d_t), intent(inout) :: slope
      type(chunkset_2d_t), intent(inout) :: offset
      type(chunkset_2d_t), intent(inout) :: interp
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_interpolate_init
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_interpolate_init_as_ref(ref,slope,offset,interp,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Reallocate as ref and copy header from ref
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: ref
      type(chunkset_2d_t), intent(inout) :: slope
      type(chunkset_2d_t), intent(inout) :: offset
      type(chunkset_2d_t), intent(inout) :: interp
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_interpolate_init_as_ref
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_interpolate_do(mjd,slope,offset,interp,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Compute linear interpolation
      !---------------------------------------------------------------------
      real(kind=8),        intent(in)    :: mjd
      type(chunkset_2d_t), intent(inout) :: slope
      type(chunkset_2d_t), intent(inout) :: offset
      type(chunkset_2d_t), intent(inout) :: interp
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_interpolate_do
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_blank(ref,blank,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Create a blank 'chunkset_2d' (all 'bad' data), duplicate of the
      ! reference, with relevant sections blanked or kept.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: ref
      type(chunkset_2d_t), intent(inout) :: blank
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_blank
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_accumulate_init(ref,acc,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! (Re)allocate and initialize a 'chunkset_2d' structure for future
      ! use in mrtcal_chunkset_2d_accumulate_2d.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: ref
      type(chunkset_2d_t), intent(inout) :: acc
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_accumulate_init
  end interface
  !
  interface
    subroutine mrtcal_chunkset_3d_accumulate_init(ref,acc,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! (Re)allocate and initialize a 'chunkset_3d' structure for future
      ! use in mrtcal_chunkset_accumulate_do.
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(in)    :: ref
      type(chunkset_3d_t), intent(inout) :: acc
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_3d_accumulate_init
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_accumulate_setweight(diff,tscale,dowei,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! ZZZ
      ! Quick and dirty subroutine to enforce chunks dataw to something
      ! non-zero (needed by simple_waverage). Currently set to 1.0 i.e.
      ! equal weights. Should probably come early and cleverly e.g.
      ! weight equal, tsys, time, maybe in mrtcal_on_minus_off.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: diff
      type(chunkset_2d_t), intent(in)    :: tscale
      logical,             intent(in)    :: dowei   ! Compute real weights or dummy?
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_accumulate_setweight
  end interface
  !
  interface
    subroutine mrtcal_chunkset_3d_accumulate_setweight(diff,tscale,dowei,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! ZZZ
      ! Quick and dirty subroutine to enforce chunks dataw to something
      ! non-zero (needed by simple_waverage). Currently set to 1.0 i.e.
      ! equal weights. Should probably come early and cleverly e.g.
      ! weight equal, tsys, time, maybe in mrtcal_on_minus_off.
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(inout) :: diff
      type(chunkset_2d_t), intent(in)    :: tscale
      logical,             intent(in)    :: dowei   ! Compute real weights or dummy?
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_3d_accumulate_setweight
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_accumulate_do(in2d,ou2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Accumulate the input chunkset_2d into the running 'ou2d'
      ! chunkset_2d.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: in2d
      type(chunkset_2d_t), intent(inout) :: ou2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_accumulate_do
  end interface
  !
  interface
    subroutine mrtcal_chunkset_3d_accumulate_do(in3d,ou3d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Accumulate the input chunkset_3d into the running 'ou3d'
      ! chunkset_3d.
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(in)    :: in3d
      type(chunkset_3d_t), intent(inout) :: ou3d
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_3d_accumulate_do
  end interface
  !
  interface
    subroutine mrtcal_chunkset_2d_noise_init(chunkset_2d,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(inout) :: chunkset_2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_2d_noise_init
  end interface
  !
  interface chunkset_2d_consistency
    subroutine chunkset_2d_consistency_2d2d(caller,c1,c2,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic chunkset_2d_consistency
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: caller  ! Calling routine name
      type(chunkset_2d_t), intent(in)    :: c1
      type(chunkset_2d_t), intent(in)    :: c2
      logical,             intent(inout) :: error
    end subroutine chunkset_2d_consistency_2d2d
    subroutine chunkset_2d_consistency_2d3d(caller,c1,c2,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic chunkset_2d_consistency
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: caller  ! Calling routine name
      type(chunkset_2d_t), intent(in)    :: c1
      type(chunkset_3d_t), intent(in)    :: c2
      logical,             intent(inout) :: error
    end subroutine chunkset_2d_consistency_2d3d
  end interface chunkset_2d_consistency
  !
  interface
    subroutine clone_chunk(in,ou,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Clone a chunk structure.
      !
      !  Nothing is done for the data and headers (not copied, not
      ! initialized e.g. to 0).
      !---------------------------------------------------------------------
      type(chunk_t), intent(in)    :: in        !
      type(chunk_t), intent(inout) :: ou        !
      logical,       intent(in)    :: doheader  ! Also clone the headers?
      logical,       intent(inout) :: error     !
    end subroutine clone_chunk
  end interface
  !
  interface
    subroutine clone_chunkset(in,ou,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Clone a chunkset structure.
      !
      !  The chunks in the chunkset are ALLOCATED so that the full structure
      ! clones exactly the input one.
      !  Nothing is done for the data and headers (not copied, not
      ! initialized e.g. to 0).
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: in        !
      type(chunkset_t), intent(inout) :: ou        !
      logical,          intent(in)    :: doheader  ! Also clone the headers?
      logical,          intent(inout) :: error     !
    end subroutine clone_chunkset
  end interface
  !
  interface clone_chunkset_2d
    subroutine clone_chunkset_2d_from_2d(in2d,ou2d,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic clone_chunkset_2d
      !  Clone a chunkset_2d structure.
      !
      !  The chunksets and chunks in the chunksets are ALLOCATED so that
      ! the full structure clones exactly in2d(:,:).
      !  Nothing is done for the data and headers (not copied, not
      ! initialized e.g. to 0).
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: in2d
      type(chunkset_2d_t), intent(inout) :: ou2d
      logical,             intent(in)    :: doheader  ! Also clone the headers?
      logical,             intent(inout) :: error
    end subroutine clone_chunkset_2d_from_2d
    subroutine clone_chunkset_2d_from_3d(in3d,ou2d,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic clone_chunkset_2d
      !  Clone a chunkset_2d structure.
      !
      !  The chunksets and chunks in the chunksets are ALLOCATED so that
      ! the full structure clones exactly in3d(:,:,itime=1).
      !  Nothing is done for the data and headers (not copied, not
      ! initialized e.g. to 0).
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(in)    :: in3d
      type(chunkset_2d_t), intent(inout) :: ou2d
      logical,             intent(in)    :: doheader  ! Also clone the headers?
      logical,             intent(inout) :: error
    end subroutine clone_chunkset_2d_from_3d
  end interface clone_chunkset_2d
  !
  interface clone_chunkset_3d
    subroutine clone_chunkset_3d_from_3d(in3d,ou3d,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic clone_chunkset_3d
      !  Clone a chunkset_3d structure.
      !---------------------------------------------------------------------
      type(chunkset_3d_t), intent(in)    :: in3d
      type(chunkset_3d_t), intent(inout) :: ou3d
      logical,             intent(in)    :: doheader  ! Also clone the headers?
      logical,             intent(inout) :: error
    end subroutine clone_chunkset_3d_from_3d
    subroutine clone_chunkset_3d_from_2d(in2d,ntime,ou3d,doheader,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic clone_chunkset_3d
      !  Create a chunkset_3d by cloning a chunkset_2d structure + extra
      ! "time" dimension.
      !---------------------------------------------------------------------
      type(chunkset_2d_t), intent(in)    :: in2d      !
      integer(kind=4),     intent(in)    :: ntime     ! Time dimension to be added
      type(chunkset_3d_t), intent(inout) :: ou3d      !
      logical,             intent(in)    :: doheader  ! Also clone the headers?
      logical,             intent(inout) :: error     !
    end subroutine clone_chunkset_3d_from_2d
  end interface clone_chunkset_3d
  !
  interface
    subroutine mrtcal_dump_command(line,error)
      use gbl_message
      use gildas_def
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command DUMP
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_dump_command
  end interface
  !
  interface
    subroutine mrtcal_imbfits_dump_data(isub,databuf,ceclass,short,olun,error)
      use gbl_message
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      integer(kind=4),           intent(in)    :: isub     ! Subscan number
      type(data_buffer_t),       intent(in)    :: databuf  !
      type(eclass_2inte2char_t), intent(in)    :: ceclass  ! Chunkset equiv classes
      logical,                   intent(in)    :: short    ! Short or verbose output?
      integer(kind=4),           intent(in)    :: olun     ! Output LUN
      logical,                   intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_imbfits_dump_data
  end interface
  !
  interface
    subroutine mrtcal_imbfits_dump_mrtcdata(mrtc,ceclass,olun,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(chunkset_3d_t),       intent(in)    :: mrtc     !
      type(eclass_2inte2char_t), intent(in)    :: ceclass  ! Chunkset equiv classes
      integer(kind=4),           intent(in)    :: olun     ! Output LUN
      logical,                   intent(inout) :: error    !
    end subroutine mrtcal_imbfits_dump_mrtcdata
  end interface
  !
  interface
    subroutine mrtcal_find_comm(line,error)
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command:
      !   MFIND
      ! Read the index file
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_find_comm
  end interface
  !
  interface
    subroutine mrtcal_index_comm(line,error)
      use gbl_message
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !   INDEX BUILD|UPDATE|OPEN|APPEND|WATCH|OUTPUT [DirName]
      ! 1       [/FILE IndexFile]
      ! 2       [/RECURSIVE]
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line  ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_index_comm
  end interface
  !
  interface
    subroutine mrtcal_entry_chopperset2calsec(backcal,calsec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(calib_backend_t), intent(in)    :: backcal  !
      type(sec_calib_t),     intent(inout) :: calsec   !
      logical,               intent(inout) :: error    !
    end subroutine mrtcal_entry_chopperset2calsec
  end interface
  !
  interface
    subroutine mrtcal_entry_calsec2chopperset(calsec,backcal,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(sec_calib_t),     intent(in)    :: calsec   !
      type(calib_backend_t), intent(inout) :: backcal  !
      logical,               intent(inout) :: error    !
    end subroutine mrtcal_entry_calsec2chopperset
  end interface
  !
  interface
    subroutine mrtcal_calsec_chunkset_consistency(calsec,c2d,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !  Check the consistency of a chunkset_2d against calibration section
      !---------------------------------------------------------------------
      type(sec_calib_t),   intent(in)    :: calsec
      type(chunkset_2d_t), intent(in)    :: c2d
      logical,             intent(inout) :: error
    end subroutine mrtcal_calsec_chunkset_consistency
  end interface
  !
  interface
    subroutine mrtcal_init(error)
      use gbl_message
      use classic_api
      use mrtcal_index_vars
      use mrtcal_buffers
      !----------------------------------------------------------------------
      ! @ private
      ! MRTCAL Initialization
      !----------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_init
  end interface
  !
  interface
    subroutine mrtcal_exit(error)
      use gbl_message
      use mrtcal_buffers
      use mrtcal_index_vars
      !----------------------------------------------------------------------
      ! @ private
      ! MRTCAL Cleaning on exit
      !----------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_exit
  end interface
  !
  interface
    subroutine mrtcal_load
      !---------------------------------------------------------------------
      ! @ private
      ! Define and load the MRTCAL language
      !---------------------------------------------------------------------
      !
    end subroutine mrtcal_load
  end interface
  !
  interface
    subroutine mrtcal_run(line,command,error)
      use gbl_message
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Support routine for the language MRTCAL.
      ! This routine is able to call the routines associated to each
      ! command of the language MRTCAL
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: line
      character(len=12), intent(in)    :: command
      logical,           intent(inout) :: error
    end subroutine mrtcal_run
  end interface
  !
  interface
    function mrtcal_error()
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for the error status of the library. 
      ! It is a scory. Please do not use it
      !---------------------------------------------------------------------
      logical :: mrtcal_error
    end function mrtcal_error
  end interface
  !
  interface
    subroutine mrtcal_list_comm(line,error)
      use gbl_message
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   LIST [IN|CURRENT]
      !   1    [/TOC]
      !   2    [/PAGE]
      !   3    [/COLUMNS List]
      !   4    [/FILE OutputFile]
      !   5    [/VARIABLE VarName]
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! Input command line
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_list_comm
  end interface
  !
  interface failed_calibrate
    function failed_calibrate_name(rname,sname,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic failed_calibrate
      !  Display the subscan name if input error is .true.
      !  Nothing done if error is .false.
      !---------------------------------------------------------------------
      logical :: failed_calibrate_name  ! Function value on return
      character(len=*), intent(in) :: rname  ! Calling routine name
      character(len=*), intent(in) :: sname  ! Subscan name
      logical,          intent(in) :: error  ! Error status
    end function failed_calibrate_name
    function failed_calibrate_num(rname,snum,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic failed_calibrate
      !  Display the subscan number if input error is .true.
      !  Nothing done if error is .false.
      !---------------------------------------------------------------------
      logical :: failed_calibrate_num  ! Function value on return
      character(len=*), intent(in) :: rname  ! Calling routine name
      integer(kind=4),  intent(in) :: snum   ! Subscan number
      logical,          intent(in) :: error  ! Error status
    end function failed_calibrate_num
  end interface failed_calibrate
  !
  interface
    subroutine calibration_to_VO(fits,backcal,error)
      use phys_const
      use gbl_format
      use gbl_message
      use class_types
      use imbfits_types
      use mrtcal_buffers
      use mrtcal_calib_types
      use pako_xml
      use results_to_vo
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_t),        intent(in)    :: fits
      type(calib_backend_t),  intent(in)    :: backcal
      logical,                intent(inout) :: error
    end subroutine calibration_to_VO
  end interface
  !
  interface
    subroutine mrtcal_pack_init(gpack_id,error)
      !----------------------------------------------------------------------
      ! @ private-mandatory
      !----------------------------------------------------------------------
      integer :: gpack_id
      logical :: error
    end subroutine mrtcal_pack_init
  end interface
  !
  interface
    subroutine mrtcal_pack_clean(error)
      !----------------------------------------------------------------------
      ! @ private-mandatory
      ! Called at end of session. Might clean here for example global buffers
      ! allocated during the session
      !----------------------------------------------------------------------
      logical :: error
    end subroutine mrtcal_pack_clean
  end interface
  !
  interface
    subroutine mrtcal_pipe_command(line,error)
      use gbl_message
      use gkernel_types
      use mrtcal_buffers
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      ! PIPELINE
      ! 1. /SHOW [*|NONE|DONE|FAILED]
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_pipe_command
  end interface
  !
  interface
    subroutine mrtcal_pipe_parse(line,iopt,select,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*),   intent(in)    :: line
      integer(kind=4),    intent(in)    :: iopt
      type(user_calib_t), intent(out)   :: select
      logical,            intent(inout) :: error
    end subroutine mrtcal_pipe_parse
  end interface
  !
  interface
    subroutine mrtcal_pipe_feedback(select,ix,cx,error)
      use gbl_message
      use mrtindex_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! User feedback: Update CX according to user choice
      !---------------------------------------------------------------------
      type(user_calib_t),        intent(in)    :: select
      type(mrtindex_optimize_t), intent(in)    :: ix
      type(mrtindex_optimize_t), intent(inout) :: cx
      logical,                   intent(inout) :: error
    end subroutine mrtcal_pipe_feedback
  end interface
  !
  interface
    subroutine mrtcal_pipe_update_cx(ix,cx,error)
      use gbl_message
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Update CX with latest version of the IX entries
      !---------------------------------------------------------------------
      type(mrtindex_optimize_t), intent(in)    :: ix
      type(mrtindex_optimize_t), intent(inout) :: cx
      logical,                   intent(inout) :: error
    end subroutine mrtcal_pipe_update_cx
  end interface
  !
  interface
    subroutine mrtcal_pipe_filter_cx(select,cx,error)
      use gbl_message
      use mrtindex_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Filter CX according to user choice
      !---------------------------------------------------------------------
      type(user_calib_t),        intent(in)    :: select
      type(mrtindex_optimize_t), intent(inout) :: cx
      logical,                   intent(inout) :: error
    end subroutine mrtcal_pipe_filter_cx
  end interface
  !
  interface
    subroutine mrtcal_separator(severity,rname,nline,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Print nline white lines as entry separators
      !---------------------------------------------------------------------
      integer(kind=4),  intent(in)    :: severity
      character(len=*), intent(in)    :: rname
      integer(kind=4),  intent(in)    :: nline
      logical,          intent(inout) :: error
    end subroutine mrtcal_separator
  end interface
  !
  interface
    subroutine mrtcal_read_command(line,error)
      use gbl_message
      use gildas_def
      use mrtcal_buffers
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   READ [Filename|FileNum|ZERO|FIRST|LAST|NEXT|PREV] [/FILENAME] [/SUBSCAN Isub]
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_read_command
  end interface
  !
  interface
    subroutine mrtcal_read_argument(line,found,error)
      use gildas_def
      use gbl_message
      use classic_api
      use mrtcal_index_vars
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command READ. Decode command 1st argument:
      !   READ [Filename|FileNum|ZERO|FIRST|LAST|NEXT|PREV] [/FILENAME]
      ! Of course, PREV or NEXT are unrelated to Filename or Filenum.
      ! This may be confusing for newcomers but there is no obvious solution
      ! as Filename or FileNum do not need to be related to the current index.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(out)   :: found ! Found a name to be opened?
      logical,          intent(inout) :: error
    end subroutine mrtcal_read_argument
  end interface
  !
  interface
    subroutine mrtcal_parse_numver(rname,line,iopt,iarg,ix,ient,error)
      use gbl_message
      use classic_api
      use mrtindex_types
      !---------------------------------------------------------------------
      ! @ private
      !  Parse the command line to retrieve an argument of the form "N" or
      ! "N.V" and convert it into the entry position in IX
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: rname  ! Calling routine name
      character(len=*),           intent(in)    :: line   ! Command line
      integer(kind=4),            intent(in)    :: iopt   ! Option number
      integer(kind=4),            intent(in)    :: iarg   ! Argument number
      type(mrtindex_optimize_t),  intent(in)    :: ix     !
      integer(kind=entry_length), intent(out)   :: ient   ! Resolved entry number
      logical,                    intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_parse_numver
  end interface
  !
  interface
    subroutine mrtcal_read_main(filename,isub,filebuf,error)
      use gildas_def
      use gbl_message
      use mrtcal_buffers
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      character(len=*),       intent(in)    :: filename
      integer(kind=4),        intent(in)    :: isub
      type(imbfits_buffer_t), intent(inout) :: filebuf
      logical,                intent(inout) :: error
    end subroutine mrtcal_read_main
  end interface
  !
  interface
    subroutine mrtcal_free_subscan_data(databuf,error)
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      ! Free of the DATA column from the current subscan, and its conversion
      ! in chunksets.
      !---------------------------------------------------------------------
      type(data_buffer_t), intent(inout) :: databuf
      logical,             intent(inout) :: error
    end subroutine mrtcal_free_subscan_data
  end interface
  !
  interface
    subroutine mrtcal_setup_comm(line,error)
      use gbl_message
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !   MSETUP INPUT|BOOKKEEPING|CALIBRATION|OUTPUT|PIPELINE|DEBUG
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_setup_comm
  end interface
  !
  interface
    subroutine mrtcal_setup_print(mrtset,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t), intent(in)    :: mrtset
      logical,              intent(inout) :: error
    end subroutine mrtcal_setup_print
  end interface
  !
  interface
    subroutine mrtcal_setup_input_parse(line,mrtsetinp,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    MSETUP INPUT BANDWIDTH   Value  ! [MHz]
      ! or MSETUP INPUT DATA        NONE|ONTRACK|ALL
      ! or MSETUP INPUT TOCHUNK     YES|NO
      ! or MSETUP INPUT BAD         YES|NO
      ! or MSETUP INPUT MJDINTER    YES|NO
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: line
      type(mrtcal_setup_input_t), intent(inout) :: mrtsetinp
      logical,                    intent(inout) :: error
    end subroutine mrtcal_setup_input_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_input_print(mrtsetinp,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_input_t), intent(in)    :: mrtsetinp
      logical,                    intent(inout) :: error
    end subroutine mrtcal_setup_input_print
  end interface
  !
  interface
    subroutine mrtcal_setup_bookkeeping_parse(line,mrtset,error)
      use gbl_message
      use ram_sizes
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command 
      ! MSETUP BOOKKEPPING SPACE value
      ! *** JP It would probably be better if it was a fraction of the
      ! *** JP available ramsize. Afterthought: Not fully clear because
      ! *** JP even with a large amount of RAM, there may be an optimal
      ! *** JP amount of buffer space. Maybe the two possibility should
      ! *** JP be authorized MSETUP BOOKKEEPING SPACE value % or value MB.
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: line
      type(mrtcal_setup_t), intent(inout) :: mrtset
      logical,              intent(inout) :: error
    end subroutine mrtcal_setup_bookkeeping_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_bookkeeping_print(mrtset,error)
      use gbl_message
      use ram_sizes
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t), intent(in)    :: mrtset
      logical,              intent(inout) :: error
    end subroutine mrtcal_setup_bookkeeping_print
  end interface
  !
  interface
    subroutine mrtcal_setup_calibration_parse(line,mrtsetcal,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    MSETUP CALIBRATION BAD         YES|NO
      ! or MSETUP CALIBRATION BANDWIDTH   Value
      ! or MSETUP CALIBRATION CHOPPER     STRICT|TOLERANT
      ! or MSETUP CALIBRATION FEEDBACK    PIXEL|SET|ELEMENT
      ! or MSETUP CALIBRATION INTERVAL    Value
      ! or MSETUP CALIBRATION MATCH       Value
      ! or MSETUP CALIBRATION MJDINTER    YES|NO
      ! or MSETUP CALIBRATION OFF         NEAREST|LINEAR
      ! or MSETUP CALIBRATION PRODUCTS    NEAREST|LINEAR|SPLINE
      ! or MSETUP CALIBRATION SCAN        NEAREST|LINEAR
      ! or MSETUP CALIBRATION WATER       SET|ELEMENT|FIXED [Value]
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: line
      type(mrtcal_setup_calib_t), intent(inout) :: mrtsetcal
      logical,                    intent(inout) :: error
    end subroutine mrtcal_setup_calibration_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_calibration_print(mrtsetcal,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_calib_t), intent(in)    :: mrtsetcal
      logical,                    intent(inout) :: error
    end subroutine mrtcal_setup_calibration_print
  end interface
  !
  interface
    subroutine mrtcal_setup_output_parse(line,mrtsetout,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      !    MSETUP OUTPUT CALIBRATION SPECTRA|ASSOCIATED|NONE
      ! or MSETUP OUTPUT CALTABLE    YES|NO
      ! or MSETUP OUTPUT CHUNK       ELEMENT|SET
      ! or MSETUP OUTPUT FOLD        YES|NO
      ! or MSETUP OUTPUT INTEGRATION CYCLE|SUBSCAN|SCAN|*
      ! or MSETUP OUTPUT SPECTRA     YES|NO
      ! or MSETUP OUTPUT USERSECTION YES|NO
      ! or MSETUP OUTPUT VDIRECTION  YES|NO
      ! or MSETUP OUTPUT VOXML       YES|NO
      ! or MSETUP OUTPUT VODIR       DirName
      ! or MSETUP OUTPUT WEIGHT      YES|NO
      !---------------------------------------------------------------------
      character(len=*),            intent(in)    :: line
      type(mrtcal_setup_output_t), intent(inout) :: mrtsetout
      logical,                     intent(inout) :: error
    end subroutine mrtcal_setup_output_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_output_print(mrtsetout,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_output_t), intent(in)    :: mrtsetout
      logical,                     intent(inout) :: error
    end subroutine mrtcal_setup_output_print
  end interface
  !
  interface
    subroutine mrtcal_setup_pipeline_parse(line,mrtset,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command 
      ! MSETUP PIPELINE ONERROR CONTINUE|STOP
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: line
      type(mrtcal_setup_t), intent(inout) :: mrtset
      logical,              intent(inout) :: error
    end subroutine mrtcal_setup_pipeline_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_pipeline_print(mrtset,error)
      use gbl_message
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t), intent(in)    :: mrtset
      logical,              intent(inout) :: error
    end subroutine mrtcal_setup_pipeline_print
  end interface
  !
  interface
    subroutine mrtcal_setup_debug_all(newseve,error)
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Set the default state for command
      !    MSET DEBUG ON|OFF
      ! for all topics
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: newseve
      logical,         intent(inout) :: error
    end subroutine mrtcal_setup_debug_all
  end interface
  !
  interface
    subroutine mrtcal_setup_debug_parse(line,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command
      ! MSETUP DEBUG [Topic [Subtopic]] ON|OFF
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_setup_debug_parse
  end interface
  !
  interface
    subroutine mrtcal_setup_debug_print(error)
      use mrtcal_messaging
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_setup_debug_print
  end interface
  !
  interface
    subroutine mrtcal_setup_variable(error)
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      ! Fill the structure SET%MRTCAL%
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_setup_variable
  end interface
  !
  interface
    subroutine mrtcal_setup_calibration_variable(parent,cal,error)
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Fill the structure SET%MRTCAL%CALIB%
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: parent
      type(mrtcal_setup_calib_t), intent(in)    :: cal
      logical,                    intent(inout) :: error
    end subroutine mrtcal_setup_calibration_variable
  end interface
  !
  interface
    subroutine mrtcal_setup_output_variable(parent,out,error)
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Fill the structure SET%MRTCAL%OUTPUT%
      !---------------------------------------------------------------------
      character(len=*),            intent(in)    :: parent
      type(mrtcal_setup_output_t), intent(in)    :: out
      logical,                     intent(inout) :: error
    end subroutine mrtcal_setup_output_variable
  end interface
  !
  interface
    subroutine mrtcal_setup_do2done(obstype,swmode,doset,doneset,error)
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      ! Translate a user setup type (which may include * choices, i.e. let
      ! Mrtcal choose) to actual setup. This depends on the current scan.
      !---------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: obstype  ! [code] Observing type
      integer(kind=4),      intent(in)    :: swmode   ! [code] Switching mode
      type(mrtcal_setup_t), intent(in)    :: doset    ! Setup (user choices)
      type(mrtcal_setup_t), intent(out)   :: doneset  ! Setup (resolved)
      logical,              intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_setup_do2done
  end interface
  !
  interface mrtcal_setup_parse
    subroutine mrtcal_setup_parse_keyword(line,iarg,mvocab,vocab,keyword,found,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_setup_parse
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      integer(kind=4),  intent(in)    :: iarg
      integer(kind=4),  intent(in)    :: mvocab
      character(len=*), intent(in)    :: vocab(mvocab)
      character(len=*), intent(out)   :: keyword
      logical,          intent(out)   :: found
      logical,          intent(inout) :: error
    end subroutine mrtcal_setup_parse_keyword
    subroutine mrtcal_setup_parse_ikey(line,iarg,mvocab,vocab,ikey,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_setup_parse
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      integer(kind=4),  intent(in)    :: iarg
      integer(kind=4),  intent(in)    :: mvocab
      character(len=*), intent(in)    :: vocab(mvocab)
      integer(kind=4),  intent(out)   :: ikey
      logical,          intent(inout) :: error
    end subroutine mrtcal_setup_parse_ikey
  end interface mrtcal_setup_parse
  !
  interface
    function eclass_offset_eq(x1,x2,y1,y2,t1,t2)
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      ! Equality routine between two pairs of offset (real*8) with a
      ! tolerance ruled by MSET CALIBRATION MATCH
      !---------------------------------------------------------------------
      logical :: eclass_offset_eq
      real(kind=8),     intent(in) :: x1,x2  ! [rad]
      real(kind=8),     intent(in) :: y1,y2  ! [rad]
      character(len=*), intent(in) :: t1,t2  ! Offset type (track, onTheFly, ...)
    end function eclass_offset_eq
  end interface
  !
  interface
    subroutine mrtcal_subscan_list_build(switchmode,sublist,imbf,error)
      use gbl_message
      use phys_const
      use gkernel_types
      use imbfits_types
      use mrtcal_calib_types
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      ! 1. Class the subscans of the current scan in TRACKED or OTF, ON or OFF
      ! 2. Associate the median offset, median MJD, and the integration time
      !---------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: switchmode
      type(subscan_list_t), intent(inout) :: sublist
      type(imbfits_t),      intent(inout) :: imbf
      logical,              intent(inout) :: error
    end subroutine mrtcal_subscan_list_build
  end interface
  !
  interface
    subroutine mrtcal_subscan_list_print(switchmode,sublist,error)
      use gbl_message
      use phys_const
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! List useful information about the subscans of the current scan
      !---------------------------------------------------------------------
      integer(kind=4),      intent(in)    :: switchmode
      type(subscan_list_t), intent(in)    :: sublist
      logical,              intent(inout) :: error
    end subroutine mrtcal_subscan_list_print
  end interface
  !
  interface
    subroutine mrtcal_switch_cycle_init(front,backdata,antslow,sublist,cycle,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      ! Note that the frequency offset in frequency switching may depend on the
      ! frontend. This imposes that the off pointer in the switch_desc_t has 
      ! noffset x nfront dimensions, and not just noffset.
      !
      ! In wobbler switching, check that offsets are giving in horizontalTrue.
      ! If true, then use the sign of the longitude offset to determine the ON and OFF
      ! phases. Indeed, the backdata%head%phaseone%val value is only indicating
      ! whether the phase corresponds to the wobbler LEFT or RIGHT, not whether
      ! it is ON or OFF (even though the value names still are ON or OFF). Yes,
      ! I know: This is confusing...
      !
      ! In frequency switching, try to use backdata%head%phaseone%val to 
      ! decide who is ON and who is OFF
      !---------------------------------------------------------------------
      type(imbfits_front_t),    intent(in)    :: front
      type(imbfits_backdata_t), intent(in)    :: backdata
      type(imbfits_antslow_t),  intent(in)    :: antslow
      type(subscan_list_t),     intent(in)    :: sublist
      type(switch_cycle_t),     intent(inout) :: cycle
      logical,                  intent(inout) :: error
    end subroutine mrtcal_switch_cycle_init
  end interface
  !
  interface
    subroutine mrtcal_switch_cycle_list(cycle,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! List useful information about the switch cycle of the current subscan
      !---------------------------------------------------------------------
      type(switch_cycle_t), intent(in)    :: cycle
      logical,              intent(inout) :: error
    end subroutine mrtcal_switch_cycle_list
  end interface
  !
  interface
    subroutine mrtcal_switch_book_list(book,error)
      use mrtcal_messaging
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(switch_book_t), intent(in)    :: book
      logical,             intent(inout) :: error
    end subroutine mrtcal_switch_book_list
  end interface
  !
  interface
    subroutine mrtcal_iterate_subscancycle(mrtset,imbf,subscanbuf,  &
      backcal,backsci,error)
      use gbl_message
      use mrtcal_buffer_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(mrtcal_setup_t),    intent(in)    :: mrtset      !
      type(imbfits_t),         intent(in)    :: imbf        !
      type(subscan_buffer_t),  intent(inout) :: subscanbuf  !
      type(calib_backend_t),   intent(in)    :: backcal     !
      type(science_backend_t), intent(inout) :: backsci     !
      logical,                 intent(inout) :: error       !
    end subroutine mrtcal_iterate_subscancycle
  end interface
  !
  interface
    subroutine mrtcal_find_next_subscancycle(sublist,swcycle,nswitch,  &
      verbose,found,ifirst,isub,ncycle,error)
      use gbl_message
      use imbfits_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(subscan_list_t), intent(in)    :: sublist
      integer(kind=4),      intent(in)    :: nswitch
      integer(kind=4),      intent(in)    :: swcycle(nswitch)
      logical,              intent(in)    :: verbose
      logical,              intent(out)   :: found
      integer(kind=4),      intent(inout) :: ifirst
      integer(kind=4),      intent(inout) :: isub
      integer(kind=4),      intent(inout) :: ncycle
      logical,              intent(inout) :: error
    end subroutine mrtcal_find_next_subscancycle
  end interface
  !
  interface
    subroutine antslow_mjd(mjd,antslow,ceil,itrace,error)
      use gbl_message
      use gildas_def
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ private
      ! Search in the input 'AntSlow' the slow trace which has the nearest
      ! MJD. Return the index of this slow trace
      !---------------------------------------------------------------------
      real(kind=8),              intent(in)    :: mjd
      type(imbfits_antslow_t),   intent(in)    :: antslow
      logical,                   intent(in)    :: ceil
      integer(kind=size_length), intent(out)   :: itrace
      logical,                   intent(inout) :: error
    end subroutine antslow_mjd
  end interface
  !
  interface
    subroutine mrtcal_get_median_elevation(subs,medelev,error)
      use gbl_message
      use phys_const
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !  Get the median elevation from CELEVATIO in AntSlow table, on track
      ! part.
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(in)    :: subs    !
      real(kind=8),            intent(out)   :: medelev ! [rad] double in contrast with CLASS
      logical,                 intent(inout) :: error   !
    end subroutine mrtcal_get_median_elevation
  end interface
  !
  interface
    subroutine mrtcal_get_time_range_for_antslow(subs,time,error)
      use gildas_def
      use imbfits_types
      use mrtcal_bookkeeping_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(in)    :: subs
      type(range_t),           intent(out)   :: time
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_time_range_for_antslow
  end interface
  !
  interface
    subroutine mrtcal_get_time_range_for_antfast(subs,time,error)
      use gildas_def
      use imbfits_types
      use mrtcal_bookkeeping_types
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(in)    :: subs
      type(range_t),           intent(out)   :: time
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_time_range_for_antfast
  end interface
  !
  interface
    subroutine mrtcal_get_time_range_for_all(subs,time,error)
      use imbfits_types
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      !  Select the whole time range (on-track and off-track)
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(in)    :: subs
      type(range_t),           intent(out)   :: time
      logical,                 intent(inout) :: error
    end subroutine mrtcal_get_time_range_for_all
  end interface
  !
  interface
    subroutine mrtcal_dicho(rname,np,x,xval,ceil,toler,ival,error)
      use gildas_def
      use gbl_message
      use mrtcal_messaging
      !---------------------------------------------------------------------
      ! @ private
      ! Find ival such as
      !    X(ival-1) < xval <= X(ival)     (ceiling mode)
      !  or
      !    X(ival) <= xval < X(ival+1)     (floor mode)
      ! Suited for MJD values only.
      ! The algorithm (dichotomic search) assumes the input data is
      ! increasingly ordered.
      !---------------------------------------------------------------------
      character(len=*),          intent(in)    :: rname  ! Calling routine name
      integer(kind=size_length), intent(in)    :: np     ! Number of input points
      real(kind=8),              intent(in)    :: x(np)  ! Input ordered Values
      real(kind=8),              intent(in)    :: xval   ! The value we search for
      logical,                   intent(in)    :: ceil   ! Ceiling or floor mode?
      real(kind=8),              intent(in)    :: toler  ! Acceptable error
      integer(kind=size_length), intent(out)   :: ival   ! Position in the array
      logical,                   intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_dicho
  end interface
  !
  interface
    subroutine mrtcal_get_dewang_from_derot(front,derot,mjd,dewang,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ private
      !  Interpolate the derotator angle from the derotator table, according
      ! to the input MJD
      !---------------------------------------------------------------------
      type(imbfits_front_t), intent(in)    :: front   !
      type(imbfits_derot_t), intent(in)    :: derot   !
      real(kind=8),          intent(in)    :: mjd     !
      real(kind=8),          intent(out)   :: dewang  ! [Derot table unit]
      logical,               intent(inout) :: error   ! Logical error flag
    end subroutine mrtcal_get_dewang_from_derot
  end interface
  !
  interface
    subroutine mrtcal_toclass_init(error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Initialize the 'toclass' buffers. This should be done only once in
      ! a session.
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_toclass_init
  end interface
  !
  interface
    subroutine mrtcal_toclass_exit(error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ private
      !  Finalize the 'toclass' buffers. This should be done only once in
      ! a session.
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine mrtcal_toclass_exit
  end interface
  !
  interface
    subroutine mrtcal_chunkset_fsw_to_obs(out,set1,set2,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !  Specific to FSW data
      !  Fold the pair of chunksets and produce a single class spectrum
      !---------------------------------------------------------------------
      type(mrtcal_setup_output_t), intent(in)    :: out
      type(chunkset_t),            intent(in)    :: set1
      type(chunkset_t),            intent(in)    :: set2
      logical,                     intent(inout) :: error
    end subroutine mrtcal_chunkset_fsw_to_obs
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_ry(set,obs,error)
      use gbl_message
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Stitch the spectra in the set and save them as the RY spectrum
      ! in the observation.
      !---------------------------------------------------------------------
      type(chunkset_t),  intent(in)    :: set
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_ry
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_assoc(set,obs,error)
      use gbl_format
      use gbl_message
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !  Stitch the spectra in the set and save them as a new associated
      ! array in the observation.
      !---------------------------------------------------------------------
      type(chunkset_t),  intent(in)    :: set
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_assoc
  end interface
  !
  interface
    subroutine mrtcal_reallocate_r4(r4,n,error)
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      real(kind=4), allocatable, intent(inout) :: r4(:)
      integer(kind=4),           intent(in)    :: n
      logical,                   intent(inout) :: error
    end subroutine mrtcal_reallocate_r4
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_head(set,obs,error)
      use gbl_message
      use class_api
      use class_types
      use mrtcal_buffers
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      !   This subroutine fills a Class header from a chunkset (collection
      ! of several chunks).
      !   General and position sections are assumed to be common between all
      ! the chunks of the chunkset. Should it be checked? *** JP
      !---------------------------------------------------------------------
      type(chunkset_t),  intent(in)    :: set
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_head
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_gen(set,gen,error)
      use gildas_def
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the general section suited for the stitched chunks
      !---------------------------------------------------------------------
      type(chunkset_t),      intent(in)    :: set
      type(class_general_t), intent(out)   :: gen
      logical,               intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_gen
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_spe(set,spe,error)
      use gbl_message
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the spectroscopic section suited for the stitched chunks
      !---------------------------------------------------------------------
      type(chunkset_t),      intent(in)    :: set
      type(class_spectro_t), intent(out)   :: spe
      logical,               intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_spe
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_cal(set,cal,error)
      use gildas_def
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Define the calibration section suited for the stitched chunks
      !---------------------------------------------------------------------
      type(chunkset_t),    intent(in)    :: set
      type(class_calib_t), intent(out)   :: cal
      logical,             intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_cal
  end interface
  !
  interface
    subroutine mrtcal_chunkset_to_obs_data(set,head,data1,dataw,error)
      use gbl_message
      use class_types
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Simple stitching. No resampling is foreseen.
      ! However, we check that the frequency axes are aligned.
      ! A simple average is performed for channels which are present in more
      ! than one chunk (use the SET BAD OR policy of CLASS).
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: set
      type(header),     intent(in)    :: head
      real(kind=4),     intent(out)   :: data1(:)
      real(kind=4),     intent(out)   :: dataw(:)
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset_to_obs_data
  end interface
  !
  interface
    subroutine mrtcal_obs_to_class(obs,error)
      use class_types
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      !  Write the observation to the current Class file
      !---------------------------------------------------------------------
      type(observation), intent(inout) :: obs
      logical,           intent(inout) :: error
    end subroutine mrtcal_obs_to_class
  end interface
  !
  interface
    function mrtcal_user_function(action)
      !---------------------------------------------------------------------
      ! @ private
      !---------------------------------------------------------------------
      logical :: mrtcal_user_function
      character(len=*), intent(in) :: action
    end function mrtcal_user_function
  end interface
  !
  interface
    subroutine mrtcal_toclass_user(mydata,version,error)
      use gbl_message
      use class_api
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Transfer and order the input 'mydata' object to the internal Class
      ! data buffer.
      !---------------------------------------------------------------------
      type(mrtcal_classuser_t), intent(in)    :: mydata   !
      integer(kind=4),          intent(in)    :: version  ! The version of the data
      logical,                  intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_toclass_user
  end interface
  !
  interface
    subroutine mrtcal_fromclass_user(mydata,version,error)
      use gbl_message
      use class_api
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private
      ! Transfer the data values from the Class data buffer to the 'mydata'
      ! instance.
      !---------------------------------------------------------------------
      type(mrtcal_classuser_t), intent(out)   :: mydata   !
      integer(kind=4),          intent(in)    :: version  ! The version of the data
      logical,                  intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_fromclass_user
  end interface
  !
  interface
    subroutine mrtcal_user_dump(version,error)
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Dump to screen the Mrtcal User Subsection
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: version ! The version of the data
      logical,         intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_user_dump
  end interface
  !
  interface
    subroutine mrtcal_user_setvar(version,error)
      use class_api
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Define SIC variables in the structure R%USER%OWNER% which map the
      ! subsection content.
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: version ! The version of the data
      logical,         intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_user_setvar
  end interface
  !
  interface
    subroutine mrtcal_user_fix(version,found,error)
      use mrtcal_index_vars
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Hook to command:
      !   LAS\FIND /USER
      !  Find or not according the Mrtcal User Subsection. Called only if
      ! the observation has a user section and it matches the one
      ! declared here.
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: version  ! The version of the data
      logical,         intent(out)   :: found    !
      logical,         intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_user_fix
  end interface
  !
  interface
    subroutine mrtcal_user_find(arg,narg,error)
      use mrtcal_index_vars
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Hook to command:
      !   LAS\FIND /USER [Arg1] ... [ArgN]
      ! Command line parsing: retrieve the arguments given to the option.
      !---------------------------------------------------------------------
      integer(kind=4),  intent(in)    :: narg       !
      character(len=*), intent(in)    :: arg(narg)  !
      logical,          intent(inout) :: error      ! Logical error flag
    end subroutine mrtcal_user_find
  end interface
  !
  interface
    subroutine mrtcal_user_varidx_fill(version,ient,error)
      use classic_api
      use mrtcal_calib_types
      use mrtcal_sicidx
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Hook to command:
      !   EXP\VARIABLE USER /INDEX  (array filling part)
      ! Fill the arrays supporting the structure IDX%USER%
      !---------------------------------------------------------------------
      integer(kind=4),            intent(in)    :: version  ! The version of the data
      integer(kind=entry_length), intent(in)    :: ient     !
      logical,                    intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_user_varidx_fill
  end interface
  !
  interface
    subroutine mrtcal_user_varidx_defvar(error)
      use classic_api
      use mrtcal_sicidx
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Hook to command:
      !   EXP\VARIABLE USER /INDEX  (variables definition)
      ! Define the Sic arrays in IDX%USER%30M%MRTCAL%
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine mrtcal_user_varidx_defvar
  end interface
  !
  interface
    subroutine mrtcal_user_varidx_realloc(nent,error)
      use gildas_def
      use classic_api
      use mrtcal_sicidx
      !---------------------------------------------------------------------
      ! @ private-mandatory
      ! Hook to command:
      !   EXP\VARIABLE USER /INDEX  (re/deallocation part)
      ! Re/Deallocate the support arrays. nent <= 0 means deallocation only
      ! (useful at exit time)
      !---------------------------------------------------------------------
      integer(kind=entry_length), intent(in)    :: nent     !
      logical,                    intent(inout) :: error    ! Logical error flag
    end subroutine mrtcal_user_varidx_realloc
  end interface
  !
  interface mrtcal_chunkset_to_obs
    subroutine mrtcal_chunkset0d_to_obs(set,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_chunkset_to_obs
      ! Stitch the spectra in the set and write them as a Class observation
      ! into the Class output file
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: set
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset0d_to_obs
    subroutine mrtcal_chunkset1d_to_obs(set,error)
      use gbl_message
      use mrtcal_calib_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_chunkset_to_obs
      ! Convert an array of chunksets to one Class observation with
      ! Associated Arrays
      !---------------------------------------------------------------------
      type(chunkset_t), intent(in)    :: set(:)
      logical,          intent(inout) :: error
    end subroutine mrtcal_chunkset1d_to_obs
  end interface mrtcal_chunkset_to_obs
  !
  interface
    subroutine mrtcal_update_command(line,error)
      use gbl_message
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command MUPDATE
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_update_command
  end interface
  !
  interface
    subroutine mrtcal_variable_comm(line,error)
      use gbl_message
      use mrtcal_buffers
      use mrtcal_index_vars
      !---------------------------------------------------------------------
      ! @ private
      !  Support routine for command
      !   VARIABLE [*|WHAT [READ|WRITE]]
      !  Create the Sic structures mapping the mrtcal internal buffers
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   !
      logical,          intent(inout) :: error  !
    end subroutine mrtcal_variable_comm
  end interface
  !
  interface
    subroutine mrtcal_variable_databuf(struct,databuf,ro,error)
      use mrtcal_buffer_types
      !---------------------------------------------------------------------
      ! @ private
      !  Create or recreate Sic variables mapping a data_buffer_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*),    intent(in)    :: struct   ! Parent structure name
      type(data_buffer_t), intent(in)    :: databuf  !
      logical,             intent(in)    :: ro       ! Read-Only
      logical,             intent(inout) :: error    !
    end subroutine mrtcal_variable_databuf
  end interface
  !
  interface
    subroutine mrtcal_variable_book(struct,book,ro,error)
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      !  Create or recreate Sic variables mapping a book_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: struct  ! Parent structure name
      type(book_t),     intent(in)    :: book    !
      logical,          intent(in)    :: ro      ! Read-Only
      logical,          intent(inout) :: error   !
    end subroutine mrtcal_variable_book
  end interface
  !
  interface
    subroutine mrtcal_variable_range(struct,range,ro,error)
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      !  Create or recreate Sic variables mapping a range_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: struct  ! Parent structure name
      type(range_t),    intent(in)    :: range   !
      logical,          intent(in)    :: ro      ! Read-Only
      logical,          intent(inout) :: error   !
    end subroutine mrtcal_variable_range
  end interface
  !
  interface
    subroutine mrtcal_variable_block(struct,block,ro,error)
      use mrtcal_bookkeeping_types
      !---------------------------------------------------------------------
      ! @ private
      !  Create or recreate Sic variables mapping a block_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: struct  ! Parent structure name
      type(block_t),    intent(in)    :: block   !
      logical,          intent(in)    :: ro      ! Read-Only
      logical,          intent(inout) :: error   !
    end subroutine mrtcal_variable_block
  end interface
  !
  interface
    subroutine mrtcal_write_command(line,error)
      use gbl_message
      use mrtcal_buffers
      !---------------------------------------------------------------------
      ! @ private
      ! Support routine for command WRITE
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line
      logical,          intent(inout) :: error
    end subroutine mrtcal_write_command
  end interface
  !
  interface
    subroutine mrtcal_write_chunkset_fsw_toclass(chunkset1,chunkset2,out,nspec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private
      !  Specific to FSW data
      !  Fold the pair of chunksets and produce a single class spectrum
      !---------------------------------------------------------------------
      type(chunkset_t),            intent(in)    :: chunkset1
      type(chunkset_t),            intent(in)    :: chunkset2
      type(mrtcal_setup_output_t), intent(in)    :: out    ! Output configuration
      integer(kind=4),             intent(inout) :: nspec  ! Cumulative number of spectra written
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_chunkset_fsw_toclass
  end interface
  !
  interface mrtcal_write_chunkset_toclass
    subroutine mrtcal_write_chunkset0d_toclass(chunkset0d,out,nspec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_write_chunkset_toclass
      !  Write a single chunk set to the Class output file by chunk or
      !  by set of chunks
      !---------------------------------------------------------------------
      type(chunkset_t),            intent(in)    :: chunkset0d
      type(mrtcal_setup_output_t), intent(in)    :: out    ! Output configuration
      integer(kind=4),             intent(inout) :: nspec  ! Cumulative number of spectra written
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_chunkset0d_toclass
    subroutine mrtcal_write_chunkset1d_toclass(chunkset1d,out,nspec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_write_chunkset_toclass
      !  Write a single chunk set to the Class output file by chunk or
      !  by set of chunks
      !---------------------------------------------------------------------
      type(chunkset_t),            intent(in)    :: chunkset1d(:)
      type(mrtcal_setup_output_t), intent(in)    :: out    ! Output configuration
      integer(kind=4),             intent(inout) :: nspec  ! Cumulative number of spectra written
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_chunkset1d_toclass
  end interface mrtcal_write_chunkset_toclass
  !
  interface mrtcal_write_toclass
    subroutine mrtcal_write_chunkset3d_toclass(chunkset_3d,out,nspec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_write_toclass
      ! Convert the input chunk sets to Class observations
      ! This version for 3D chunk sets (i.e. not yet time averaged)
      !---------------------------------------------------------------------
      type(chunkset_3d_t),         intent(in)    :: chunkset_3d
      type(mrtcal_setup_output_t), intent(in)    :: out    ! Output configuration
      integer(kind=4),             intent(inout) :: nspec  ! Cumulative number of spectra written
      logical,                     intent(inout) :: error
    end subroutine mrtcal_write_chunkset3d_toclass
    subroutine mrtcal_write_chunkset2d_toclass(data_2d,out,nspec,error)
      use gbl_message
      use mrtcal_calib_types
      use mrtcal_setup_types
      !---------------------------------------------------------------------
      ! @ private-generic mrtcal_write_toclass
      ! Convert the input chunk sets to Class observations
      ! This version for 2D chunk sets (i.e. already time averaged)
      !---------------------------------------------------------------------
      type(chunkset_2d_t),           intent(in)    :: data_2d  ! The data RY to be written
      type(mrtcal_setup_output_t),   intent(in)    :: out      ! Output configuration
      integer(kind=4),               intent(inout) :: nspec    ! Cumulative number of spectra written
      logical,                       intent(inout) :: error    !
    end subroutine mrtcal_write_chunkset2d_toclass
  end interface mrtcal_write_toclass
  !
end module mrtcal_interfaces_private
