diff --git a/parm/soca/berror/soca_diagb.yaml.j2 b/parm/soca/berror/soca_diagb.yaml.j2 index 8c394d67c..1493ea1d4 100644 --- a/parm/soca/berror/soca_diagb.yaml.j2 +++ b/parm/soca/berror/soca_diagb.yaml.j2 @@ -26,35 +26,12 @@ max ssh: 0.0 # Limits the amplitude of the unbalanced bkg err min depth: 500.0 # zero out the bkg. error. at less than min depth number of halo points: 4 number of neighbors: 16 + simple smoothing: horizontal iterations: 10 vertical iterations: 1 -# TODO(G): Start using when the normalization is optional +# TODO(G): Too slow for the below scale #diffusion: -# saber block name: EXPLICIT_DIFFUSION -# active variables: [tocn, socn, ssh, cicen, hicen, hsnon] -# geometry: -# mom6_input_nml: mom_input.nml -# fields metadata: ./fields_metadata.yaml -# group mapping: -# - name: ocean -# variables: -# - tocn -# - socn -# - ssh -# - name: ice -# variables: -# - cicen -# - hicen -# - hsnon -# read: -# groups: -# - name: ocean -# horizontal: -# filename: hz_ocean.nc -# vertical: -# filename: vt_ocean.nc -# - name: ice -# horizontal: -# filename: hz_ice.nc +# horizontal: 500.0e3 +# vertical: 3.0 diff --git a/parm/soca/fields_metadata.yaml b/parm/soca/fields_metadata.yaml index d239c4000..586d8557e 100644 --- a/parm/soca/fields_metadata.yaml +++ b/parm/soca/fields_metadata.yaml @@ -75,7 +75,7 @@ - name: hicen getval name: sea_ice_category_thickness io file: ice - io name: hicen + io name: hi_h property: positive_definite fill value: 0.0 @@ -83,13 +83,13 @@ getval name: sea_ice_category_area_fraction getval name surface: sea_ice_area_fraction # note: not accurate, should be "sum" not "surface" io file: ice - io name: aicen + io name: aice_h fill value: 0.0 - name: hsnon getval name: sea_ice_category_snow_thickness io file: ice - io name: hsnon + io name: hs_h property: positive_definite fill value: 0.0 diff --git a/parm/soca/obs/config/insitu_profile_argo.yaml b/parm/soca/obs/config/insitu_profile_argo.yaml index 9b054931f..617d494c5 100644 --- a/parm/soca/obs/config/insitu_profile_argo.yaml +++ b/parm/soca/obs/config/insitu_profile_argo.yaml @@ -15,7 +15,7 @@ obs space: obsfile: !ENV ${DATA}/diags/insitu_profile_argo.${PDY}${cyc}.nc4 simulated variables: [waterTemperature, salinity] observed variables: [waterTemperature, salinity] - derived variables: [waterPressure] +# derived variables: [waterPressure] io pool: max pool size: 1 obs operator: @@ -181,83 +181,83 @@ obs filters: #------------------------------------------------------------------------------- ### Spike test #----------------------------------------------------------------------------- - - filter: Create Diagnostic Flags - filter variables: - - name: waterTemperature - - name: salinity - flags: - - name: spike - initial value: false - - name: step - initial value: false - - - filter: Spike and Step Check - filter variables: - - name: ObsValue/waterTemperature - dependent: ObsValue/waterTemperature # dy/ - independent: MetaData/depth # dx - count spikes: true - count steps: true - tolerance: - nominal value: 10 # K nominal, in the case of temperature (not really) - gradient: 0.1 # K/m - if dy/dx greater, could be a spike - gradient x resolution: 10 # m - can't know dx to better precision - factors: [1,1,0.5] # multiply tolerance, for ranges bounded by... - x boundaries: [0,500,500] # ...these values of x (depth in m) - boundary layer: - x range: [0.0,300.0] # when bounded by these x values (depth in m)... - step tolerance range: [0.0,-2.0] # ...relax tolerance for steps in boundary layer... - maximum x interval: [50.0,100.0] # ...and ignore level if dx greater than this - action: - name: reject - - #### Count spikes - #----------------------------------------------------------------------------- - - filter: Variable Assignment # create derived obs value containing only T spikes - assignments: - - name: DerivedMetaData/waterTemperature_spikes - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: DiagnosticFlags/spike/waterTemperature - value: is_true - - #### Count steps - #----------------------------------------------------------------------------- - - filter: Variable Assignment # create derived obs value containing only T steps - assignments: - - name: DerivedMetaData/waterTemperature_steps - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: DiagnosticFlags/step/waterTemperature - value: is_true - #### Count total rejections - #----------------------------------------------------------------------------- - - filter: Variable Assignment # compute sum 2*spikes+steps - assignments: - - name: DerivedMetaData/waterTemperature_rejections - type: int - function: - name: IntObsFunction/LinearCombination - options: - variables: [DerivedMetaData/waterTemperature_spikes, DerivedMetaData/waterTemperature_steps] - coefs: [2,1] - #### Reject entire profile if total rejctions > threshold - #----------------------------------------------------------------------------- - - filter: Perform Action # reject whole profile if 2*spikes+steps>=rejection threshold - where: - - variable: - name: DerivedMetaData/waterTemperature_rejections - minvalue: 3 - action: - name: reject +# - filter: Create Diagnostic Flags +# filter variables: +# - name: waterTemperature +# - name: salinity +# flags: +# - name: spike +# initial value: false +# - name: step +# initial value: false +# +# - filter: Spike and Step Check +# filter variables: +# - name: ObsValue/waterTemperature +# dependent: ObsValue/waterTemperature # dy/ +# independent: MetaData/depth # dx +# count spikes: true +# count steps: true +# tolerance: +# nominal value: 10 # K nominal, in the case of temperature (not really) +# gradient: 0.1 # K/m - if dy/dx greater, could be a spike +# gradient x resolution: 10 # m - can't know dx to better precision +# factors: [1,1,0.5] # multiply tolerance, for ranges bounded by... +# x boundaries: [0,500,500] # ...these values of x (depth in m) +# boundary layer: +# x range: [0.0,300.0] # when bounded by these x values (depth in m)... +# step tolerance range: [0.0,-2.0] # ...relax tolerance for steps in boundary layer... +# maximum x interval: [50.0,100.0] # ...and ignore level if dx greater than this +# action: +# name: reject +# +# #### Count spikes +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # create derived obs value containing only T spikes +# assignments: +# - name: DerivedMetaData/waterTemperature_spikes +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: DiagnosticFlags/spike/waterTemperature +# value: is_true +# +# #### Count steps +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # create derived obs value containing only T steps +# assignments: +# - name: DerivedMetaData/waterTemperature_steps +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: DiagnosticFlags/step/waterTemperature +# value: is_true +# #### Count total rejections +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # compute sum 2*spikes+steps +# assignments: +# - name: DerivedMetaData/waterTemperature_rejections +# type: int +# function: +# name: IntObsFunction/LinearCombination +# options: +# variables: [DerivedMetaData/waterTemperature_spikes, DerivedMetaData/waterTemperature_steps] +# coefs: [2,1] +# #### Reject entire profile if total rejctions > threshold +# #----------------------------------------------------------------------------- +# - filter: Perform Action # reject whole profile if 2*spikes+steps>=rejection threshold +# where: +# - variable: +# name: DerivedMetaData/waterTemperature_rejections +# minvalue: 3 +# action: +# name: reject #------------------------------------------------------------------------------- ## Filters for S: @@ -392,70 +392,70 @@ obs filters: #------------------------------------------------------------------------------- ### Spike test #----------------------------------------------------------------------------- - - filter: Spike and Step Check - filter variables: - - name: ObsValue/salinity - dependent: ObsValue/salinity # dy/ - independent: MetaData/depth # dx - count spikes: true - count steps: true - tolerance: - nominal value: 1.0 # PSU nominal, in the case of salinity (not really) - threshold: 0.6 # weird salinity thing - factors: [1,1,0.2] # multiply tolerance, for ranges bounded by... - x boundaries: [0,200,600] # ...these values of x (depth in m) - boundary layer: - x range: [0.0,300.0] # when bounded by these x values (depth in m)... - maximum x interval: [50.0,100.0] # ...and ignore level if dx greater than this - action: - name: reject - - #### Count spikes - #----------------------------------------------------------------------------- - - filter: Variable Assignment # create derived obs value containing only S spikes - assignments: - - name: DerivedMetaData/salinity_spikes - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: DiagnosticFlags/spike/salinity - value: is_true - #### Count steps - #----------------------------------------------------------------------------- - - filter: Variable Assignment # create derived obs value containing only S steps - assignments: - - name: DerivedMetaData/salinity_steps - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: DiagnosticFlags/step/salinity - value: is_true - #### Count total rejections - #----------------------------------------------------------------------------- - - filter: Variable Assignment # compute sum 2*spikes+steps - assignments: - - name: DerivedMetaData/salinity_rejections - type: int - function: - name: IntObsFunction/LinearCombination - options: - variables: [DerivedMetaData/salinity_spikes, DerivedMetaData/salinity_steps] - coefs: [2,1] - #### Reject entire profile if total rejctions > threshold - #----------------------------------------------------------------------------- - - filter: Perform Action # reject whole profile if 2*spikes+steps>=rejection threshold - where: - - variable: - name: DerivedMetaData/salinity_rejections - minvalue: 3 - action: - name: reject +# - filter: Spike and Step Check +# filter variables: +# - name: ObsValue/salinity +# dependent: ObsValue/salinity # dy/ +# independent: MetaData/depth # dx +# count spikes: true +# count steps: true +# tolerance: +# nominal value: 1.0 # PSU nominal, in the case of salinity (not really) +# threshold: 0.6 # weird salinity thing +# factors: [1,1,0.2] # multiply tolerance, for ranges bounded by... +# x boundaries: [0,200,600] # ...these values of x (depth in m) +# boundary layer: +# x range: [0.0,300.0] # when bounded by these x values (depth in m)... +# maximum x interval: [50.0,100.0] # ...and ignore level if dx greater than this +# action: +# name: reject +# +# #### Count spikes +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # create derived obs value containing only S spikes +# assignments: +# - name: DerivedMetaData/salinity_spikes +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: DiagnosticFlags/spike/salinity +# value: is_true +# #### Count steps +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # create derived obs value containing only S steps +# assignments: +# - name: DerivedMetaData/salinity_steps +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: DiagnosticFlags/step/salinity +# value: is_true +# #### Count total rejections +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment # compute sum 2*spikes+steps +# assignments: +# - name: DerivedMetaData/salinity_rejections +# type: int +# function: +# name: IntObsFunction/LinearCombination +# options: +# variables: [DerivedMetaData/salinity_spikes, DerivedMetaData/salinity_steps] +# coefs: [2,1] +# #### Reject entire profile if total rejctions > threshold +# #----------------------------------------------------------------------------- +# - filter: Perform Action # reject whole profile if 2*spikes+steps>=rejection threshold +# where: +# - variable: +# name: DerivedMetaData/salinity_rejections +# minvalue: 3 +# action: +# name: reject #------------------------------------------------------------------------------- ### End of Spike test #----------------------------------------------------------------------------- @@ -469,126 +469,126 @@ obs filters: #### get pressure from depth #----------------------------------------------------------------------------- - - filter: Variable Transforms - Transform: OceanDepthToPressure - ocean depth variable: depth - ocean depth group: MetaData - #### Create diagonostic flags for spike step - #----------------------------------------------------------------------------- - - filter: Create Diagnostic Flags - filter variables: - - name: DerivedObsValue/waterPressure - flags: - - name: DensitySpike - initial value: false - - name: DensityStep - initial value: false - - name: Superadiabat - initial value: false - #### - #----------------------------------------------------------------------------- - - filter: Ocean Vertical Stability Check - where: - - variable: - name: ObsValue/waterTemperature - value: is_valid - filter variables: - - name: DerivedObsValue/waterPressure # density spikes/steps --> flag d - variables: - temperature: ObsValue/waterTemperature - salinity: ObsValue/salinity - pressure: DerivedObsValue/waterPressure - count spikes: true - count steps: true - nominal tolerance: -0.05 - threshold: 0.25 - actions: - - name: set - flag: Superadiabat - - name: reject - #### where there are any density inversions, reject temperature only: - #----------------------------------------------------------------------------- - - filter: Perform Action - filter variables: - - name: ObsValue/waterTemperature - where: - - variable: - name: DiagnosticFlags/Superadiabat/waterPressure - value: is_true - action: - name: reject - #### where density spikes, reject all vars (temperature and salinity): - #----------------------------------------------------------------------------- - - filter: Perform Action - filter variables: - - name: ObsValue/waterTemperature - - name: ObsValue/salinity - where: - - variable: - name: DiagnosticFlags/DensitySpike/waterPressure - value: is_true - action: - name: reject - #### create derived metadata counting levels: - #----------------------------------------------------------------------------- - - filter: Variable Assignment - assignments: - - name: DerivedMetaData/number_of_levels - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: ObsValue/waterTemperature - value: is_valid - #### create derived metadata counting spikes and steps: - #----------------------------------------------------------------------------- - - filter: Variable Assignment - assignments: - - name: DerivedMetaData/ocean_density_inversions - type: int - function: - name: IntObsFunction/ProfileLevelCount - options: - where: - - variable: - name: DiagnosticFlags/DensitySpike/waterPressure - value: is_true - - variable: - name: DiagnosticFlags/DensityStep/waterPressure - value: is_true - where operator: or - - #### whole profile is rejected if spikes+steps >= numlev/4, so compute - #### 4*( sum spikes+steps ) minus numlev - #### in order to check it against 0: - #----------------------------------------------------------------------------- - - filter: Variable Assignment - assignments: - - name: DerivedMetaData/ocean_density_rejections - type: int - function: - name: IntObsFunction/LinearCombination - options: - variables: [DerivedMetaData/ocean_density_inversions, DerivedMetaData/number_of_levels] - coefs: [4, -1] - #### reject whole profile if spikes+steps >= numlev/4 AND >= 2: - #----------------------------------------------------------------------------- - - filter: Perform Action - filter variables: - - name: ObsValue/waterTemperature - - name: ObsValue/salinity - where: - - variable: - name: DerivedMetaData/ocean_density_rejections - minvalue: 0 - - variable: - name: DerivedMetaData/ocean_density_inversions - minvalue: 2 - where operator: and - action: - name: reject +# - filter: Variable Transforms +# Transform: OceanDepthToPressure +# ocean depth variable: depth +# ocean depth group: MetaData +# #### Create diagonostic flags for spike step +# #----------------------------------------------------------------------------- +# - filter: Create Diagnostic Flags +# filter variables: +# - name: DerivedObsValue/waterPressure +# flags: +# - name: DensitySpike +# initial value: false +# - name: DensityStep +# initial value: false +# - name: Superadiabat +# initial value: false +# #### +# #----------------------------------------------------------------------------- +# - filter: Ocean Vertical Stability Check +# where: +# - variable: +# name: ObsValue/waterTemperature +# value: is_valid +# filter variables: +# - name: DerivedObsValue/waterPressure # density spikes/steps --> flag d +# variables: +# temperature: ObsValue/waterTemperature +# salinity: ObsValue/salinity +# pressure: DerivedObsValue/waterPressure +# count spikes: true +# count steps: true +# nominal tolerance: -0.05 +# threshold: 0.25 +# actions: +# - name: set +# flag: Superadiabat +# - name: reject +# #### where there are any density inversions, reject temperature only: +# #----------------------------------------------------------------------------- +# - filter: Perform Action +# filter variables: +# - name: ObsValue/waterTemperature +# where: +# - variable: +# name: DiagnosticFlags/Superadiabat/waterPressure +# value: is_true +# action: +# name: reject +# #### where density spikes, reject all vars (temperature and salinity): +# #----------------------------------------------------------------------------- +# - filter: Perform Action +# filter variables: +# - name: ObsValue/waterTemperature +# - name: ObsValue/salinity +# where: +# - variable: +# name: DiagnosticFlags/DensitySpike/waterPressure +# value: is_true +# action: +# name: reject +# #### create derived metadata counting levels: +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment +# assignments: +# - name: DerivedMetaData/number_of_levels +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: ObsValue/waterTemperature +# value: is_valid +# #### create derived metadata counting spikes and steps: +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment +# assignments: +# - name: DerivedMetaData/ocean_density_inversions +# type: int +# function: +# name: IntObsFunction/ProfileLevelCount +# options: +# where: +# - variable: +# name: DiagnosticFlags/DensitySpike/waterPressure +# value: is_true +# - variable: +# name: DiagnosticFlags/DensityStep/waterPressure +# value: is_true +# where operator: or +# +# #### whole profile is rejected if spikes+steps >= numlev/4, so compute +# #### 4*( sum spikes+steps ) minus numlev +# #### in order to check it against 0: +# #----------------------------------------------------------------------------- +# - filter: Variable Assignment +# assignments: +# - name: DerivedMetaData/ocean_density_rejections +# type: int +# function: +# name: IntObsFunction/LinearCombination +# options: +# variables: [DerivedMetaData/ocean_density_inversions, DerivedMetaData/number_of_levels] +# coefs: [4, -1] +# #### reject whole profile if spikes+steps >= numlev/4 AND >= 2: +# #----------------------------------------------------------------------------- +# - filter: Perform Action +# filter variables: +# - name: ObsValue/waterTemperature +# - name: ObsValue/salinity +# where: +# - variable: +# name: DerivedMetaData/ocean_density_rejections +# minvalue: 0 +# - variable: +# name: DerivedMetaData/ocean_density_inversions +# minvalue: 2 +# where operator: and +# action: +# name: reject #------------------------------------------------------------------------------- ### End of ocean vertical stability test #----------------------------------------------------------------------------- @@ -601,3 +601,27 @@ obs filters: - variable: QCflagsData/waterTemperature minvalue: 1 defer to post: true + + #-------------------------------------------------------------------------- + ### Set in situ obs multiplier coef for T,S + #-------------------------------------------------------------------------- + - filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 + - filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/salinity + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_bathy.yaml b/parm/soca/obs/config/insitu_profile_bathy.yaml index 8742f44fc..03fa7df0a 100644 --- a/parm/soca/obs/config/insitu_profile_bathy.yaml +++ b/parm/soca/obs/config/insitu_profile_bathy.yaml @@ -15,3 +15,14 @@ obs operator: name: InsituTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_dbuoy.yaml b/parm/soca/obs/config/insitu_profile_dbuoy.yaml index 5f81902e2..5946b0ac8 100644 --- a/parm/soca/obs/config/insitu_profile_dbuoy.yaml +++ b/parm/soca/obs/config/insitu_profile_dbuoy.yaml @@ -20,3 +20,15 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 + diff --git a/parm/soca/obs/config/insitu_profile_dbuoyb.yaml b/parm/soca/obs/config/insitu_profile_dbuoyb.yaml index 29052312a..b4796a87b 100644 --- a/parm/soca/obs/config/insitu_profile_dbuoyb.yaml +++ b/parm/soca/obs/config/insitu_profile_dbuoyb.yaml @@ -20,3 +20,14 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_glider.yaml b/parm/soca/obs/config/insitu_profile_glider.yaml index 17242b585..36a2b9b9a 100644 --- a/parm/soca/obs/config/insitu_profile_glider.yaml +++ b/parm/soca/obs/config/insitu_profile_glider.yaml @@ -20,3 +20,15 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 + diff --git a/parm/soca/obs/config/insitu_profile_marinemammal.yaml b/parm/soca/obs/config/insitu_profile_marinemammal.yaml index 682b02f0a..2b92a47c2 100644 --- a/parm/soca/obs/config/insitu_profile_marinemammal.yaml +++ b/parm/soca/obs/config/insitu_profile_marinemammal.yaml @@ -20,3 +20,14 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_mbuoy.yaml b/parm/soca/obs/config/insitu_profile_mbuoy.yaml index c2b2ca614..4bd80363b 100644 --- a/parm/soca/obs/config/insitu_profile_mbuoy.yaml +++ b/parm/soca/obs/config/insitu_profile_mbuoy.yaml @@ -20,3 +20,14 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_mbuoyb.yaml b/parm/soca/obs/config/insitu_profile_mbuoyb.yaml index f8ad55e6d..6cd2d6f00 100644 --- a/parm/soca/obs/config/insitu_profile_mbuoyb.yaml +++ b/parm/soca/obs/config/insitu_profile_mbuoyb.yaml @@ -20,3 +20,14 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_tesac.yaml b/parm/soca/obs/config/insitu_profile_tesac.yaml index bc8342dc8..20920b8a3 100644 --- a/parm/soca/obs/config/insitu_profile_tesac.yaml +++ b/parm/soca/obs/config/insitu_profile_tesac.yaml @@ -18,3 +18,14 @@ obs operator: - name: InsituTemperature variables: - name: waterTemperature +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_tesac_salinity.yaml b/parm/soca/obs/config/insitu_profile_tesac_salinity.yaml index 9190e46ef..41e2b3fb7 100644 --- a/parm/soca/obs/config/insitu_profile_tesac_salinity.yaml +++ b/parm/soca/obs/config/insitu_profile_tesac_salinity.yaml @@ -20,3 +20,14 @@ obs operator: interpolation method: linear obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/salinity + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_profile_xbtctd.yaml b/parm/soca/obs/config/insitu_profile_xbtctd.yaml index a868fc8c7..ce4b26744 100644 --- a/parm/soca/obs/config/insitu_profile_xbtctd.yaml +++ b/parm/soca/obs/config/insitu_profile_xbtctd.yaml @@ -20,3 +20,14 @@ obs operator: - name: waterTemperature obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/waterTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_surface_altkob.yaml b/parm/soca/obs/config/insitu_surface_altkob.yaml index d39bf59b1..9ef833f6f 100644 --- a/parm/soca/obs/config/insitu_surface_altkob.yaml +++ b/parm/soca/obs/config/insitu_surface_altkob.yaml @@ -16,3 +16,14 @@ obs operator: observation alias file: obsop_name_map.yaml obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/seaSurfaceTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_surface_trkob.yaml b/parm/soca/obs/config/insitu_surface_trkob.yaml index e35230223..a2ec408c0 100644 --- a/parm/soca/obs/config/insitu_surface_trkob.yaml +++ b/parm/soca/obs/config/insitu_surface_trkob.yaml @@ -16,3 +16,14 @@ obs operator: observation alias file: ./obsop_name_map.yaml obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/seaSurfaceTemperature + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/insitu_surface_trkob_salinity.yaml b/parm/soca/obs/config/insitu_surface_trkob_salinity.yaml index f32e66588..40c9a315c 100644 --- a/parm/soca/obs/config/insitu_surface_trkob_salinity.yaml +++ b/parm/soca/obs/config/insitu_surface_trkob_salinity.yaml @@ -16,3 +16,14 @@ obs operator: observation alias file: ./obsop_name_map.yaml obs error: covariance model: diagonal +obs filters: +- filter: Perform Action + action: + name: assign error + error function: + name: ObsFunction/LinearCombination + options: + variables: + - ObsError/seaSurfaceSalinity + coefs: + - 1000.0 diff --git a/parm/soca/obs/config/sst_abi_g16_l3c.yaml b/parm/soca/obs/config/sst_abi_g16_l3c.yaml index b9d999843..31be05739 100644 --- a/parm/soca/obs/config/sst_abi_g16_l3c.yaml +++ b/parm/soca/obs/config/sst_abi_g16_l3c.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_abi_g17_l3c.yaml b/parm/soca/obs/config/sst_abi_g17_l3c.yaml index a7ada5774..8cab63227 100644 --- a/parm/soca/obs/config/sst_abi_g17_l3c.yaml +++ b/parm/soca/obs/config/sst_abi_g17_l3c.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_ahi_h08_l3c.yaml b/parm/soca/obs/config/sst_ahi_h08_l3c.yaml index ed0efd721..a9891720e 100644 --- a/parm/soca/obs/config/sst_ahi_h08_l3c.yaml +++ b/parm/soca/obs/config/sst_ahi_h08_l3c.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_avhrr_ma_l3u.yaml b/parm/soca/obs/config/sst_avhrr_ma_l3u.yaml index 73c048891..e156e49c0 100644 --- a/parm/soca/obs/config/sst_avhrr_ma_l3u.yaml +++ b/parm/soca/obs/config/sst_avhrr_ma_l3u.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_avhrr_mb_l3u.yaml b/parm/soca/obs/config/sst_avhrr_mb_l3u.yaml index ccac3cc4e..1207c8d93 100644 --- a/parm/soca/obs/config/sst_avhrr_mb_l3u.yaml +++ b/parm/soca/obs/config/sst_avhrr_mb_l3u.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_avhrr_mc_l3u.yaml b/parm/soca/obs/config/sst_avhrr_mc_l3u.yaml index 9c34bcd56..9679dda63 100644 --- a/parm/soca/obs/config/sst_avhrr_mc_l3u.yaml +++ b/parm/soca/obs/config/sst_avhrr_mc_l3u.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_viirs_n20_l3u.yaml b/parm/soca/obs/config/sst_viirs_n20_l3u.yaml index 04021235f..60a33c438 100644 --- a/parm/soca/obs/config/sst_viirs_n20_l3u.yaml +++ b/parm/soca/obs/config/sst_viirs_n20_l3u.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/config/sst_viirs_npp_l3u.yaml b/parm/soca/obs/config/sst_viirs_npp_l3u.yaml index 6df13028a..1727a2e2d 100644 --- a/parm/soca/obs/config/sst_viirs_npp_l3u.yaml +++ b/parm/soca/obs/config/sst_viirs_npp_l3u.yaml @@ -40,10 +40,10 @@ obs filters: where: - variable: {name: GeoVaLs/sea_surface_temperature} minvalue: -1.0 -#- filter: Domain Check -# where: -# - variable: {name: GeoVaLs/distance_from_coast} -# minvalue: 100e3 +- filter: Domain Check + where: + - variable: {name: GeoVaLs/distance_from_coast} + minvalue: 100e3 - filter: Perform Action action: name: assign error @@ -53,4 +53,4 @@ obs filters: variables: - ObsError/seaSurfaceTemperature coefs: - - 0.05 + - 1.0 diff --git a/parm/soca/obs/obs_list.yaml b/parm/soca/obs/obs_list.yaml index f7be24da5..3eb1d2bd1 100644 --- a/parm/soca/obs/obs_list.yaml +++ b/parm/soca/obs/obs_list.yaml @@ -17,16 +17,16 @@ observers: - !INC ${OBS_YAML_DIR}/icec_amsr2_south.yaml # in situ: monthly -- !INC ${OBS_YAML_DIR}/insitu_profile_bathy.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_bathy.yaml - !INC ${OBS_YAML_DIR}/insitu_profile_argo.yaml -- !INC ${OBS_YAML_DIR}/insitu_profile_glider.yaml -- !INC ${OBS_YAML_DIR}/insitu_profile_tesac.yaml -- !INC ${OBS_YAML_DIR}/insitu_profile_tesac_salinity.yaml -- !INC ${OBS_YAML_DIR}/insitu_profile_marinemammal.yaml -- !INC ${OBS_YAML_DIR}/insitu_profile_xbtctd.yaml -- !INC ${OBS_YAML_DIR}/insitu_surface_altkob.yaml -- !INC ${OBS_YAML_DIR}/insitu_surface_trkob.yaml -- !INC ${OBS_YAML_DIR}/insitu_surface_trkob_salinity.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_glider.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_tesac.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_tesac_salinity.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_marinemammal.yaml +#- !INC ${OBS_YAML_DIR}/insitu_profile_xbtctd.yaml +#- !INC ${OBS_YAML_DIR}/insitu_surface_altkob.yaml +#- !INC ${OBS_YAML_DIR}/insitu_surface_trkob.yaml +#- !INC ${OBS_YAML_DIR}/insitu_surface_trkob_salinity.yaml # in situ: daily #- !INC ${OBS_YAML_DIR}/insitu_profile_dbuoy.yaml diff --git a/parm/soca/obsop_name_map.yaml b/parm/soca/obsop_name_map.yaml new file mode 100644 index 000000000..150ded8b5 --- /dev/null +++ b/parm/soca/obsop_name_map.yaml @@ -0,0 +1,25 @@ +variable maps: + - name: depthBelowWaterSurface + alias: ocean_depth + - name: waterTemperature + alias: ocean_temperature + - name: seaSurfaceTemperature + alias: sea_surface_temperature + - name: salinity + alias: sea_water_salinity + - name: seaSurfaceSalinity + alias: sea_surface_salinity + - name: seaIceFraction + alias: sea_ice_area_fraction + - name: waterSurfaceZonalVelocity + alias: surface_eastward_sea_water_velocity + - name: waterSurfaceMeridionalVelocity + alias: surface_northward_sea_water_velocity + - name: seaSurfaceChlorophyllMassConcentration + alias: sea_surface_chlorophyll + - name: oceanSurfaceBiomassContent + alias: sea_surface_biomass_in_p_units + - name: waveHeightSignificant + alias: sea_surface_wave_significant_height + - name: chlorophyllMassConcentration + alias: mass_concentration_of_chlorophyll_in_sea_water diff --git a/parm/soca/soca_fix_stage_025.yaml.j2 b/parm/soca/soca_fix_stage_025.yaml.j2 index fdd502276..2c41dcad4 100644 --- a/parm/soca/soca_fix_stage_025.yaml.j2 +++ b/parm/soca/soca_fix_stage_025.yaml.j2 @@ -5,13 +5,11 @@ mkdir: # fix files to copy ###################################### copy: -- ["{{ SOCA_INPUT_FIX_DIR }}/rossrad.nc", "{{ DATA }}/rossrad.nc"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/field_table", "{{ DATA }}/field_table"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/diag_table", "{{ DATA }}/diag_table"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/MOM_input", "{{ DATA }}/MOM_input"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/fields_metadata.yaml", "{{ DATA }}/fields_metadata.yaml"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/obsop_name_map.yaml", "{{ DATA }}/obsop_name_map.yaml"] # -- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/grid_spec.nc", "{{ DATA }}/INPUT/grid_spec.nc"] # +- ["{{ SOCA_INPUT_FIX_DIR }}/rossrad.nc", "{{ DATA }}/rossrad.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/field_table", "{{ DATA }}/field_table"] +- ["{{ SOCA_INPUT_FIX_DIR }}/diag_table", "{{ DATA }}/diag_table"] +- ["{{ SOCA_INPUT_FIX_DIR }}/MOM_input", "{{ DATA }}/MOM_input"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/grid_spec.nc", "{{ DATA }}/INPUT/grid_spec.nc"] - ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/hycom1_75_800m.nc", "{{ DATA }}/INPUT/hycom1_75_800m.nc"] - ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/layer_coord.nc", "{{ DATA }}/INPUT/layer_coord.nc"] - ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/ocean_hgrid.nc", "{{ DATA }}/INPUT/ocean_hgrid.nc"] diff --git a/parm/soca/soca_utils_stage.yaml.j2 b/parm/soca/soca_utils_stage.yaml.j2 new file mode 100644 index 000000000..26570abe3 --- /dev/null +++ b/parm/soca/soca_utils_stage.yaml.j2 @@ -0,0 +1,7 @@ +###################################### +# Utility yaml files to copy +###################################### +copy: +- ["{{ HOMEgfs }}/parm/gdas/soca/fields_metadata.yaml", "{{ DATA }}/fields_metadata.yaml"] +- ["{{ HOMEgfs }}/parm/gdas/soca/obsop_name_map.yaml", "{{ DATA }}/obsop_name_map.yaml"] +- ["{{ HOMEgfs }}/parm/gdas/soca/gridgen/gridgen.yaml", "{{ DATA }}/gridgen.yaml"] diff --git a/scripts/exgdas_global_marine_analysis_chkpt.sh b/scripts/exgdas_global_marine_analysis_chkpt.sh index f6ada550f..27a0e9a4f 100755 --- a/scripts/exgdas_global_marine_analysis_chkpt.sh +++ b/scripts/exgdas_global_marine_analysis_chkpt.sh @@ -68,6 +68,7 @@ fi # the mom6 incr postprocessing from above. $APRUN_OCNANAL ${JEDI_BIN}/gdas.x soca convertstate soca_2cice_arctic.yaml +err=$?; err_chk $APRUN_OCNANAL ${JEDI_BIN}/gdas.x soca convertstate soca_2cice_antarctic.yaml export err=$?; err_chk diff --git a/scripts/exgdas_global_marine_analysis_prep.py b/scripts/exgdas_global_marine_analysis_prep.py index 3b601c680..532e52ad4 100755 --- a/scripts/exgdas_global_marine_analysis_prep.py +++ b/scripts/exgdas_global_marine_analysis_prep.py @@ -161,10 +161,17 @@ def parse_obs_list_file(): ################################################################################ # stage static files - logger.info(f"---------------- Stage static files") ufsda.stage.soca_fix(stage_cfg) +# copy obsop_name_map.yaml and fields_metadata.yaml +io_yaml_path = os.path.join(gdas_home, 'parm', 'soca') +io_yaml_list = [] +for io_yaml in ['obsop_name_map.yaml', 'fields_metadata.yaml']: + io_yaml_list.append([os.path.join(io_yaml_path, io_yaml), + os.path.join(anl_dir, io_yaml)]) +FileHandler({'copy': io_yaml_list}).sync() + ################################################################################ # stage ensemble members diff --git a/sorc/oops b/sorc/oops index b9c322afc..e6485c0a6 160000 --- a/sorc/oops +++ b/sorc/oops @@ -1 +1 @@ -Subproject commit b9c322afc959c189f6c256ea74da91e8cbd925e3 +Subproject commit e6485c0a659103f0daa2b7e2cece39a15bfb0d60 diff --git a/ush/soca/bkg_utils.py b/ush/soca/bkg_utils.py index 488fcf697..b37e1d732 100755 --- a/ush/soca/bkg_utils.py +++ b/ush/soca/bkg_utils.py @@ -123,28 +123,17 @@ def gen_bkg_list(bkg_path, out_path, window_begin=' ', yaml_name='bkg.yaml', ice # prepare the seaice background, aggregate if the backgrounds are CICE restarts ice_filename = ocn_filename.replace("ocean", "ice") - agg_ice_filename = ocn_filename.replace("ocean", "agg_ice") - if ice_rst: - # if this is a CICE restart, aggregate seaice variables and dump - # aggregated ice bkg in out_path - # TODO: This option is turned off for now, figure out what to do with it. - agg_seaice(os.path.join(bkg_path, ice_filename), - os.path.join(out_path, agg_ice_filename)) - else: - # Process the CICE history file so they can be read by soca/fms - # TODO: Add date check of the cice history - # TODO: bkg_path should be 1 level up - cice_hist2fms(os.path.join(os.getenv('COM_ICE_HISTORY_PREV'), ice_filename), - os.path.join(out_path, agg_ice_filename)) - - # prepare list of ocean bkg to be copied to RUNDIR + + # prepare list of ocean and ice bkg to be copied to RUNDIR bkg_list_src_dst.append([os.path.join(bkg_path, ocn_filename), os.path.join(out_path, ocn_filename)]) + bkg_list_src_dst.append([os.path.join(os.getenv('COM_ICE_HISTORY_PREV'), ice_filename), + os.path.join(out_path, ice_filename)]) bkg_dict = {'date': bkg_date.strftime('%Y-%m-%dT%H:%M:%SZ'), 'basename': './bkg/', 'ocn_filename': ocn_filename, - 'ice_filename': agg_ice_filename, + 'ice_filename': ice_filename, 'read_from_file': 1} bkg_date = bkg_date + timedelta(hours=dt_pseudo) # TODO: make the bkg interval a configurable @@ -168,7 +157,7 @@ def stage_ic(bkg_dir, anl_dir, gcyc): ics_list.append([mom_ic_src, mom_ic_dst]) # seaice IC's - cice_ic_src = os.path.join(bkg_dir, f'gdas.agg_ice.t{gcyc}z.inst.f003.nc') + cice_ic_src = os.path.join(bkg_dir, f'gdas.ice.t{gcyc}z.inst.f003.nc') cice_ic_dst = os.path.join(anl_dir, 'INPUT', 'cice.res.nc') ics_list.append([cice_ic_src, cice_ic_dst]) FileHandler({'copy': ics_list}).sync() diff --git a/utils/soca/gdas_soca_diagb.h b/utils/soca/gdas_soca_diagb.h index 62cff84f7..f45ac8313 100644 --- a/utils/soca/gdas_soca_diagb.h +++ b/utils/soca/gdas_soca_diagb.h @@ -20,6 +20,7 @@ #include "oops/base/FieldSet3D.h" #include "oops/base/GeometryData.h" +#include "oops/generic/Diffusion.h" #include "oops/mpi/mpi.h" #include "oops/runs/Application.h" #include "oops/util/DateTime.h" @@ -28,8 +29,6 @@ #include "oops/util/FieldSetOperations.h" #include "oops/util/Logger.h" -#include "soca/ExplicitDiffusion/ExplicitDiffusion.h" -#include "soca/ExplicitDiffusion/ExplicitDiffusionParameters.h" #include "soca/Geometry/Geometry.h" #include "soca/Increment/Increment.h" #include "soca/State/State.h" @@ -419,25 +418,39 @@ namespace gdasapp { /// Use explicit diffusion to smooth the background error // ------------------------------------------------------ - // TODO(G): Use this once Travis adds the option to skip the normalization. - // The output is currently in [0, ~1000] - // Initialize the diffusion central block if (fullConfig.has("diffusion")) { - const eckit::LocalConfiguration diffusionConfig(fullConfig, "diffusion"); - soca::ExplicitDiffusionParameters params; - params.deserialize(diffusionConfig); + const eckit::LocalConfiguration diffConfig(fullConfig, "diffusion"); + oops::Log::info() << "====================== apply explicit diffusion filtering" + << std::endl; + // Create the diffusion object oops::GeometryData geometryData(geom.functionSpace(), bkgErrFs["tocn"], true, this->getComm()); - const oops::FieldSet3D dumyXb(configD.cycleDate, this->getComm()); - soca::ExplicitDiffusion diffuse(geometryData, configD.socaVars, - diffusionConfig, params, dumyXb, dumyXb); - diffuse.read(); - - // Smooth the field - oops::FieldSet3D dx(configD.cycleDate, this->getComm()); - dx.deepCopy(bkgErrFs); - diffuse.multiply(dx); - bkgErrFs = dx.fieldSet(); + oops::Diffusion diffuse(geometryData); + diffuse.calculateDerivedGeom(geometryData); + + // Lambda function to construct a field with a constant filtering value + auto assignScale = [&](double scale, const std::string& fieldName) { + atlas::Field field; + auto levels = xbFs["tocn"].shape(1); + field = geom.functionSpace().createField(atlas::option::levels(levels) | + atlas::option::name(fieldName)); + auto viewField = atlas::array::make_view(field); + viewField.assign(scale); + return field; + }; + + // read the scales from the configuration + auto hzScales = assignScale(diffConfig.getDouble("horizontal"), "hzScales"); + auto vtScales = assignScale(diffConfig.getDouble("vertical"), "vtScales"); + + // Add the scales to the fieldset + atlas::FieldSet scalesFs; + scalesFs.add(hzScales); + scalesFs.add(vtScales); + + // Apply the diffusion filtering + diffuse.setParameters(scalesFs); + diffuse.multiply(bkgErrFs, oops::Diffusion::Mode::HorizontalOnly); } // Rescale