!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine imbfits_read_header(filename,imbf,bandwidth,error)
  use gildas_def
  use gbl_message
  use imbfits_interfaces, except_this => imbfits_read_header
  use imbfits_types
  !---------------------------------------------------------------------
  ! @ public
  ! Open the file, read the leading HDUs, and build the list
  ! (equivalence classes) of subscans.
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: filename
  type(imbfits_t),  intent(inout) :: imbf
  real(kind=4),     intent(in)    :: bandwidth  ! IMBF-backend slicing width (0 = no slicing)
  logical,          intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='READ>HEADER'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  call imbfits_reopen_file(filename,imbf%file,imbf%hdus,error)
  if (error) return
  !
  call imbfits_read_leadhdus(imbf,bandwidth,error)
  if (error) return
  !
  call imbfits_check_leadhdus(imbf,error)
  if (error) return
  !
  call imbfits_read_subscan_eclass(imbf,error)
  if (error)  return
  !
end subroutine imbfits_read_header
!
subroutine imbfits_reopen_file(filename,file,hdus,error)
  use gildas_def
  use gbl_message
  use imbfits_types
  use imbfits_interfaces, except_this => imbfits_reopen_file
  !---------------------------------------------------------------------
  ! @ private
  ! Open, if needed, the given file. Close of needed any previous file
  ! (if different).
  !---------------------------------------------------------------------
  character(len=*),     intent(in)    :: filename
  type(imbfits_file_t), intent(inout) :: file
  type(imbfits_hdus_t), intent(inout) :: hdus
  logical,              intent(inout) :: error
  !
  if (file%name.eq.'') then
    ! No previous file in memory
    call imbfits_open_file(filename,file,hdus,error)
    !
  elseif (filename.eq.file%name) then
    ! Same file, is it closed or opened?
    if (file%unit.eq.0) then
      ! File is closed, open it
      call imbfits_open_file(filename,file,hdus,error)
    else
      ! Same file, already opened: nothing to do
      continue
    endif
  else
    ! Not the same file name
    if (file%unit.ne.0) then
      ! The old file is still opened: close it
      call imbfits_close_file(file,error)
      if (error)  return
    endif
    call imbfits_open_file(filename,file,hdus,error)
  endif
  !
