Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/opsinputs/CxWriterParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ class CxWriterParameters : public oops::ObsFilterParametersBase {
/// default is true.
oops::Parameter<bool> geoValsAreTopToBottom{"geovals_are_top_to_bottom", true, this};

/// Fill radiosonde CX columns using H(x) values rather than GeoVaLs.
/// This can be used to produce a set of CX columns (which are used as H(x) in VAR)
/// that correspond closely to the H(x) produced by JADA.
/// In other words it enables a 'JADA compatibility mode' for VAR.
/// This option only has an effect for airTemperature, potentialTemperature, windEastward,
/// windNorthward and relativeHumidity.
oops::Parameter<bool> writeHofXIntoCX{"write_hofx_into_cx", false, this};

/// If this list of ufo::variable is defined in the yaml a subset of the flags
/// will be made with just these variables present. This will allow Fortran calls such-as
/// "reject_obs_with_all_variables_failing_qc" and channel numbering to work correctly.
Expand Down
87 changes: 48 additions & 39 deletions src/opsinputs/opsinputs_cxwriter_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module opsinputs_cxwriter_mod
use opsinputs_fill_mod, only: &
opsinputs_fill_fillreal, &
opsinputs_fill_fillrealfromgeoval, &
opsinputs_fill_fillreal2dfromgeoval
opsinputs_fill_fillreal2dfromgeovalorhofx
use opsinputs_mpl_mod, only: opsinputs_mpl_allgather_integer
use opsinputs_obsspace_mod, only: opsinputs_obsspace_get_db_datetime_offset_in_seconds
use opsinputs_utils_mod, only: &
Expand Down Expand Up @@ -137,6 +137,7 @@ module opsinputs_cxwriter_mod
logical :: RejectObsWithAnyVariableFailingQC
logical :: RejectObsWithAllVariablesFailingQC
logical :: GeoVaLsAreTopToBottom
logical :: WriteHofXIntoCX

character(len=100) :: latitudeName
character(len=100) :: longitudeName
Expand Down Expand Up @@ -257,6 +258,9 @@ function opsinputs_cxwriter_create(self, f_conf, geovars)
call f_conf % get_or_die("geovals_are_top_to_bottom", &
self % GeoVaLsAreTopToBottom)

call f_conf % get_or_die("write_hofx_into_cx", &
self % WriteHofXIntoCX)

call f_conf % get_or_die ("latitude_name", StringValue)
self % latitudeName = StringValue

Expand Down Expand Up @@ -1087,174 +1091,179 @@ subroutine opsinputs_cxwriter_populatecx(self, ReportFlags, Cx)

! Upper-air variables
case (StashItem_theta) ! IndexCxtheta
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % theta, "theta", Cx % theta, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_theta, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
self % JediToOpsLayoutMapping, self % hofx, self % varnames, &
"potentialTemperature", self % WriteHofXIntoCX)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the extra options provided to theta, T, u, v and RH. These options are not needed otherwise.

