From 7614dedb9765f25e3974791d2a896b089dcf7fe0 Mon Sep 17 00:00:00 2001 From: Chris Thomas <32307951+ctgh@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:56:39 +0100 Subject: [PATCH] Radar reflectivity (#223) * reflectivity * exner_levels --- Varfields.md | 16 +++--- etc/ukv/cx/RadarZ.nl | 12 +++++ etc/ukv/varobs/RadarZ.nl | 11 ++++ src/opsinputs/opsinputs_cxfields_mod.F90 | 4 +- src/opsinputs/opsinputs_varobswriter_mod.F90 | 23 +++++++-- test/CMakeLists.txt | 21 +++++++- test/generate_unittest_netcdfs.py | 39 ++++++++++++--- test/testinput/039_UpperAirCxField_Exner.nc4 | Bin 0 -> 6192 bytes test/testinput/039_UpperAirCxField_Exner.yaml | 41 +++++++++++++++ test/testinput/040_UpperAirCxField_Qrain.nc4 | Bin 0 -> 6192 bytes test/testinput/040_UpperAirCxField_Qrain.yaml | 41 +++++++++++++++ .../063_VarField_radialVelocity.yaml | 2 +- test/testinput/070_VarField_reflectivity.nc4 | Bin 0 -> 15970 bytes test/testinput/070_VarField_reflectivity.yaml | 40 +++++++++++++++ .../RadarZ.nl | 3 ++ .../RadarZ.nl | 3 ++ .../RadarZ.nl | 3 ++ .../cx_ukvnamelist_radar_reflectivity.nc4 | Bin 0 -> 13171 bytes ...writer_ukvnamelist_radar_reflectivity.yaml | 41 +++++++++++++++ .../varobs_ukvnamelist_radar_reflectivity.nc4 | Bin 0 -> 12985 bytes ...writer_ukvnamelist_radar_reflectivity.yaml | 47 ++++++++++++++++++ 21 files changed, 324 insertions(+), 23 deletions(-) create mode 100644 etc/ukv/cx/RadarZ.nl create mode 100644 etc/ukv/varobs/RadarZ.nl create mode 100644 test/testinput/039_UpperAirCxField_Exner.nc4 create mode 100644 test/testinput/039_UpperAirCxField_Exner.yaml create mode 100644 test/testinput/040_UpperAirCxField_Qrain.nc4 create mode 100644 test/testinput/040_UpperAirCxField_Qrain.yaml create mode 100644 test/testinput/070_VarField_reflectivity.nc4 create mode 100644 test/testinput/070_VarField_reflectivity.yaml create mode 100644 test/testinput/CxWriterNamelists_039_UpperAirCxField_Exner/RadarZ.nl create mode 100644 test/testinput/CxWriterNamelists_040_UpperAirCxField_Qrain/RadarZ.nl create mode 100644 test/testinput/VarObsWriterNamelists_070_VarField_reflectivity/RadarZ.nl create mode 100644 test/testinput/cx_ukvnamelist_radar_reflectivity.nc4 create mode 100644 test/testinput/cxwriter_ukvnamelist_radar_reflectivity.yaml create mode 100644 test/testinput/varobs_ukvnamelist_radar_reflectivity.nc4 create mode 100644 test/testinput/varobswriter_ukvnamelist_radar_reflectivity.yaml diff --git a/Varfields.md b/Varfields.md index 3f6e9c2e..2df498ec 100644 --- a/Varfields.md +++ b/Varfields.md @@ -56,19 +56,19 @@ | 60 | `VarField_z` | | | | Implement | | 61 | `VarField_SBUVozone` | | | | Implement | | 62 | `VarField_GeoBriTemp` | | | | Implement | -| 63 | `VarField_RadialVelocity` | | | | Implement | -| 64 | `VarField_RadarBeamElev` | | | | Implement | -| 65 | `VarField_RadarObRange` | | | | Implement | -| 66 | `VarField_RadarObAzim` | `RadarObAzim(:,:)` | Azimut of radar ob | `MetaData/radarAzimuth` | | +| 63 | `VarField_RadialVelocity` | `RadialVelocSO(:,:)` | Radar radial velocity | `ObsValue/radialVelocity` | | +| 64 | `VarField_RadarBeamElev` | `RadarBeamElev(:,:)` | Radar beam tilt | `MetaData/beamTiltAngle` | | +| 65 | `VarField_RadarObRange` | `RadarObRange(:,:)` | Radar gate range | `MetaData/gateRange` | | +| 66 | `VarField_RadarObAzim` | `RadarObAzim(:,:)` | Radar beam azimuth | `MetaData/beamAzimuthAngle` | | | 67 | `VarField_GPS_Station_Height` | `GPS_Station_Height(:)`| Height of the Ground GNSS stations | `MetaData/stationElevation` | | | 68 | `VarField_clw` | CLW(:,:) | retrieved clw from 1Dvar | OneDVar/liquidWaterContent | | -| 69 | `VarField_RadIdent` | | | | Implement Implement | -| 70 | `VarField_Reflectivity` | | | | Implement | +| 69 | `VarField_RadIdent` | `RadIdent(:)` | Radar numerical identifier | `MetaData/stationIdentification` | | +| 70 | `VarField_Reflectivity` | `ReflectivitySO(:,:)` | Radar reflectivity | `ObsValue/reflectivity` | | | 71 | `VarField_BendingAngle` | `BendingAngle(:,:)` or `BendingAngleAll(:,:)` | GPSRO bending angle (L1, L2, LC etc or just LC) | `ObsValue/bendingAngle` | Decide if a separate variable corresponding to BendingAngleAll is needed | | 72 | `VarField_ImpactParam` | `ImpactParam(:,:)` or `ImpactParamAll(:,:)` | GPSRO impact parameter (L1, L2, LC etc or just LC) | `ObsValue/impactParameterRO` | Decide if a separate variable corresponding to ImpactParamAll is needed | | 73 | `VarField_RO_Rad_Curv` | `RO_Rad_Curv(:)` | GPSRO Earth\'s local radius of curvature (m) | `MetaData/earthRadiusCurvature` | | | 74 | `VarField_RO_geoid_und` | `RO_geoid_und(:)` | GPSRO Geoid undulation (above WGS-84 ellipsoid, m) | `MetaData/geoidUndulation` | | -| 75 | `VarField_RadAltAboveMSL` | | | | Implement | +| 75 | `VarField_RadAltAboveMSL` | `RadAltAboveMSL(:,:)` | Radar station elevation above mean sea level | `MetaData/stationElevation` | | | 76 | `VarField_BriTempVarError` | `BriTempVarError(:,:)` | scene dependent obs errors for BTs (oblocation, channel) | `ObsErrorData/brightnessTemperature` | | | 77 | `VarField_AOD` | `AOD(:,:)` | aerosol optical depth | `ObsValue/aerosolOpticalDepth` | | | 78 | `VarField_Theta` | `theta(:,:)` | potential temperature | `ObsValue/airTemperature` | | @@ -97,4 +97,4 @@ | 101 | `VarField_dWinddP` | | | | Implement | | 102 | `VarField_AzimuthCOG` | | | | Implement | | 103 | `VarField_HeightCOG` | | | | Implement | -| 104 | `VarField_RadFlag` | | | | | | Implement | +| 104 | `VarField_RadFlag` | `RadFlag(:,:)` | Radar preprocessing flag | `QualityInformation/reflectivity` | | diff --git a/etc/ukv/cx/RadarZ.nl b/etc/ukv/cx/RadarZ.nl new file mode 100644 index 00000000..8d24b02d --- /dev/null +++ b/etc/ukv/cx/RadarZ.nl @@ -0,0 +1,12 @@ +&CXControlNL +! These STASH codes correspond to the following variables: +! 4: theta +! 10: q +! 12: qcf +! 33: orography +! 254: qcl +! 255: exnerA +! 272: qrain +! 407: p +CxFields=4,10,12,33,254,255,272,407 +/ diff --git a/etc/ukv/varobs/RadarZ.nl b/etc/ukv/varobs/RadarZ.nl new file mode 100644 index 00000000..a8947de9 --- /dev/null +++ b/etc/ukv/varobs/RadarZ.nl @@ -0,0 +1,11 @@ +&VarobsControlNL +! These indices correspond to the following variables: +! 64: Beam tilt (elevation in OPS terminology) +! 65: Gate range +! 66: Gate azimuth +! 69: Station identifier +! 70: Reflectivity +! 75: Station elevation (altitude above MSL in OPS terminology) +! 104: Radar QC flag +Varfields=64,65,66,69,70,75,104 +/ diff --git a/src/opsinputs/opsinputs_cxfields_mod.F90 b/src/opsinputs/opsinputs_cxfields_mod.F90 index b24d18a6..c91594be 100644 --- a/src/opsinputs/opsinputs_cxfields_mod.F90 +++ b/src/opsinputs/opsinputs_cxfields_mod.F90 @@ -86,8 +86,8 @@ module opsinputs_cxfields_mod character(len=*), parameter, public :: opsinputs_cxfields_RH_AMC = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_Cl = "liquid_cloud_volume_fraction_in_atmosphere_layer" character(len=*), parameter, public :: opsinputs_cxfields_Cf = "ice_cloud_volume_fraction_in_atmosphere_layer" -character(len=*), parameter, public :: opsinputs_cxfields_qrain = opsinputs_cxfields_unknown -character(len=*), parameter, public :: opsinputs_cxfields_ExnerA = opsinputs_cxfields_unknown +character(len=*), parameter, public :: opsinputs_cxfields_qrain = "qrain" +character(len=*), parameter, public :: opsinputs_cxfields_ExnerA = "exner_levels" character(len=*), parameter, public :: opsinputs_cxfields_RichNumber = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_SoilMoisture = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_SoilTemp = opsinputs_cxfields_unknown diff --git a/src/opsinputs/opsinputs_varobswriter_mod.F90 b/src/opsinputs/opsinputs_varobswriter_mod.F90 index 3717287a..dc374b5b 100644 --- a/src/opsinputs/opsinputs_varobswriter_mod.F90 +++ b/src/opsinputs/opsinputs_varobswriter_mod.F90 @@ -105,6 +105,7 @@ module opsinputs_varobswriter_mod ObsGroupAircraft, & ObsGroupGPSRO, & ObsGroupOceanWinds, & + ObsGroupRadarZ, & ObsGroupSatwind, & ObsGroupScatwind, & ObsGroupScatwindChosen, & @@ -707,7 +708,7 @@ subroutine opsinputs_varobswriter_populateobservations( & integer :: nVarFields integer :: iVarField integer :: iobs - +character(len=200) :: varname logical :: FillChanNum = .false. logical :: FillNumChans = .false. @@ -1034,8 +1035,14 @@ subroutine opsinputs_varobswriter_populateobservations( & 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) + ! Write DerivedObsValue/reflectivity to both Ob % ReflectivitySO and Ob % Reflectivity. + ! See the explanation given for RadialVelocity above. + call opsinputs_fill_fillelementtype2dfromsimulatedvariable( & + Ob % Header % ReflectivitySO, "ReflectivitySO", JediToOpsLayoutMapping, Ob % ReflectivitySO, & + ObsSpace, self % channels, Flags, ObsErrors, self % VarobsLength, "reflectivity", "ObsValue") + call opsinputs_fill_fillelementtype2dfromsimulatedvariable( & + Ob % Header % Reflectivity, "Reflectivity", JediToOpsLayoutMapping, Ob % Reflectivity, & + ObsSpace, self % channels, Flags, ObsErrors, self % VarobsLength, "reflectivity", "ObsValue") case (VarField_ReflectivityR) ! TODO(someone): handle this varfield ! call Ops_Alloc(Ob % Header % ReflectivityR, "ReflectivityR", Ob % Header % NumObsLocal, Ob % ReflectivityR) @@ -1066,8 +1073,14 @@ subroutine opsinputs_varobswriter_populateobservations( & ! TODO(someone): handle this varfield ! call Ops_Alloc(Ob % Header % RadNoiseLvl, "RadNoiseLvl", Ob % Header % NumObsLocal, Ob % RadNoiseLvl) case (VarField_RadFlag) - ! TODO(someone): handle this varfield - ! call Ops_Alloc(Ob % Header % RadFlag, "RadFlag", Ob % Header % NumObsLocal, Ob % RadFlag) + if (Ob % header % ObsGroup == ObsGroupRadarZ) then + varname = "reflectivity" + else + call gen_fail(RoutineName, "Invalid observation name for RadFlag") + end if + call opsinputs_fill_fillinteger2d( & + Ob % Header % RadFlag, "RadFlag", JediToOpsLayoutMapping, Ob % RadFlag, & + ObsSpace, self % channels, self % VarobsLength, trim(varname), "QualityInformation") case (VarField_clw) call opsinputs_fill_fillelementtype2dfromnormalvariablewithlevels( & Ob % Header % CLW , "CLW" , Ob % Header % NumObsLocal, ob % CLW, & diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2367121e..02f11687 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -234,6 +234,10 @@ ADD_WRITER_TEST(NAME varobswriter_068_VarField_clw YAML 068_VarField_clw.yaml NAMELIST VarObsWriterNamelists_068_VarField_clw/AMSUB.nl DATA 068_VarField_clw.nc4) +ADD_WRITER_TEST(NAME varobswriter_070_VarField_reflectivity + YAML 070_VarField_reflectivity.yaml + NAMELIST VarObsWriterNamelists_070_VarField_reflectivity/RadarZ.nl + DATA 070_VarField_reflectivity.nc4) ADD_WRITER_TEST(NAME varobswriter_071_VarField_bendingangle YAML 071_VarField_bendingangle.yaml DATA 071_VarField_bendingangle.nc4) @@ -382,6 +386,10 @@ ADD_WRITER_TEST(NAME varobswriter_ukvnamelist_radar_doppler_wind YAML varobswriter_ukvnamelist_radar_doppler_wind.yaml NAMELIST ../../etc/ukv/varobs/Radar.nl DATA varobs_ukvnamelist_radar_doppler_wind.nc4) +ADD_WRITER_TEST(NAME varobswriter_ukvnamelist_radar_reflectivity + YAML varobswriter_ukvnamelist_radar_reflectivity.yaml + NAMELIST ../../etc/ukv/varobs/RadarZ.nl + DATA varobs_ukvnamelist_radar_reflectivity.nc4) ### CxWriter tests @@ -504,7 +512,14 @@ ADD_WRITER_TEST(NAME cxwriter_035_UpperAirCxField_Cl YAML 035_UpperAirCxField_Cl.yaml NAMELIST CxWriterNamelists_035_UpperAirCxField_Cl/AMSUB.nl DATA 035_UpperAirCxField_Cl.nc4 dummy.nc4) - +ADD_WRITER_TEST(NAME cxwriter_039_UpperAirCxField_Exner + YAML 039_UpperAirCxField_Exner.yaml + NAMELIST CxWriterNamelists_039_UpperAirCxField_Exner/RadarZ.nl + DATA 039_UpperAirCxField_Exner.nc4 dummy.nc4) +ADD_WRITER_TEST(NAME cxwriter_040_UpperAirCxField_Qrain + YAML 040_UpperAirCxField_Qrain.yaml + NAMELIST CxWriterNamelists_040_UpperAirCxField_Qrain/RadarZ.nl + DATA 040_UpperAirCxField_Qrain.nc4 dummy.nc4) ADD_WRITER_TEST(NAME cxwriter_041-042_UpperAirCxField_dust1-dust2 YAML 041-042_UpperAirCxField_dust1-dust2.yaml NAMELIST CxWriterNamelists_041-042_UpperAirCxField_dust1-dust2/AOD.nl @@ -704,6 +719,10 @@ ADD_WRITER_TEST(NAME cxwriter_ukvnamelist_radar_doppler_wind YAML cxwriter_ukvnamelist_radar_doppler_wind.yaml NAMELIST ../../etc/ukv/cx/Radar.nl DATA cx_ukvnamelist_radar_doppler_wind.nc4 dummy.nc4) +ADD_WRITER_TEST(NAME cxwriter_ukvnamelist_radar_reflectivity + YAML cxwriter_ukvnamelist_radar_reflectivity.yaml + NAMELIST ../../etc/ukv/cx/RadarZ.nl + DATA cx_ukvnamelist_radar_reflectivity.nc4 dummy.nc4) ### Tests of auxiliary classes diff --git a/test/generate_unittest_netcdfs.py b/test/generate_unittest_netcdfs.py index f46abeb1..749aa402 100644 --- a/test/generate_unittest_netcdfs.py +++ b/test/generate_unittest_netcdfs.py @@ -16,7 +16,8 @@ missing_float_nc = 9.969209968386869e+36 -def output_1d_simulated_var_to_netcdf(var_name, file_name, with_bias=False, radar_doppler_wind=False): +def output_1d_simulated_var_to_netcdf(var_name, file_name, with_bias=False, + radar_doppler_wind=False, radar_reflectivity=False): f = nc4.Dataset(file_name, 'w', format="NETCDF4") nlocs = 4 @@ -35,10 +36,10 @@ def output_1d_simulated_var_to_netcdf(var_name, file_name, with_bias=False, rada var[:] = [1 * minute, 2 * minute, 3 * minute, 4 * minute] # Station ID - if radar_doppler_wind: - # The radar Doppler wind processing uses integers for station identification because - # `MetaData/stationIdentification` is mapped to the ODB variable `rad_ident`, - # which is an integer. + if radar_doppler_wind or radar_reflectivity: + # The radar Doppler wind and reflectivity processing both use integers for + # station identification because `MetaData/stationIdentification` is mapped + # to the ODB variable `rad_ident`, which is an integer. var = f.createVariable('MetaData/stationIdentification', 'i', ('Location')) var[:] = [1, 2, 3, 4] else: @@ -48,7 +49,7 @@ def output_1d_simulated_var_to_netcdf(var_name, file_name, with_bias=False, rada var[i] = s # Extra variables for radar - if radar_doppler_wind: + if radar_doppler_wind or radar_reflectivity: var = f.createVariable('MetaData/radar_family', 'i', ('Location',)) var[:] = [11, 12, 13, 14] var = f.createVariable('MetaData/beamTiltAngle', 'i', ('Location',)) @@ -59,6 +60,9 @@ def output_1d_simulated_var_to_netcdf(var_name, file_name, with_bias=False, rada var[:] = [11, 12, 13, 14] var = f.createVariable('MetaData/stationElevation', 'i', ('Location',)) var[:] = [11, 12, 13, 14] + if radar_reflectivity: + var = f.createVariable('QualityInformation/reflectivity', 'i', ('Location',)) + var[:] = [11, 12, 13, 14] var = f.createVariable('ObsValue/' + var_name, 'f', ('Location',)) obsVal = [1.1, missing_float, 1.3, 1.4] @@ -726,6 +730,7 @@ def copy_var_to_var(Group, invarname, outvarname, filename): 'thickness_200_50hPa_satid_5Predictor', 'thickness_200_50hPa_satid_8Predictor', 'legendre_order_1_satid_5Predictor', 'legendre_order_1_satid_8Predictor'], 'testinput/080_VarField_biaspredictors.nc4', predictors=True) + output_1d_simulated_var_to_netcdf ('reflectivity', 'testinput/070_VarField_reflectivity.nc4', radar_reflectivity=True) output_2d_simulated_var_to_netcdf('bendingAngle', 'testinput/071_VarField_bendingangle.nc4', add_occulting_satid=True) output_2d_normal_var_to_netcdf('impactParameterRO', 'MetaData', 'testinput/072_VarField_impactparam.nc4') output_1d_normal_var_to_netcdf('earthRadiusCurvature', 'MetaData', 'testinput/073_VarField_ro_rad_curv.nc4') @@ -901,6 +906,18 @@ def copy_var_to_var(Group, invarname, outvarname, filename): ['MetaData/stationIdentification'], 'testinput/varobs_ukvnamelist_radar_doppler_wind.nc4') + # Radar reflectivity - UKV + output_full_varobs_to_netcdf(['MetaData/latitude', + 'MetaData/longitude', + 'MetaData/beamTiltAngle', + 'MetaData/gateRange', + 'MetaData/beamAzimuthAngle', + 'MetaData/stationElevation', + 'ObsValue/reflectivity', 'ObsError/reflectivity'], + [], + ['MetaData/stationIdentification', 'QualityInformation/reflectivity',], + 'testinput/varobs_ukvnamelist_radar_reflectivity.nc4') + @@ -936,6 +953,8 @@ def copy_var_to_var(Group, invarname, outvarname, filename): output_2d_geoval_to_netcdf ('liquid_cloud_volume_fraction_in_atmosphere_layer', 'testinput/035_UpperAirCxField_Cl.nc4') output_2d_geovals_to_netcdf (['mass_fraction_of_dust00%s_in_air' % i for i in range(1, 7)], 'testinput/041-046_UpperAirCxField_dust1-dust6.nc4') output_2d_geovals_to_netcdf (['eastward_wind', 'northward_wind'], 'testinput/CxWriter_UnRotateWinds.nc4', shift_by_varindex=False) + output_2d_geoval_to_netcdf ('exner_levels', 'testinput/039_UpperAirCxField_Exner.nc4') + output_2d_geoval_to_netcdf ('qrain', 'testinput/040_UpperAirCxField_Qrain.nc4') # Cx full output for an obsgroup testing # list of 1d-variables; list of 2d-variables; filename for output @@ -1167,3 +1186,11 @@ def copy_var_to_var(Group, invarname, outvarname, filename): ['eastward_wind', 'northward_wind', 'upward_air_velocity'], 'testinput/cx_ukvnamelist_radar_doppler_wind.nc4') + # Radar reflectivity - UKV + output_full_cx_to_netcdf(['surface_altitude'], + ['potential_temperature', 'specific_humidity', 'air_pressure_levels', + 'cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water', + 'cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water', + 'exner_levels', 'qrain'], + 'testinput/cx_ukvnamelist_radar_reflectivity.nc4') + diff --git a/test/testinput/039_UpperAirCxField_Exner.nc4 b/test/testinput/039_UpperAirCxField_Exner.nc4 new file mode 100644 index 0000000000000000000000000000000000000000..188e6fdaa7de3a3bee344286356b368dd2e77252 GIT binary patch literal 6192 zcmeHI&ubG=5PrLxgb=p2+DcS}uHs2+XqzfZsok>Km}0uorXYwA(q@+~q)EuGwPMAC zAQU|HAf$*?3L<#*CiL1%`ww{ZA5hVQw>tBFG#XpbgNpDTO(r{UX5RO{{bst7%VfI} zClYErPQ=>fYw#HJ4DyYet6!fLa+zsWf1{qJK276WBBj$NRH9%=PY-^-kK#8Wo6Ha* z(qr@_B|>9iGg_;ww0eK7D+F-kQ=;PW^&4QijxJWRJ11YHqmdvtsx=G5}b)Co5q_werDbe4EQS> zH8->}S)<}FxV6Bq*NoXap;4=c?XAUf(=X3f-IO8L2thz9)IUUY1XOa|aIWHwWc&rc zLV7?C?1}~j2WP^1QGEUUXAZ?{+_S&P;dQQu|CYn_?{UcFz45lO%s3oXlrzYx3PNOD zw_Bp~nd{QnN0$jytag@Vd|Zwn!J3*vI@(t#^xzKBZJJ5?KoHO%LJ(HH-mLhwa_9y> z$^zO)^rWy@0I#XvX4>rrbwjDPwDXh28FCyVQ1wap;M~DR6cvP}WbvVdzVDw=Xz$9O zt`w}?HE~_h=5*4)zFtK#HPTH65y7;bwWn>zvP%@fMJS1pm2y}P+^`L0uZKt+_Zg|s z0)UVr0H3g8^ni;lfBo~*{SfJV|L-9Z2)DL&lZZ&nR}KW{Yke;GAaLElA23eDD=4x=oxeW5WY5a9~u7jifH8(&sBUi0ciQJ>kH7#k(*zlo}dN z4eO&!0tu!jVA?H(Frlc1*o!sy<@L*4ZV65!&iefpTDkrl16Qp=o~nhnjZhA6JR&qA zy0X(RM!xWi|JefZt8Vd2TFHQ9Kr$d1kPJu$Bm{ysu?fHiIa zRQ}M;Hd5MHD7qr$lG~^!TV}&oh}@_-e)(3o^}(aihAEl~t$T}ivCHGP8xI)#j`NDr zLp!UAqEIpoVYMDYy#M&I&|^S63h{dw5n*T1V*D&?VZsv21`s&f_Qau|rce#qAxdjo znbCY6y3s}4(BV?!6LvN~p34^U)@a5C{Td(^4I(@tJ33*rcr%Qjp7ZMl{v4z123Bg! zDEjkmx$alW#>~yYC|81=sfJVYotcuGFvJ)H0;J;l`#>i^g{&LQ7QMlgKkpZz3-!Q{ zXb1vv+voXL&wl1ms9@XvB8QWq9{yVnlfTCy*Z1n1>H_C*NKsBAsi2||IoG5QK3d;H zT^hUSGDeEkPVtP73(*6#f~G)A`3i;ZT`9WFGNA_rfdwK2VO1)%qF;6bxBjCnuzW;O z3QG&nG4<_FMBA&AmEClyNo5i$hm z6IQe!bg|*De15VUB0Ze{dx!+W_4TbdArcKX1VRnAGF$&3a9yDX>I1AX6|&Z3tx|Ps zfsY@Y8dL%=`UDNPM%`t2pcfkswu<4w#DzriOwnz)rAifhPtZG8^v(|VC;A5x1Nsn` zK#Z#inRW{Sb||JH{$b5sdHph*zKy#!iflF2{!_*R%jZjWlcpx+)saPe jjUdD0Ovc&5} z$`6VJ{Z_6z$Q+GL~EYxflzdQR#062=}<&rIq03aS72Cmc{%h=A%~?Xq0TzNosTvXmTZ;) zk?T1m3CrvX?P?eEYh9Z$5n=YnFro6&f2i8nm-+W(>zw^sN z*^kYKA_yBqL=p?RVqT-ToU&%d>QObWn|E|2Vo76|PmFtNL>*170#6uZ&tPhe8Xwi7 z3k1QY*LS^Nb879G^m|is7Byw>Qd1!3S&c=gQ(Vahy8XRIazrys9l%6ouZIVfeM~b@ zQ(GDqg7SjewKUc*uU~RQR2$Rc$q~?FbK&}EY-!8l`o#_P4ZUkVejpz*<1GxCK|r_u zG&zPG%B?iwl-BUw`O6@hI&}DZ!d!f%+VM1y(!x&5FAfnyW;qFHX1OJeq8X!pq~u-F zPqC!S>_@Jbm(UX(#neB|;hE*M(r1=`F3Wp8S<1_@luyf2UY?~~7PIZtkP7VBM!-hE zM!-hEM!-hEM!-hEM!-hEM!-hEMj$T;Jk`e7et2F!#Mo;PpM!_B!&wwO?soQ_H#*n^ zJb#2|){i^Jw{LGA-|lWXayZ-q=@tcu@oWIk0q~n2zo+rr8NZY9(>B-nBZu!@@%YHM zFT`T|RxDX^V8xNchg&ee=b?vMA>DfF=sT^LH)htgp8Qp+6~{OEfvg>D1Z)Is1Z)Is z1pe<42=#ULGCX8=a4VO@gY24Mw&H>8Se7Z3%mK2VPS<5NYXmz4t0k_=jQL=7-qk=2 z7MwV7QCBbQoONeD>_)!Aup8l~>(0s(7ux$f17KzcXmPt0t=)Ws0JM}5ny;_<&00=X zj8tfp0IC}^sSeHD*B**MUyK+pm?XAPf?E8#STEZM%%hrHrCn#XB%=6SlmGN%NH!@v z^M_3b^1;+ag~3$ZML+V!T`e4bjzCRdf>IS94o7s5P-7K>}^OnnT@$D0>R zKHMtf{6vivJI3GY>J&^a|0FK~4{pvU`)U+T@(zHiZR8!WvM`v7YVzya-yg}nr582- zmZqW|X)FJ$Hw*6GO-x3~;(=TSEMqLV3=Jro=qKW%}*9mQo^CE2^K! zCG)>t7|h2#)$H+!`}4v4r%_Ne z?+^1K486<$E5dN>OwHC$DGZUiv|wPWWY&uh3gKWm*%NHLQo?but1h^?im-qZ|3-Xt zVB+oe{&0vD4NlZ5+`qV%g&+Hwmz{#vSF=aXmAA7YNLI05ZrkE#Z$i??o;>;PSJ@&? zaImTFYiu5Dk!slYZtuOFRYGYs`{L4j_A~HjgkI`mJkg-<{k1h1{Gh4A2t#DkD9 z@`RHzLXLA%rXJqav4-gFI6nyFaxVP-m7NPW%oh;-M|0un(UK@*H$K|*g-~ap9p^bK z%y_=>+4Q%pI}V=D=4ez~CIw${k-C(`lZhc-_YEobii>o|Jz{97)Tp7+NkrPO+GWC> zgALb+_bD#Yr^=MceXP5p;K;1Uba54B?L49*Me`VHR5b=->aZTagEq$L&!)0LO&#vn z<7Qi8D6Y|7NpX=TmJETDdY_sY(rBqvT%?v>Y}@uNeR$Md&zp}dq_>l*dgUmCacztb zcUPkY+-Eb9%dO+?E2R;+_29-6yz^!6R|;ryd*$M_!hi^E&3`i9BdtQwU%jz;XFd?y zUl@p?h5mS8&nSl|$7hVkn~(tz^80c6kL6x|qotT1HK!;0s}d>G&=W(agF0>yxEbE2V^YnfB z5W1sEd!n+ zC9p|NX>faqE@fFa2bmk|#WL>WjHCM%6w}rL$atXb0_ACsKzZ66P@Xmcl&4jn^0dlR zo>q3s(=tx^%r)COqL&2LL7&W9XFoD;eg4aQv$EwDA%wX(ct2Sf!iOfWvOQ-veWLKe bO{nQP6+XKCLvf)CpEdVOVf^dEbzk`xT-JO( literal 0 HcmV?d00001 diff --git a/test/testinput/070_VarField_reflectivity.yaml b/test/testinput/070_VarField_reflectivity.yaml new file mode 100644 index 00000000..f5cc6038 --- /dev/null +++ b/test/testinput/070_VarField_reflectivity.yaml @@ -0,0 +1,40 @@ +time window: + begin: 2018-01-01T00:00:00Z + end: 2018-01-01T02:00:00Z + +observations: + - obs space: + name: RadarZ + obsdatain: + engine: + type: H5File + obsfile: Data/070_VarField_reflectivity.nc4 + simulated variables: [reflectivity] + obs filters: + # Set the flag of observations with missing values to "pass": we want to check if these + # values are encoded correctly in the VarObsFile. + - filter: Reset Flags to Pass + flags_to_reset: [10, 15] # missing, Hfailed + # Reject observation 3: we want to check if it is omitted from the VarObs file, as expected. + - filter: Domain Check + where: + - variable: + name: MetaData/latitude + minvalue: 0.0 + - filter: VarObs Writer + reject_obs_with_any_variable_failing_qc: true + namelist_directory: testinput/VarObsWriterNamelists_070_VarField_reflectivity + general_mode: debug + station_ID_int_to_string: true + - filter: VarObs Checker + expected_main_table_columns: + # Only observations 1, 2 and 4 are passed; observation 3 is rejected by the domain check + field: ["64","65","66","69","70","75","104","64","65","66","69","70","75","104","64","65","66","69","70","75","104"] + ob value: ["11.00000","11.00000","11.00000","1.00000","1.10000","11.00000","11.00000","12.00000","12.00000","12.00000","2.00000","-1073741824.00000","12.00000","12.00000","14.00000","14.00000","14.00000","4.00000","1.40000","14.00000","14.00000"] + lat: ["21.00000","21.00000","21.00000","21.00000","21.00000","21.00000","21.00000","22.00000","22.00000","22.00000","22.00000","22.00000","22.00000","22.00000","24.00000","24.00000","24.00000","24.00000","24.00000","24.00000","24.00000"] + lon: ["31.00000","31.00000","31.00000","31.00000","31.00000","31.00000","31.00000","32.00000","32.00000","32.00000","32.00000","32.00000","32.00000","32.00000","34.00000","34.00000","34.00000","34.00000","34.00000","34.00000","34.00000"] + time: ["-3540.00000","-3540.00000","-3540.00000","-3540.00000","-3540.00000","-3540.00000","-3540.00000","-3480.00000","-3480.00000","-3480.00000","-3480.00000","-3480.00000","-3480.00000","-3480.00000","-3360.00000","-3360.00000","-3360.00000","-3360.00000","-3360.00000","-3360.00000","-3360.00000"] + Callsign: ["1","1","1","1","1","1","1","2","2","2","2","2","2","2","4","4","4","4","4","4","4"] + HofX: ObsValue # just a placeholder -- not used, but needed to force calls to postFilter. + benchmarkFlag: 1000 # just to keep the ObsFilters test happy + flaggedBenchmark: 0 diff --git a/test/testinput/CxWriterNamelists_039_UpperAirCxField_Exner/RadarZ.nl b/test/testinput/CxWriterNamelists_039_UpperAirCxField_Exner/RadarZ.nl new file mode 100644 index 00000000..dde597f6 --- /dev/null +++ b/test/testinput/CxWriterNamelists_039_UpperAirCxField_Exner/RadarZ.nl @@ -0,0 +1,3 @@ +&CXControlNL +CxFields=255 +/ diff --git a/test/testinput/CxWriterNamelists_040_UpperAirCxField_Qrain/RadarZ.nl b/test/testinput/CxWriterNamelists_040_UpperAirCxField_Qrain/RadarZ.nl new file mode 100644 index 00000000..cab03206 --- /dev/null +++ b/test/testinput/CxWriterNamelists_040_UpperAirCxField_Qrain/RadarZ.nl @@ -0,0 +1,3 @@ +&CXControlNL +CxFields=272 +/ diff --git a/test/testinput/VarObsWriterNamelists_070_VarField_reflectivity/RadarZ.nl b/test/testinput/VarObsWriterNamelists_070_VarField_reflectivity/RadarZ.nl new file mode 100644 index 00000000..8945c1e8 --- /dev/null +++ b/test/testinput/VarObsWriterNamelists_070_VarField_reflectivity/RadarZ.nl @@ -0,0 +1,3 @@ +&VarobsControlNL +Varfields=64,65,66,69,70,75,104 +/ diff --git a/test/testinput/cx_ukvnamelist_radar_reflectivity.nc4 b/test/testinput/cx_ukvnamelist_radar_reflectivity.nc4 new file mode 100644 index 0000000000000000000000000000000000000000..9c6525a0978514b0603129e07484660724c66cde GIT binary patch literal 13171 zcmeGjZERFk_PqJ1WgNZ)Y%y*aun0=2ZKq2hEK8@InH|C~44uIs!90hVH}Xt7Q)XVF zZh);ZF>8W}ABjsRG1;sik&hrTo85&Nmem+dY)#Y{jUj&F9|?Y}*(EE{;5ql+Gi^uP zZIhuc?7L;=oO|wh=bd}*IrqLd=kRbO7@q05$>XT41#XvBEBYm+Sq;qpvhC>RNU+P{ z{j+0XwMNzIx_@P=DrXO+#TIE+hr0F?7x+ zjpr_2q$ob9tA)DXA%|Pc#p$8B%z)jk;xd#WA~isRinqk%*M<{^n} z@hRKz|tl@p&Z^5 z+Y_gbp8By3opKOG$u>C~*1~CJ^l#L4Y(vl0VnhGbY$#pjz@9IcN*k`#v<8~G13g%o zqHM#;zOt$BC;ZYw9_zeaUh(z5+8aowQ-gYf035z--3g*CMEp*SG!bp=5S{saA!Ft+ z_KIWO0>h5{mKsCCX`0?0(syU0cVn!LxOQ|yA_)tTgS@^DKNQ6j!7PEHFqYbsh&H-U zj`l(7pTFMR8QI9w<*mbuW7NDu6sAs?jRrssxi4bhPRSm=ePSD*SUAwc3NR=AB_S)q-vXOTSjZ&nGtw)b_#tZpgqhOi1q_hP! z;fIX8$0*SLv97fdw-nqA*0nXQY4Wek7<-KFd@t@UR^zTr_Lu8gnp#?$TH$8A1S+Yc zIot!WbJEx0iu!u<&*|&(a04G11K>Uh0Ip|5!9&Z=eou=b*%M17d4Rdd{Mc$5=v#B~ zUOKnfYoyJrnbvpp;l6BI_p_VT2rtlFyi?3enFYPKU=)je1w-$qB`dNEzV(22Im!J| z`%UNOsPJEMc5DJir~(hZ64a6SuB5Y?O!up4uu@ECIeZ*f(pBh`@5^#H)++hA&yeNM zQ2H{RHuq|L) z;Ht7fHv8QA(%|6w;h}@;{r-9FPxtP>oXys>`~8Xb;h|`IHXCj)4L*$UA*4Nsw6=iX z?+=s)TLQyF!2t1>1_OvEk)A;M7Q{1%rx8yDve_dD4+UW@or#2XNAK>RkvzZ~(E zNN+@XBjPQHHzVGR_$I`oh({6MqWI&8Z$)|%=}E-zLVO$I+Ys+V+(O(!{C>sXkNAG1 z??d{&j?&-&!U3ew=bW%%Y4CHj)rIz}${B2BZ41~Iuq|L);Qz(~B0E&oTpj(wFR}>g zCu#a+f6a#EHo8-dNYiL8&N8@jn5HQ5Z_qUx$?Teoa|El?-TA(ZZl(>r$Lu$A_v(d| zW#;w01xxSAn?*~fj7KV$(bM@{1~cDAM&FBB$^s|aY8FX>oJ8;%{W+tcQX`ygyEOk| z55VKi$KunGl)dNYOjK1jDNE}+dZ8)xQhIm&uIjrKB{N3fiINyEynkcw$cl3+^|1%@ zr#q67AQo9*B5F4BWtQ(~M1akMf3iJu`I%1?3X$VGE=|Y6KYHyfJmt(rF9+qy4qv?c zWVkC57s+vlNUbXib6y^E)uM6ox?D1#GKOlnyhz+14`PO~e5KF^e5h6I4(89b{yr{T z!A*RmGrGd=xzJHVAVffwx?Hib&EQ5~=hFk=p#FWc2xX(Fp?(=EEecnsB|H{&X zXQ#t4zP@%GgR^ufv&e?@N@Gu4cUs*Ay_Uwqx)U1Ut(9{6mYS zqg>fy7ax^RVQZFPGG&w@Vy#MH*VyWnaf@A^tv^@lNJhipKDOirAN&<>zY#9vyBnYn z9itxJ-CAshM-aUQ&L4Pc4LpVnx56o3XaMkO3>x6GqX!PcN<{17k4;ZL4s_<%!$*Ib zc^vM<%N9ZW$mzd`>dPct{P%Z%2b$t?c=PRFkSM$T4_H8~KL;PE6~wiZO|EVE2$##p zxX=eGI7F?YTOW<=wsg$*01RU_Hl&62)fB)|VQz+w(tJ9vJ zlO|Ed9iUlF>9prvnIQ@AM(H7r9>^wJ!p&EYfogH6z%ak?oi8Tb6wcCHdNm&b*)te& T?9lwEUFl7s($Pw*nqT?>x8YCQ literal 0 HcmV?d00001 diff --git a/test/testinput/cxwriter_ukvnamelist_radar_reflectivity.yaml b/test/testinput/cxwriter_ukvnamelist_radar_reflectivity.yaml new file mode 100644 index 00000000..3e614668 --- /dev/null +++ b/test/testinput/cxwriter_ukvnamelist_radar_reflectivity.yaml @@ -0,0 +1,41 @@ +time window: + begin: 2018-01-01T00:00:00Z + end: 2018-01-01T01:00:00Z + +observations: + - obs space: + name: RadarZ + obsdatain: + engine: + type: H5File + obsfile: Data/dummy.nc4 + simulated variables: [dummy] + geovals: + filename: Data/cx_ukvnamelist_radar_reflectivity.nc4 + obs filters: + # Set the flag of observations with missing values to "pass": we want to check if these + # values are encoded correctly in the Cx file. + - filter: Reset Flags to Pass + flags_to_reset: [10] # missing + # Reject observation 3: we want to check if it is omitted from the Cx file, as expected. + - filter: Domain Check + where: + - variable: + name: MetaData/latitude + minvalue: 0.0 + - filter: Cx Writer + namelist_directory: ../etc/ukv/cx + reject_obs_with_any_variable_failing_qc: true + general_mode: debug + geovals_are_top_to_bottom: false + - filter: Cx Checker + expected_surface_variables: ["1"] + expected_upper_air_variables: ["1","5","11","29","30","39","40"] + expected_main_table_columns: + - # observation 3 is rejected by the tests above hence only 3 (1,2,4) columns + - ["7.10","1.30","1.20","1.10","11.30","11.20","11.10","21.30","21.20","21.10","31.30","31.20","31.10","41.30","41.20","41.10","51.30","51.20","51.10","61.30","61.20","61.10"] + - ["**********","2.30","**********","2.10","12.30","**********","12.10","22.30","**********","22.10","32.30","**********","32.10","42.30","**********","42.10","52.30","**********","52.10","62.30","**********","62.10"] + - ["7.40","4.30","4.20","4.10","14.30","14.20","14.10","24.30","24.20","24.10","34.30","34.20","34.10","44.30","44.20","44.10","54.30","54.20","54.10","64.30","64.20","64.10"] + HofX: ObsValue # just a placeholder -- not used""but needed to force calls to postFilter. + benchmarkFlag: 1000 # just to keep the ObsFilters test happy + flaggedBenchmark: 0 diff --git a/test/testinput/varobs_ukvnamelist_radar_reflectivity.nc4 b/test/testinput/varobs_ukvnamelist_radar_reflectivity.nc4 new file mode 100644 index 0000000000000000000000000000000000000000..00c19f834bd682ebbc045db4895f4b03b753d75d GIT binary patch literal 12985 zcmeHNeQZ-z6u)h^u9WTr+#DN3i}(Quvug)o;KJIju!gO3ADW0U%iH?8J=3+Mds~p8 zEEm=iYl>>(c@nI;Fmw z_T6{xJ@4N8e&^i#?m6ea(B8J8++FXsyIhRYRhi!NixQu#m_FI`N>_VZkKJ?3eituu zl*uZ3#GJeB%!Vw^g?P1<;1!drBR#0-S~~TepjlNF-kg#QJ7g&&O8&lKZPW`t#hX&~aN7oNTpLkSqkyV+U`+R>(t5UPT*+w4 zKvHe+Qfgv2AUm{Q0j~oC>W``VU_8;(rj2NERt5SXF!A!iL7$Me?pVK2V7M^{Lx-q@ zrbKdh5X0OSO5IrESdJ~i&4g<{ayo2LDPWIy&_J;yKZ-&AB&&u&gAi%Z;dD9^*HVhE zj{c!z6ftzjQ*Ms$j@aI~FhJuGEVD3h+Mw{l!%8ZpCON2%8wC|d^yTW8kN#OL=kO6T zM)~#Ck{~5@zgxCIis{G?>3>TxoBy6-BKZBwFP`fPw{H@w$cKD#Gxmf;K&)~;_&*;+I+1uW7zn%+oS8l& z=`Vmj8%!jsLs%aO)P$yX*Mt&@2PNGCbPLdNNvlAsp+I1g(^I=ALo?HpKu<|}3h1d2 zjsYgt1g_4gK;@F22RXha;uEcb3nVPdrEy~B(q?{%Ek0@`3jqrO3jqrO3xWSV0w%+V ztSQ=!nR7CX#ExYdeuW`z6&Yi0x)Hf^5$3iM+QH6Arc*{{E z@${i(V1{=~6IzrpcJ}ed4irLYYHYQ&9cq2vAvtRX*y-`BWirLPfweLmk>UnBg$ZOWM3#pL7juk{5upZwb9Kx=oUdo zjOO%XIENod6n@ZFe&&=Kp!~JS;zV&M1Ifqev2l%sn=v(fIY>4zkV&O5oJ`>voU1j2rqMCz3~2fxl)iPo$}dM3gbg1m1O+~DUVQ+%4E7#=lq)T&(nVaa