end subroutine imbfits_reopen_file
!
subroutine imbfits_open_file(filename,file,hdus,error)
  use gbl_message
  use gildas_def
  use cfitsio_api
  use gkernel_interfaces
  use imbfits_types
  use imbfits_interfaces, except_this => imbfits_open_file
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  character(len=*),     intent(in)    :: filename
  type(imbfits_file_t), intent(out)   :: file
  type(imbfits_hdus_t), intent(out)   :: hdus
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='IMBFITS>OPEN>FILE'
  integer(kind=4) :: status
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  ! CFITSIO is able to deal with several files at the same time as long
  ! as we identify them with different logical units.
  status = sic_getlun(file%unit)
  if (status.ne.1) then
    call imbfits_message(seve%e,rname,'Could not get new logical unit')
    error = .true.
    return
  endif
  !
  status = 0
  file%name = filename
  call ftopen(file%unit,file%name,file%rwstatus,file%block,status)
  if (status.gt.0) then
     call imbfits_message(seve%e,rname,'Do not succeed to open '''//trim(file%name)//'''')
     call cfitsio_message(status)
     error = .true.
     ! Must clean before exit
     file%name = ''
     call sic_frelun(file%unit)
     file%unit = 0
     return
  endif
  !
  call imbfits_hdus(file,hdus,error)
  if (error)  return
  !
end subroutine imbfits_open_file
!
subroutine imbfits_read_leadhdus(imbf,bandwidth,error)
  use imbfits_types
  use imbfits_interfaces, except_this=>imbfits_read_leadhdus
  !---------------------------------------------------------------------
  ! @ public
  ! Read the 4 first leading HDUs
  !---------------------------------------------------------------------
  type(imbfits_t), intent(inout) :: imbf       !
  real(kind=4),    intent(in)    :: bandwidth  ! IMBF-backend slicing width (0 = no slicing)
  logical,         intent(inout) :: error      !
  ! Local
  character(len=*), parameter :: rname='READ>LEADHDUS'
  !
  call imbfits_read_header_primary(imbf%file,imbf%primary,error)
  if (error)  return
  imbf%file%isholography = imbf%primary%instrume%val.eq.'holo'
  !
  call imbfits_read_header_scan(imbf,imbf%scan,error)
  if (error)  return
  !
  call imbfits_read_header_frontend(imbf%file,imbf%front,error)
  if (error)  return
  imbf%file%isarray = any(imbf%front%table%nofeeds%val.gt.1)
  !
  ! Backend-HDU: must come after Frontend-HDU
  call imbfits_read_header_backend(imbf,bandwidth,error)
  if (error)  return
  !
  ! Derotator: only for array receivers
  if (imbf%file%isarray) then
    call imbfits_read_header_derot(imbf,imbf%derot,error)
  else
    call imbfits_free_header_derot(imbf%derot,error)
  endif
  if (error)  return
  !
end subroutine imbfits_read_leadhdus
!
subroutine imbfits_check_leadhdus(imbf,error)
  use imbfits_types
  use imbfits_interfaces, except_this => imbfits_check_leadhdus
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 4 first HDUs
  !---------------------------------------------------------------------
  type(imbfits_t),  intent(inout) :: imbf      !
  logical,          intent(inout) :: error     !
  ! Local
  character(len=*), parameter :: rname='CHECK>LEADHDUS'
  !
  call imbfits_check_header_primary(imbf%file,imbf%primary,error)
  if (error)  return
  call imbfits_check_header_scan(imbf%primary,imbf%scan,error)
  if (error)  return
  ! call imbfits_check_header_frontend(imbf%file,imbf%front,error)
  ! if (error)  return
  call imbfits_check_header_backend(imbf%back,error)
  if (error)  return
  !
end subroutine imbfits_check_leadhdus
!
subroutine imbfits_read_subscan_eclass(imbf,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>imbfits_read_subscan_eclass
  use imbfits_types
  !---------------------------------------------------------------------
  ! @ private
  ! Run through all the subscans headers and build equivalences classes
  ! for all of them
  !---------------------------------------------------------------------
  type(imbfits_t), intent(inout) :: imbf
  logical,         intent(inout) :: error
  ! Local
  integer(kind=4) :: isub,nsub
  type(imbfits_subscan_t) :: subs
  !
  nsub = imbf%primary%n_obsp%val
  !
  call reallocate_eclass_char(imbf%seclass,nsub,error)
  if (error)  return
  !
  do isub=1,nsub
    ! Read IMBF-antenna ONLY for efficiency purpose
    call imbfits_read_header_antslow(imbf,isub,subs%antslow,error)
    if (error)  goto 100
    !
    imbf%seclass%val(isub) = subs%antslow%head%substype%val
    imbf%seclass%cnt(isub) = 1
  enddo
  !
  ! Compute equivalence classes to gather the subscans by family:
  call eclass_char(eclass_char_eq,imbf%seclass)
  !
100 continue
  call imbfits_free_header_antslow(subs%antslow,error)
  if (error)  return
  !
end subroutine imbfits_read_subscan_eclass
!
subroutine imbfits_close_file(file,error)
  use gbl_message
  use gildas_def
  use cfitsio_api
  use gkernel_interfaces
  use imbfits_types
  use imbfits_interfaces, except_this => imbfits_close_file
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(imbfits_file_t), intent(inout) :: file
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='IMBFITS>CLOSE>FILE'
  integer(kind=4) :: status
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  status = 0
  call ftclos(file%unit,status)
  if (status.gt.0) then
     call imbfits_message(seve%e,rname,'Do not succeed to close '//trim(file%name))
     call cfitsio_message(status)
     error = .true.
     return
  endif
  !
  call sic_frelun(file%unit)
  file%unit = 0
  !
end subroutine imbfits_close_file
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine imbfits_free_leadhdus(imbf,error)
  use imbfits_types
  use imbfits_interfaces, except_this=>imbfits_free_leadhdus
  !---------------------------------------------------------------------
  ! @ public
  ! Free the leading HDUs
  !---------------------------------------------------------------------
  type(imbfits_t), intent(inout) :: imbf      !
  logical,         intent(inout) :: error     !
  !
  call imbfits_free_header_primary(imbf%primary,error)
  if (error)  return
  call imbfits_free_header_scan(imbf%scan,error)
  if (error)  return
  call imbfits_free_header_frontend(imbf%front,error)
  if (error)  return
  call imbfits_free_header_backend(imbf%back,error)
  if (error)  return
  call imbfits_free_header_derot(imbf%derot,error)
  if (error)  return
  !
end subroutine imbfits_free_leadhdus
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
