subroutine rgen(set,obs,error)
  use classcore_interfaces, except_this=>rgen
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -2 General
  !  Caution: part of the GEN section is actually copied from the
  ! index, and not read here
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_gen_id,error)
end subroutine rgen
!
subroutine rpos(set,obs,error)
  use classcore_interfaces, except_this=>rpos
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -3 Position
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_pos_id,error)
end subroutine rpos
!
subroutine rspec(set,obs,error)
  use classcore_interfaces, except_this=>rspec
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -4 Spectroscopy
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_spe_id,error)
  !
  ! Factorize here some duplicates of the spectroscopic section. It
  ! is unclear where this action should be factorized. Here is good
  ! for spectra from disk, subroutine 'abscissa' is good for a memory
  ! only spectrum, but 'abscissa' is not suited when the other data
  ! arrays are not needed (waste of time)...
  obs%cbad = obs%head%spe%bad
  obs%cnchan = obs%head%spe%nchan
  !
end subroutine rspec
!
subroutine rres(set,obs,error)
  use classcore_interfaces, except_this=>rres
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -21 Resolution description
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_res_id,error)
end subroutine rres
!
subroutine rbase(set,obs,error)
  use classcore_interfaces, except_this=>rbase
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -5 Baseline
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_bas_id,error)
end subroutine rbase
!
subroutine rorig(set,obs,error)
  use classcore_interfaces, except_this=>rorig
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -6 Origin
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_his_id,error)
end subroutine rorig
!
subroutine rplot(set,obs,error)
  use classcore_interfaces, except_this=>rplot
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -7 Plotting parameters
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_plo_id,error)
end subroutine rplot
!
subroutine rswi(set,obs,error)
  use classcore_interfaces, except_this=>rswi
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -8 Switching description
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_swi_id,error)
end subroutine rswi
!
subroutine rgaus(set,obs,error)
  use classcore_interfaces, except_this=>rgaus
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -9 Gauss fit
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_gau_id,error)
end subroutine rgaus
!
subroutine rcont(set,obs,error)
  use classcore_interfaces, except_this=>rcont
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -10 Drift continuum
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_dri_id,error)
  !
  obs%cnchan = obs%head%dri%npoin
  obs%cbad = obs%head%dri%bad
end subroutine rcont
!
subroutine rbeam(set,obs,error)
  use classcore_interfaces, except_this=>rbeam
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -11 Beam Switch
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_bea_id,error)
end subroutine rbeam
!
subroutine rshel(set,obs,error)
  use classcore_interfaces, except_this=>rshel
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -12 SHELL fit
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_she_id,error)
end subroutine rshel
!
subroutine rnh3(set,obs,error)
  use classcore_interfaces, except_this=>rnh3
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -13 NH3 fit
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_hfs_id,error)
end subroutine rnh3
!
subroutine rabs(set,obs,error)
  use classcore_interfaces, except_this=>rabs
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -18 ABS fit
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_abs_id,error)
end subroutine rabs
!
subroutine rcal(set,obs,error)
  use classcore_interfaces, except_this=>rcal
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -14 Calibration
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_cal_id,error)
end subroutine rcal
!
subroutine rpoint(set,obs,error)
  use classcore_interfaces, except_this=>rpoint
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -15 Pointing fit
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_poi_id,error)
end subroutine rpoint
!
subroutine rsky(set,obs,error)
  use classcore_interfaces, except_this=>rsky
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -16 Skydip
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_sky_id,error)
end subroutine rsky
!
subroutine rxcoo(set,obs,error)
  use classcore_interfaces, except_this=>rxcoo
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -17 X coordinates (irregularly spaced data).
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec_xcoo(set,obs,error)
end subroutine rxcoo
!
subroutine rdescr(set,obs,error)
  use classcore_interfaces, except_this=>rdescr
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -30 Data Section descriptor
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_desc_id,error)
end subroutine rdescr
!
subroutine rcom(set,obs,error)
  use classcore_interfaces, except_this=>rcom
  use class_types
  !-------------------------------------------------------------------
  ! @ private
  ! -1  Comment section
  !-------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_com_id,error)
end subroutine rcom
!
subroutine ruser(set,obs,error)
  use classcore_interfaces, except_this=>ruser
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! Write the USER defined section description
  !----------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_user_id,error)
end subroutine ruser
!
subroutine rassoc(set,obs,error)
  use classcore_interfaces, except_this=>rassoc
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! -19 ASSOCiated arrays section
  !----------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_assoc_id,error)
end subroutine rassoc
!
subroutine rherschel(set,obs,error)
  use classcore_interfaces, except_this=>rherschel
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! HERSCHEL section
  !----------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  type(observation),   intent(inout) :: obs
  logical,             intent(inout) :: error
  call crsec(set,obs,class_sec_her_id,error)
