!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine mrtcal_calib_otf_psw(mrtset,backcal,backsci,filebuf,error)
  use gbl_message
  use gkernel_interfaces
  use mrtcal_buffer_types
  use mrtcal_setup_types
  use mrtcal_interfaces, except_this => mrtcal_calib_otf_psw
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  type(mrtcal_setup_t),    intent(in)    :: mrtset
  type(calib_backend_t),   intent(in)    :: backcal
  type(science_backend_t), intent(inout) :: backsci
  type(imbfits_buffer_t),  intent(inout) :: filebuf
  logical,                 intent(inout) :: error
  ! Local
  integer(kind=4) :: ion,non
  character(len=*), parameter :: rname='CALIB>OTF>PSW'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  call mrtcal_init_onloop(backsci,non,error)
  if (error) return
  do ion=1,non
     call mrtcal_get_nexton(backsci,error)
     if (error) return
     call mrtcal_psw_prepare_nextoff(mrtset,filebuf,backsci,error)
     if (error) return
     call mrtcal_sanity_check(backsci,error)
     if (error) return
     call mrtcal_init_cycleloop(&
          mrtset,&
          backsci%list,&
          backsci%on%curr%isub,&
          'onTheFly',&
          filebuf%imbf,&
          filebuf%subscanbuf,&
          backsci%switch,&
          error)
     if (error) return
     do while (backsci%switch%book%idump.lt.backsci%switch%book%ndump)
        call mrtcal_get_nextcycle(&
             filebuf%imbf,&
             filebuf%subscanbuf%subscan,&
             filebuf%subscanbuf%databuf,&
             backsci,error)
        if (error) return
        if (backsci%switch%book%found) then
           call reassociate_chunkset_2d(backsci%switch%cycle%data(1),backsci%on%curr,error)
           if (error) return
           call mrtcal_psw_select_off(mrtset,backsci,error)
           if (error) return
           call mrtcal_on_minus_off(isotfmap,notfsw,backsci,error)
           if (error) return
           call mrtcal_tscale_computation(backcal,backsci,error)
           if (error) return
           call mrtcal_tscale_application(backsci%tscale,backsci%diff,error)
           if (error) return
           call mrtcal_write_toclass(backsci%diff,mrtset%out,backsci%nspec,error)
           if (error) return
        endif
     enddo ! switch%book%idump
     call mrtcal_switch_book_list(backsci%switch%book,error)
     if (error) return
     ! User can interrupt the pipeline
     if (sic_ctrlc_status()) then
        error = .true.
        exit
     endif
  enddo !ion
  !
end subroutine mrtcal_calib_otf_psw
!
subroutine mrtcal_psw_select_off(mrtset,backsci,error)
  use mrtcal_interfaces, except_this=>mrtcal_psw_select_off
  use mrtcal_messaging
  use mrtcal_calib_types
  use mrtcal_setup_types
  !---------------------------------------------------------------------
  ! @ private
  ! Select the OFF subscan to be used. It can be either a linear
  ! interpolation of the previous and next OFF or the nearest neighbour
  ! in time. That's MRTSET%CAL%INTERPOFF that switches the behavior.
  !---------------------------------------------------------------------
  type(mrtcal_setup_t),            intent(in)    :: mrtset
  type(science_backend_t), target, intent(inout) :: backsci
  logical,                         intent(inout) :: error
  ! Local
  real(kind=8) :: dist_onprev,dist_onnext
  real(kind=8), parameter :: mjd_tol = 2d0/(24d0*3600d0) ! 2 sec in mjd
  character(len=*), parameter :: rname='PSW>SELECT>OFF'
  !
  call mrtcal_message(seve%t,rname,'Welcome')
  !
  ! *** JP 1. This can be checked for each dump. It would be more efficiency
  ! *** JP    to have the address of the right subroutine decided earlier
  ! *** JP    and passed here. Is it needed?
  ! *** JP 2. OFF interpolation should be forbidden for tracked position
  ! *** JP    switched
  select case(mrtset%cal%interpoff)
  case (interp_linear)
     ! Interpolate
     call mrtcal_chunkset_2d_interpolate_do(&
          backsci%on%curr%mjd%med,&
          backsci%off%slope,&
          backsci%off%offset,&
          backsci%off%interp,&
          error)
     !
  case (interp_nearest)
     ! Use off nearest in time
     if ((backsci%off%prev%isub.gt.0).and.(backsci%off%next%isub.gt.0)) then
        dist_onprev = backsci%on%curr%mjd%beg-backsci%off%prev%mjd%end
        dist_onnext = backsci%off%next%mjd%beg-backsci%on%curr%mjd%end
        ! *** JP The MJD tolerance should probably depend on the observing mode
        ! *** JP 0 sec for OTF, 2 sec for tracked???
        if (dist_onprev-dist_onnext.le.mjd_tol) then
           call mrtcal_message(mseve%calib%book,rname,'Using previous OFF')
           backsci%off%curr => backsci%off%prev
        else
           call mrtcal_message(mseve%calib%book,rname,'Using next OFF')
           backsci%off%curr => backsci%off%next
        endif
     else if (backsci%off%prev%isub.gt.0) then
        ! *** JP Transfered Warning into Information to avoid too many messages.
        ! *** JP Is there anything else to be done for TRACKED observations?
        call mrtcal_message(mseve%calib%book,rname,'Only previous OFF available')
        backsci%off%curr => backsci%off%prev
     else if (backsci%off%next%isub.gt.0) then
        ! *** JP Transfered Warning into Information to avoid too many messages.
        ! *** JP Is there anything else to be done for TRACKED observations?
        call mrtcal_message(mseve%calib%book,rname,'Only next OFF available')
        backsci%off%curr => backsci%off%next
     else
        call mrtcal_message(seve%e,rname,'No subscans associated to previous nor to next OFF')
        error = .true.
        return
     endif
     !
  case default
     call mrtcal_message(seve%e,rname,'Interpolation mode not implemented')
     error = .true.
     return
     !
  end select
  !
end subroutine mrtcal_psw_select_off
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