case (StashCode_rh, StashCode_rh_p) ! IndexCxrh
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % rh, "rh", Cx % rh, &
self % GeoVaLs, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_rh, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
self % JediToOpsLayoutMapping, self % hofx, self % varnames, &
"relativeHumidity", self % WriteHofXIntoCX)
case (StashItem_u, StashCode_u_p_B_grid) ! IndexCxu
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % u, "u", Cx % u, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_u, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
self % JediToOpsLayoutMapping, self % hofx, self % varnames, &
"windEastward", self % WriteHofXIntoCX)
case (StashItem_v) ! IndexCxv
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % v, "v", Cx % v, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_v, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
self % JediToOpsLayoutMapping, self % hofx, self % varnames, &
"windNorthward", self % WriteHofXIntoCX)
case (StashItem_w) ! IndexCxw
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % w, "w", Cx % w, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_w, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_q) ! IndexCxq
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % q, "q", Cx % q, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_q, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_qc) ! IndexCxqc
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qc, "qc", Cx % qc, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qc, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_p_bar) ! IndexCxp_bar
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % p_bar, "p_bar", Cx % p_bar, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_p_bar, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
! wsmigaj: I haven't been able to identify the stash code associated with this field
! case (?) ! IndexCxcloud
! call opsinputs_fill_fillreal2dfromgeoval( &
! call opsinputs_fill_fillreal2dfromgeovalorhofx( &
! Cx % Header % cloud, "cloud", Cx % cloud, &
! self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_cloud, &
! self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_ql_layer) ! IndexCxql_layer
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % ql_layer, "ql_layer", Cx % ql_layer, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_ql_layer, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_p) ! IndexCxP
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % PLevelsA, "PLevelsA", Cx % PLevelsA, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_PLevelsA, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (AncilCode_salt) ! IndexCxSalt
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % Salt, "Salt", Cx % Salt, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_Salt, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_t_p) ! IndexCxt
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % t, "t", Cx % t, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_t, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
self % JediToOpsLayoutMapping, self % hofx, self % varnames, &
"airTemperature", self % WriteHofXIntoCX)
case (StashCode_qf_layer) ! IndexCxqf_layer
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qf_layer, "qf_layer", Cx % qf_layer, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qf_layer, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_RainRate_layer) ! IndexCxRainRate_layer
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % RainRate_layer, "RainRate_layer", Cx % RainRate_layer, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_RainRate_layer, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_cloud_conv) ! IndexCxcloud_conv
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % cloud_conv, "cloud_conv", Cx % cloud_conv, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_cloud_conv, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_qc_conv) ! IndexCxqc_conv
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qc_conv, "qc_conv", Cx % qc_conv, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qc_conv, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_cloud_layer) ! IndexCxcloud_layer
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % cloud_layer, "cloud_layer", Cx % cloud_layer, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_cloud_layer, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_ozone_new) ! IndexCxOzone
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % ozone, "ozone", Cx % ozone, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_ozone, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_qcf) ! IndexCxqcf
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qcf, "qcf", Cx % qcf, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qcf, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_qcl) ! IndexCxqcl
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qcl, "qcl", Cx % qcl, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qcl, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_cloud_bulk) ! IndexCxcloud_bulk
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % cloud_bulk, "cloud_bulk", Cx % cloud_bulk, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_cloud_bulk, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
! wsmigaj: I haven't been able to identify the stash code associated with this field
! case (?)
! if (Cx % Header % ObsGroup == ObsGroupGroundLidar) then
! call opsinputs_fill_fillreal2dfromgeoval( &
! call opsinputs_fill_fillreal2dfromgeovalorhofx( &
! Cx % Header % aerosol_p, "aerosol_p", Cx % aerosol_p, &
! self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_aerosol_p, &
! self % JediToOpsLayoutMapping, self % hofx, self % varnames)
! end if
case (StashCode_CDNC) ! IndexCxCDNC
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % CDNC, "CDNC", Cx % CDNC, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_CDNC, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_RH_AfterMainCloud) ! IndexCxRH_AMC
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % RH_AMC, "RH_AMC", Cx % RH_AMC, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_RH_AMC, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_Cl) ! IndexCxCl
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % Cl, "Cl", Cx % Cl, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_Cl, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_Cf) ! IndexCxCf
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % Cf, "Cf", Cx % Cf, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_Cf, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_qrain) ! IndexCxqrain
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % qrain, "qrain", Cx % qrain, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_qrain, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_Exner) ! IndexCxExnerA
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % ExnerA, "ExnerA", Cx % ExnerA, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_ExnerA, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_RichNumber) ! IndexCxRichNumber
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % RichNumber, "RichNumber", Cx % RichNumber, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_RichNumber, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_SoilMoisture) ! IndexCxSoilMoisture
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % SoilMoisture, "SoilMoisture", Cx % SoilMoisture, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_SoilMoisture, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashCode_SoilTemp) ! IndexCxSoilTemp
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % SoilTemp, "SoilTemp", Cx % SoilTemp, &
self % GeoVals, self % GeoVaLsAreTopToBottom, opsinputs_cxfields_SoilTemp, &
self % JediToOpsLayoutMapping, self % hofx, self % varnames)
case (StashItem_dustMin:StashItem_dustMax) ! IndexCxDust1:IndexCxDust6
DustBinIndex = CxField - StashItem_dustMin + 1
if (DustBinIndex <= NDustBins) then
write (DustBinIndexStr, '(i1)') DustBinIndex
call opsinputs_fill_fillreal2dfromgeoval( &
call opsinputs_fill_fillreal2dfromgeovalorhofx( &
Cx % Header % dustp, "dustp", Cx % dustp(DustBinIndex) % field, &
self % GeoVals, self % GeoVaLsAreTopToBottom, &
opsinputs_cxfields_dustp_start // DustBinIndexStr // opsinputs_cxfields_dustp_end, &
Expand Down
Loading
Loading