!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_write_command(line,error)
  use mrtcal_messaging
  use mrtcal_buffers
  use mrtcal_interfaces, except_this => mrtcal_write_command
  !---------------------------------------------------------------------
  ! @ private
  ! Support routine for command WRITE
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line
  logical,          intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='WRITE>COMMAND'
  integer(kind=4) :: nspec
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  nspec = 0
  call mrtcal_write_toclass(rfile%subscanbuf%databuf%mrtc,rsetup%out,nspec,error)
  if (error)  return
  !
  ! ZZZ feedback nspec?
  !
end subroutine mrtcal_write_command
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_write_chunkset3d_toclass(chunkset_3d,out,nspec,error)
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this=>mrtcal_write_chunkset3d_toclass
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  integer(kind=4) :: itime,ipix,iset
  character(len=*), parameter :: rname='WRITE>CHUNSET3D>TOCLASS'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  select case (chunkset_3d%kind)
  case (ckind_time)
    ! Convert chunk sets to Class observations
    do itime=1,chunkset_3d%ntime
      do ipix=1,chunkset_3d%npix
        do iset=1,chunkset_3d%nset
          call mrtcal_write_chunkset_toclass(  &
            chunkset_3d%chunkset(iset,ipix,itime),out,nspec,error)
          if (error)  return
        enddo
      enddo
    enddo
    !
  case (ckind_calib)
    ! Convert chunk sets to Class observations, but the Ntime dimension
    ! produces a single spectrum including (N-1) associated arrays.
    do ipix=1,chunkset_3d%npix
      do iset=1,chunkset_3d%nset
        call mrtcal_write_chunkset_toclass(  &
         chunkset_3d%chunkset(iset,ipix,:),out,nspec,error)
         if (error)  return
      enddo
    enddo
    !
  case (ckind_onoff)
    ! Collections of ON-OFF
    if (chunkset_3d%ntime.eq.1) then
      ! "time" dimension is 1: write as is
      do ipix=1,chunkset_3d%npix
        do iset=1,chunkset_3d%nset
          call mrtcal_write_chunkset_toclass(  &
            chunkset_3d%chunkset(iset,ipix,1),out,nspec,error)
          if (error)  return
        enddo
      enddo
    elseif (chunkset_3d%ntime.eq.2) then
      ! "time" dimension if 2: assume frequency switch and fold them together
      do ipix=1,chunkset_3d%npix
        do iset=1,chunkset_3d%nset
          ! The chunksets are sent separately to avoid array contiguity issues.
          call mrtcal_write_chunkset_fsw_toclass(  &
            chunkset_3d%chunkset(iset,ipix,1),     &
            chunkset_3d%chunkset(iset,ipix,2),     &
            out,nspec,error)
          if (error)  return
        enddo
      enddo
    else
      call mrtcal_message(seve%e,rname,'Kind of chunkset 3D not supported (1)')
      error = .true.
      return
    endif
    !
  case default
    call mrtcal_message(seve%e,rname,'Kind of chunkset 3D not supported (2)')
    error = .true.
    return
  end select
  !
end subroutine mrtcal_write_chunkset3d_toclass
!
subroutine mrtcal_write_chunkset2d_toclass(data_2d,out,nspec,error)
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this => mrtcal_write_chunkset2d_toclass
  !---------------------------------------------------------------------
  ! @ 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    !
  ! Local
  character(len=*), parameter :: rname='WRITE>CHUNSET2D>TOCLASS'
  integer(kind=size_length) :: ipix,iset,ichunk
  type(chunkset_t), pointer :: data
  type(chunkset_t) :: twosets(2)
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  if (out%weight) then
    ! Write each spectrum, plus its weight array as an Associated Array. We
    ! have to split RY (data1) and W (dataw) in 2 different chunksets.
    ! mrtcal_write_chunkset_toclass will understand it has to write the
    ! first one as the main spectrum and the second one as an Associated
    ! Array.
    !
    do ipix=1,data_2d%npix
      do iset=1,data_2d%nset
        data => data_2d%chunkset(iset,ipix)
        !
        ! Create a pair of chunksets. First is the spectrum, just need
        ! pointers. Minor cost, no data duplicated.
        call twosets(1)%reassociate(data,error)
        if (error)  return
        !
        ! Second is the weight array, but we need to duplicate it to store the
        ! dataw(:) as data1(:) in a new chunkset. This needs another allocated
        ! chunkset:
        call twosets(2)%clone(data,.true.,error)
        if (error)  return
        !
        do ichunk=1,twosets(2)%n
          twosets(2)%chunks(ichunk)%pos%sourc = 'W'
          twosets(2)%chunks(ichunk)%data1(:) = data%chunks(ichunk)%dataw(:)
        enddo
        !
        ! Write this pair as 1 spectrum + 1 associated array
        call mrtcal_write_chunkset_toclass(twosets,out,nspec,error)
        if (error)  return
        !
      enddo ! iset
    enddo ! ipix
    ! NB: we free only twosets(2). twosets(1) was only associated
    call twosets(2)%free(error)
    if (error)  return
    !
  else
    !
    do ipix=1,data_2d%npix
      do iset=1,data_2d%nset
        call mrtcal_write_chunkset_toclass(data_2d%chunkset(iset,ipix),out,nspec,error)
        if (error)  return
      enddo ! iset
    enddo ! ipix
    !
  endif
  !
