subroutine modify_frame_velocity(new_velo,rchan,freq,fres,old_velo,vres,error)
  use phys_const
  !---------------------------------------------------------------------
  ! @ public
  ! Change Frame Velocity
  ! All updated values are intent(inout) because they are not modified
  ! if there is nothing to be done.
  !---------------------------------------------------------------------
  real(kind=4), intent(in)    :: new_velo  ! Desired velocity
  real(kind=8), intent(inout) :: rchan     ! Reference channel
  real(kind=8), intent(in)    :: freq      ! Frequency at ref. channel
  real(kind=8), intent(inout) :: fres      ! Frequency resolution
  real(kind=4), intent(inout) :: old_velo  ! Velocity at ref. channel
  real(kind=4), intent(inout) :: vres      ! Velocity resolution
  logical,      intent(inout) :: error     ! Logical error flag
  !
  if (new_velo.eq.old_velo)  return
  !
  !      i_B = i_A + F / Df_L (V_A-V_B) / c
  !  The old resolution in frame A is Df_A = Df_L / (1-V_A/c), so
  !    i_B = i_A + F / Df_A * (1-V_A/c) * (V_A - V_B) / c
  !  which is equal to
  !    i_B = i_A + F / Df_B * (1-V_B/c) * (V_A - V_B) / c
  !  showing the reversibility of the computation.
  !
  rchan = rchan + freq/fres * (1.d0 - dble(old_velo)/clight_kms) * &
         dble(old_velo - new_velo)/clight_kms
  !
  fres = fres * (1.d0 - dble(old_velo)/clight_kms) /  &
                (1.d0 - dble(new_velo)/clight_kms)
  !
  vres = -clight_kms*fres/freq
  !
  old_velo = new_velo
  !
end subroutine modify_frame_velocity
!
subroutine modify_rest_frequency(new_freq,rchan,old_freq,image,fres,vres,error)
  use phys_const
  !---------------------------------------------------------------------
  ! @ public
  ! Change Rest Frequency
  ! All updated values are intent(inout) because they are not modified
  ! if there is nothing to be done.
  !---------------------------------------------------------------------
  real(kind=8), intent(in)    :: new_freq  ! Desired frequency
  real(kind=8), intent(inout) :: rchan     ! Reference channel
  real(kind=8), intent(inout) :: old_freq  ! Frequency at ref. channel
  real(kind=8), intent(inout) :: image     ! Image frequency at ref. channel
  real(kind=8), intent(inout) :: fres      ! Frequency resolution
  real(kind=4), intent(inout) :: vres      ! Velocity resolution
  logical,      intent(inout) :: error     ! Logical error flag
  ! Local
  real(kind=8), parameter :: fimage_null=0.d0  ! This parameter should be shared with the type(gildas)!!!
  real(kind=8) :: fshift
  !
  if (new_freq.eq.old_freq)  return
  !
  !    i_B = i_A + (F_B-F_A)/Df_L*(1-V/c)    (Radio)
  !
  !  The frequency resolution is still Df = (1+V/c) Df_L (Optical) or
  !  Df = (1-V/c) Df_L (radio), and remains unchanged, like V. So the
  !  above equation is just simply
  !    i_B = i_A + (F_B-F_A)/Df
  !
  !  Note that Dv is also changed into
  !    Dv_B = - c Df / F_B
  !  Again, the computation is fully reversible.
  !
  fshift = new_freq-old_freq
  !
  rchan = rchan + fshift / fres
  !
  vres = -clight_kms*fres/new_freq
  !
  if (image.ne.fimage_null)  image = image-fshift
  !
  old_freq = new_freq
  !
end subroutine modify_rest_frequency
