diff --git a/Varfields.md b/Varfields.md index e64813d6..32735449 100644 --- a/Varfields.md +++ b/Varfields.md @@ -17,7 +17,7 @@ | 10 | `VarField_britemp` | `CorBriTemp(:,:)` | bias-corrected brightness temperatures | `BiasCorrObsValue/brightnessTemperature` | | | 11 | `VarField_tskin` | `Tskin(:)` | skin temperature | `OneDVar/skinTemperature` | | | 12 | `VarField_gpstzdelay` | `gpstzdelay(:)`| Ground based GNSS Total Zenith Delay | `BiasCorrObsValue/zenithTotalDelay` | | -| 15 | `VarField_cloud` | | | | Implement | +| 15 | `VarField_cloud` | `cloud(:,:)` | cloud fraction | `DerivedObsValue/cloudAmount`| | | 16 | `VarField_rainrate` | | | | Implement | | 17 | `VarField_mwemiss` | `Emissivity(:,:)` | surface emissivity | `Emiss/emissivity` | | | 18 | `VarField_tcozone` | `TCozone(:)` | total column ozone (Du) | `MetaData/ozoneTotal` | | diff --git a/deps/ops/code/OpsMod_Varobs/Ops_SetupVarArray.inc b/deps/ops/code/OpsMod_Varobs/Ops_SetupVarArray.inc index 76cab3ca..b3aa3f33 100644 --- a/deps/ops/code/OpsMod_Varobs/Ops_SetupVarArray.inc +++ b/deps/ops/code/OpsMod_Varobs/Ops_SetupVarArray.inc @@ -388,7 +388,7 @@ DO Ivar = 1, NumValidVarFields RArrVrbl1d => Ob % AMSUb_Temp CASE (VarField_cloud) ObHdrVrbl = Ob % header % Cloud - ObVrblMulti => Ob % Cloud + ObVrblMulti => Ob % Cloud(:,:) Pge_2D => Pge % Cloud CASE (VarField_rainrate) ObHdrVrbl = Ob % header % Rainrate diff --git a/etc/ukv/cx/SurfaceCloud.nl b/etc/ukv/cx/SurfaceCloud.nl new file mode 100644 index 00000000..44ee703f --- /dev/null +++ b/etc/ukv/cx/SurfaceCloud.nl @@ -0,0 +1,8 @@ +&CXControlNL +! Quantities for which H(x) is not calculated so GeoVaLs are used to produced CX columns. +! - multi-level +! 4 = theta, 10 = q, 12 = qcf, 254 = qcl, 407 = p, 9201 = cloud_layer +! - single-level +! 1 = pstar, 31 = seaice, 33 = orog, 9217 = CloudAmount +CxFields=1,4,10,12,31,33,254,407,9201,9217 +/ diff --git a/etc/ukv/varobs/SurfaceCloud.nl b/etc/ukv/varobs/SurfaceCloud.nl new file mode 100644 index 00000000..a9547200 --- /dev/null +++ b/etc/ukv/varobs/SurfaceCloud.nl @@ -0,0 +1,3 @@ +&VarobsControlNL +Varfields=15 +/ diff --git a/src/opsinputs/opsinputs_cxfields_mod.F90 b/src/opsinputs/opsinputs_cxfields_mod.F90 index f3992624..3ab39838 100644 --- a/src/opsinputs/opsinputs_cxfields_mod.F90 +++ b/src/opsinputs/opsinputs_cxfields_mod.F90 @@ -76,7 +76,7 @@ module opsinputs_cxfields_mod character(len=*), parameter, public :: opsinputs_cxfields_RainRate_layer = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_cloud_conv = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_qc_conv = opsinputs_cxfields_unknown -character(len=*), parameter, public :: opsinputs_cxfields_cloud_layer = opsinputs_cxfields_unknown +character(len=*), parameter, public :: opsinputs_cxfields_cloud_layer = "cloud_layer" character(len=*), parameter, public :: opsinputs_cxfields_ozone = opsinputs_cxfields_unknown character(len=*), parameter, public :: opsinputs_cxfields_qcf = var_cli character(len=*), parameter, public :: opsinputs_cxfields_qcl = var_clw diff --git a/src/opsinputs/opsinputs_varobswriter_mod.F90 b/src/opsinputs/opsinputs_varobswriter_mod.F90 index 78a20089..eeeb995a 100644 --- a/src/opsinputs/opsinputs_varobswriter_mod.F90 +++ b/src/opsinputs/opsinputs_varobswriter_mod.F90 @@ -963,6 +963,10 @@ subroutine opsinputs_varobswriter_populateobservations( & ! TODO(someone): handle this varfield ! call Ops_Alloc(Ob % Header % AMSUb_Temp, "AMSUb_Temp", Ob % Header % NumObsLocal, Ob % AMSUb_Temp) case (VarField_cloud) + call opsinputs_fill_fillelementtype2dfromnormalvariablewithlevels( & + Ob % Header % Cloud, "Cloud", Ob % Header % NumObsLocal, Ob % Cloud, & + ObsSpace, self % modlevs, "cloudAmount_", "DerivedObsValue", self % GeoVaLsAreTopToBottom, & + "cloudAmount_", "DerivedObsError") ! TODO(someone): handle this varfield ! call Ops_Alloc(Ob % Header % Cloud, "Cloud", Ob % Header % NumObsLocal, Ob % Cloud) case (VarField_rainrate) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ba40064d..880e0020 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -144,6 +144,9 @@ ADD_WRITER_TEST(NAME varobswriter_011_VarField_tskin ADD_WRITER_TEST(NAME varobswriter_012_VarField_gpstzdelay YAML 012_VarField_gpstzdelay.yaml DATA 012_VarField_gpstzdelay.nc4) +ADD_WRITER_TEST(NAME varobswriter_015_VarField_cloud + YAML 015_VarField_cloud.yaml + DATA 015_VarField_cloud.nc4) ADD_WRITER_TEST(NAME varobswriter_017_VarField_mwemiss YAML 017_VarField_mwemiss.yaml NAMELIST VarObsWriterNamelists_017_VarField_mwemiss/AMSUB.nl @@ -347,6 +350,10 @@ ADD_WRITER_TEST(NAME varobswriter_ukvnamelist_sonde YAML varobswriter_ukvnamelist_sonde.yaml NAMELIST ../../etc/ukv/varobs/Sonde.nl DATA varobs_ukvnamelist_sonde.nc4) +ADD_WRITER_TEST(NAME varobswriter_ukvnamelist_surfacecloud + YAML varobswriter_ukvnamelist_surfacecloud.yaml + NAMELIST ../../etc/ukv/varobs/SurfaceCloud.nl + DATA varobs_ukvnamelist_surfacecloud.nc4) ### CxWriter tests @@ -429,6 +436,10 @@ ADD_WRITER_TEST(NAME cxwriter_011_UpperAirCxField_P YAML 011_UpperAirCxField_P.yaml NAMELIST CxWriterNamelists_011_UpperAirCxField_P/AMSUB.nl DATA 011_UpperAirCxField_P.nc4 dummy.nc4) +ADD_WRITER_TEST(NAME cxwriter_015_UpperAirCxField_cloud_layer + YAML 015_UpperAirCxField_cloud_layer.yaml + NAMELIST CxWriterNamelists_015_UpperAirCxField_cloud_layer/SurfaceCloud.nl + DATA 015_UpperAirCxField_cloud_layer.nc4 dummy.nc4) ADD_WRITER_TEST(NAME cxwriter_029_UpperAirCxField_qcf YAML 029_UpperAirCxField_qcf.yaml NAMELIST CxWriterNamelists_029_UpperAirCxField_qcf/AMSUB.nl @@ -618,6 +629,10 @@ ADD_WRITER_TEST(NAME cxwriter_ukvnamelist_sonde YAML cxwriter_ukvnamelist_sonde.yaml NAMELIST ../../etc/ukv/cx/Sonde.nl DATA cx_ukvnamelist_sonde.nc4 dummy.nc4) +ADD_WRITER_TEST(NAME cxwriter_ukvnamelist_surfacecloud + YAML cxwriter_ukvnamelist_surfacecloud.yaml + NAMELIST ../../etc/ukv/cx/SurfaceCloud.nl + DATA cx_ukvnamelist_surfacecloud.nc4 dummy.nc4) ### Tests of auxiliary classes diff --git a/test/generate_unittest_netcdfs.py b/test/generate_unittest_netcdfs.py index a04c74ea..480fefd3 100644 --- a/test/generate_unittest_netcdfs.py +++ b/test/generate_unittest_netcdfs.py @@ -651,6 +651,7 @@ def copy_var_to_var(Group, invarname, outvarname, filename): output_1d_simulated_var_to_netcdf('precipitableWater', 'testinput/007_VarField_tcwv.nc4') output_2d_simulated_var_to_netcdf('brightnessTemperature', 'testinput/010_VarField_britemp.nc4', with_bias=True) output_1d_normal_var_to_netcdf ('skinTemperature', 'OneDVar', 'testinput/011_VarField_tskin.nc4') + output_2d_normal_var_to_netcdf ('cloudAmount', 'DerivedObsValue', 'testinput/015_VarField_cloud.nc4', use_chans=True) output_2d_normal_var_to_netcdf ('emissivity', 'Emiss', 'testinput/017_VarField_mwemiss.nc4', use_chans=True) output_1d_normal_var_to_netcdf ('ozoneTotal', 'MetaData', 'testinput/018_VarField_tcozone.nc4') output_1d_normal_var_to_netcdf ('sensorZenithAngle', 'MetaData', 'testinput/019_VarField_satzenith.nc4') @@ -765,6 +766,13 @@ def copy_var_to_var(Group, invarname, outvarname, filename): copy_var_to_var('ObsValue', 'potentialTemperature', 'airTemperature', 'testinput/varobs_ukvnamelist_sonde.nc4') copy_var_to_var('ObsError', 'potentialTemperature', 'airTemperature', 'testinput/varobs_ukvnamelist_sonde.nc4') + # SurfaceCloud - UKV + output_full_varobs_to_netcdf(['MetaData/latitude', + 'MetaData/longitude'], + ['ObsValue/cloud_layer', 'DerivedObsValue/cloudAmount', 'DerivedObsError/cloudAmount'], + [], + 'testinput/varobs_ukvnamelist_surfacecloud.nc4') + # Scatwind output_full_varobs_to_netcdf(['MetaData/latitude', 'MetaData/longitude'], ['ObsValue/windEastward', 'ObsError/windEastward', 'GrossErrorProbability/windEastward', @@ -830,6 +838,7 @@ def copy_var_to_var(Group, invarname, outvarname, filename): output_2d_geoval_to_netcdf ('specific_humidity', 'testinput/005_UpperAirCxField_q.nc4') output_2d_geoval_to_netcdf ('air_pressure', 'testinput/033_UpperAirCxField_p_bar.nc4') output_2d_geoval_to_netcdf ('air_pressure_levels', 'testinput/011_UpperAirCxField_P.nc4') + output_2d_geoval_to_netcdf ('cloud_layer', 'testinput/015_UpperAirCxField_cloud_layer.nc4') output_2d_geoval_to_netcdf ('mass_content_of_cloud_ice_in_atmosphere_layer', 'testinput/029_UpperAirCxField_qcf.nc4') output_2d_geoval_to_netcdf ('mass_content_of_cloud_liquid_water_in_atmosphere_layer', 'testinput/030_UpperAirCxField_qcl.nc4') output_2d_geoval_to_netcdf ('cloud_volume_fraction_in_atmosphere_layer', 'testinput/031_UpperAirCxField_cloud_bulk.nc4') @@ -904,7 +913,7 @@ def copy_var_to_var(Group, invarname, outvarname, filename): 'mass_content_of_cloud_liquid_water_in_atmosphere_layer', 'air_pressure_levels', 'cloud_volume_fraction_in_atmosphere_layer', 'liquid_cloud_volume_fraction_in_atmosphere_layer', 'ice_cloud_volume_fraction_in_atmosphere_layer'], 'testinput/cx_globalnamelist_ssmis.nc4') - + # MWSFY3 output_full_cx_to_netcdf(['skin_temperature','ice_area_fraction','surface_altitude','surface_pressure','uwind_at_10m', 'vwind_at_10m','surface_temperature','relative_humidity_2m','surface_pressure_at_mean_sea_level'], @@ -947,6 +956,16 @@ def copy_var_to_var(Group, invarname, outvarname, filename): 'ice_cloud_volume_fraction_in_atmosphere_layer'], 'testinput/cx_ukvnamelist_sonde.nc4') + # SurfaceCloud - UKV + output_full_cx_to_netcdf(['surface_altitude', + 'surface_pressure', + 'ice_area_fraction', + 'total_cloud_amount'], + ['potential_temperature', 'specific_humidity', 'air_pressure_levels', 'cloud_layer', + 'mass_content_of_cloud_ice_in_atmosphere_layer', + 'mass_content_of_cloud_liquid_water_in_atmosphere_layer'], + 'testinput/cx_ukvnamelist_surfacecloud.nc4') + # SatTCWV output_full_cx_to_netcdf(['surface_altitude', 'surface_pressure', 'ice_area_fraction', 'total_cloud_amount'], ['potential_temperature', 'specific_humidity', 'air_pressure_levels', 'mass_content_of_cloud_ice_in_atmosphere_layer', diff --git a/test/testinput/015_UpperAirCxField_cloud_layer.nc4 b/test/testinput/015_UpperAirCxField_cloud_layer.nc4 new file mode 100644 index 00000000..b675353f Binary files /dev/null and b/test/testinput/015_UpperAirCxField_cloud_layer.nc4 differ diff --git a/test/testinput/015_UpperAirCxField_cloud_layer.yaml b/test/testinput/015_UpperAirCxField_cloud_layer.yaml new file mode 100644 index 00000000..f429e61e --- /dev/null +++ b/test/testinput/015_UpperAirCxField_cloud_layer.yaml @@ -0,0 +1,40 @@ +window begin: 2018-01-01T00:00:00Z +window end: 2018-01-01T01:00:00Z + +observations: + - obs space: + name: SurfaceCloud + obsdatain: + engine: + type: H5File + obsfile: Data/dummy.nc4 + simulated variables: [dummy] + geovals: + filename: Data/015_UpperAirCxField_cloud_layer.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, 15] # missing, Hfailed + # 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: testinput/CxWriterNamelists_015_UpperAirCxField_cloud_layer + reject_obs_with_any_variable_failing_qc: true + general_mode: debug + IC_PLevels: 5 + - filter: Cx Checker + expected_surface_variables: [] + expected_upper_air_variables: ["15"] # IndexCxcloud_layer + expected_main_table_columns: + - # batch 1 + - ["1.10", "1.20", "1.30"] # column 1 + - ["2.10", "**********", "2.30"] # column 2 (the asterisks represent a missing float) + - ["4.10", "4.20", "4.30"] # column 3 + 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/015_VarField_cloud.nc4 b/test/testinput/015_VarField_cloud.nc4 new file mode 100644 index 00000000..4a3dee6c Binary files /dev/null and b/test/testinput/015_VarField_cloud.nc4 differ diff --git a/test/testinput/015_VarField_cloud.yaml b/test/testinput/015_VarField_cloud.yaml new file mode 100644 index 00000000..beb39e73 --- /dev/null +++ b/test/testinput/015_VarField_cloud.yaml @@ -0,0 +1,58 @@ +window begin: 2018-01-01T00:00:00Z +window end: 2018-01-01T02:00:00Z + +observations: + - obs space: + name: SurfaceCloud + obsdatain: + engine: + type: H5File + obsfile: Data/015_VarField_cloud.nc4 + simulated variables: [dummy] + channels: 1-3 + 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 + namelist_directory: ../etc/ukv/varobs + general_mode: debug + IC_PLevels: 3 + geovals_are_top_to_bottom: false + - filter: VarObs Checker + expected_main_table_columns: + # In the arrays below, rows denote locations and columns channels. + field: ["15", "15", "15", + "15", "15", "15", + "15", "15", "15", + "15", "15", "15"] + ob value: ["4.10000" ,"5.10000","6.10000", + "-1073741824.00000","5.20000","6.20000", + "4.30000" ,"5.30000","6.30000", + "4.40000" ,"5.40000","6.40000"] + lat: ["21.00000", "21.00000", "21.00000", + "22.00000", "22.00000", "22.00000", + "-23.00000", "-23.00000", "-23.00000", + "24.00000", "24.00000", "24.00000"] + lon: ["31.00000", "31.00000", "31.00000", + "32.00000", "32.00000", "32.00000", + "33.00000", "33.00000", "33.00000", + "34.00000", "34.00000", "34.00000"] + time: ["-3540.00000", "-3540.00000", "-3540.00000", + "-3480.00000", "-3480.00000", "-3480.00000", + "-3420.00000", "-3420.00000", "-3420.00000", + "-3360.00000", "-3360.00000", "-3360.00000"] + Callsign: ["station_1", "station_1", "station_1", + "station_2", "station_2", "station_2", + "station_3", "station_3", "station_3", + "station_4", "station_4", "station_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_015_UpperAirCxField_cloud_layer/SurfaceCloud.nl b/test/testinput/CxWriterNamelists_015_UpperAirCxField_cloud_layer/SurfaceCloud.nl new file mode 100644 index 00000000..3b02cd57 --- /dev/null +++ b/test/testinput/CxWriterNamelists_015_UpperAirCxField_cloud_layer/SurfaceCloud.nl @@ -0,0 +1,3 @@ +&CXControlNL +CxFields=9201 +/ diff --git a/test/testinput/VarObsWriterNamelists_015_VarField_cloud/SurfaceCloud.nl b/test/testinput/VarObsWriterNamelists_015_VarField_cloud/SurfaceCloud.nl new file mode 100644 index 00000000..a9547200 --- /dev/null +++ b/test/testinput/VarObsWriterNamelists_015_VarField_cloud/SurfaceCloud.nl @@ -0,0 +1,3 @@ +&VarobsControlNL +Varfields=15 +/ diff --git a/test/testinput/cx_ukvnamelist_surfacecloud.nc4 b/test/testinput/cx_ukvnamelist_surfacecloud.nc4 new file mode 100644 index 00000000..6ab22c29 Binary files /dev/null and b/test/testinput/cx_ukvnamelist_surfacecloud.nc4 differ diff --git a/test/testinput/cxwriter_ukvnamelist_surfacecloud.yaml b/test/testinput/cxwriter_ukvnamelist_surfacecloud.yaml new file mode 100644 index 00000000..f540fbba --- /dev/null +++ b/test/testinput/cxwriter_ukvnamelist_surfacecloud.yaml @@ -0,0 +1,46 @@ +window begin: 2018-01-01T00:00:00Z +window end: 2018-01-01T01:00:00Z + +observations: + - obs space: + name: SurfaceCloud + obsdatain: + engine: + type: H5File + obsfile: Data/dummy.nc4 + simulated variables: [dummy] + geovals: + filename: Data/cx_ukvnamelist_surfacecloud.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","2","17","24"] + expected_upper_air_variables: ["1","5","11","15","29","30"] + expected_main_table_columns: + - # observation 3 is rejected by the tests above hence only 3 (1,2,4) columns + - ["7.10","17.10","27.10","37.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"] + - ["**********","**********","**********","**********","2.30","**********","2.10","12.30", + "**********","12.10","22.30","**********","22.10","32.30","**********","32.10","42.30", + "**********","42.10","52.30","**********","52.10"] + - ["7.40","17.40","27.40","37.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"] + 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_surfacecloud.nc4 b/test/testinput/varobs_ukvnamelist_surfacecloud.nc4 new file mode 100644 index 00000000..b19c73a5 Binary files /dev/null and b/test/testinput/varobs_ukvnamelist_surfacecloud.nc4 differ diff --git a/test/testinput/varobswriter_ukvnamelist_surfacecloud.yaml b/test/testinput/varobswriter_ukvnamelist_surfacecloud.yaml new file mode 100644 index 00000000..09cbd69b --- /dev/null +++ b/test/testinput/varobswriter_ukvnamelist_surfacecloud.yaml @@ -0,0 +1,57 @@ +window begin: 2018-01-01T00:00:00Z +window end: 2018-01-01T02:00:00Z + +observations: + - obs space: + name: SurfaceCloud + obsdatain: + engine: + type: H5File + obsfile: Data/varobs_ukvnamelist_surfacecloud.nc4 + simulated variables: [cloud_layer, cloudAmount] + observed variables: [] + derived variables: [cloud_layer, cloudAmount] + channels: 1-3 + 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] # missing + # Blacklist all missing entries in the original profiles (i.e. observation 2) + # This must be run after the Reset Flags to Pass filter, + # which sets the flags of any missing values in the original profiles + # to 'pass'. Therefore this filter is run with the 'defer to post' option set to true. + - filter: BlackList + where: + - variable: + name: MetaData/latitude + is_not_defined: + defer to post: true + - filter: VarObs Writer + namelist_directory: ../etc/ukv/varobs + general_mode: debug + IC_PLevels: 3 + reject_obs_with_all_variables_failing_qc: true + - filter: VarObs Checker + expected_main_table_columns: + # Rows are locations, columns are filter variables + # The blacklist prevents the missing ob from being written out + field: [15,15,15, + 15,15,15, + 15,15,15, + 15,15,15] + ob value: ["11.30000","11.20000","11.10000", + "12.30000","-1073741824.00000","12.10000", + "13.30000","13.20000","13.10000", + "14.30000","14.20000","14.10000"] + lat: ["7.10000","7.10000","7.10000", + "-1073741824.00000","-1073741824.00000","-1073741824.00000", + "7.30000","7.30000","7.30000", + "7.40000","7.40000","7.40000"] + lon: ["17.10000","17.10000","17.10000", + "-1073741824.00000","-1073741824.00000","-1073741824.00000", + "17.30000","17.30000","17.30000", + "17.40000","17.40000","17.40000"] + 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