end subroutine rherschel
!
subroutine rdata(set,obs,nv4,values,error)
  use gildas_def
  use gbl_message
  use classic_api
  use classcore_dependencies_interfaces
  use classcore_interfaces, except_this=>rdata
  use class_types
  use class_common
  !----------------------------------------------------------------------
  ! @ private
  ! Read the whole data section
  !----------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set          !
  type(observation),   intent(in)    :: obs          ! Observation
  integer(kind=4),     intent(inout) :: nv4          ! Number of data words
  real(kind=4),        intent(out)   :: values(nv4)  ! Data array
  logical,             intent(inout) :: error        !
  ! Local
  integer(kind=4) :: l1,i,k
  integer(kind=data_length) :: first,last,nv8
  !
  error = .false.
  !
  if (obs%head%presec(class_sec_desc_id) ) then
     ! OTF data (presumably)
     nv4 = min(nv4,obs%desc%ldata)
     nv8 = nv4
     call classic_entry_data_read(values,nv8,obs%desc,ibufobs,error)
     if (error)  return
     nv4 = nv8
     if (obs%head%des%ldump.gt.nv4 .or. obs%head%des%ndump*obs%head%des%ldump.gt.nv4) then
        call class_message(seve%f,'RDATA','Inconsistent data section')
        write(6,*) 'r_ndump, r_ldump, r_ldpar, nv'
        write(6,*)  obs%head%des%ndump, obs%head%des%ldump, obs%head%des%ldpar, nv4
        error = .true.
        return
     endif
     l1 = obs%head%des%ldump-obs%head%des%ldpar
     k = 1
     do i=1,obs%head%des%ndump
        call convert_dh (values(k),obs%head%des%ldpar,filein%conv)
        k = k+obs%head%des%ldpar
        call filein%conv%read%r4(values(k),values(k),l1)
        k = k+l1
     enddo
     !
  else
    ! Normal data
    first = 1_8
    last = nv4
    nv8 = nv4
    call rdata_sub(set,obs,first,last,nv8,values,error)
    nv4 = nv8
    if (error)  return
  endif
  !
end subroutine rdata
!
subroutine rdata_sub(set,obs,first,last,nv,values,error)
  use classic_api
  use classcore_interfaces, except_this=>rdata_sub
  use class_common
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! Read a subset of the data section.
  ! No support for OTF data
  !----------------------------------------------------------------------
  type(class_setup_t),       intent(in)    :: set         !
  type(observation),         intent(in)    :: obs         ! Observation
  integer(kind=data_length), intent(in)    :: first       ! First data word to read
  integer(kind=data_length), intent(in)    :: last        ! Last data word to read
  integer(kind=data_length), intent(inout) :: nv          ! Input and actual number of values read
  real(kind=4),              intent(out)   :: values(nv)  ! Data array
  logical,                   intent(inout) :: error       ! Logical error flag
  !
  error = .false.
  !
  if (filein_isvlm) then
    call rdata_sub_vlm(obs%desc%xnum,first,last,nv,values,error)
  else
    call rdata_sub_classic(obs,first,last,nv,values,error)
  endif
  if (error)  return
  !
  ! Chase NaN
  if (set%chase_nan)  &
    call modify_blanking(values,nv,obs_bad(obs%head),obs_bad(obs%head))
  !
end subroutine rdata_sub
!
subroutine rdata_sub_classic(obs,first,last,nv,values,error)
  use gildas_def
  use gbl_message
  use classic_api
  use classcore_dependencies_interfaces
  use classcore_interfaces, except_this=>rdata_sub_classic
  use class_common
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  !  Read a (subset of) the data array from an entry of a Classic file
  !---------------------------------------------------------------------
  type(observation),         intent(in)      :: obs         ! Observation
  integer(kind=data_length), intent(in)      :: first       ! First data word to read
  integer(kind=data_length), intent(in)      :: last        ! Last data word to read
  integer(kind=data_length), intent(inout)   :: nv          ! Input and actual number of values read
  real(kind=4),              intent(out)     :: values(nv)  ! Data array
  logical,                   intent(inout)   :: error       ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='RDATA'
  integer(kind=4) :: nv4
  !
  if (obs%head%presec(class_sec_desc_id)) then
    ! OTF data (presumably)
    call class_message(seve%e,rname,'Can not read subset of old OTF data section')
    error = .true.
    return
  endif
  !
  ! Read 'data' block
  call classic_entry_data_readsub(values,nv,first,last,obs%desc,ibufobs,error)
  if (error)  return
  nv4 = nv
  !
  if (filein%conv%code.ne.0) then
    ! Non-native, conversion needed.
    call filein%conv%read%r4(values,values,nv4)
  endif
  !
end subroutine rdata_sub_classic
!
subroutine convert_dh (iwin,nw,conv)
  use gbl_convert
  use gkernel_interfaces
  use classic_api
  !---------------------------------------------------------------------
  ! @ private
  !  Convert data header IWIN using conversion code CONVE, assuming NW
  ! is the length of the data header.
  !---------------------------------------------------------------------
  real(kind=4),             intent(inout) :: iwin(*)  ! Array containing data header to be converted
  integer(kind=4),          intent(in)    :: nw       ! Size of IWIN
  type(classic_fileconv_t), intent(in)    :: conv     ! Conversion structure
  ! Local
  !
  if (conv%code.eq.0) return
  !
  ! Non native, conversion needed. NB: inplace modification is not
  ! Fortran standard and might not work! Should use a temporary buffer.
  ! As for now, everything is in R4 format.
  call conv%read%r4(iwin(1),iwin(1),nw)
  !
end subroutine convert_dh
