From 5df5739020fea4d033304cc428475400445531c6 Mon Sep 17 00:00:00 2001 From: Guillaume Vernieres Date: Wed, 2 Aug 2023 11:03:59 -0400 Subject: [PATCH] post proc ensemble of incr --- parm/soca/variational/socaincr2mom6.yaml | 4 +- .../exgdas_global_marine_analysis_chkpt.sh | 2 +- test/soca/gw/CMakeLists.txt | 2 +- test/soca/testinput/socaincr2mom6.yaml | 3 +- utils/CMakeLists.txt | 12 +-- utils/gdas_incr_handler.cc | 8 ++ ...as_socaincr2mom6.h => gdas_incr_handler.h} | 35 +++++---- utils/gdas_postprocincr.cc | 55 -------------- utils/gdas_postprocincr.h | 75 +++++++++++++------ utils/gdas_socaincr2mom6.cc | 8 -- 10 files changed, 88 insertions(+), 116 deletions(-) create mode 100644 utils/gdas_incr_handler.cc rename utils/{gdas_socaincr2mom6.h => gdas_incr_handler.h} (61%) delete mode 100644 utils/gdas_postprocincr.cc delete mode 100644 utils/gdas_socaincr2mom6.cc diff --git a/parm/soca/variational/socaincr2mom6.yaml b/parm/soca/variational/socaincr2mom6.yaml index 9fb1b3679..737110934 100644 --- a/parm/soca/variational/socaincr2mom6.yaml +++ b/parm/soca/variational/socaincr2mom6.yaml @@ -14,8 +14,8 @@ vertical geometry: ocn_filename: MOM.res.nc read_from_file: 1 -soca increment: - date: '{{ATM_WINDOW_BEGIN}}' +soca increments: +- date: '{{ATM_WINDOW_BEGIN}}' basename: ./Data/ ocn_filename: 'ocn.3dvarfgat_pseudo.incr.{{ATM_WINDOW_MIDDLE}}.nc' read_from_file: 1 diff --git a/scripts/exgdas_global_marine_analysis_chkpt.sh b/scripts/exgdas_global_marine_analysis_chkpt.sh index be506379d..8b585693d 100755 --- a/scripts/exgdas_global_marine_analysis_chkpt.sh +++ b/scripts/exgdas_global_marine_analysis_chkpt.sh @@ -55,7 +55,7 @@ EOF --out "${mom6_iau_incr}" \ --nsst_yaml "nsst.yaml" else - $APRUN_OCNANAL ${JEDI_BIN}/gdas_socaincr2mom6.x socaincr2mom6.yaml + $APRUN_OCNANAL ${JEDI_BIN}/gdas_incr_handler.x socaincr2mom6.yaml fi export err=$? if [ $err -gt 0 ]; then diff --git a/test/soca/gw/CMakeLists.txt b/test/soca/gw/CMakeLists.txt index e1b20f602..acb7d3d54 100644 --- a/test/soca/gw/CMakeLists.txt +++ b/test/soca/gw/CMakeLists.txt @@ -78,7 +78,7 @@ foreach(jjob ${jjob_list}) endforeach() # Test gdas/oops applications -set(ctest_list "socahybridweights" "socaincr2mom6") +set(ctest_list "socahybridweights" "incr_handler") foreach(ctest ${ctest_list}) set(TEST ${ctest}) set(EXEC ${PROJECT_BINARY_DIR}/bin/gdas_${ctest}.x) diff --git a/test/soca/testinput/socaincr2mom6.yaml b/test/soca/testinput/socaincr2mom6.yaml index 61d3ccd9b..8279ce54c 100644 --- a/test/soca/testinput/socaincr2mom6.yaml +++ b/test/soca/testinput/socaincr2mom6.yaml @@ -45,4 +45,5 @@ output increment: date: 2018-04-15T09:00:00Z exp: mom6_iau type: incr - output file: inc.nc + output file: inc.%mem%.nc + pattern: %mem% \ No newline at end of file diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 311f60a5d..86be649b2 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -5,14 +5,14 @@ find_package(oops REQUIRED) find_package(atlas REQUIRED) find_package(soca REQUIRED) -ecbuild_add_executable( TARGET gdas_socaincr2mom6.x - SOURCES gdas_socaincr2mom6.cc gdas_postprocincr.h) - -target_compile_features( gdas_socaincr2mom6.x PUBLIC cxx_std_17) -target_link_libraries( gdas_socaincr2mom6.x PUBLIC NetCDF::NetCDF_CXX oops atlas soca) +# Increment post processing +ecbuild_add_executable( TARGET gdas_incr_handler.x + SOURCES gdas_incr_handler.cc gdas_postprocincr.h) +target_compile_features( gdas_incr_handler.x PUBLIC cxx_std_17) +target_link_libraries( gdas_incr_handler.x PUBLIC NetCDF::NetCDF_CXX oops atlas soca) +# Hybrid-Weight ecbuild_add_executable( TARGET gdas_socahybridweights.x SOURCES gdas_socahybridweights.cc ) - target_compile_features( gdas_socahybridweights.x PUBLIC cxx_std_17) target_link_libraries( gdas_socahybridweights.x PUBLIC NetCDF::NetCDF_CXX oops atlas soca) diff --git a/utils/gdas_incr_handler.cc b/utils/gdas_incr_handler.cc new file mode 100644 index 000000000..65ce9ac43 --- /dev/null +++ b/utils/gdas_incr_handler.cc @@ -0,0 +1,8 @@ +#include "gdas_incr_handler.h" +#include "oops/runs/Run.h" + +int main(int argc, char ** argv) { + oops::Run run(argc, argv); + gdasapp::SocaIncrHandler incrhandler; + return run.execute(incrhandler); +} diff --git a/utils/gdas_socaincr2mom6.h b/utils/gdas_incr_handler.h similarity index 61% rename from utils/gdas_socaincr2mom6.h rename to utils/gdas_incr_handler.h index c4978e3b3..54d2504b0 100644 --- a/utils/gdas_socaincr2mom6.h +++ b/utils/gdas_incr_handler.h @@ -22,11 +22,11 @@ namespace gdasapp { - class SocaIncr2Mom6 : public oops::Application { + class SocaIncrHandler : public oops::Application { public: - explicit SocaIncr2Mom6(const eckit::mpi::Comm & comm = oops::mpi::world()) + explicit SocaIncrHandler(const eckit::mpi::Comm & comm = oops::mpi::world()) : Application(comm) {} - static const std::string classname() {return "gdasapp::SocaIncr2Mom6";} + static const std::string classname() {return "gdasapp::SocaIncrHandler";} int execute(const eckit::Configuration & fullConfig, bool /*validate*/) const { @@ -41,24 +41,23 @@ namespace gdasapp { oops::Log::info() << "soca increments: " << std::endl << postProcIncr.inputIncrConfig_ << std::endl; - std::vector increments; - fullConfig.get("soca increments", increments); - oops::Log::info() << "ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" << std::endl; - oops::Log::info() << increments[0] << std::endl; - oops::Log::info() << "ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" << std::endl; + // Process list of increments + int result = 0; + for (size_t i = 0; i < postProcIncr.inputIncrConfig_.size(); ++i) { + oops::Log::info() << postProcIncr.inputIncrConfig_[0] << std::endl; - // At the very minimum, we run this script to append the layers state, so do that! - soca::Increment incr = postProcIncr.appendLayer(); + // At the very minimum, we run this script to append the layers state, so do that! + soca::Increment incr = postProcIncr.appendLayer(i); - // Zero out specified fields - incr = postProcIncr.setToZero(incr); + // Zero out specified fields + incr = postProcIncr.setToZero(incr); - // Apply linear change of variables - incr = postProcIncr.applyLinVarChange(incr); - - // Save final increment - int result = postProcIncr.save(incr); + // Apply linear change of variables + incr = postProcIncr.applyLinVarChange(incr); + // Save final increment + result = postProcIncr.save(incr, i+1); + } return result; } // ----------------------------------------------------------------------------- @@ -67,7 +66,7 @@ namespace gdasapp { // ----------------------------------------------------------------------------- std::string appname() const { - return "gdasapp::SocaIncr2Mom6"; + return "gdasapp::SocaIncrHandler"; } }; diff --git a/utils/gdas_postprocincr.cc b/utils/gdas_postprocincr.cc deleted file mode 100644 index 8d8fc74dc..000000000 --- a/utils/gdas_postprocincr.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -#include "eckit/config/LocalConfiguration.h" - -#include "atlas/field.h" - -#include "oops/base/PostProcessor.h" -#include "oops/mpi/mpi.h" -#include "oops/runs/Application.h" -#include "oops/util/DateTime.h" -#include "oops/util/Duration.h" -#include "oops/util/Logger.h" - -#include "soca/Geometry/Geometry.h" -#include "soca/Increment/Increment.h" -#include "soca/LinearVariableChange/LinearVariableChange.h" -#include "soca/State/State.h" - -namespace gdasapp { - -class PostProcIncr { -public: - // Constructor - PostProcIncr(const eckit::Configuration & fullConfig) - : dt_(getDate(fullConfig)), layerVar(getLayerVar(fullConfig)) { - oops::Log::info() << "Date: " << std::endl << dt_ << std::endl; - } - - // Method to run the post-processing - void run(); - - // Initializers - // ----------------------------------------------------------------------------- - // Date from config - util::DateTime getDate(const eckit::Configuration& fullConfig) const { - std::string strdt; - fullConfig.get("date", strdt); - return util::DateTime(strdt); - } - - // ----------------------------------------------------------------------------- - // get the layer variable - oops::Variables getLayerVarName(const eckit::Configuration& fullConfig) const { - oops::Variables layerVar(fullConfig, "layers variable"); - ASSERT(layerVar.size() == 1); - return layerVar; - } - -private: - util::DateTime dt_; // valid date of increment - oops::Variables layerVar_; // layer variable -}; - -} // namespace gdasapp diff --git a/utils/gdas_postprocincr.h b/utils/gdas_postprocincr.h index 699533d88..25c03e187 100644 --- a/utils/gdas_postprocincr.h +++ b/utils/gdas_postprocincr.h @@ -10,9 +10,7 @@ #include "oops/base/PostProcessor.h" #include "oops/mpi/mpi.h" -//#include "oops/runs/Application.h" #include "oops/util/DateTime.h" -#include "oops/util/Duration.h" #include "oops/util/Logger.h" #include "soca/Geometry/Geometry.h" @@ -40,12 +38,9 @@ class PostProcIncr { ASSERT(socaIncrVar.size() >= 1); socaIncrVar_ = socaIncrVar; - // Input increment configuration - eckit::LocalConfiguration inputIncrConfig = fullConfig.getSubConfiguration("soca increments"); - inputIncrConfig_ = inputIncrConfig; + // Input increments configuration + fullConfig.get("soca increments", inputIncrConfig_); - std::cout << "------------------------------------------" << std::endl; - std::cout << inputIncrConfig_ << std::endl; // Output incrememnt configuration eckit::LocalConfiguration outputIncrConfig(fullConfig, "output increment"); outputIncrConfig_ = outputIncrConfig; @@ -68,12 +63,13 @@ class PostProcIncr { } // Append layer thicknesses to increment - soca::Increment appendLayer(){ + // TODO: There's got to be a better way to append a variable. + soca::Increment appendLayer(const int n){ oops::Log::info() << "==========================================" << std::endl; oops::Log::info() << "====== Append Layers" << std::endl; // read the soca increment soca::Increment socaIncr(geom_, socaIncrVar_, dt_); - socaIncr.read(inputIncrConfig_); + socaIncr.read(inputIncrConfig_[n]); oops::Log::info() << "-------------------- input increment: " << std::endl; oops::Log::info() << socaIncr << std::endl; @@ -141,8 +137,6 @@ class PostProcIncr { return socaIncr; } oops::Log::info() << "====== applying specified change of variables" << std::endl; - //const eckit::LocalConfiguration trajConfig(lvcConfig_, "trajectory"); - //soca::State xTraj(this->geom_, trajConfig); soca::LinearVariableChangeParameters params; params.deserialize(lvcConfig_); oops::Log::info() << params << std::endl; @@ -156,7 +150,7 @@ class PostProcIncr { } // Save increment - int save(soca::Increment socaIncr) { + int save(soca::Increment socaIncr, int ensMem = 1) { oops::Log::info() << "==========================================" << std::endl; oops::Log::info() << "-------------------- save increment: " << std::endl; socaIncr.write(outputIncrConfig_); @@ -169,18 +163,17 @@ class PostProcIncr { if ( comm_.rank() == 0 ) { std::string outputFileName; outputIncrConfig_.get("output file", outputFileName); + if (outputIncrConfig_.has("pattern")) { + std::string pattern; + outputIncrConfig_.get("pattern", pattern); + outputFileName = this->swapPattern(outputFileName, pattern, std::to_string(ensMem)); + oops::Log::info() << "-------------------- pattern: " << pattern << std::endl; + } + const char* charPtrOut = outputFileName.c_str(); - std::string datadir; - outputIncrConfig_.get("datadir", datadir); - std::filesystem::path pathToResolve = datadir; - std::string exp; - outputIncrConfig_.get("exp", exp); - std::string outputType; - outputIncrConfig_.get("type", outputType); - std::string incrFname = std::filesystem::canonical(pathToResolve); - incrFname += "/ocn." + exp + "." + outputType + "." + dt_.toString() + ".nc"; + std::string incrFname = this->socaFname(); const char* charPtr = incrFname.c_str(); - const char* charPtrOut = outputFileName.c_str(); + oops::Log::info() << "rename: " << incrFname << " to " << outputFileName << std::endl; result = std::rename(charPtr, charPtrOut); } @@ -228,13 +221,48 @@ class PostProcIncr { } } + // ----------------------------------------------------------------------------- + + // Utility functions + // ----------------------------------------------------------------------------- + // Recreate the soca filename from the configuration + std::string socaFname() { + std::string datadir; + outputIncrConfig_.get("datadir", datadir); + std::filesystem::path pathToResolve = datadir; + std::string exp; + outputIncrConfig_.get("exp", exp); + std::string outputType; + outputIncrConfig_.get("type", outputType); + std::string incrFname = std::filesystem::canonical(pathToResolve); + incrFname += "/ocn." + exp + "." + outputType + "." + dt_.toString() + ".nc"; + + return incrFname; + } + + // Function to replace all occurrences of a pattern in a string with a replacement + std::string swapPattern(const std::string& input, + const std::string& pattern, + const std::string& replacement) { + std::string result = input; + size_t startPos = 0; + + while ((startPos = result.find(pattern, startPos)) != std::string::npos) { + result.replace(startPos, pattern.length(), replacement); + startPos += replacement.length(); + } + + return result; +} + + public: util::DateTime dt_; // valid date of increment oops::Variables layerVar_; // layer variable const soca::Increment Layers_; // layer thicknesses const soca::Geometry & geom_; const eckit::mpi::Comm & comm_; - eckit::LocalConfiguration inputIncrConfig_; + std::vector inputIncrConfig_; eckit::LocalConfiguration outputIncrConfig_; eckit::LocalConfiguration zeroIncrConfig_; eckit::LocalConfiguration lvcConfig_; @@ -244,7 +272,6 @@ class PostProcIncr { const soca::State xTraj_; oops::Variables socaZeroIncrVar_; }; - } // namespace gdasapp #endif // GDAS_POSTPROCINCR_H diff --git a/utils/gdas_socaincr2mom6.cc b/utils/gdas_socaincr2mom6.cc deleted file mode 100644 index 0b1230f56..000000000 --- a/utils/gdas_socaincr2mom6.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "gdas_socaincr2mom6.h" -#include "oops/runs/Run.h" - -int main(int argc, char ** argv) { - oops::Run run(argc, argv); - gdasapp::SocaIncr2Mom6 socaincr2mom6; - return run.execute(socaincr2mom6); -}