subroutine uv_baseline_main(line,error)
  use gbl_message
  use mapping_interfaces, except_this=>uv_baseline_main
  use gildas_def
  !----------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  ! Command line interaction for UV_BASELINE command
  !----------------------------------------------------------
  character(len=*), intent(inout) :: line  ! Command line
  logical, intent(out)            :: error ! Error flag
  !
  character(len=*), parameter :: rname='UV_BASELINE'
  !
  integer                    :: degree           ! degree of the baseline to subtract
  integer, allocatable       :: channellist(:,:) ! list of ranges of channels to exclude
  integer(kind=size_length)  :: nelem            ! Number of excluded ranges
  logical                    :: dozero           ! Just to hold info from uv_filter_parsing, always false
  !
  degree = 0
  call sic_i4(line,0,1,degree,.false.,error)
  if (error) return
  if (degree.ne.0 .and. degree.ne.1) then
     call map_message(seve%e,rname,'Only degree 0 or 1 supported')
     error = .true.
     return
  endif
  !
  ! Call UV Filter to do the filtering.
  call uv_filter_parsing(line,channellist,nelem,dozero,rname,error)
  if (error) return
  !
  ! Now do the work
  call uv_baseline_sub(degree,channellist,nelem,error)
end subroutine uv_baseline_main
!
subroutine uv_baseline_sub(degree,channellist,nelem,error)
  use gildas_def
  use mapping_interfaces, except_this=>uv_baseline_sub
  use clean_arrays
  use gbl_message
  use gkernel_interfaces
  !----------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  ! Coordinates baseline fitting and subtraction
  !----------------------------------------------------------
  integer, intent(in)                   :: degree           ! Polynomial degree of baseline
  integer, allocatable,intent(in)       :: channellist(:,:) ! list of ranges of channels to exclude
  integer(kind=size_length),intent(in)  :: nelem            ! Number of excluded ranges
  logical, intent(out)                  :: error            ! Error flag
  !
  character(len=*), parameter :: rname='UV_BASELINE'
  !
  integer(kind=size_length)              :: nvisi         ! Number of visibilities
  integer(kind=index_length)             :: ivisi         ! visibility index
  integer(kind=index_length)             :: iranges       ! spectral ranges index
  integer(kind=index_length)             :: ichan         ! channel index
  integer(kind=index_length)             :: ivalid        ! valid channel index
  integer(kind=index_length),allocatable :: rindexes(:)   ! indexes for valid real channels
  integer(kind=index_length),allocatable :: iindexes(:)   ! indexes for valid imaginary channels
  integer(kind=index_length),allocatable :: cnumbers(:)   ! valid channels
  real,allocatable                       :: rdata(:)      ! valid real channels
  real,allocatable                       :: idata(:)      ! valid imaginary channels
  integer(kind=4),allocatable            :: notflagged(:)
  integer(kind=size_length)              :: nchan         ! number of channels
  integer                                :: ier
  integer                                :: nvalid        ! NUmber of valid channels
  integer                                :: fchan, lchan  ! First and last channels in a range of channels
  character(len=50)                      :: warning       ! Warning message
  integer(kind=index_length)             :: cols(3)       ! Columns for a specific channel
  integer(kind=1), parameter             :: bit=1         ! 1 in i1
  real                                   :: areal,breal   ! Fit parameters for real part
  real                                   :: aimag,bimag   ! Fit parameters for imaginary part
  !
  !
  nchan = huv%gil%nchan
  nvisi = huv%gil%nvisi
  allocate(notflagged(nchan),stat=ier)
  if (failed_allocate(rname,'Flagged list',ier,error))  return
  notflagged(:) = 1
  !
  ! Getting the flagged ranges
  do iranges=1, nelem
     fchan = channellist(1,iranges)
     lchan = channellist(2,iranges)
     if (lchan.lt.1.or.fchan.gt.huv%gil%nchan) then
        write(warning,1000) iranges,"-th spectral range is outside UV table"
        call map_message(seve%w,rname, trim(warning))
     else
        if (lchan.gt.nchan) lchan = nchan
        if (fchan.lt.1)     fchan = 1
        notflagged(fchan:lchan) = 0
     endif
  enddo
  nvalid = sum(notflagged)
  allocate(rindexes(nvalid),iindexes(nvalid),rdata(nvalid),idata(nvalid),cnumbers(nvalid),stat=ier)
  if (failed_allocate(rname,'Real and imaginary arrays',ier,error))  return
  ivalid=1
  do ichan=1,nchan
     if (notflagged(ichan).eq.bit) then
        call uv_spectral_getcols(ichan,cols)
        rindexes(ivalid) = cols(1)
        iindexes(ivalid) = cols(2)
        cnumbers(ivalid) = ichan
        ivalid = ivalid+1
     endif
  end do
  deallocate(notflagged)
  do ivisi=1, nvisi
     do ivalid=1,nvalid
        rdata(ivalid) = duv(rindexes(ivalid),ivisi)
        idata(ivalid) = duv(iindexes(ivalid),ivisi)
     enddo
     call uv_baseline_baseline(cnumbers,rdata,nvalid,degree,areal,breal,error)
     call uv_baseline_baseline(cnumbers,idata,nvalid,degree,aimag,bimag,error)
     do ichan=1,nchan
        call uv_spectral_getcols(ichan,cols)
        duv(cols(1),ivisi) =  duv(cols(1),ivisi)-(areal*ichan+breal)
        duv(cols(2),ivisi) =  duv(cols(2),ivisi)-(aimag*ichan+bimag)
     enddo
  enddo
1000 format(i4,a38) 
end subroutine uv_baseline_sub
!
subroutine uv_baseline_baseline(xdata,ydata,npoints,degree,acoeff,bcoeff,error)
  use mapping_interfaces, except_this=>uv_baseline_baseline
  use gkernel_interfaces
  use gildas_def
  !----------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  ! Computes baseline from input arrays
  !----------------------------------------------------------
  integer(kind=index_length),allocatable,intent(in) :: xdata(:)
  real,allocatable,intent(in)                       :: ydata(:)
  integer,intent(in)                                :: npoints
  integer,intent(in)                                :: degree
  real,intent(out)                                  :: acoeff
  real,intent(out)                                  :: bcoeff
  logical, intent(out)                              :: error
  !
  character(len=*), parameter :: rname='UV_BASELINE'
  !
  real              :: sumx  ! Sum of xdata
  real              :: sumy  ! Sum of y data
  real              :: sumxy ! Sum of x*y
  real              :: sumxx ! Sum of x^2
  real              :: delta ! midway coefficient
  real, allocatable :: warr(:) ! allocatable workhorse array
  integer           :: ier   ! error flag
  !
  if (degree.eq.0) then
     acoeff = 0.0
     bcoeff = sum(ydata)/npoints
  else if (degree.eq.1)then
     allocate(warr(npoints),stat=ier)
     if (failed_allocate(rname,'Work array',ier,error))  return
     sumx = sum(xdata)
     sumy = sum(ydata)
     warr = xdata**2
     sumxx = sum(warr)
     warr = xdata*ydata
     sumxy = sum(warr)
     delta = (npoints*sumxx-sumx**2)
     bcoeff = (sumxx*sumy-sumx*sumxy)/delta
     acoeff = (npoints*sumxy-sumx*sumy)/delta
     deallocate(warr)
  endif
end subroutine uv_baseline_baseline
