SUBROUTINE ropp_fm_roprof2obs1drefrac(ro_data, y)

! 2.1 Declarations
! ----------------

  USE typesizes, ONLY: wp => EightByteReal
  USE ropp_utils
  USE ropp_io
  USE ropp_io_types, ONLY: ROprof
  USE ropp_fm
  USE ropp_fm_types, ONLY: Obs1dRefrac
  USE ropp_fm_copy,  not_this => ropp_fm_roprof2obs1drefrac

  IMPLICIT NONE

  TYPE(ROprof),          INTENT(in)    :: ro_data    ! RO data structure
  TYPE(Obs1dRefrac),     INTENT(inout) :: y          ! Refractivity structure

  INTEGER                              :: i, n
  INTEGER, DIMENSION(8)                :: DT8
  
  CHARACTER(len = 256)                 :: routine
  CHARACTER(len = 10)                  :: err_val

! 2.2 Error handling
! ------------------

  CALL message_get_routine(routine)
  CALL message_set_routine('ropp_fm_roprof2obs (1D refractivity)')

  y%obs_ok = .TRUE.

! 2.3 Check and copy geolocation and time
! ---------------------------------------

  IF (isinrange(ro_data%georef%lon, ro_data%georef%range%lon)) THEN
    y%lon = ro_data%georef%lon
  ELSE
    WRITE(err_val, '(e8.1)') ro_data%georef%lon
    CALL message(msg_warn, &
         "Longitude data for observations out of range or missing. " // &
         "(longitude value = " // TRIM(err_val) // ")")
    CALL message(msg_warn, "Check input data and valid_range attributes")
  ENDIF

  IF (isinrange(ro_data%georef%lat, ro_data%georef%range%lat)) THEN
    y%lat = ro_data%georef%lat
  ELSE
    WRITE(err_val, '(e8.1)') ro_data%georef%lat
    CALL message(msg_warn, &
         "Latitude data for observations out of range or missing. " // &
         "(latitude value = " // TRIM(err_val) // ")")
    CALL message(msg_warn, "Check input data and valid_range attributes")
  ENDIF

  IF ( isinrange(ro_data%DTocc%year,   ro_data%DTocc%range%year)   .AND. &
       isinrange(ro_data%DTocc%month,  ro_data%DTocc%range%month)  .AND. &
       isinrange(ro_data%DTocc%day,    ro_data%DTocc%range%day)    .AND. &
       isinrange(ro_data%DTocc%hour,   ro_data%DTocc%range%hour)   .AND. &
       isinrange(ro_data%DTocc%minute, ro_data%DTocc%range%minute) .AND. &
       isinrange(ro_data%DTocc%second, ro_data%DTocc%range%second) ) THEN
    DT8 = (/ro_data%DTocc%year,   ro_data%DTocc%month,  &
            ro_data%DTocc%day,    0,                    &
            ro_data%DTocc%hour,   ro_data%DTocc%minute, &
            ro_data%DTocc%second, ro_data%DTocc%msec/)
    CALL TimeSince ( DT8, y%time, 1, Base="JS2000" )
  ELSE
    CALL message(msg_warn, &
         "Time data for observations out of range or missing.")
    CALL message(msg_warn, "Check input data and valid_range attributes")
    CALL message(msg_warn, "Set status flag state%ok to FALSE")
    y%obs_ok = .FALSE.
  ENDIF
  
! 2.4 Check that profiles are increasing in height - 1st element towards surface
! ------------------------------------------------
  
  CALL ropp_io_ascend(ro_data)

! 2.5 Check and copy observation data
! -----------------------------------

  IF (ro_data%Lev2a%Npoints == 0) THEN
    CALL message(msg_warn, &
         "RO data has no Level 2a (refractivity) data.")
    CALL message(msg_warn, "Check input data and valid_range attributes")
    CALL message(msg_warn, "Set status flag state%ok to FALSE")
    y%obs_ok = .FALSE.
  ENDIF

  n = ro_data%Lev2a%Npoints
  
  ALLOCATE(y%geop(n), y%refrac(n), y%weights(n))
  y%geop    = ro_data%Lev2a%geop_refrac(1:n)
  y%refrac  = ro_data%Lev2a%refrac(1:n)
  y%weights = 1.0_wp

! 2.6 Check and copy sigmas to diagonal error covariance
! ------------------------------------------------------

  y%cov_ok = .TRUE.

  IF (ASSOCIATED(y%cov%d)) DEALLOCATE(y%cov%d)
  CALL callocate(y%cov%d, (n*(n+1)/2))

  DO i = 1, n
    IF (ro_data%Lev2a%refrac(i) > 0.0_wp) THEN
      IF (ro_data%Lev2a%refrac_sigma(i) > 0.0_wp) THEN
       ! matrix_pp type, uplo = 'U'
        y%cov%d(i + i*(i-1)/2) = ro_data%Lev2a%refrac_sigma(i)**2
      ELSE
        y%cov_ok = .FALSE.
      END IF
    ELSE 
      y%cov%d(i + i*(i-1)/2) = 0.0003_wp
    ENDIF
  END DO

  IF (ASSOCIATED(y%cov%e)) DEALLOCATE(y%cov%e)
  IF (ASSOCIATED(y%cov%f)) DEALLOCATE(y%cov%f)
  IF (ASSOCIATED(y%cov%s)) DEALLOCATE(y%cov%s)

  y%cov%fact_chol = .FALSE.
  y%cov%equi_chol = 'N'

! 2.7 Clean up
! ------------

  CALL message_set_routine(routine)

END SUBROUTINE ropp_fm_roprof2obs1drefrac
