subroutine rheader(set,obs,entry_num,user_function,error,readsec_in)
  use gbl_message
  use gbl_constant
  use classcore_interfaces, except_this=>rheader
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  !  Reset the observation and read all present header sections by
  ! default, or read a subset if optional argument is present.
  !----------------------------------------------------------------------
  type(class_setup_t),        intent(in)    :: set                    !
  type(observation),          intent(inout) :: obs                    !
  integer(kind=entry_length), intent(in)    :: entry_num              !
  logical,                    intent(out)   :: error                  !
  logical,                    external      :: user_function          !
  logical, optional,          intent(in)    :: readsec_in(-mx_sec:0)  !
  ! Local
  logical :: notok
  logical :: readsec(-mx_sec:0)  ! Which section are to be read
  !
  error = .false.
  !
  ! Reset the input observation header
  call rzero(obs,'KEEP',user_function)
  !
  ! Read its descriptor, index, and presec array. Note that part of the
  ! header is filled here.
  call robs(obs,entry_num,error)
  if (error)  return
  !
  if (present(readsec_in)) then
    readsec(:) = readsec_in(:)
  else
    ! Read all the (available) sections
    readsec(:) = .true.
  endif
  call rheader_sub(set,obs,readsec,error)
  if (error)  return
  !
  ! Now, read user section if any
  notok = user_function('GET')
  if (notok) then
     call class_message(seve%w,'GET','Error reading user sections')
  endif
  !