end subroutine mrtcal_write_chunkset2d_toclass
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_write_chunkset0d_toclass(chunkset0d,out,nspec,error)
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this => mrtcal_write_chunkset0d_toclass
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  character(len=*), parameter :: rname='WRITE>CHUNKSET0D>TOCLASS'
  integer(kind=4) :: ichunk
  type(chunkset_t) :: single
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  if (out%bychunk) then
    ! Convert each chunk
    if (out%toclass) then
      do ichunk=1,chunkset0d%n
        ! Create a dummy chunkset containing a single chunk
        call single%reassociate(chunkset0d,error,ichunk)
        if (error)  return
        call mrtcal_chunkset_to_obs(single,error)
        if (error)  return
      enddo
    endif
    nspec = nspec+chunkset0d%n
  else
    ! Stitch by set of chunks and convert
    if (out%toclass) then
      call mrtcal_chunkset_to_obs(chunkset0d,error)
      if (error)  return
    endif
    nspec = nspec+1
  endif
  !
end subroutine mrtcal_write_chunkset0d_toclass
!
subroutine mrtcal_write_chunkset1d_toclass(chunkset1d,out,nspec,error)
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this=>mrtcal_write_chunkset1d_toclass
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  character(len=*), parameter :: rname='WRITE>CHUNKSET1D>TOCLASS'
  integer(kind=4) :: nchunk,ichunk,nset,iset
  type(chunkset_t), allocatable :: single1d(:)
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  if (out%bychunk) then
    ! Convert each chunk
    nchunk = chunkset1d(1)%n  ! Assume all chunkset have same number of chunks
    if (out%toclass) then
      nset = size(chunkset1d)
      allocate(single1d(nset))
      do ichunk=1,nchunk
        ! Create a dummy chunkset1d with single chunk each
        do iset=1,nset
          call single1d(iset)%reassociate(chunkset1d(iset),error,ichunk)
          if (error)  return
        enddo
        call mrtcal_chunkset_to_obs(single1d,error)
        if (error)  return
      enddo
      deallocate(single1d)
    endif
    nspec = nspec+nchunk
  else
    ! Stitch by set of chunks and convert
    if (out%toclass) then
      call mrtcal_chunkset_to_obs(chunkset1d,error)
      if (error)  return
    endif
    nspec = nspec+1
  endif
  !
end subroutine mrtcal_write_chunkset1d_toclass
!
subroutine mrtcal_write_chunkset_fsw_toclass(chunkset1,chunkset2,out,nspec,error)
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this=>mrtcal_write_chunkset_fsw_toclass
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  character(len=*), parameter :: rname='WRITE>CHUNKSET>FSW>TOCLASS'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  if (out%bychunk) then
    ! Probably not worth implementing this mode. The chunks are typically
    ! 20 Mhz while the throw is about 5 to 10 MHz => we would loose almost
    ! everything!
    call mrtcal_message(seve%e,rname,'Can not write FSW data per chunk')
    error = .true.
    return
    !
  else
    ! Stitch by set of chunks and convert
    if (out%toclass) then
      call mrtcal_chunkset_fsw_to_obs(out,chunkset1,chunkset2,error)
      if (error)  return
    endif
    nspec = nspec+1
  endif
  !
end subroutine mrtcal_write_chunkset_fsw_toclass
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
