!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine consistency_defaults(set,cons)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>consistency_defaults
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set   !
  type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  select case (set%kind)
  case (kind_spec)
    call consistency_defaults_spec(cons)
  case (kind_cont)
    call consistency_defaults_cont(cons)
  ! case default
    ! No default set at this stage (i.e. can be called from FIND with any
    ! kind). Non supported kinds will be trappped when actually trying to
    ! check their consistency.
  end select
  !
end subroutine consistency_defaults
!
subroutine consistency_check_selection(set,line,iopt,cons,error)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>consistency_check_selection
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set    !
  character(len=*),    intent(in)    :: line   ! Command line
  integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  logical,             intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  select case (set%kind)
  case (kind_spec)
    call consistency_check_selection_spec(set,line,iopt,cons,error)
  case (kind_cont)
    call consistency_check_selection_cont(set,line,iopt,cons,error)
  case default
    call class_message(seve%e,rname,'Unsupported kind of data')
    error = .true.
  end select
  !
end subroutine consistency_check_selection
!
subroutine consistency_check_gen(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'general' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%gen%check.and.cons%gen%done) then
     if (cons%gen%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%gen%check = .false.
     endif
     write(mess,100) 'Data type',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_gen
!
subroutine consistency_check_sou(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'source' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%sou%check.and.cons%sou%done) then
     if (cons%sou%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%sou%check = .false.
     endif
     write(mess,100) 'Source name',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_sou
!
subroutine consistency_check_pos(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'position' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%pos%check.and.cons%pos%done) then
     if (cons%pos%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%pos%check = .false.
     endif
     write(mess,100) 'Position information',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_pos
!
subroutine consistency_check_off(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'offset' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%off%check.and.cons%off%done) then
     if (cons%off%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%off%check = .false.
     endif
     write(mess,100) 'Offset position',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_off
!
subroutine consistency_check_lin(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'line' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%lin%check.and.cons%lin%done) then
     if (cons%lin%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%lin%check = .false.
     endif
     write(mess,100) 'Line name',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_lin
!
subroutine consistency_check_spe(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'spectroscopy' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%spe%check.and.cons%spe%done) then
     if (cons%spe%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%spe%check = .false.
     endif
     write(mess,100) 'Spectroscopic information',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_spe
!
subroutine consistency_check_cal(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'calibration' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%cal%check.and.cons%cal%done) then
     if (cons%cal%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%cal%check = .false.
     endif
     write(mess,100) 'Calibration information',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_cal
!
subroutine consistency_check_swi(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'switching' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%swi%check.and.cons%swi%done) then
     if (cons%swi%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%swi%check = .false.
     endif
     write(mess,100) 'Switching information',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_swi
!
subroutine consistency_check_dri(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check if 'drift' consistency has already been checked
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1
  integer(kind=4) :: sever
  character(len=message_length) :: mess
  !
  if (cons%dri%check.and.cons%dri%done) then
     if (cons%dri%prob) then
        chain1 = 'Inconsistent'
        sever = seve%w
     else
        chain1 = 'Consistent'
        sever = seve%i
        cons%dri%check = .false.
     endif
     write(mess,100) 'Drift information',chain1
     call class_message(sever,rname,mess)
  endif
  !
100 format('Already checked ',A,':',T44,A)
end subroutine consistency_check_dri
!
subroutine consistency_print(set,ref_head,cons)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>consistency_print
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  select case (set%kind)
  case (kind_spec)
    call consistency_print_spec(ref_head,cons)
  case (kind_cont)
    call consistency_print_cont(ref_head,cons)
  case default
    call class_message(seve%e,rname,'Unsupported kind of data')
    ! error = .true.
  end select
  !
end subroutine consistency_print
!
subroutine consistency_print_gen(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'general' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%gen%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Data type and regular x-axis sampling')
  !
end subroutine consistency_print_gen
!
subroutine consistency_print_sou(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'source' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%sou%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Source Name')
  !
end subroutine consistency_print_sou
!
subroutine consistency_print_pos(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'position' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%pos%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Position information')
  !
end subroutine consistency_print_pos
!
subroutine consistency_print_off(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'offset' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%off%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Offset position')
  !
end subroutine consistency_print_off
!
subroutine consistency_print_lin(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'line' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%lin%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Line Name')
  !
end subroutine consistency_print_lin
!
subroutine consistency_print_spe(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'spectroscopy' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%spe%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Spectroscopic information')
  !
end subroutine consistency_print_spe
!
subroutine consistency_print_cal(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'calibration' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%cal%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Calibration information')
  !
end subroutine consistency_print_cal
!
subroutine consistency_print_swi(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'switching' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%swi%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Switching information')
  !
end subroutine consistency_print_swi
!
subroutine consistency_print_dri(cons)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Print checking status of the 'drift' consistency
  !---------------------------------------------------------------------
  type(consistency_t), intent(in) :: cons  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=11) :: chain1
  !
  if (cons%dri%check) then
     chain1 = '  Checking'
  else
     chain1 = '  Leaving'
  endif
  call class_message(seve%r,rname,chain1//'Drift information')
  !
end subroutine consistency_print_dri
!
subroutine observation_consistency_check(set,ref_head,obs_head,cons)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(header),        intent(in)    :: obs_head  ! Header to be checked
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  select case (set%kind)
  case (kind_spec)
    call spectrum_consistency_check(set,ref_head,obs_head,cons)
  case (kind_cont)
    call continuum_consistency_check(set,ref_head,obs_head,cons)
  case default
    call class_message(seve%e,rname,'Unsupported kind of data')
    ! error = .true.
  end select
  !
end subroutine observation_consistency_check
!
subroutine observation_consistency_check_gen(kind,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_gen
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'general' consistency of the input observation header
  !---------------------------------------------------------------------
  integer(kind=4),     intent(in)    :: kind      ! Expected kind of data
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  if (cons%gen%check) then
     cons%gen%prob = .false.
     if (obs_head%gen%kind.ne.kind) then
        if (cons%gen%mess) then
           call observation_consistency_warn(obs_head,warned)
           call class_message(seve%w,rname,  &
             '  Kind of data not supported')
        endif
        cons%gen%prob = .true.
        cons%prob = .true.
     endif
     if (obs_head%presec(class_sec_xcoo_id)) then
        if (cons%gen%mess) then
           call observation_consistency_warn(obs_head,warned)
           call class_message(seve%w,rname,  &
             '  Irregular sampling along the x-axis data unsupported')
        endif
        cons%gen%prob = .true.
        cons%prob = .true.
     endif
     if (cons%gen%prob) then
        cons%gen%num = obs_head%gen%num
     endif
  endif
  !
end subroutine observation_consistency_check_gen
!
subroutine observation_consistency_check_sou(ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_sou
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'source' consistency of the input observation header
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  !
  if (cons%sou%check) then
     cons%sou%prob = .false.
     if (obs_head%pos%sourc.ne.ref_head%pos%sourc) then
        if (cons%sou%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,101) 'Source Name: ',ref_head%pos%sourc,obs_head%pos%sourc
           call class_message(seve%w,rname,mess)
        endif
        cons%sou%num = obs_head%gen%num
        cons%sou%prob = .true.
        cons%prob = .true.
     endif
  endif
  !
101 format(2x,a,a,    ', ',a)      ! Strings
end subroutine observation_consistency_check_sou
!
subroutine observation_consistency_check_pos(set,ref_head,obs_head,cons,warned)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_pos
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'position' consistency of the input observation header
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  !
  if (cons%pos%check) then
     cons%pos%prob = .false.
     if (obs_head%pos%system.ne.ref_head%pos%system) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,102) 'Coordinate System: ',ref_head%pos%system,obs_head%pos%system
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     if (obs_head%pos%system.eq.type_eq.and.(obs_head%pos%equinox.ne.ref_head%pos%equinox)) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,103) 'Equinox: ',ref_head%pos%equinox,obs_head%pos%equinox
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     if (obs_head%pos%proj.ne.ref_head%pos%proj) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,102) 'Projection System: ',ref_head%pos%proj,obs_head%pos%proj
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     if (abs(obs_head%pos%lam-ref_head%pos%lam).gt.cons%ptole) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,104) 'Lambda Proj Centers: ',ref_head%pos%lam,obs_head%pos%lam
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     if (abs(obs_head%pos%bet-ref_head%pos%bet).gt.cons%ptole) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,104) 'Beta Proj Centers: ',ref_head%pos%bet,obs_head%pos%bet
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     if (obs_head%pos%projang.ne.ref_head%pos%projang) then
        if (cons%pos%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,104) 'Proj. Angles: ',ref_head%pos%projang,obs_head%pos%projang
           call class_message(seve%w,rname,mess)
        endif
        cons%pos%prob = .true.
     endif
     !
     call observation_consistency_check_off(set,ref_head,obs_head,cons,warned)
     !
     if (cons%pos%prob) then
        cons%pos%num = obs_head%gen%num
        cons%prob = .true.
     endif
  endif
  !
  ! Formats. Display all digits for floating points for best understanding
  ! of the mismatch, if any.
102 format(2x,a,i0,     ', ',i0)       ! Integers
103 format(2x,a,1pg14.7, ', ',1pg14.7)   ! Single precision
104 format(2x,a,1pg23.16,', ',1pg23.16)  ! Double precision
end subroutine observation_consistency_check_pos
!
subroutine observation_consistency_check_off(set,ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_off
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'offset' consistency of the input observation header
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  real(kind=4) :: dpos2
  !
  if (cons%off%check) then
    ! Also check the offset positions. Check distance around reference:
    cons%off%prob = .false.
    dpos2 = (  &
      (ref_head%pos%lam+ref_head%pos%lamof-obs_head%pos%lam-obs_head%pos%lamof)  &
      *cos(ref_head%pos%bet))**2 +  &
      (ref_head%pos%bet+ref_head%pos%betof-obs_head%pos%bet-obs_head%pos%betof)**2
    if (dpos2.gt.set%tole**2) then
      if (cons%off%mess) then
        call observation_consistency_warn(obs_head,warned)
        call class_message(seve%w,rname,'Position offsets are not compatible')
      endif
      cons%off%prob = .true.
    endif
    if (cons%off%prob) then
      cons%off%num = obs_head%gen%num
      cons%prob = .true.
    endif
  endif
  !
end subroutine observation_consistency_check_off
!
subroutine observation_consistency_check_lin(ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_lin
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'line' consistency of the input observation header
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  !
  if (cons%lin%check) then
     cons%lin%prob = .false.
     if (obs_head%spe%line.ne.ref_head%spe%line) then
        if (cons%lin%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,101) 'Line Name: ',ref_head%spe%line,obs_head%spe%line
           call class_message(seve%w,rname,mess)
        endif
        cons%lin%num = obs_head%gen%num
        cons%lin%prob = .true.
        cons%prob = .true.
     endif
  endif
  !
101 format(2x,a,a,    ', ',a)      ! Strings
end subroutine observation_consistency_check_lin
!
subroutine observation_consistency_check_spe(ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_spe
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'spectroscopy' consistency of the input observation header
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  real(kind=8) :: ref_val,spe_val,cha_val
  integer(kind=4) :: nc
  !
  if (cons%spe%check) then
     cons%spe%prob = .false.
     if (obs_head%spe%nchan.ne.ref_head%spe%nchan) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,102) 'Number of channels: ',ref_head%spe%nchan,obs_head%spe%nchan
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     if (obs_head%spe%fres*ref_head%spe%fres.le.0.d0) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           write(mess,105) 'F resolution sign: ',ref_head%spe%fres,obs_head%spe%fres
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     ! Signal frequency range
     call abscissa_sigabs_left(obs_head,spe_val)          ! Freq at left of spectrum
     call abscissa_sigabs2chan(ref_head,spe_val,cha_val)  ! Chan position in ref
     if (abs(cha_val-.5d0).gt.cons%ctole) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call abscissa_sigabs_left(ref_head,ref_val)
           write(mess,106) 'F range (left) : ',  &
             ref_val,spe_val,cha_val-.5d0
           call sic_noir(mess,nc)
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     call abscissa_sigabs_right(obs_head,spe_val)         ! Freq at right of spectrum
     call abscissa_sigabs2chan(ref_head,spe_val,cha_val)  ! Chan position in ref
     if (abs(cha_val-ref_head%spe%nchan-.5d0).gt.cons%ctole) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call abscissa_sigabs_right(ref_head,ref_val)
           write(mess,106) 'F range (right): ',  &
             ref_val,spe_val,cha_val-ref_head%spe%nchan-.5d0
           call sic_noir(mess,nc)
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     ! Velocity range
     call abscissa_velo_left(obs_head,spe_val)          ! Velo at left of spectrum
     call abscissa_velo2chan(ref_head,spe_val,cha_val)  ! Chan position in ref
     if (abs(cha_val-.5d0).gt.cons%ctole) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call abscissa_velo_left(ref_head,ref_val)
           write(mess,106) 'V range (left) : ',  &
             ref_val,spe_val,cha_val-.5d0
           call sic_noir(mess,nc)
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     call abscissa_velo_right(obs_head,spe_val)         ! Velo at right of spectrum
     call abscissa_velo2chan(ref_head,spe_val,cha_val)  ! Chan position in ref
     if (abs(cha_val-ref_head%spe%nchan-.5d0).gt.cons%ctole) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call abscissa_velo_right(ref_head,ref_val)
           write(mess,106) 'V range (right): ',  &
             ref_val,spe_val,cha_val-ref_head%spe%nchan-.5d0
           call sic_noir(mess,nc)
           call class_message(seve%w,rname,mess)
        endif
        cons%spe%prob = .true.
     endif
     ! Velocity types
     if (obs_head%spe%vtype.ne.ref_head%spe%vtype) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call class_message(seve%w,rname,'  V type')
        endif
        cons%spe%prob = .true.
     endif
     ! Velocity conventions
     if (obs_head%spe%vconv.ne.ref_head%spe%vconv) then
        if (cons%spe%mess) then
           call observation_consistency_warn(obs_head,warned)
           call class_message(seve%w,rname,'  V convention')
        endif
        cons%spe%prob = .true.
     endif
     if (cons%spe%prob) then
        cons%spe%num = obs_head%gen%num
        cons%prob = .true.
     endif
  endif
  !
102 format(2x,a,i0,   ', ',i0)     ! Integers
105 format(2x,a,e13.6,', ',e13.6)  ! Floats (e13.6 digits)
! Frequency resolution: down to 1 kHz
! Velocity resolution: down to 1 m/s @ 300 GHz
106 format(2x,a,f0.3,', ',f0.3,' (',f9.2,' channels)')
end subroutine observation_consistency_check_spe
!
subroutine observation_consistency_check_cal(set,ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_cal
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'calibration' consistency of the input observation header
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  !
  if (cons%cal%check                    .and.  &
      obs_head%presec(class_sec_cal_id) .and.  &
      ref_head%presec(class_sec_cal_id)) then
    cons%cal%prob = .false.
    if (set%beamt.gt.0.) then
      if (abs(obs_head%cal%beeff-ref_head%cal%beeff).gt.set%beamt) then
        if (cons%cal%mess) then
          call observation_consistency_warn(obs_head,warned)
          write(mess,108) 'Beam efficiencies',ref_head%cal%beeff,obs_head%cal%beeff
          call class_message(seve%w,rname,mess)
        endif
        cons%cal%prob = .true.
      endif
    endif
    if (set%gaint.gt.0.) then
      if (abs(obs_head%cal%gaini-ref_head%cal%gaini).gt.set%gaint) then
        if (cons%cal%mess) then
          call observation_consistency_warn(obs_head,warned)
          write(mess,108) 'Gain ratios',ref_head%cal%gaini,obs_head%cal%gaini
          call class_message(seve%w,rname,mess)
        endif
        cons%cal%prob = .true.
      endif
    endif
    if (cons%cal%prob) then
      cons%cal%num = obs_head%gen%num
      cons%prob = .true.
    endif
  endif
  !
108 format(2x,a,f7.3, ', ',f7.3)   ! Floats (f7.3 digit)
end subroutine observation_consistency_check_cal
!
subroutine observation_consistency_check_swi(ref_head,obs_head,cons,warned)
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_swi
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'switching' consistency of the input observation header
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  integer(kind=4) :: iphas
  !
  if (cons%swi%check                    .and.  &
      obs_head%presec(class_sec_swi_id) .and.  &
      ref_head%presec(class_sec_swi_id)) then
    cons%swi%prob = .false.
    if (ref_head%swi%swmod.ne.obs_head%swi%swmod) then  ! Different modes
      ! Only a problem if combining unfolded fsw to something else
      cons%swi%prob = ref_head%swi%swmod.eq.mod_freq .or.  &
                      obs_head%swi%swmod.eq.mod_freq
      if (cons%swi%prob .and. cons%swi%mess) then
        call observation_consistency_warn(obs_head,warned)
        write(mess,101) 'Switching modes: ',trim(obs_swmod(ref_head%swi%swmod)),  &
                                            trim(obs_swmod(obs_head%swi%swmod))
        call class_message(seve%w,rname,mess)
      endif
    elseif (ref_head%swi%swmod.eq.mod_freq) then  ! Both are unfolded FSW
      if (ref_head%swi%nphas.ne.obs_head%swi%nphas) then
        ! Not the same number of phases
        if (cons%swi%mess) then
          call observation_consistency_warn(obs_head,warned)
          write(mess,102) 'Number of phases: ',ref_head%swi%nphas,obs_head%swi%nphas
          call class_message(seve%w,rname,mess)
        endif
        cons%swi%prob = .true.
      else
        ! Same number of phases
        do iphas=1,ref_head%swi%nphas
          if (ref_head%swi%decal(iphas).ne.obs_head%swi%decal(iphas)) then
            if (cons%swi%mess) then
              call observation_consistency_warn(obs_head,warned)
              write(mess,103) 'Frequency switching offsets: ',iphas,ref_head%swi%decal(iphas),obs_head%swi%decal(iphas)
              call class_message(seve%w,rname,mess)
            endif
            cons%swi%prob = .true.
          endif
        enddo
      endif
    elseif (ref_head%swi%swmod.eq.mod_pos) then   ! Both are PSW
      ! Is this fully safe?
    elseif (ref_head%swi%swmod.eq.mod_fold) then  ! Both are folded FSW
      ! Is this fully safe?
    elseif (ref_head%swi%swmod.eq.mod_wob) then   ! Both are WSW
      ! Is this fully safe?
    elseif (ref_head%swi%swmod.eq.mod_mix) then   ! Both are mixed modes
      ! Is this fully safe? By construction, CLASS builds "mixed" spectra
      ! from a consistent index, so it should be safe.
    endif
    if (cons%swi%prob) then
      cons%swi%num = obs_head%gen%num
      cons%prob = .true.
    endif
  endif
  !
101 format(2x,a,a,             ', ',a)     ! Characters
102 format(2x,a,i0,            ', ',i0)    ! Integers
103 format(2x,a,'#',i0,1x,f7.3,', ',f7.3)  ! Floats (f7.3 digit)
end subroutine observation_consistency_check_swi
!
subroutine observation_consistency_check_dri(set,ref_head,obs_head,cons,warned)
  use phys_const
  use gbl_message
  use classcore_interfaces, except_this=>observation_consistency_check_dri
  use class_setup_new
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Check the 'drift' consistency of the input observation header
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  !
  type(header),        intent(in)    :: obs_head  !
  type(consistency_t), intent(inout) :: cons      !
  logical,             intent(inout) :: warned    ! Warning flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  real(kind=8) :: ref_val,ang_val,cha_val
  integer(kind=4) :: nc
  real(kind=8) :: apos1,apos2
  logical :: notsame,notopposite
  !
  if (cons%dri%check) then
    cons%dri%prob = .false.
    if (obs_head%dri%npoin.ne.ref_head%dri%npoin) then
      if (cons%dri%mess) then
        call observation_consistency_warn(obs_head,warned)
        write(mess,102) 'Number of points: ',ref_head%dri%npoin,obs_head%dri%npoin
        call class_message(seve%w,rname,mess)
      endif
      cons%dri%prob = .true.
    endif
    if (obs_head%dri%ares*ref_head%dri%ares.le.0.d0) then
      if (cons%dri%mess) then
        call observation_consistency_warn(obs_head,warned)
        write(mess,105) 'A resolution sign: ',ref_head%dri%ares,obs_head%dri%ares
        call class_message(seve%w,rname,mess)
      endif
      cons%dri%prob = .true.
    endif
    ! Angle range
    call abscissa_angl_left(obs_head,ang_val)          ! Angle at left of drift
    call abscissa_angl2chan(ref_head,ang_val,cha_val)  ! Chan position in ref
    if (abs(cha_val-.5d0).gt.cons%ptole) then
      if (cons%dri%mess) then
        call observation_consistency_warn(obs_head,warned)
        call abscissa_angl_left(ref_head,ref_val)
        write(mess,106) 'A range (left) : ',  &
          ref_val*class_setup_get_fangle(),   &
          ang_val*class_setup_get_fangle(),   &
          cha_val-.5d0
        call sic_noir(mess,nc)
        call class_message(seve%w,rname,mess)
      endif
      cons%dri%prob = .true.
    endif
    call abscissa_angl_right(obs_head,ang_val)         ! Angle at right of drift
    call abscissa_angl2chan(ref_head,ang_val,cha_val)  ! Chan position in ref
    if (abs(cha_val-ref_head%dri%npoin-.5d0).gt.cons%ptole) then
      if (cons%dri%mess) then
        call observation_consistency_warn(obs_head,warned)
        call abscissa_angl_right(ref_head,ref_val)
        write(mess,106) 'A range (right): ',  &
          ref_val*class_setup_get_fangle(),   &
          ang_val*class_setup_get_fangle(),   &
          cha_val-ref_head%dri%npoin-.5d0
        call sic_noir(mess,nc)
        call class_message(seve%w,rname,mess)
      endif
      cons%dri%prob = .true.
    endif
    ! Position angles are consistent if equal +- pi. Do not use modulo as value
    ! 'pi-eps' is not reduced to '0-eps' almost equal to 0.
    apos1 = abs(ref_head%dri%apos-obs_head%dri%apos)
    apos2 = abs(apos1-pi)
    notsame = apos1.gt.cons%atole
    notopposite = apos2.gt.cons%atole
    if (notsame.and.notopposite) then
      if (cons%dri%mess) then
        call observation_consistency_warn(obs_head,warned)
        call class_message(seve%w,rname,'Drift angles are not compatible')
      endif
      cons%dri%prob = .true.
    endif
    if (cons%dri%prob) then
      cons%dri%num = obs_head%gen%num
      cons%prob = .true.
    endif
  endif
  !
102 format(2x,a,i0,   ', ',i0)     ! Integers
105 format(2x,a,e13.6,', ',e13.6)  ! Floats (e13.6 digits)
! Angle resolution: down to 1 mas
106 format(2x,a,f0.3,', ',f0.3,' (',f9.2,' channels)')
end subroutine observation_consistency_check_dri
!
subroutine observation_consistency_warn(obs_head,warned)
  use gbl_message
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  ! Warn user about inconsistant spectrum, if not yet done
  !---------------------------------------------------------------------
  type(header), intent(in)    :: obs_head  !
  logical,      intent(inout) :: warned    !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=message_length) :: mess
  !
  if (warned)  return  ! Already done
  !
  write(mess,'(a,i0,a)') 'Obs #',obs_head%gen%num,' differs. Inconsistent:'
  call class_message(seve%w,rname,mess)
  warned = .true.
  !
end subroutine observation_consistency_warn
!
subroutine consistency_tole(ref_head,cons)
  use phys_const
  use classcore_interfaces, except_this=>consistency_tole
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  !
  ! Tolerance 10% of channel at spectrum edges
  cons%ctole = 1.d-1
  !
  ! Tolerance 10 milli-arcsec for position/projection center
  cons%ptole = 1.d-2 * rad_per_sec
  !
  ! Tolerance 0.01 degree for position angles
  cons%atole = 1.d-2 * rad_per_deg
  !
end subroutine consistency_tole
!
subroutine index_consistency_analysis(set,cons,rname)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>index_consistency_analysis
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set    !
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  character(len=*),    intent(in)    :: rname  ! Calling routine name
  !
  select case (set%kind)
  case (kind_spec)
    call index_consistency_analysis_spec(cons,rname)
  case (kind_cont)
    call index_consistency_analysis_cont(cons,rname)
  case default
    call class_message(seve%e,rname,'Unsupported kind of data')
    ! error = .true.
  end select
  !
end subroutine index_consistency_analysis
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine consistency_defaults_spec(cons)
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For spectroscopic data
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
  !
  ! Default is to check everything
  cons%gen%check = .true.
  cons%sou%check = .true.
  cons%pos%check = .true.
  cons%off%check = .true.
  cons%lin%check = .true.
  cons%spe%check = .true.
  cons%cal%check = .true.
  cons%swi%check = .true.
  !
  ! Default is to give feedback to users
  cons%gen%mess = .true.
  cons%sou%mess = .true.
  cons%pos%mess = .true.
  cons%off%mess = .true.
  cons%lin%mess = .true.
  cons%spe%mess = .true.
  cons%cal%mess = .true.
  cons%swi%mess = .true.
  !
  ! At start, there is no problem
  cons%prob     = .false.
  cons%gen%prob = .false.
  cons%sou%prob = .false.
  cons%pos%prob = .false.
  cons%off%prob = .false.
  cons%lin%prob = .false.
  cons%spe%prob = .false.
  cons%cal%prob = .false.
  cons%swi%prob = .false.
  !
  ! At start, nothing has been checked
  cons%gen%done = .false.
  cons%sou%done = .false.
  cons%pos%done = .false.
  cons%off%done = .false.
  cons%lin%done = .false.
  cons%spe%done = .false.
  cons%cal%done = .false.
  cons%swi%done = .false.
  !
  ! At start, no spectrum is faulty
  cons%gen%num = -1
  cons%sou%num = -1
  cons%pos%num = -1
  cons%off%num = -1
  cons%lin%num = -1
  cons%spe%num = -1
  cons%cal%num = -1
  cons%swi%num = -1
  !
end subroutine consistency_defaults_spec
!
subroutine consistency_check_selection_spec(set,line,iopt,cons,error)
  use gbl_message
  use classcore_dependencies_interfaces
  use classcore_interfaces, except_this=>consistency_check_selection_spec
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For spectroscopic data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set    !
  character(len=*),    intent(in)    :: line   ! Command line
  integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  logical,             intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1,chain2
  integer(kind=4) :: iarg,nchain,nctype
  integer(kind=4), parameter :: mctype=7
  character(len=12) :: ctype(mctype)
  data ctype/'SOURCE','POSITION','OFFSET','LINE','SPECTROSCOPY','CALIBRATION','SWITCHING'/
  !
  ! Default checks are ruled by the general SET [NO]CHECK tuning
  cons%gen%check = .true.
  cons%sou%check = set%check%sou
  cons%pos%check = set%check%pos
  cons%off%check = set%check%pos.and.set%check%off.and.set%match
  cons%lin%check = set%check%lin
  cons%spe%check = set%check%spe
  cons%cal%check = set%check%cal.and.(set%beamt.gt.0..or.set%gaint.gt.0.)
  cons%swi%check = set%check%swi
  !
  ! Parse line for the /NOCHECK option
  if (sic_present(iopt,0)) then
     if (sic_narg(iopt).eq.0) then
        cons%sou%check = .false.
        cons%pos%check = .false.
        cons%off%check = .false.
        cons%lin%check = .false.
        cons%spe%check = .false.
        cons%cal%check = .false.
        cons%swi%check = .false.
     else
        do iarg = 1, sic_narg(iopt)
           call sic_ke(line,iopt,iarg,chain1,nchain,.true.,error)
           call sic_ambigs('/NOCHECK',chain1,chain2,nctype,ctype,mctype,error)
           if (error) return
           select case (nctype)
           case(1) ! SOURCE
              cons%sou%check = .false.
           case(2) ! POSITION+OFFSET
              cons%pos%check = .false.
              cons%off%check = .false.
           case(3) ! OFFSET
              cons%off%check = .false.
           case(4) ! LINE
              cons%lin%check = .false.
           case(5) ! SPECTROSCOPY
              cons%spe%check = .false.
           case(6) ! CALIBRATION
              cons%cal%check = .false.
           case(7) ! SWITCHING
              cons%swi%check = .false.
           end select
        enddo
     endif
  endif
  !
  ! Avoid checking again when consistency is proved
  call consistency_check_gen(cons)
  call consistency_check_sou(cons)
  call consistency_check_pos(cons)
  call consistency_check_off(cons)
  call consistency_check_lin(cons)
  call consistency_check_spe(cons)
  call consistency_check_cal(cons)
  call consistency_check_swi(cons)
  !
  ! This subroutine is called before a new check. So cons%prob must be
  ! reset. Now there is NO problem if the user says so, e.g. if the user
  ! turns off all the checks even though there may be an already located
  ! inconsistency...
  cons%prob = (cons%gen%check.and.cons%gen%done.and.cons%gen%prob) .or.  &
              (cons%sou%check.and.cons%sou%done.and.cons%sou%prob) .or.  &
              (cons%pos%check.and.cons%pos%done.and.cons%pos%prob) .or.  &
              (cons%off%check.and.cons%off%done.and.cons%off%prob) .or.  &
              (cons%lin%check.and.cons%lin%done.and.cons%lin%prob) .or.  &
              (cons%spe%check.and.cons%spe%done.and.cons%spe%prob) .or.  &
              (cons%cal%check.and.cons%cal%done.and.cons%cal%prob) .or.  &
              (cons%swi%check.and.cons%swi%done.and.cons%swi%prob)
  !
  ! Is there anything left to be checked?
  cons%check = cons%gen%check .or.  &
               cons%sou%check .or.  &
               cons%pos%check .or.  &
               cons%off%check .or.  &
               cons%lin%check .or.  &
               cons%spe%check .or.  &
               cons%cal%check .or.  &
               cons%swi%check
  !
  ! User feedback
  if (.not.cons%check) then
     if (cons%prob) then
        call class_message(seve%e,rname,'Index is inconsistent')
     else
        call class_message(seve%i,rname,'Index is consistent')
     endif
  endif
  !
end subroutine consistency_check_selection_spec
!
subroutine consistency_print_spec(ref_head,cons)
  use gbl_constant
  use phys_const
  use gbl_message
  use classcore_interfaces, except_this=>consistency_print_spec
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For spectroscopic data
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=256) :: chain
  !
  ! First: What will be checked
  call class_message(seve%r,rname,'Consistency checks:')
  call consistency_print_gen(cons)  ! General
  call consistency_print_sou(cons)  ! Source name
  call consistency_print_pos(cons)  ! Position information
  call consistency_print_off(cons)  ! Offset positions
  call consistency_print_lin(cons)  ! Line name
  call consistency_print_spe(cons)  ! Spectroscopy information
  call consistency_print_cal(cons)  ! Calibration information
  call consistency_print_swi(cons)  ! Switching information
  !
  ! Second: Reference information
  call class_message(seve%r,rname,'Reference spectrum:')
  !
  ! Source name
  write(chain,101) 'Source Name',ref_head%pos%sourc
  call class_message(seve%r,rname,chain)
  !
  ! Position information
  if (ref_head%pos%system.eq.type_eq) then
     write(chain,102) 'Coordinate System','EQUATORIAL ',ref_head%pos%equinox
     call class_message(seve%r,rname,chain)
  elseif (ref_head%pos%system.eq.type_ga) then
     write(chain,101) 'Coordinate System','GALACTIC'
     call class_message(seve%r,rname,chain)
  elseif (ref_head%pos%system.eq.type_ic) then
     write(chain,101) 'Coordinate System','ICRS'
     call class_message(seve%r,rname,chain)
  endif
  write(chain,103) 'Proj. Center (rad)','lambda ',ref_head%pos%lam,  &
                                      ', beta ',ref_head%pos%bet,    &
                                      ', tolerance ',cons%ptole
  call class_message(seve%r,rname,chain)
  !
  ! Line name
  write(chain,101) 'Line Name',ref_head%spe%line
  call class_message(seve%r,rname,chain)
  !
  ! Spectroscopic information
  write(chain,105) 'Frequency (MHz)','rest ',ref_head%spe%restf,  &
                                   ', resol ',ref_head%spe%fres
  call class_message(seve%r,rname,chain)
  write(chain,105) 'Velocity (km/s)','resol ',ref_head%spe%vres,  &
                                   ', offset ',ref_head%spe%voff
  call class_message(seve%r,rname,chain)
  write(chain,106) 'Alignment (chan)','tolerance ',cons%ctole*1.d2
  call class_message(seve%r,rname,chain)
  !
  ! Calibration information
  if (ref_head%presec(class_sec_cal_id)) then
    write(chain,107) 'Calibration','beeff',ref_head%cal%beeff,  &
                                  ',gain',ref_head%cal%gaini
    call class_message(seve%r,rname,chain)
  endif
  !
  ! Switching information
  if (ref_head%presec(class_sec_swi_id)) then
    ! The kind of data displayed is the same as the kind of data
    ! diff'ed in observation_consistency_check_swi
    if (ref_head%swi%swmod.eq.mod_freq) then
      write(chain,108) 'Switching',trim(obs_swmod(ref_head%swi%swmod)),  &
                       ', nphase ',ref_head%swi%nphas, &
                       ', offsets',ref_head%swi%decal(1:ref_head%swi%nphas)
    else
      write(chain,108) 'Switching',trim(obs_swmod(ref_head%swi%swmod))
    endif
    call class_message(seve%r,rname,chain)
  endif
  !
101 format(2x,a,t21,': ',a)
102 format(2x,a,t21,': ',a,f7.1)
107 format(2x,a,t21,': ',a,f7.3,a,f7.3)  ! 2 floats (f7.3 digit)
103 format(2x,a,t21,': ',a,f12.6, a,f12.6, a,1pg7.1)
105 format(2x,a,t21,': ',a,es12.3,a,es12.3)
106 format(2x,a,t21,': ',a,f7.1,'%')  ! Percents
108 format(2x,a,t21,': ',a,a,i0,a,8(1x,f0.3))
end subroutine consistency_print_spec
!
subroutine spectrum_consistency_check(set,ref_head,spe_head,cons)
  use gbl_constant
  use classcore_interfaces, except_this=>spectrum_consistency_check
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For spectroscopic data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(header),        intent(in)    :: spe_head  ! Header to be checked
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  logical :: warned
  !
  ! If the program arrived here, it means that something must be checked and
  ! the basic assumption is there is no problem... On the other hand, the subsection
  ! problem variables are initialized to .false. only when the subsection is checked
  ! to avoid loosing the history
  warned = .false.
  cons%prob = .false.
  !
  call observation_consistency_check_gen(kind_spec,spe_head,cons,warned)
  call observation_consistency_check_sou(ref_head,spe_head,cons,warned)
  call observation_consistency_check_pos(set,ref_head,spe_head,cons,warned)
  ! Offsets checked above, if enabled
  call observation_consistency_check_lin(ref_head,spe_head,cons,warned)
  call observation_consistency_check_spe(ref_head,spe_head,cons,warned)
  call observation_consistency_check_cal(set,ref_head,spe_head,cons,warned)
  call observation_consistency_check_swi(ref_head,spe_head,cons,warned)
  !
end subroutine spectrum_consistency_check
!
subroutine index_consistency_analysis_spec(cons,rname)
  use gbl_message
  use classcore_interfaces, except_this=>index_consistency_analysis_spec
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For spectroscopic data
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  character(len=*),    intent(in)    :: rname  ! Calling routine name
  !
  if (cons%prob) then
     ! Only the parts that are inconsistent can be marked as checked
     if (cons%gen%prob) cons%gen%done = .true.
     if (cons%sou%prob) cons%sou%done = .true.
     if (cons%pos%prob) cons%pos%done = .true.
     if (cons%off%prob) cons%off%done = .true.
     if (cons%lin%prob) cons%lin%done = .true.
     if (cons%spe%prob) cons%spe%done = .true.
     if (cons%cal%prob) cons%cal%done = .true.
     if (cons%swi%prob) cons%swi%done = .true.
     call class_message(seve%e,rname,'Index is inconsistent')
  else
     ! The parts that have been checked are consistent
     if (cons%gen%check) cons%gen%done = .true.
     if (cons%sou%check) cons%sou%done = .true.
     if (cons%pos%check) cons%pos%done = .true.
     if (cons%off%check) cons%off%done = .true.
     if (cons%lin%check) cons%lin%done = .true.
     if (cons%spe%check) cons%spe%done = .true.
     if (cons%cal%check) cons%cal%done = .true.
     if (cons%swi%check) cons%swi%done = .true.
     call class_message(seve%i,rname,'Index is consistent')
  endif
  !
end subroutine index_consistency_analysis_spec
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine consistency_defaults_cont(cons)
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For continuum data
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons  ! Performed actions, tolerances and results
  !
  ! Default is to check everything
  cons%gen%check = .true.
  cons%sou%check = .true.
  cons%pos%check = .true.
  cons%off%check = .true.
  cons%dri%check = .true.
  !
  ! Default is to give feedback to users
  cons%gen%mess = .true.
  cons%sou%mess = .true.
  cons%pos%mess = .true.
  cons%off%mess = .true.
  cons%dri%mess = .true.
  !
  ! At start, there is no problem
  cons%prob     = .false.
  cons%gen%prob = .false.
  cons%sou%prob = .false.
  cons%pos%prob = .false.
  cons%off%prob = .false.
  cons%dri%prob = .false.
  !
  ! At start, nothing has been checked
  cons%gen%done = .false.
  cons%sou%done = .false.
  cons%pos%done = .false.
  cons%off%done = .false.
  cons%dri%done = .false.
  !
  ! At start, no spectrum is faulty
  cons%gen%num = -1
  cons%sou%num = -1
  cons%pos%num = -1
  cons%off%num = -1
  cons%dri%num = -1
  !
end subroutine consistency_defaults_cont
!
subroutine consistency_check_selection_cont(set,line,iopt,cons,error)
  use gbl_message
  use classcore_dependencies_interfaces
  use classcore_interfaces, except_this=>consistency_check_selection_cont
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set    !
  character(len=*),    intent(in)    :: line   ! Command line
  integer(kind=4),     intent(in)    :: iopt   ! Number of the /NOCHECK option
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  logical,             intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=64) :: chain1,chain2
  integer(kind=4) :: iarg,nchain,nctype
  integer(kind=4), parameter :: mctype=4
  character(len=12) :: ctype(mctype)
  data ctype/'SOURCE','POSITION','OFFSET','DRIFT'/
  !
  ! Check everything by default
  cons%gen%check = .true.
  cons%sou%check = .true.
  cons%pos%check = .true.
  cons%off%check = set%match
  cons%dri%check = .true.
  !
  ! Parse line for the /NOCHECK option
  if (sic_present(iopt,0)) then
     if (sic_narg(iopt).eq.0) then
        cons%sou%check = .false.
        cons%pos%check = .false.
        cons%off%check = .false.
        cons%dri%check = .false.
     else
        do iarg = 1, sic_narg(iopt)
           call sic_ke(line,iopt,iarg,chain1,nchain,.true.,error)
           call sic_ambigs('/NOCHECK',chain1,chain2,nctype,ctype,mctype,error)
           if (error) return
           select case (nctype)
           case(1) ! SOURCE
              cons%sou%check = .false.
           case(2) ! POSITION
              cons%pos%check = .false.
           case(3) ! OFFSET
              cons%off%check = .false.
           case(4) ! DRIFT
              cons%dri%check = .false.
           end select
        enddo
     endif
  endif
  !
  ! Avoid checking again when consistency is proved
  call consistency_check_gen(cons)
  call consistency_check_sou(cons)
  call consistency_check_pos(cons)
  call consistency_check_off(cons)
  call consistency_check_dri(cons)
  !
  ! This subroutine is called before a new check. So cons%prob must be
  ! reset. Now there is NO problem if the user says so, e.g. if the user
  ! turns off all the checks even though there may be an already located
  ! inconsistency...
  cons%prob = (cons%gen%check.and.cons%gen%done.and.cons%gen%prob) .or.  &
              (cons%sou%check.and.cons%sou%done.and.cons%sou%prob) .or.  &
              (cons%pos%check.and.cons%pos%done.and.cons%pos%prob) .or.  &
              (cons%off%check.and.cons%off%done.and.cons%off%prob) .or.  &
              (cons%dri%check.and.cons%dri%done.and.cons%dri%prob)
  !
  ! Is there anything left to be checked?
  cons%check = cons%gen%check .or.  &
               cons%sou%check .or.  &
               cons%pos%check .or.  &
               cons%off%check .or.  &
               cons%dri%check
  !
  ! User feedback
  if (.not.cons%check) then
     if (cons%prob) then
        call class_message(seve%e,rname,'Index is inconsistent')
     else
        call class_message(seve%i,rname,'Index is consistent')
     endif
  endif
  !
end subroutine consistency_check_selection_cont
!
subroutine consistency_print_cont(ref_head,cons)
  use gbl_constant
  use phys_const
  use gbl_message
  use classcore_interfaces, except_this=>consistency_print_cont
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For continuum data
  !---------------------------------------------------------------------
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  character(len=256) :: chain
  !
  ! First: What will be checked
  call class_message(seve%r,rname,'Consistency checks:')
  call consistency_print_gen(cons)  ! General
  call consistency_print_sou(cons)  ! Source name
  call consistency_print_pos(cons)  ! Position information
  call consistency_print_off(cons)  ! Offset positions
  call consistency_print_dri(cons)  ! Offset positions
  !
  ! Second: Reference information
  call class_message(seve%r,rname,'Reference drift:')
  !
  ! Source name
  write(chain,101) 'Source Name',ref_head%pos%sourc
  call class_message(seve%r,rname,chain)
  !
  ! Position information
  if (ref_head%pos%system.eq.type_eq) then
     write(chain,102) 'Coordinate System','EQUATORIAL ',ref_head%pos%equinox
     call class_message(seve%r,rname,chain)
  elseif (ref_head%pos%system.eq.type_ga) then
     write(chain,101) 'Coordinate System','GALACTIC'
     call class_message(seve%r,rname,chain)
  elseif (ref_head%pos%system.eq.type_ic) then
     write(chain,101) 'Coordinate System','ICRS'
     call class_message(seve%r,rname,chain)
  endif
  write(chain,103) 'Proj. Center (rad)','lambda ',ref_head%pos%lam,  &
                                      ', beta ',ref_head%pos%bet,    &
                                      ', tolerance ',cons%ptole
  call class_message(seve%r,rname,chain)
  !
101 format(2x,a,t21,': ',a)
102 format(2x,a,t21,': ',a,f7.1)
103 format(2x,a,t21,': ',a,f12.6, a,f12.6, a,1pg7.1)
end subroutine consistency_print_cont
!
subroutine continuum_consistency_check(set,ref_head,dri_head,cons)
  use gbl_constant
  use gbl_message
  use classcore_interfaces, except_this=>continuum_consistency_check
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set       !
  type(header),        intent(in)    :: ref_head  ! Reference header
  type(header),        intent(in)    :: dri_head  ! Header to be checked
  type(consistency_t), intent(inout) :: cons      ! Performed actions, tolerances and results
  ! Local
  logical :: warned
  !
  ! If the program arrived here, it means that something must be checked and
  ! the basic assumption is there is no problem... On the other hand, the subsection
  ! problem variables are initialized to .false. only when the subsection is checked
  ! to avoid loosing the history
  warned = .false.
  cons%prob = .false.
  !
  call observation_consistency_check_gen(kind_cont,dri_head,cons,warned)
  call observation_consistency_check_sou(ref_head,dri_head,cons,warned)
  call observation_consistency_check_pos(set,ref_head,dri_head,cons,warned)
  ! Offsets checked above, if enabled
  call observation_consistency_check_dri(set,ref_head,dri_head,cons,warned)
  !
end subroutine continuum_consistency_check
!
subroutine index_consistency_analysis_cont(cons,rname)
  use gbl_message
  use classcore_interfaces, except_this=>index_consistency_analysis_cont
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! For continuum data
  !---------------------------------------------------------------------
  type(consistency_t), intent(inout) :: cons   ! Performed actions, tolerances and results
  character(len=*),    intent(in)    :: rname  ! Calling routine name
  !
  if (cons%prob) then
     ! Only the parts that are inconsistent can be marked as checked
     if (cons%gen%prob) cons%gen%done = .true.
     if (cons%sou%prob) cons%sou%done = .true.
     if (cons%pos%prob) cons%pos%done = .true.
     if (cons%off%prob) cons%off%done = .true.
     if (cons%dri%prob) cons%dri%done = .true.
     call class_message(seve%e,rname,'Index is inconsistent')
  else
     ! The parts that have been checked are consistent
     if (cons%gen%check) cons%gen%done = .true.
     if (cons%sou%check) cons%sou%done = .true.
     if (cons%pos%check) cons%pos%done = .true.
     if (cons%off%check) cons%off%done = .true.
     if (cons%dri%check) cons%dri%done = .true.
     call class_message(seve%i,rname,'Index is consistent')
  endif
  !
end subroutine index_consistency_analysis_cont
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine index_consistency_check(set,line,error,user_function)
  use classcore_interfaces, except_this=>index_consistency_check
  use class_index
  use class_types
  !---------------------------------------------------------------------
  ! @ public
  ! Generic for spectroscopic or continuum data
  ! Support routine for command
  !     CONSISTENCY [/NOCHECK [SOURCE|POSITION|OFFSET|LINE|SPECTROSCOPY|
  !                            CALIBRATION|SWITCHING]]
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set            !
  character(len=*),    intent(in)    :: line           ! Command line
  logical,             intent(inout) :: error          ! Logical error flag
  logical,             external      :: user_function  !
  ! Local
  character(len=*), parameter :: rname='CONSISTENCY'
  !
  ! Select what will be checked according to user input
  call consistency_check_selection(set,line,1,cx%cons,error)
  if (error .or. cx%cons%prob) return
  !
  ! It happens after analysis that nothing needs to be checked...
  if (.not.cx%cons%check)  return
  !
  ! Check consistency according to selection
  call consistency_check_do(set,rname,cx,error,user_function)
  if (error)  return
  !
end subroutine index_consistency_check
!
subroutine consistency_check_do(set,rname,idx,error,user_function)
  use gbl_message
  use gkernel_types
  use classcore_dependencies_interfaces
  use classcore_interfaces, except_this=>consistency_check_do
  use class_types
  !---------------------------------------------------------------------
  ! @ private
  ! Generic for spectroscopic or continuum data
  !---------------------------------------------------------------------
  type(class_setup_t), intent(in)    :: set
  character(len=*),    intent(in)    :: rname
  type(optimize),      intent(inout) :: idx
  logical,             intent(inout) :: error
  logical,             external      :: user_function
  ! Local
  type(observation) :: obs
  integer(kind=entry_length) :: iobs,nobs
  type(time_t) :: time
  !
  ! Sanity check
  nobs = idx%next-1
  if (nobs.le.0) then
     call class_message(seve%e,rname,'Index is empty')
     error = .true.
     return
  endif
  !
  ! Read first index spectrum to set its header as reference
  call init_obs(obs)
  call get_it(set,obs,idx%ind(1),user_function,error)
  if (error) return
  call sic_upper(obs%head%gen%teles)
  call sic_upper(obs%head%pos%sourc)
  call sic_upper(obs%head%spe%line)
  call copy_header(obs%head,idx%cons%head)
  !
  ! Set checking tolerances
  call consistency_tole(idx%cons%head,idx%cons)
  !
  ! Give user feedback on what will be done
  call consistency_print(set,idx%cons%head,idx%cons)
  !
  ! Loop on observations
  call gtime_init(time,nobs,error)
  if (error)  goto 100
  if (set%kind.eq.kind_spec) then
    do iobs = 1,nobs
      call gtime_current(time)
      ! Exit when asked by user
      call class_controlc(rname,error)
      if (error)  exit
      ! Read useful header sections
      call robs(obs,idx%ind(iobs),error)
      if (error) exit
      call rgen(set,obs,error)
      if (error) exit
      call rpos(set,obs,error)
      if (error) exit
      call rspec(set,obs,error)
      if (error) exit
      if (obs%head%presec(class_sec_cal_id)) then
        call rcal(set,obs,error)
        if (error) exit
      endif
      if (obs%head%presec(class_sec_swi_id)) then
        call rswi(set,obs,error)
        if (error) exit
      endif
      call sic_upper(obs%head%gen%teles)
      call sic_upper(obs%head%pos%sourc)
      call sic_upper(obs%head%spe%line)
      call spectrum_consistency_check(set,idx%cons%head,obs%head,idx%cons)
      ! There is a consistency problem => Exit the loop
      if (idx%cons%prob)  exit
    enddo
  elseif (set%kind.eq.kind_cont) then
    do iobs = 1,nobs
      call gtime_current(time)
      ! Exit when asked by user
      call class_controlc(rname,error)
      if (error)  exit
      ! Read useful header sections
      call robs(obs,idx%ind(iobs),error)
      if (error) exit
      call rgen(set,obs,error)
      if (error) exit
      call rpos(set,obs,error)
      if (error) exit
      call rcont(set,obs,error)
      if (error)  exit
      call sic_upper(obs%head%gen%teles)
      call sic_upper(obs%head%pos%sourc)
      call continuum_consistency_check(set,idx%cons%head,obs%head,idx%cons)
      ! There is a consistency problem => Exit the loop
      if (idx%cons%prob)  exit
    enddo
  else
    call class_message(seve%e,rname,'Unsupported kind of data')
    error = .true.
    goto 100
  endif
  !
  ! Feedback
  call index_consistency_analysis(set,idx%cons,rname)
  !
100 continue
  call free_obs(obs)
  !
end subroutine consistency_check_do
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