end subroutine rheader
!
subroutine rheader_sub(set,obs,readsec_in,error)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>rheader_sub
  use class_parameter
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! CLASS internal routine
  !  Read only the requested sections (if they exist)
  ! FixMe:
  !   - rename this subroutine!
  !   - use a specific type instead of "readsec_in(-mx_sec:0)"
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set                    !
  type(observation),   intent(inout) :: obs                    !
  logical,             intent(in)    :: readsec_in(-mx_sec:0)  !
  logical,             intent(inout) :: error                  ! Logical error flag
  ! Local
  logical :: readsec(-mx_sec:0)  ! Which section are effectively to be read
  logical :: err
  !
  ! 1) Get the general informations (always)
  err = .false.
  call rgen(set,obs,err)
  error = error.or.err
  err = .false.
  !
  ! 2) Setup the sections to be read
  readsec(:) = .false.  ! Default no for any section
  readsec(class_sec_pos_id) = readsec_in(class_sec_pos_id)
  !
  ! Optional, not type-specific sections
  readsec(class_sec_user_id)  = obs%head%presec(class_sec_user_id) .and.readsec_in(class_sec_user_id)
  readsec(class_sec_res_id)   = obs%head%presec(class_sec_res_id)  .and.readsec_in(class_sec_res_id)
  readsec(class_sec_bas_id)   = obs%head%presec(class_sec_bas_id)  .and.readsec_in(class_sec_bas_id)
  readsec(class_sec_plo_id)   = obs%head%presec(class_sec_plo_id)  .and.readsec_in(class_sec_plo_id)
  readsec(class_sec_his_id)   = obs%head%presec(class_sec_his_id)  .and.readsec_in(class_sec_his_id)
  readsec(class_sec_swi_id)   = obs%head%presec(class_sec_swi_id)  .and.readsec_in(class_sec_swi_id)
  readsec(class_sec_gau_id)   = obs%head%presec(class_sec_gau_id)  .and.readsec_in(class_sec_gau_id)
  readsec(class_sec_cal_id)   = obs%head%presec(class_sec_cal_id)  .and.readsec_in(class_sec_cal_id)
  readsec(class_sec_bea_id)   = obs%head%presec(class_sec_bea_id)  .and.readsec_in(class_sec_bea_id)
  readsec(class_sec_sky_id)   = obs%head%presec(class_sec_sky_id)  .and.readsec_in(class_sec_sky_id)
  readsec(class_sec_her_id)   = obs%head%presec(class_sec_her_id)  .and.readsec_in(class_sec_her_id)
  readsec(class_sec_com_id)   = obs%head%presec(class_sec_com_id)  .and.readsec_in(class_sec_com_id)
  readsec(class_sec_assoc_id) = obs%head%presec(class_sec_assoc_id).and.readsec_in(class_sec_assoc_id)
  readsec(class_sec_desc_id)  = obs%head%presec(class_sec_desc_id) .and.readsec_in(class_sec_desc_id)  ! the OTF section if any
  !
  ! Type-specific sections
  if (obs%head%gen%kind.eq.kind_spec) then
    readsec(class_sec_spe_id) = readsec_in(class_sec_spe_id)
    ! Recover fits results (NH3/HFS, ABS, SHELL), if any
    readsec(class_sec_hfs_id) = obs%head%presec(class_sec_hfs_id).and.readsec_in(class_sec_hfs_id)
    readsec(class_sec_abs_id) = obs%head%presec(class_sec_abs_id).and.readsec_in(class_sec_abs_id)
    readsec(class_sec_she_id) = obs%head%presec(class_sec_she_id).and.readsec_in(class_sec_she_id)
    !
  elseif (obs%head%gen%kind.eq.kind_cont .or. &
          obs%head%gen%kind.eq.kind_onoff) then
    readsec(class_sec_dri_id) = readsec_in(class_sec_dri_id)
    ! Recover continuum fit parameters, if any
    readsec(class_sec_poi_id) = obs%head%presec(class_sec_poi_id).and.readsec_in(class_sec_poi_id)
    !
  elseif (obs%head%gen%kind.eq.kind_sky) then
    readsec(class_sec_cal_id) = readsec_in(class_sec_cal_id)
    readsec(class_sec_sky_id) = readsec_in(class_sec_sky_id)
  endif
  !
  ! 3) Effectively read the selected sections
  if (readsec(class_sec_pos_id)) then
    call rpos(set,obs,err)
    error = error.or.err
    err = .false.
    call convert_pos(set,obs%head,error)
  endif
  if (readsec(class_sec_spe_id)) then
     call rspec(set,obs,err)
     error = error.or.err
     err = .false.
     call convert_vtype(set,obs%head,error)
  endif
  if (readsec(class_sec_res_id)) then
     call rres(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_hfs_id)) then
    call rnh3(set,obs,err)
    error = error.or.err
    err = .false.
  endif
  if (readsec(class_sec_abs_id)) then
    call rabs(set,obs,err)
    error = error.or.err
    err = .false.
  endif
  if (readsec(class_sec_she_id)) then
    call rshel(set,obs,err)
    error = error.or.err
    err = .false.
  endif
  if (readsec(class_sec_swi_id)) then
    call rswi(set,obs,err)
    error = error.or.err
    err = .false.
  else
    obs%head%swi%nphas = 0
    obs%head%swi%swmod = mod_pos
  endif
  if (readsec(class_sec_dri_id)) then
     call rcont(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_poi_id)) then
    call rpoint(set,obs,err)
    error = error.or.err
    err = .false.
  endif
  if (readsec(class_sec_bas_id)) then
     call rbase(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_plo_id)) then
     call rplot(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_his_id)) then
     call rorig(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_gau_id)) then
     call rgaus(set,obs,err)
     error = error.or.err
     err = .false.
  else
     obs%head%gau%sigba = 0.0
  endif
  if (readsec(class_sec_cal_id)) then
     call rcal(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_bea_id)) then
     call rbeam(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_sky_id)) then
     call rsky(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_her_id)) then
     call rherschel(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_com_id)) then
     call rcom(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_desc_id))  then
     call rdescr(set,obs,err)
     call class_message(seve%i,'GET','OTF Section')
     obs%is_otf = .true.
     error = error.or.err
     err = .false.
  else
     obs%head%des%ldump = 0  ! Not old OTF format - needed to avoid pb
     obs%head%des%ndump = 1  ! Not old OTF format - needed to avoid pb
     obs%is_otf = .false.
  endif
  if (readsec(class_sec_assoc_id)) then
     call rassoc(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  if (readsec(class_sec_user_id)) then
     if (set%verbose)  call class_message(seve%i,'GET','User Section')
     call ruser(set,obs,err)
     error = error.or.err
     err = .false.
  endif
  !
end subroutine rheader_sub
