!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_chunkset_2d_swi_fill(swmode,swdesc,chunkset2d,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_swi_fill
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  type(chunkset_t), pointer :: chunkset
  integer(kind=size_length) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>2D>SWI>FILL'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  do ipix=1,chunkset2d%npix
     do iset=1,chunkset2d%nset
        chunkset => chunkset2d%chunkset(iset,ipix)
        do ichunk=1,chunkset%n
           call mrtcal_chunk_swi_fill(swmode,swdesc,chunkset%chunks(ichunk),error)
           if (error) return
        enddo ! ichunk
     enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_swi_fill
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_chunkset_2d_copy_data(in,out,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_copy_data
  !---------------------------------------------------------------------
  ! @ private
  ! Data are copied
  !---------------------------------------------------------------------
  type(chunkset_2d_t), intent(in)    :: in
  type(chunkset_2d_t), intent(inout) :: out
  logical,             intent(inout) :: error
  ! Local
  type(chunkset_t), pointer :: inset,outset
  integer(kind=size_length) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>2D>COPY>DATA'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  do ipix=1,out%npix
     do iset=1,out%nset
        inset => in%chunkset(iset,ipix)
        outset => out%chunkset(iset,ipix)
        do ichunk=1,outset%n
           call mrtcal_chunk_copy_data(inset%chunks(ichunk),outset%chunks(ichunk),error)
           if (error) return
        enddo ! ichunk
     enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_copy_data
!
subroutine mrtcal_chunkset_2d_init_data(chunkset_2d,v,w,c,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_2d_init_data
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  type(chunkset_t), pointer :: chunkset
  integer(kind=size_length) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>2D>INIT>DATA'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  do ipix=1,chunkset_2d%npix
    do iset=1,chunkset_2d%nset
      chunkset => chunkset_2d%chunkset(iset,ipix)
      do ichunk=1,chunkset%n
        call mrtcal_chunk_init_data(chunkset%chunks(ichunk),v,w,c,error)
        if (error) return
      enddo ! ichunk
    enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_init_data
!
subroutine mrtcal_chunkset_3d_init_data(chunkset_3d,v,w,c,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_init_data
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  type(chunkset_t), pointer :: chunkset
  integer(kind=size_length) :: itime,ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>3D>INIT>DATA'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  do itime=1,chunkset_3d%ntime
    do ipix=1,chunkset_3d%npix
      do iset=1,chunkset_3d%nset
        chunkset => chunkset_3d%chunkset(iset,ipix,itime)
        do ichunk=1,chunkset%n
          call mrtcal_chunk_init_data(chunkset%chunks(ichunk),v,w,c,error)
          if (error) return
        enddo ! ichunk
      enddo ! iset
    enddo ! ipix
  enddo ! itime
  !
end subroutine mrtcal_chunkset_3d_init_data
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine chunkset_2d_consistency_2d2d(caller,c1,c2,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>chunkset_2d_consistency_2d2d
  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
  ! Local
  integer(kind=4) :: ipix,iset
  character(len=message_length) :: mess
  !
  ! Note that this test works also on unallocated arrays (dimensions=0)
  if (c1%npix.ne.c2%npix) then
    write(mess,'(A,I0,1X,I0)')  'Inconsistent number of pixels: ',c1%npix,c2%npix
    call mrtcal_message(seve%e,caller,mess)
    error = .true.
    return
  endif
  if (c1%nset.ne.c2%nset) then
    write(mess,'(A,I0,1X,I0)')  'Inconsistent number of sets: ',c1%nset,c2%nset
    call mrtcal_message(seve%e,caller,mess)
    error = .true.
    return
  endif
  !
  do ipix=1,c1%npix
    do iset=1,c1%nset
      call chunkset_consistency(caller,c1%chunkset(iset,ipix),c2%chunkset(iset,ipix),error)
      if (error)  return
    enddo
  enddo
  !
end subroutine chunkset_2d_consistency_2d2d
!
subroutine chunkset_2d_consistency_2d3d(caller,c1,c2,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>chunkset_2d_consistency_2d3d
  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
  ! Local
  integer(kind=4) :: ipix,iset
  character(len=message_length) :: mess
  !
  ! Note that this test works also on unallocated arrays (dimensions=0)
  if (c1%npix.ne.c2%npix) then
    write(mess,'(A,I0,1X,I0)')  'Inconsistent number of pixels: ',c1%npix,c2%npix
    call mrtcal_message(seve%e,caller,mess)
    error = .true.
    return
  endif
  if (c1%nset.ne.c2%nset) then
    write(mess,'(A,I0,1X,I0)')  'Inconsistent number of sets: ',c1%nset,c2%nset
    call mrtcal_message(seve%e,caller,mess)
    error = .true.
    return
  endif
  ! c2 is 3D: ignore its ntime dimension
  !
  do ipix=1,c1%npix
    do iset=1,c1%nset
      call chunkset_consistency(caller,c1%chunkset(iset,ipix),  &
                                       c2%chunkset(iset,ipix,1),error)
      if (error)  return
    enddo
  enddo
  !
end subroutine chunkset_2d_consistency_2d3d
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_chunkset_2d_interpolate_init(prev,next,slope,offset,interp,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_interpolate_init
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  integer(kind=size_length) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>2D>INTERPOLATE>INIT'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call chunkset_2d_consistency(rname,prev,next,error)
  if (error) return
  call mrtcal_chunkset_2d_interpolate_init_as_ref(prev,slope,offset,interp,error)
  if (error) return
  !
  do ipix=1,prev%npix
     do iset=1,prev%nset
        do ichunk=1,prev%chunkset(iset,ipix)%n
           call mrtcal_chunk_interpolate_init(&
                prev%chunkset(iset,ipix)%chunks(ichunk),&
                next%chunkset(iset,ipix)%chunks(ichunk),&
                slope%chunkset(iset,ipix)%chunks(ichunk),&
                offset%chunkset(iset,ipix)%chunks(ichunk),&
                error)
           if (error) return
        enddo ! ichunk
     enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_interpolate_init
!
subroutine mrtcal_chunkset_2d_interpolate_init_as_ref(ref,slope,offset,interp,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_interpolate_init_as_ref
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  character(len=*), parameter :: rname='CHUNKSET>2D>INTERPOLATE>INIT>AS>REF'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call clone_chunkset_2d(ref,slope,.true.,error)
  if (error) return
  call clone_chunkset_2d(ref,offset,.true.,error)
  if (error) return
  call clone_chunkset_2d(ref,interp,.true.,error)
  if (error) return
  !
end subroutine mrtcal_chunkset_2d_interpolate_init_as_ref
!
subroutine mrtcal_chunkset_2d_interpolate_do(mjd,slope,offset,interp,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_interpolate_do
  !---------------------------------------------------------------------
  ! @ 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
  ! Local
  integer(kind=size_length) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET>2D>INTERPOLATE>DO'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call chunkset_2d_consistency(rname,slope,offset,error)
  if (error) return
  call chunkset_2d_consistency(rname,slope,interp,error)
  if (error) return
  !
  do ipix=1,slope%npix
     do iset=1,slope%nset
        do ichunk=1,slope%chunkset(iset,ipix)%n
           call mrtcal_chunk_interpolate_do(mjd,&
                slope%chunkset(iset,ipix)%chunks(ichunk),&
                offset%chunkset(iset,ipix)%chunks(ichunk),&
                interp%chunkset(iset,ipix)%chunks(ichunk),&
                error)
           if (error) return
        enddo ! ichunk
     enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_interpolate_do
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_chunkset_2d_blank(ref,blank,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_2d_blank
  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
  ! Local
  integer(kind=4) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET2D>BLANK'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  ! Clone and duplicate headers, in particular the spectroscopic axis
  ! description
  call clone_chunkset_2d(ref,blank,.true.,error)
  if (error)  return
  !
  ! Reset irrelevant header values
  do ipix=1,blank%npix
    do iset=1,blank%nset
      do ichunk=1,blank%chunkset(iset,ipix)%n
! *** JP Still to be done
!        blank%chunkset(iset,ipix)%chunks(ichunk)%pos%sourc = ''
      enddo
    enddo
  enddo
  !
  ! Blank data and continuum, 0 weight.
  call mrtcal_chunkset_2d_init_data(blank,class_bad,0.,class_bad,error)
  if (error) return
  !
end subroutine mrtcal_chunkset_2d_blank
!
subroutine mrtcal_chunkset_2d_accumulate_init(ref,acc,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_2d_accumulate_init
  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
  ! Local
  integer(kind=4) :: ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET2D>ACCUMULATE>INIT'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call clone_chunkset_2d(ref,acc,.true.,error)
  if (error)  return
  !
  ! Reset integration time in 'accumulate' instance
  do ipix=1,acc%npix
    do iset=1,acc%nset
      do ichunk=1,acc%chunkset(iset,ipix)%n
        acc%chunkset(iset,ipix)%chunks(ichunk)%gen%time = 0.
        acc%chunkset(iset,ipix)%chunks(ichunk)%swi%duree(:) = 0.
      enddo
    enddo
  enddo
  !
  ! Reset values and weights in 'accumulate' instance
  call mrtcal_chunkset_2d_init_data(acc,0.,0.,0.,error)
  if (error) return
  !
end subroutine mrtcal_chunkset_2d_accumulate_init
!
subroutine mrtcal_chunkset_3d_accumulate_init(ref,acc,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_accumulate_init
  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
  ! Local
  integer(kind=4) :: itime,ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET3D>ACCUMULATE>INIT'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call clone_chunkset_3d(ref,acc,.true.,error)
  if (error)  return
  !
  ! Reset integration time in 'accumulate' instance
  do itime=1,acc%ntime
    do ipix=1,acc%npix
      do iset=1,acc%nset
        do ichunk=1,acc%chunkset(iset,ipix,itime)%n
          acc%chunkset(iset,ipix,itime)%chunks(ichunk)%gen%time = 0.
          acc%chunkset(iset,ipix,itime)%chunks(ichunk)%swi%duree(:) = 0.
        enddo
      enddo
    enddo
  enddo
  !
  ! Reset values and weights in 'accumulate' instance
  call mrtcal_chunkset_3d_init_data(acc,0.,0.,0.,error)
  if (error) return
  !
end subroutine mrtcal_chunkset_3d_accumulate_init
!
subroutine mrtcal_chunkset_2d_accumulate_setweight(diff,tscale,dowei,error)
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_2d_accumulate_setweight
  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
  ! Local
  integer(kind=size_length) :: ipix,iset
  !
  do ipix=1,diff%npix
    do iset=1,diff%nset
      call mrtcal_chunkset_accumulate_setweight(  &
        diff%chunkset(iset,ipix),    &
        tscale%chunkset(iset,ipix),  &
        dowei,error)
      if (error)  return
    enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_accumulate_setweight
!
subroutine mrtcal_chunkset_3d_accumulate_setweight(diff,tscale,dowei,error)
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_accumulate_setweight
  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
  ! Local
  integer(kind=size_length) :: itime,ipix,iset
  !
  do itime=1,diff%ntime
    do ipix=1,diff%npix
      do iset=1,diff%nset
        call mrtcal_chunkset_accumulate_setweight(  &
          diff%chunkset(iset,ipix,itime),    &
          tscale%chunkset(iset,ipix),        &
          dowei,error)
        if (error)  return
      enddo ! iset
    enddo ! ipix
  enddo ! itime
  !
end subroutine mrtcal_chunkset_3d_accumulate_setweight
!
subroutine mrtcal_chunkset_2d_accumulate_do(in2d,ou2d,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_2d_accumulate_do
  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
  ! Local
  integer(kind=size_length) :: ipix,iset
  character(len=*), parameter :: rname='CHUNKSET2D>ACCUMULATE>DO'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  ! ZZZ Something to be done on acc%corr?
  !
  ! ZZZ Something to be done on acc%isub? Makes probably no sense
  !
  do ipix=1,in2d%npix
    do iset=1,in2d%nset
      call mrtcal_chunkset_accumulate_do(  &
        in2d%chunkset(iset,ipix),    &
        ou2d%chunkset(iset,ipix),    &
        error)
    enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_accumulate_do
!
subroutine mrtcal_chunkset_3d_accumulate_do(in3d,ou3d,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_accumulate_do
  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
  ! Local
  integer(kind=size_length) :: itime,ipix,iset
  character(len=*), parameter :: rname='CHUNKSET3D>ACCUMULATE>DO'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  ! ZZZ Something to be done on acc%corr?
  !
  ! ZZZ Something to be done on acc%isub? Makes probably no sense
  !
  do itime=1,in3d%ntime  ! Not a time dimension here
    do ipix=1,in3d%npix
      do iset=1,in3d%nset
        call mrtcal_chunkset_accumulate_do(  &
          in3d%chunkset(iset,ipix,itime),    &
          ou3d%chunkset(iset,ipix,itime),    &
          error)
      enddo ! iset
    enddo ! ipix
  enddo ! itime
  !
end subroutine mrtcal_chunkset_3d_accumulate_do
!
subroutine mrtcal_chunkset_3d_append_init(ref,acc,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_append_init
  use mrtcal_calib_types
  !---------------------------------------------------------------------
  ! @ private
  ! (Re)allocate and initialize a 'chunkset_3d' structure for future
  ! use in mrtcal_chunkset_append_do
  !---------------------------------------------------------------------
  type(chunkset_3d_t), intent(in)    :: ref
  type(chunkset_3d_t), intent(inout) :: acc
  logical,             intent(inout) :: error
  ! Local
  integer(kind=4) :: itime,ipix,iset,ichunk
  character(len=*), parameter :: rname='CHUNKSET3D>APPEND>INIT'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call clone_chunkset_3d(ref,acc,.true.,error)
  if (error)  return
  !
  ! In append mode, the 'acc' object must start with 0 chunk in
  ! each chunkset. Just nullify their number in use (chunkset%n).
  ! Avoid deallocation as we will reallocate soon.
  do itime=1,acc%ntime
    do ipix=1,acc%npix
      do iset=1,acc%nset
        do ichunk=1,acc%chunkset(iset,ipix,itime)%n
          acc%chunkset(iset,ipix,itime)%n = 0
        enddo
      enddo
    enddo
  enddo
  !
end subroutine mrtcal_chunkset_3d_append_init
!
subroutine mrtcal_chunkset_3d_append_do(in3d,ou3d,error)
  use gbl_message
  use mrtcal_interfaces, except_this=>mrtcal_chunkset_3d_append_do
  use mrtcal_calib_types
  !---------------------------------------------------------------------
  ! @ private
  ! Append 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
  ! Local
  integer(kind=size_length) :: itime,ipix,iset
  character(len=*), parameter :: rname='CHUNKSET3D>APPEND>DO'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  ! ZZZ Something to be done on acc%corr?
  !
  ! ZZZ Something to be done on acc%isub? Makes probably no sense
  !
  do itime=1,in3d%ntime  ! Not a time dimension here
    do ipix=1,in3d%npix
      do iset=1,in3d%nset
        call mrtcal_chunkset_append_do(  &
          in3d%chunkset(iset,ipix,itime),    &
          ou3d%chunkset(iset,ipix,itime),    &
          error)
      enddo ! iset
    enddo ! ipix
  enddo ! itime
  !
end subroutine mrtcal_chunkset_3d_append_do
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_chunkset_2d_noise_init(chunkset_2d,error)
  use gbl_message
  use mrtcal_calib_types
  use mrtcal_interfaces, except_this => mrtcal_chunkset_2d_noise_init
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  type(chunkset_2d_t), intent(inout) :: chunkset_2d
  logical,             intent(inout) :: error
  ! Local
  integer(kind=4) :: ipix,iset,ichunk
  type(chunkset_t), pointer :: chunkset
  character(len=*), parameter :: rname='CHUNKSET2D>NOISE>INIT'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  do ipix=1,chunkset_2d%npix
     do iset=1,chunkset_2d%nset
        chunkset => chunkset_2d%chunkset(iset,ipix)
        do ichunk=1,chunkset%n
           call mrtcal_chunk_noise_init(chunkset%chunks(ichunk),error)
           if (error)  return
        enddo ! ichunk
     enddo ! iset
  enddo ! ipix
  !
end subroutine mrtcal_chunkset_2d_noise_init
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
