Skip to content

Commit

Permalink
Merge branch 'develop' into feature/addoceanwindspeed
Browse files Browse the repository at this point in the history
  • Loading branch information
ghalloran committed Jul 10, 2024
2 parents 287628c + 0c512bd commit ae8fa38
Show file tree
Hide file tree
Showing 16 changed files with 343 additions and 110 deletions.
8 changes: 8 additions & 0 deletions etc/ukv/cx/Radar.nl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
&CXControlNL
! These STASH codes correspond to the following variables:
! 2: upper-air u
! 3: upper-air v
! 33: orography
! 150: upper-air w
CxFields=2,3,33,150
/
10 changes: 10 additions & 0 deletions etc/ukv/varobs/Radar.nl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
&VarobsControlNL
! These indices correspond to the following variables:
! 63: Radial velocity
! 64: Beam tilt (elevation in OPS terminology)
! 65: Gate range
! 66: Gate azimuth
! 69: Station identifier
! 75: Station elevation (altitude above MSL in OPS terminology)
Varfields=63,64,65,66,69,75
/
2 changes: 1 addition & 1 deletion src/opsinputs/opsinputs_cxfields_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module opsinputs_cxfields_mod
character(len=*), parameter, public :: opsinputs_cxfields_rh = var_rh
character(len=*), parameter, public :: opsinputs_cxfields_u = var_u
character(len=*), parameter, public :: opsinputs_cxfields_v = var_v
character(len=*), parameter, public :: opsinputs_cxfields_w = opsinputs_cxfields_unknown
character(len=*), parameter, public :: opsinputs_cxfields_w = var_w
character(len=*), parameter, public :: opsinputs_cxfields_q = var_q
character(len=*), parameter, public :: opsinputs_cxfields_qc = opsinputs_cxfields_unknown
character(len=*), parameter, public :: opsinputs_cxfields_p_bar = var_prs
Expand Down
122 changes: 102 additions & 20 deletions src/opsinputs/opsinputs_fill_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ module opsinputs_fill_mod
opsinputs_fill_fillelementtypefromsimulatedvariable, &
opsinputs_fill_fillelementtype2dfromsimulatedvariable, &
opsinputs_fill_fillinteger, &
opsinputs_fill_fillinteger2d, &
opsinputs_fill_fillreal, &
opsinputs_fill_fillreal2d, &
opsinputs_fill_fillrealfromgeoval, &
Expand Down Expand Up @@ -580,11 +581,11 @@ end subroutine opsinputs_fill_fillelementtype2dfromsimulatedvariable
!> \param[in] JediValueVarName
!> Name of the JEDI variable containing observation values.
!> \param[in] JediValueGroup
!> Group of the JEDI variable containing observation values.
!> Group name of the JEDI variable containing observation values.
!> \param[in] JediErrorVarName
!> (Optional) Name of the JEDI variable containing observation errors.
!> \param[in] JediErrorGroup
!> (Optional) Group of the JEDI variable containing observation errors.
!> (Optional) Group name of the JEDI variable containing observation errors.
!> \param[in] PackPGEs
!> Optional; true by default. If set to false, PGEs won't be stored in packed form.
!> The Ops_VarobPGEs subroutine expects PGEs to be stored in packed form for most varobs fields,
Expand Down Expand Up @@ -693,11 +694,11 @@ end subroutine opsinputs_fill_fillelementtypefromnormalvariable
!> \param[in] JediValueVarName
!> Name of the JEDI variable containing observation values.
!> \param[in] JediValueGroup
!> Group of the JEDI variable containing observation values.
!> Group name of the JEDI variable containing observation values.
!> \param[in] JediErrorVarName
!> (Optional) Name of the JEDI variable containing observation errors.
!> \param[in] JediErrorGroup
!> (Optional) Group of the JEDI variable containing observation errors.
!> (Optional) Group name of the JEDI variable containing observation errors.
!> \param[in] PackPGEs
!> Optional; true by default. If set to false, PGEs won't be stored in packed form.
!> The Ops_VarobPGEs subroutine expects PGEs to be stored in packed form for most varobs fields,
Expand Down Expand Up @@ -829,13 +830,13 @@ end subroutine opsinputs_fill_fillelementtype2dfromnormalvariable
!> \param[in] JediValueVarName
!> Name of the JEDI variable containing observation values.
!> \param[in] JediValueGroup
!> Group of the JEDI variable containing observation values.
!> Group name of the JEDI variable containing observation values.
!> \param[in] LevelsAreTopToBottom
!> A logical to specify if the levels being passed in are top to bottom in the atmosphere.
!> \param[in] JediErrorVarName
!> (Optional) Name of the JEDI variable containing observation errors.
!> \param[in] JediErrorGroup
!> (Optional) Group of the JEDI variable containing observation errors.
!> (Optional) Group name of the JEDI variable containing observation errors.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -950,7 +951,7 @@ end subroutine opsinputs_fill_fillelementtype2dfromnormalvariablewithlevels
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Real1.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real1.
!> Group name of the JEDI variable used to populate \p Real1.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -1030,7 +1031,7 @@ end subroutine opsinputs_fill_fillreal
!> variable with no channel suffix (in which case \p Real2 will have only a single row) or a set
!> of variables with suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!> \param[in] compressVarChannels
!> Whether to apply var channel compression (No NaN spaces between channels)
!> \param[in] sizeOfVarobsArray
Expand Down Expand Up @@ -1165,7 +1166,7 @@ end subroutine opsinputs_fill_fillreal2d_norecords
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Real2.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -1235,7 +1236,7 @@ end subroutine opsinputs_fill_fillreal2d_records
!> \param[inout] Hdr
!> Header to be populated.
!> \param[in] OpsVarName
!> Name of the OB_type field to which \p Real1 corresponds.
!> Name of the OB_type field to which \p Real2 corresponds.
!> \param[in] JediToOpsLayoutMapping
!> Data needed to map JEDI locations stored on the current PE to OPS observations.
!> \param[inout] Real2
Expand All @@ -1254,7 +1255,7 @@ end subroutine opsinputs_fill_fillreal2d_records
!> suffix (in which case \p Real2 will have only a single row) or a set of variables with
!> suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -1764,7 +1765,7 @@ end subroutine opsinputs_fill_fillreal2dfromgeovalformultilevelobs
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Int1.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Int1.
!> Group name of the JEDI variable used to populate \p Int1.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -1817,6 +1818,87 @@ subroutine opsinputs_fill_fillinteger( &
end if
end subroutine opsinputs_fill_fillinteger


! ------------------------------------------------------------------------------
!> Populate a 2D array of integers and its header from a JEDI variable.
!>
!> \param[inout] Hdr
!> Header to be populated.
!> \param[in] OpsVarName
!> Name of the OB_type field to which \p Int2 corresponds.
!> \param[in] JediToOpsLayoutMapping
!> Data needed to map JEDI locations stored on the current PE to OPS observations.
!> \param[inout] Int2
!> Pointer to the array to be populated.
!> \param[in] ObsSpace
!> Pointer to ioda::ObsSpace object containing the specified JEDI variable. The variable can
!> have either no channel suffix (in which case \p Int2 will have only a single row) or suffixes
!> representing the indices specified in \p Channels.
!> \param[in] Channels
!> Indices returned by ioda::ObsSpace::obsvariables().channels().
!> \param[in] VarobsLength
!> Length of varobs profile.
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Int2. If each JEDI location needs to be mapped
!> to a separate OPS observation, this can represent either a single variable with no channel
!> suffix (in which case \p Int2 will have only a single row) or a set of variables with
!> suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group name of the JEDI variable used to populate \p Int2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
!> are not found.
subroutine opsinputs_fill_fillinteger2d( &
Hdr, OpsVarName, JediToOpsLayoutMapping, Int2, ObsSpace, Channels, &
VarobsLength, JediVarName, JediVarGroup)
implicit none

! Subroutine arguments:
type(ElementHeader_Type), intent(inout) :: Hdr
character(len=*), intent(in) :: OpsVarName
type(opsinputs_jeditoopslayoutmapping), intent(in) :: JediToOpsLayoutMapping
integer(integer64), pointer, intent(out) :: Int2(:,:)
type(c_ptr), value, intent(in) :: ObsSpace
integer(c_int), intent(in) :: Channels(:)
integer(integer64), intent(in) :: VarobsLength
character(len=*), intent(in) :: JediVarName
character(len=*), intent(in) :: JediVarGroup
! todo(someone): add optional arguments used in opsinputs_fill_fillreal2d if there is a need.

! Local declarations:
integer(kind=c_int) :: VarValue(JediToOpsLayoutMapping % NumJediObs)
integer(kind=c_int) :: CurrentVarValue
integer(kind=c_int) :: MissingInt
integer :: i
integer :: numchans

! Body:

MissingInt = missing_value(0_c_int32_t)

! todo(someone): add this if needed
if (JediToOpsLayoutMapping % ConvertRecordsToMultilevelObs) then
call abor1_ftn("must extend opsinputs_fill_fillreal2d to deal with multi-level observations")
end if

! todo(someone): make this configurable if required
numchans = 1

if (obsspace_has(ObsSpace, JediVarGroup, JediVarName)) then
! Retrieve data from JEDI
call obsspace_get_db(ObsSpace, JediVarGroup, JediVarName, VarValue)

! Fill the OPS data structures
call Ops_Alloc(Hdr, OpsVarName, JediToOpsLayoutMapping % NumOpsObs, Int2, &
num_levels = int(numchans, kind=integer64))
do i = 1, JediToOpsLayoutMapping % NumOpsObs
CurrentVarValue = VarValue(i)
if (CurrentVarValue /= MissingInt) Int2(i, 1) = CurrentVarValue
end do
end if
end subroutine opsinputs_fill_fillinteger2d

! ------------------------------------------------------------------------------

!> Populate a 1D array of strings and its header from a JEDI variable.
Expand All @@ -1837,7 +1919,7 @@ end subroutine opsinputs_fill_fillinteger
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p String1.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p String1.
!> Group name of the JEDI variable used to populate \p String1.
!> \param[in] ConvertIntToSTring
!> Convert an integer-valued ObsSpace vector to a string.
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
Expand Down Expand Up @@ -1934,7 +2016,7 @@ end subroutine opsinputs_fill_fillstring
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Real1.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real1.
!> Group name of the JEDI variable used to populate \p Real1.
!> \param[in] ReferenceTime
!> Reference time. JEDI datetimes will be converted into offsets from this time.
!>
Expand Down Expand Up @@ -2010,7 +2092,7 @@ end subroutine opsinputs_fill_filltimeoffsets
!> variable with no channel suffix (in which case \p Real2 will have only a single row) or a set
!> of variables with suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!> \param[in] ReferenceTime
!> Reference time. JEDI datetimes will be converted into offsets from this time.
!>
Expand Down Expand Up @@ -2085,7 +2167,7 @@ end subroutine opsinputs_fill_filltimeoffsets2d_norecords
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Real2.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!> \param[in] ReferenceTime
!> Reference time. JEDI datetimes will be converted into offsets from this time.
!>
Expand Down Expand Up @@ -2181,7 +2263,7 @@ end subroutine opsinputs_fill_filltimeoffsets2d_records
!> suffix (in which case \p Real2 will have only a single row) or a set of variables with
!> suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> Group name of the JEDI variable used to populate \p Real2.
!> \param[in] ReferenceTime
!> Reference time. JEDI datetimes will be converted into offsets from this time.
!>
Expand Down Expand Up @@ -2249,7 +2331,7 @@ end subroutine opsinputs_fill_filltimeoffsets2d
!> variable with no channel suffix (in which case \p Coord2 will have only a single row) or a set
!> of variables with suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Coord2.
!> Group name of the JEDI variable used to populate \p Coord2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -2318,7 +2400,7 @@ end subroutine opsinputs_fill_fillcoord2d_norecords
!> \param[in] JediVarName
!> Name of the JEDI variable used to populate \p Coord2.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Coord2.
!> Group name of the JEDI variable used to populate \p Coord2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down Expand Up @@ -2390,7 +2472,7 @@ end subroutine opsinputs_fill_fillcoord2d_records
!> suffix (in which case \p Coord2 will have only a single row) or a set of variables with
!> suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Coord2.
!> Group name of the JEDI variable used to populate \p Coord2.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
Expand Down
38 changes: 26 additions & 12 deletions src/opsinputs/opsinputs_varobswriter_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module opsinputs_varobswriter_mod
opsinputs_fill_fillelementtypefromsimulatedvariable, &
opsinputs_fill_fillelementtype2dfromsimulatedvariable, &
opsinputs_fill_fillinteger, &
opsinputs_fill_fillinteger2d, &
opsinputs_fill_fillreal, &
opsinputs_fill_fillreal2d, &
opsinputs_fill_fillrealfromgeoval, &
Expand Down Expand Up @@ -1017,8 +1018,17 @@ subroutine opsinputs_varobswriter_populateobservations( &
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % SBUVozone, "SBUVozone", Ob % Header % NumObsLocal, Ob % SBUVozone)
case (VarField_RadialVelocity)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadialVelocSO, "RadialVelocSO", Ob % Header % NumObsLocal, Ob % RadialVelocSO)
! Write DerivedObsValue/radialVelocity to both Ob % RadialVelocSO and Ob % RadialVelocity.
! This ensures that the code in deps/ops/stubs/OpsMod_Varobs/Ops_VarobPGEs.inc works correctly.
! The logical `RadWind_SuperOb` is always false in opsinputs, but is true in operational OPS.
! By default that results in PGEs not being filled correctly. Writing out both OPS variables
! fixes the problem.
call opsinputs_fill_fillelementtype2dfromsimulatedvariable( &
Ob % Header % RadialVelocSO, "RadialVelocSO", JediToOpsLayoutMapping, Ob % RadialVelocSO, &
ObsSpace, self % channels, Flags, ObsErrors, self % VarobsLength, "radialVelocity", "ObsValue")
call opsinputs_fill_fillelementtype2dfromsimulatedvariable( &
Ob % Header % RadialVelocity, "RadialVelocity", JediToOpsLayoutMapping, Ob % RadialVelocity, &
ObsSpace, self % channels, Flags, ObsErrors, self % VarobsLength, "radialVelocity", "ObsValue")
case (VarField_Reflectivity)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % ReflectivitySO, "ReflectivitySO", Ob % Header % NumObsLocal, Ob % ReflectivitySO)
Expand All @@ -1029,21 +1039,25 @@ subroutine opsinputs_varobswriter_populateobservations( &
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % ReflectivityI, "ReflectivityI", Ob % Header % NumObsLocal, Ob % ReflectivityI)
case (VarField_RadarBeamElev)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadarBeamElev, "RadarBeamElev", Ob % Header % NumObsLocal, Ob % RadarBeamElev)
call opsinputs_fill_fillreal2d( &
Ob % Header % RadarBeamElev, "RadarBeamElev", JediToOpsLayoutMapping, Ob % RadarBeamElev, &
ObsSpace, self % channels, self % VarobsLength, "beamTiltAngle", "MetaData")
case (VarField_RadarObRange)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadarObRange, "RadarObRange", Ob % Header % NumObsLocal, Ob % RadarObRange)
call opsinputs_fill_fillreal2d( &
Ob % Header % RadarObRange, "RadarObRange", JediToOpsLayoutMapping, Ob % RadarObRange, &
ObsSpace, self % channels, self % VarobsLength, "gateRange", "MetaData")
case (VarField_RadarObAzim)
call opsinputs_fill_fillreal2d( &
Ob % Header % RadarObAzim, "RadarObAzim", JediToOpsLayoutMapping, Ob % RadarObAzim, &
ObsSpace, self % channels, self % VarobsLength, "radarAzimuth", "MetaData")
Ob % Header % RadarObAzim, "RadarObAzim", JediToOpsLayoutMapping, Ob % RadarObAzim, &
ObsSpace, self % channels, self % VarobsLength, "beamAzimuthAngle", "MetaData")
case (VarField_RadIdent)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadIdent, "RadIdent", Ob % Header % NumObsLocal, Ob % RadIdent)
call opsinputs_fill_fillinteger2d( &
Ob % Header % RadIdent, "RadIdent", JediToOpsLayoutMapping, Ob % RadIdent, &
ObsSpace, self % channels, self % VarobsLength, "stationIdentification", "MetaData")
case (VarField_RadAltAboveMSL)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadAltAboveMSL, "RadAltAboveMSL", Ob % Header % NumObsLocal, Ob % RadAltAboveMSL)
call opsinputs_fill_fillreal2d( &
Ob % Header % RadAltAboveMSL, "RadAltAboveMSL", JediToOpsLayoutMapping, Ob % RadAltAboveMSL, &
ObsSpace, self % channels, self % VarobsLength, "stationElevation", "MetaData")
case (VarField_RadNoiseLvl)
! TODO(someone): handle this varfield
! call Ops_Alloc(Ob % Header % RadNoiseLvl, "RadNoiseLvl", Ob % Header % NumObsLocal, Ob % RadNoiseLvl)
Expand Down
Loading

0 comments on commit ae8fa38

Please sign in to comment.