diff --git a/.gitignore b/.gitignore index cbab8be5b..322611a56 100644 --- a/.gitignore +++ b/.gitignore @@ -183,4 +183,5 @@ install*/ /sorc/gdas /sorc/gdas-utils !/bundle/CMakeLists.txt +!/bundle/fv3-interface.cmake /bundle/* diff --git a/.gitmodules b/.gitmodules index a4e4d00c2..945b2d291 100644 --- a/.gitmodules +++ b/.gitmodules @@ -49,10 +49,6 @@ path = sorc/icepack url = https://github.com/JCSDA-internal/Icepack.git branch = feature/ecbuild-new -[submodule "sorc/mom6"] - path = sorc/mom6 - url = https://github.com/jcsda-internal/MOM6.git - branch = main-ecbuild [submodule "sorc/soca"] path = sorc/soca url = https://github.com/jcsda-internal/soca.git @@ -73,10 +69,10 @@ path = sorc/crtm url = https://github.com/jcsda/crtm.git branch = release/crtm_jedi_v2.4.1 -[submodule "sorc/fms"] - path = sorc/fms - url = https://github.com/jcsda/fms.git - branch = release-stable +[submodule "sorc/jcb"] + path = sorc/jcb + url = https://github.com/noaa-emc/jcb.git + branch = develop [submodule "parm/jcb-gdas"] path = parm/jcb-gdas url = https://github.com/noaa-emc/jcb-gdas @@ -85,3 +81,11 @@ path = parm/jcb-algorithms url = https://github.com/noaa-emc/jcb-algorithms branch = develop +[submodule "sorc/da-utils"] + path = sorc/da-utils + url = https://github.com/noaa-emc/da-utils.git + branch = develop +[submodule "sorc/bufr-query"] + path = sorc/bufr-query + url = https://github.com/noaa-emc/bufr-query.git + branch = develop diff --git a/README.md b/README.md index 7ac52d734..9ea507f55 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,25 @@ Global Data Assimilation System Application The one app to rule them all +## Notes to developers + +1 - As a developer, you will have to build the GDASApp againt the `dev/gdasapp` branch of the `global-workflow` + +```bash +git clone --recursive --jobs 8 --branch dev/gdasapp https://github.com/NOAA-EMC/global-workflow.git +``` + +2 - For the most part (boundaries of that terminology is stil TBD), changes to the `global-workflow` related to the `GDASApp` developement will be issued in the `dev/gdasapp` branch. + +3 - If your feature development involves changes to the global-workflow and the GDASApp, you will have to issue a PR in each repository. The GDASApp PR will have to have the same name in order for the GDASApp CI to build and run the correct branches. + +4 - If your work is contained within the `global-workflow` only, you will have to submit a dummy PR in the `GDASApp` with the same branch name. +To submit a dummy PR, just create a branch with an empty commit: +``` +git commit --allow-empty -m "Dummy commit to trigger PR" +``` + + [![Orion](https://github.com/NOAA-EMC/GDASApp/actions/workflows/orion.yaml/badge.svg)](https://github.com/NOAA-EMC/GDASApp/actions/workflows/orion.yaml) [![Hera](https://github.com/NOAA-EMC/GDASApp/actions/workflows/hera.yaml/badge.svg)](https://github.com/NOAA-EMC/GDASApp/actions/workflows/hera.yaml) diff --git a/build.sh b/build.sh index 502cf7f88..801f3c8bc 100755 --- a/build.sh +++ b/build.sh @@ -87,7 +87,7 @@ case ${BUILD_TARGET} in ;; esac -CMAKE_OPTS+=" -DCLONE_JCSDADATA=$CLONE_JCSDADATA" +CMAKE_OPTS+=" -DCLONE_JCSDADATA=$CLONE_JCSDADATA -DMACHINE=$BUILD_TARGET" BUILD_DIR=${BUILD_DIR:-$dir_root/build} if [[ $CLEAN_BUILD == 'YES' ]]; then @@ -126,7 +126,7 @@ set -x if [[ $BUILD_JCSDA == 'YES' ]]; then make -j ${BUILD_JOBS:-6} VERBOSE=$BUILD_VERBOSE else - builddirs="gdas iodaconv land-imsproc land-jediincr gdas-utils" + builddirs="gdas iodaconv land-imsproc land-jediincr gdas-utils bufr-query" for b in $builddirs; do cd $b make -j ${BUILD_JOBS:-6} VERBOSE=$BUILD_VERBOSE diff --git a/bundle/CMakeLists.txt b/bundle/CMakeLists.txt index 9493ac0c8..4f628faff 100644 --- a/bundle/CMakeLists.txt +++ b/bundle/CMakeLists.txt @@ -36,6 +36,19 @@ option(BUILD_GDASBUNDLE "Build GDAS Bundle" ON) option(CLONE_JCSDADATA "Clone JCSDA test data repositories" OFF) option(WORKFLOW_TESTS "Include global-workflow dependent tests" OFF) +# Depend path for non-ecbuild packages +set(DEPEND_LIB_ROOT ${CMAKE_CURRENT_BINARY_DIR}/Depends) +list(APPEND CMAKE_PREFIX_PATH ${DEPEND_LIB_ROOT}) + +# Library path for non-ecbuild packages +link_directories(${CMAKE_CURRENT_BINARY_DIR}/lib) + +include( GNUInstallDirs ) +if(APPLE) + list( APPEND CMAKE_INSTALL_RPATH $ENV{llvm_openmp_ROOT}/lib ) +endif() +list( APPEND CMAKE_INSTALL_RPATH ${CMAKE_CURRENT_BINARY_DIR}/fv3 ) + # Initialize bundle # ----------------- ecbuild_bundle_initialize() @@ -75,6 +88,9 @@ if(BUILD_GDASBUNDLE) # Gibbs seawater ecbuild_bundle( PROJECT gsw SOURCE "../sorc/gsw" ) +# EMC BUFR-query library + ecbuild_bundle( PROJECT bufr-query SOURCE "../sorc/bufr-query" ) + # Core JEDI repositories ecbuild_bundle( PROJECT oops SOURCE "../sorc/oops" ) ecbuild_bundle( PROJECT vader SOURCE "../sorc/vader" ) @@ -84,8 +100,8 @@ if(BUILD_GDASBUNDLE) option(ENABLE_UFO_DATA "Obtain ufo test data from ufo-data repository (vs tarball)" ON) ecbuild_bundle( PROJECT ufo SOURCE "../sorc/ufo" ) -# FMS and FV3 dynamical core - ecbuild_bundle( PROJECT fms SOURCE "../sorc/fms" ) +# FV3 dynamical core + include(fv3-interface.cmake) ecbuild_bundle( PROJECT fv3 SOURCE "../sorc/fv3" ) # fv3-jedi and associated repositories @@ -100,11 +116,11 @@ if(BUILD_GDASBUNDLE) if ( BUILD_ICEPACK ) ecbuild_bundle( PROJECT icepack SOURCE "../sorc/icepack" ) endif() - ecbuild_bundle( PROJECT mom6 SOURCE "../sorc/mom6" ) ecbuild_bundle( PROJECT soca SOURCE "../sorc/soca" ) # Build JEDI/DA or other peripherals ecbuild_bundle( PROJECT gdas-utils SOURCE "../utils" ) + ecbuild_bundle( PROJECT da-utils SOURCE "../sorc/da-utils" ) # Build IODA converters option(BUILD_IODA_CONVERTERS "Build IODA Converters" ON) diff --git a/bundle/fv3-interface.cmake b/bundle/fv3-interface.cmake new file mode 100644 index 000000000..45e7ad633 --- /dev/null +++ b/bundle/fv3-interface.cmake @@ -0,0 +1,18 @@ +# FV3 dycore +set(OPENMP ON ) +set(32BIT OFF) +set(DEBUG OFF) +set(MOVING_NEST OFF) +set(MULTI_GASES OFF) +set(USE_GFSL63 ON ) +set(NO_PHYS ON ) +set(GFS_PHYS OFF) +set(GFS_TYPES OFF) +set(use_WRTCOMP OFF) +set(INTERNAL_FILE_NML ON ) +set(ENABLE_QUAD_PRECISION ON ) + +add_library(fv3dycore IMPORTED SHARED) +set_target_properties(fv3dycore PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/fv3/libfv3.${CMAKE_SHARED_LIBRARY_SUFFIX}) + +message(WARN "WE ARE USING fv3-interface.cmake") diff --git a/ci/driver.sh b/ci/driver.sh index 4b0ea550a..ce6372c59 100755 --- a/ci/driver.sh +++ b/ci/driver.sh @@ -60,11 +60,32 @@ repo_url="https://github.com/NOAA-EMC/GDASApp.git" for pr in $open_pr_list; do gh pr edit $pr --remove-label $CI_LABEL --add-label ${CI_LABEL}-Running echo "Processing Pull Request #${pr}" + + # get the branch name used for the PR + gdasapp_branch=$(gh pr view $pr --json headRefName -q ".headRefName") + + # get the fork information + pr_details=$(gh pr view $pr --repo ${repo_url} --json headRepository,headRepositoryOwner,headRefName) + + # extract the necessary info + fork_owner=$(gh pr view $pr --repo ${repo_url} --json headRepositoryOwner --jq '.headRepositoryOwner.login') + fork_name=$(gh pr view $pr --repo ${repo_url} --json headRepository --jq '.headRepository.name') + + # construct the fork URL + gdasapp_url="https://github.com/$fork_owner/${fork_name}.git" + + echo "Fork URL: $gdasapp_url" + echo "Branch Name: $gdasapp_branch" + + # create PR specific directory + if [ -d $GDAS_CI_ROOT/PR/$pr ]; then + rm -rf $GDAS_CI_ROOT/PR/$pr + fi mkdir -p $GDAS_CI_ROOT/PR/$pr cd $GDAS_CI_ROOT/PR/$pr # clone copy of repo - git clone --recursive $repo_url + git clone --recursive --jobs 8 --branch $gdasapp_branch $gdasapp_url cd GDASApp # checkout pull request @@ -94,11 +115,11 @@ for pr in $open_pr_list; do # run build and testing command $my_dir/run_ci.sh -d $GDAS_CI_ROOT/PR/$pr/GDASApp -o $GDAS_CI_ROOT/PR/$pr/output_${commit} ci_status=$? - gh pr comment $pr --body-file $GDAS_CI_ROOT/PR/$pr/output_${commit} + gh pr comment $pr --repo ${repo_url} --body-file $GDAS_CI_ROOT/PR/$pr/output_${commit} if [ $ci_status -eq 0 ]; then - gh pr edit $pr --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Passed + gh pr edit $pr --repo ${repo_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Passed else - gh pr edit $pr --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Failed + gh pr edit $pr --repo ${repo_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Failed fi done diff --git a/ci/gw_driver.sh b/ci/gw_driver.sh index afbbdf96e..e85684f84 100755 --- a/ci/gw_driver.sh +++ b/ci/gw_driver.sh @@ -61,11 +61,36 @@ workflow_url="https://github.com/NOAA-EMC/global-workflow.git" for pr in $open_pr_list; do gh pr edit $pr --remove-label $CI_LABEL --add-label ${CI_LABEL}-Running echo "Processing Pull Request #${pr}" + + # get the branch name used for the PR + gdasapp_branch=$(gh pr view $pr --json headRefName -q ".headRefName") + + # check for a companion PR in the global-workflow + companion_pr_exists=$(gh pr list --repo ${workflow_url} --head ${gdasapp_branch} --state open) + if [ -n "$companion_pr_exists" ]; then + # get the PR number + companion_pr=$(echo "$companion_pr_exists" | awk '{print $1;}') + + # extract the necessary info + fork_owner=$(gh pr view $companion_pr --repo $workflow_url --json headRepositoryOwner --jq '.headRepositoryOwner.login') + fork_name=$(gh pr view $companion_pr --repo $workflow_url --json headRepository --jq '.headRepository.name') + + # Construct the fork URL + workflow_url="https://github.com/$fork_owner/$fork_name.git" + + echo "Fork URL: $workflow_url" + echo "Branch Name: $gdasapp_branch" + fi + + # create PR specific directory + if [ -d $GDAS_CI_ROOT/workflow/PR/$pr ]; then + rm -rf $GDAS_CI_ROOT/workflow/PR/$pr + fi mkdir -p $GDAS_CI_ROOT/workflow/PR/$pr cd $GDAS_CI_ROOT/workflow/PR/$pr - + # clone global workflow develop branch - git clone --recursive $workflow_url + git clone --recursive --jobs 8 --branch dev/gdasapp $workflow_url # checkout pull request cd $GDAS_CI_ROOT/workflow/PR/$pr/global-workflow/sorc/gdas.cd diff --git a/ci/hera.sh b/ci/hera.sh index 5eb5c4df6..ec3858370 100644 --- a/ci/hera.sh +++ b/ci/hera.sh @@ -1,8 +1,8 @@ -export GDAS_CI_ROOT=/scratch1/NCEPDEV/da/Cory.R.Martin/CI/GDASApp +export GDAS_CI_ROOT=/scratch1/NCEPDEV/da/role.jedipara/CI/GDASApp export GDAS_CI_HOST='hera' export GDAS_MODULE_USE=$GDAS_CI_ROOT/repo/modulefiles export SLURM_ACCOUNT=da-cpu export SALLOC_ACCOUNT=$SLURM_ACCOUNT export SBATCH_ACCOUNT=$SLURM_ACCOUNT export SLURM_QOS=debug -export PATH=$PATH:/scratch1/NCEPDEV/da/Cory.R.Martin/CI/gh/gh_2.46.0_linux_amd64/bin +export PATH=$PATH:/home/role.jedipara/bin diff --git a/mains/gdas.cc b/mains/gdas.cc old mode 100644 new mode 100755 index 7fdbee0b1..4a894b365 --- a/mains/gdas.cc +++ b/mains/gdas.cc @@ -14,6 +14,7 @@ #include "ufo/instantiateObsFilterFactory.h" #include "ufo/ObsTraits.h" +#include "oops/runs/ConvertToStructuredGrid.h" #include "oops/runs/ConvertState.h" #include "oops/runs/HofX4D.h" #include "oops/runs/LocalEnsembleDA.h" @@ -52,6 +53,9 @@ int runApp(int argc, char** argv, const std::string traits, const std::string ap // Define a map from app names to lambda functions that create unique_ptr to Applications std::map()>> apps; + apps["converttostructuredgrid"] = []() { + return std::make_unique>(); + }; apps["convertstate"] = []() { return std::make_unique>(); }; @@ -96,6 +100,7 @@ int main(int argc, char ** argv) { // Check that the application is recognized // ---------------------------------------- const std::set validApps = { + "converttostructuredgrid", "convertstate", "hofx4d", "localensembleda", diff --git a/modulefiles/GDAS/gaea.intel.lua b/modulefiles/GDAS/gaea.intel.lua index 744995ca7..85d779669 100644 --- a/modulefiles/GDAS/gaea.intel.lua +++ b/modulefiles/GDAS/gaea.intel.lua @@ -43,6 +43,7 @@ load("fftw/3.3.10") load("fckit/0.11.0") load("fiat/1.2.0") load("ectrans/1.2.0") +load("fms/2023.04") load("atlas/0.35.1") load("sp/2.5.0") load("gsl-lite/0.37.0") @@ -74,9 +75,6 @@ load("py-xarray/2023.7.0") load("py-f90nml/1.4.3") load("py-pip/23.1.2") --- hack for wxflow ---prepend_path("PYTHONPATH", "/scratch1/NCEPDEV/da/python/gdasapp/wxflow/20240307/src") - setenv("CC","cc") setenv("CXX","CC") setenv("FC","ftn") diff --git a/modulefiles/GDAS/hera.intel.lua b/modulefiles/GDAS/hera.intel.lua index 109b1e938..613205f6f 100644 --- a/modulefiles/GDAS/hera.intel.lua +++ b/modulefiles/GDAS/hera.intel.lua @@ -43,6 +43,7 @@ load("fftw/3.3.10") load("fckit/0.11.0") load("fiat/1.2.0") --load("ectrans/1.2.0") +load("fms/2023.04") load("atlas/0.35.1") load("sp/2.5.0") load("gsl-lite/0.37.0") @@ -73,9 +74,7 @@ load("py-scipy/1.11.3") load("py-xarray/2023.7.0") load("py-f90nml/1.4.3") load("py-pip/23.1.2") - --- hack for wxflow -prepend_path("PYTHONPATH", "/scratch1/NCEPDEV/da/python/gdasapp/wxflow/20240307/src") +load("py-click/8.1.7") setenv("CC","mpiicc") setenv("FC","mpiifort") @@ -86,9 +85,9 @@ local mpinproc = '-n' setenv('MPIEXEC_EXEC', mpiexec) setenv('MPIEXEC_NPROC', mpinproc) -setenv("CRTM_FIX","/scratch1/NCEPDEV/da/Cory.R.Martin/GDASApp/fix/crtm/2.4.0") -setenv("GDASAPP_TESTDATA","/scratch1/NCEPDEV/da/Cory.R.Martin/CI/GDASApp/data") -setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/scratch1/NCEPDEV/da/Cory.R.Martin/CI/GDASApp/data/test") +setenv("CRTM_FIX","/scratch1/NCEPDEV/da/role.jedipara/GDASApp/fix/crtm/2.4.0") +setenv("GDASAPP_TESTDATA","/scratch1/NCEPDEV/da/role.jedipara/GDASApp/testdata") +setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/scratch1/NCEPDEV/da/role.jedipara/GDASApp/unittestdata") --prepend_path("PATH","/scratch2/NCEPDEV/nwprod/hpc-stack/libs/hpc-stack/intel-18.0.5.274/prod_util/1.2.2/bin") whatis("Name: ".. pkgName) diff --git a/modulefiles/GDAS/hercules.intel.lua b/modulefiles/GDAS/hercules.intel.lua index 0042d6075..fb97a90b7 100644 --- a/modulefiles/GDAS/hercules.intel.lua +++ b/modulefiles/GDAS/hercules.intel.lua @@ -40,6 +40,7 @@ load("fftw/3.3.10") load("fckit/0.11.0") load("fiat/1.2.0") load("ectrans/1.2.0") +load("fms/2023.04") load("atlas/0.35.1") load("sp/2.5.0") load("gsl-lite/0.37.0") @@ -60,7 +61,7 @@ load("py-pybind11/2.11.0") --load("crtm/v2.4_jedi") load("contrib/0.1") load("noaatools/3.1") -load("rocoto/1.3.5") +load("rocoto/1.3.7") load("hpc/1.2.0") unload("python/3.10.13") @@ -79,9 +80,9 @@ local mpinproc = '-n' setenv('MPIEXEC_EXEC', mpiexec) setenv('MPIEXEC_NPROC', mpinproc) -setenv("CRTM_FIX","/work2/noaa/da/cmartin/GDASApp/fix/crtm/2.4.0") -setenv("GDASAPP_TESTDATA","/work2/noaa/da/cmartin/CI/GDASApp/data") -setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/work2/noaa/da/cmartin/CI/GDASApp/data/test/") +setenv("CRTM_FIX","/work2/noaa/da/role-da/GDASApp/fix/crtm/2.4.0") +setenv("GDASAPP_TESTDATA","/work2/noaa/da/role-da/GDASApp/testdata") +setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/work2/noaa/da/role-da/GDASApp/unittestdata") prepend_path("PATH","/apps/contrib/NCEP/libs/hpc-stack/intel-2018.4/prod_util/1.2.2/bin") execute{cmd="ulimit -s unlimited",modeA={"load"}} diff --git a/modulefiles/GDAS/noaacloud.intel.lua b/modulefiles/GDAS/noaacloud.intel.lua index b976d75bc..dec012d26 100644 --- a/modulefiles/GDAS/noaacloud.intel.lua +++ b/modulefiles/GDAS/noaacloud.intel.lua @@ -41,6 +41,7 @@ load("fftw/3.3.10") load("fckit/0.11.0") load("fiat/1.2.0") load("ectrans/1.2.0") +load("fms/2023.04") load("atlas/0.35.1") load("sp/2.5.0") load("gsl-lite/0.37.0") @@ -72,9 +73,6 @@ load("py-xarray/2023.7.0") load("py-f90nml/1.4.3") load("py-pip/23.1.2") --- hack for wxflow ---prepend_path("PYTHONPATH", "/contrib/Wei.Huang/data/glopara/data/gdasapp-wxflow-20240307/src/wxflow") - setenv("CC","mpiicc") setenv("FC","mpiifort") setenv("CXX","mpiicpc") diff --git a/modulefiles/GDAS/orion.intel.lua b/modulefiles/GDAS/orion.intel.lua index 7f5038ac5..1c4c60ac3 100644 --- a/modulefiles/GDAS/orion.intel.lua +++ b/modulefiles/GDAS/orion.intel.lua @@ -6,18 +6,19 @@ local pkgName = myModuleName() local pkgVersion = myModuleVersion() local pkgNameVer = myModuleFullName() -prepend_path("MODULEPATH", '/work/noaa/epic/role-epic/spack-stack/orion/spack-stack-1.6.0/envs/unified-env/install/modulefiles/Core') +prepend_path("MODULEPATH", '/work/noaa/epic/role-epic/spack-stack/orion/spack-stack-1.6.0/envs/unified-env-rocky9/install/modulefiles/Core') prepend_path("MODULEPATH", '/work2/noaa/da/python/opt/modulefiles/stack') -- below two lines get us access to the spack-stack modules -load("stack-intel/2022.0.2") -load("stack-intel-oneapi-mpi/2021.5.1") +load("stack-intel/2021.9.0") +load("stack-intel-oneapi-mpi/2021.9.0") +--load("stack-python/3.10.8") -- JCSDA has 'jedi-fv3-env/unified-dev', but we should load these manually as needed load("cmake/3.23.1") load("curl/8.4.0") load("zlib/1.2.13") -load("git/2.28.0") -load("pkg-config/0.27.1") +load("git/2.31.1") +--load("pkg-config/0.27.1") load("hdf5/1.14.0") load("parallel-netcdf/1.12.2") load("netcdf-c/4.9.2") @@ -25,10 +26,10 @@ load("nccmp/1.9.0.1") load("netcdf-fortran/4.6.1") load("nco/5.0.6") load("parallelio/2.5.10") -load("wget/1.21.3") +load("wget/1.21.1") load("boost/1.83.0") load("bufr/12.0.1") -load("git-lfs/2.12.0") +load("git-lfs/3.1.2") load("ecbuild/3.7.2") load("openjpeg/2.3.1") load("eccodes/2.32.0") @@ -39,11 +40,12 @@ load("fftw/3.3.10") load("fckit/0.11.0") load("fiat/1.2.0") load("ectrans/1.2.0") +load("fms/2023.04") load("atlas/0.35.1") load("sp/2.5.0") load("gsl-lite/0.37.0") load("libjpeg/2.1.0") -load("krb5/1.15.1") +load("krb5/1.20.1") load("libtirpc/1.3.3") load("hdf/4.2.15") load("jedi-cmake/1.4.0") @@ -59,7 +61,7 @@ load("py-pybind11/2.11.0") --load("crtm/v2.4_jedi") load("contrib/0.1") load("noaatools/3.1") -load("rocoto/1.3.3") +load("rocoto/1.3.7") load("hpc/1.2.0") unload("python/3.10.13") @@ -78,9 +80,9 @@ local mpinproc = '-n' setenv('MPIEXEC_EXEC', mpiexec) setenv('MPIEXEC_NPROC', mpinproc) -setenv("CRTM_FIX","/work2/noaa/da/cmartin/GDASApp/fix/crtm/2.4.0") -setenv("GDASAPP_TESTDATA","/work2/noaa/da/cmartin/CI/GDASApp/data") -setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/work2/noaa/da/cmartin/CI/GDASApp/data/test/") +setenv("CRTM_FIX","/work2/noaa/da/role-da/GDASApp/fix/crtm/2.4.0") +setenv("GDASAPP_TESTDATA","/work2/noaa/da/role-da/GDASApp/testdata") +setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/work2/noaa/da/role-da/GDASApp/unittestdata") prepend_path("PATH","/apps/contrib/NCEP/libs/hpc-stack/intel-2018.4/prod_util/1.2.2/bin") execute{cmd="ulimit -s unlimited",modeA={"load"}} diff --git a/modulefiles/GDAS/wcoss2.intel.lua b/modulefiles/GDAS/wcoss2.intel.lua index 4607f0a09..8fb769c96 100644 --- a/modulefiles/GDAS/wcoss2.intel.lua +++ b/modulefiles/GDAS/wcoss2.intel.lua @@ -33,6 +33,7 @@ load("nco/5.0.6") load("gsl/2.7") load("prod_util/2.0.14") load("bufr/12.0.1") +load("fms-C/2023.04") -- hack for pybind11 setenv("pybind11_ROOT", "/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk/lib/python3.8/site-packages/pybind11/share/cmake/pybind11") @@ -40,14 +41,17 @@ setenv("pybind11_ROOT", "/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmj -- hack for git-lfs prepend_path("PATH", "/apps/spack/git-lfs/2.11.0/gcc/11.2.0/m6b6nl5kfqngfteqbggydc7kflxere3s/bin") +-- hack for FMS +setenv('fms_ROOT', '/apps/prod/hpc-stack/i-19.1.3.304__m-8.1.12__h-1.14.0__n-4.9.2__p-2.5.10__e-8.6.0pnetcdf/intel-19.1.3.304/cray-mpich-8.1.12/fms/2023.04') + local mpiexec = '/pe/intel/compilers_and_libraries_2020.4.304/linux/mpi/intel64/bin/mpirun' local mpinproc = '-n' setenv('MPIEXEC_EXEC', mpiexec) setenv('MPIEXEC_NPROC', mpinproc) setenv("CRTM_FIX","/lfs/h2/emc/da/noscrub/emc.da/GDASApp/fix/crtm/2.4.0") -setenv("GDASAPP_TESTDATA","/lfs/h2/emc/da/noscrub/emc.da/GDASApp/data") -setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/lfs/h2/emc/da/noscrub/emc.da/GDASApp/data/test") +setenv("GDASAPP_TESTDATA","/lfs/h2/emc/da/noscrub/emc.da/GDASApp/testdata") +setenv("GDASAPP_UNIT_TEST_DATA_PATH", "/lfs/h2/emc/da/noscrub/emc.da/GDASApp/unittestdata") whatis("Name: ".. pkgName) whatis("Version: ".. pkgVersion) diff --git a/parm/aero/berror/aero_diagb.yaml.j2 b/parm/aero/berror/aero_diagb.yaml.j2 index f8e22f61f..31cf00b34 100644 --- a/parm/aero/berror/aero_diagb.yaml.j2 +++ b/parm/aero/berror/aero_diagb.yaml.j2 @@ -1,3 +1,5 @@ +{% set offset_td = "+6H" | to_timedelta %} +{% set background_time = current_cycle | add_to_datetime(offset_td) %} geometry: fms initialization: namelist filename: ./fv3jedi/fmsmpp.nml @@ -6,13 +8,13 @@ geometry: layout: - {{ layout_x }} - {{ layout_y }} - npx: {{ npx_ges }} - npy: {{ npy_ges }} - npz: {{ npz_ges }} + npx: {{ npx_anl }} + npy: {{ npy_anl }} + npz: {{ npz_anl }} field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml -date: '{{ current_cycle | to_isotime }}' +date: '{{ background_time | to_isotime }}' background: - datetime: '{{ current_cycle | to_isotime }}' + datetime: '{{ background_time | to_isotime }}' filetype: fms restart state variables: [mass_fraction_of_sulfate_in_air, mass_fraction_of_hydrophobic_black_carbon_in_air, @@ -25,9 +27,9 @@ background: mass_fraction_of_sea_salt002_in_air, mass_fraction_of_sea_salt003_in_air, mass_fraction_of_sea_salt004_in_air] datapath: ./bkg - filename_core: '{{ current_cycle | to_fv3time }}.fv_core.res.nc' - filename_trcr: '{{ current_cycle | to_fv3time }}.fv_tracer.res.nc' - filename_cplr: '{{ current_cycle | to_fv3time }}.coupler.res' + filename_core: '{{ background_time | to_fv3time }}.anlres.fv_core.res.nc' + filename_trcr: '{{ background_time | to_fv3time }}.anlres.fv_tracer.res.nc' + filename_cplr: '{{ background_time | to_fv3time }}.anlres.coupler.res' background error: filetype: fms restart @@ -35,6 +37,28 @@ background error: filename_trcr: stddev.fv_tracer.res.nc filename_cplr: stddev.coupler.res +climate background error: + geometry: + fms initialization: + namelist filename: ./fv3jedi/fmsmpp.nml + field table filename: ./fv3jedi/field_table + akbk: ./fv3jedi/akbk.nc4 + layout: + - {{ layout_x }} + - {{ layout_y }} + npx: {{ npx_clim_b }} + npy: {{ npy_clim_b }} + npz: {{ npz_ges }} + field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml + climate background error stddev: + filetype: fms restart + skip coupler file: true + datapath: ./clm_stddev + filename_trcr: stddev.fv_tracer.res.nc + filename_cplr: stddev.coupler.res + diagb weight: {{ aero_diagb_weight }} + staticb rescaling factor: {{ aero_staticb_rescaling_factor }} + variables: name: - mass_fraction_of_sulfate_in_air @@ -52,9 +76,9 @@ variables: - mass_fraction_of_sea_salt003_in_air - mass_fraction_of_sea_salt004_in_air -rescale: 2.0 # rescales the filtered std. dev. by "rescale" -number of halo points: 4 -number of neighbors: 16 +rescale: {{ aero_diagb_rescale }} # rescales the filtered std. dev. by "rescale" +number of halo points: {{ aero_diagb_n_halo }} +number of neighbors: {{ aero_diagb_n_neighbors }} simple smoothing: - horizontal iterations: 0 - vertical iterations: 0 + horizontal iterations: {{ aero_diagb_smooth_horiz_iter }} + vertical iterations: {{ aero_diagb_smooth_vert_iter }} diff --git a/parm/aero/berror/aero_diffusionparm.yaml.j2 b/parm/aero/berror/aero_diffusionparm.yaml.j2 index d0b982a6e..9423bdffa 100644 --- a/parm/aero/berror/aero_diffusionparm.yaml.j2 +++ b/parm/aero/berror/aero_diffusionparm.yaml.j2 @@ -1,20 +1,25 @@ +{% set offset_td = "+6H" | to_timedelta %} +{% set background_time = current_cycle | add_to_datetime(offset_td) %} geometry: fms initialization: namelist filename: ./fv3jedi/fmsmpp.nml field table filename: ./fv3jedi/field_table akbk: ./fv3jedi/akbk.nc4 - npx: {{ npx_ges }} - npy: {{ npy_ges }} - npz: {{ npz_ges }} + layout: + - {{ layout_x }} + - {{ layout_y }} + npx: {{ npx_anl }} + npy: {{ npy_anl }} + npz: {{ npz_anl }} field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml -date: '{{ current_cycle | to_isotime }}' +date: '{{ background_time | to_isotime }}' background: - datetime: '{{ current_cycle | to_isotime }}' + datetime: '{{ background_time | to_isotime }}' filetype: fms restart datapath: ./bkg - filename_core: '{{ current_cycle | to_fv3time }}.fv_core.res.nc' - filename_trcr: '{{ current_cycle | to_fv3time }}.fv_tracer.res.nc' - filename_cplr: '{{ current_cycle | to_fv3time }}.coupler.res' + filename_core: '{{ background_time | to_fv3time }}.anlres.fv_core.res.nc' + filename_trcr: '{{ background_time | to_fv3time }}.anlres.fv_tracer.res.nc' + filename_cplr: '{{ background_time | to_fv3time }}.anlres.coupler.res' state variables: [mass_fraction_of_sulfate_in_air, mass_fraction_of_hydrophobic_black_carbon_in_air, mass_fraction_of_hydrophilic_black_carbon_in_air, @@ -32,16 +37,16 @@ background error: saber block name: diffusion calibration: normalization: - iterations: {{ diff_iter }} + iterations: {{ aero_diffusion_iter }} groups: - horizontal: - fixed value: {{ horiz_len }} + fixed value: {{ aero_diffusion_horiz_len }} write: - filepath: ./diffusion_hz + filepath: "{{ DATA }}/diffusion/diffusion_hz" - vertical: levels: {{ npz_ges }} - fixed value: {{ fixed_val }} + fixed value: {{ aero_diffusion_fixed_val }} as gaussian: true write: - filepath: ./diffusion_vt + filepath: "{{ DATA }}/diffusion/diffusion_vt" diff --git a/parm/aero/berror/aero_interp.yaml.j2 b/parm/aero/berror/aero_interp.yaml.j2 new file mode 100644 index 000000000..674345e53 --- /dev/null +++ b/parm/aero/berror/aero_interp.yaml.j2 @@ -0,0 +1,50 @@ +{% set offset_td = "+6H" | to_timedelta %} +{% set background_time = current_cycle | add_to_datetime(offset_td) %} +input geometry: + fms initialization: + namelist filename: ./fv3jedi/fmsmpp.nml + field table filename: ./fv3jedi/field_table + akbk: ./fv3jedi/akbk.nc4 + layout: + - {{ layout_x }} + - {{ layout_y }} + npx: {{ npx_ges }} + npy: {{ npy_ges }} + npz: {{ npz_ges }} + field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml +output geometry: + fms initialization: + namelist filename: ./fv3jedi/fmsmpp.nml + field table filename: ./fv3jedi/field_table + akbk: ./fv3jedi/akbk.nc4 + layout: + - {{ layout_x }} + - {{ layout_y }} + npx: {{ npx_anl }} + npy: {{ npy_anl }} + npz: {{ npz_anl }} + field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml +states: +- input: + datetime: '{{ background_time | to_isotime }}' + filetype: fms restart + state variables: [mass_fraction_of_sulfate_in_air, + mass_fraction_of_hydrophobic_black_carbon_in_air, + mass_fraction_of_hydrophilic_black_carbon_in_air, + mass_fraction_of_hydrophobic_organic_carbon_in_air, + mass_fraction_of_hydrophilic_organic_carbon_in_air, + mass_fraction_of_dust001_in_air, mass_fraction_of_dust002_in_air, + mass_fraction_of_dust003_in_air, mass_fraction_of_dust004_in_air, + mass_fraction_of_dust005_in_air, mass_fraction_of_sea_salt001_in_air, + mass_fraction_of_sea_salt002_in_air, mass_fraction_of_sea_salt003_in_air, + mass_fraction_of_sea_salt004_in_air] + datapath: ./bkg + filename_core: '{{ background_time | to_fv3time }}.fv_core.res.nc' + filename_trcr: '{{ background_time | to_fv3time }}.fv_tracer.res.nc' + filename_cplr: '{{ background_time | to_fv3time }}.coupler.res' + output: + filetype: fms restart + datapath: ./bkg + filename_core: 'anlres.fv_core.res.nc' + filename_trcr: 'anlres.fv_tracer.res.nc' + filename_cplr: 'anlres.coupler.res' diff --git a/parm/aero/berror/staticb_diffusion.yaml.j2 b/parm/aero/berror/staticb_diffusion.yaml.j2 new file mode 100644 index 000000000..c43891d1f --- /dev/null +++ b/parm/aero/berror/staticb_diffusion.yaml.j2 @@ -0,0 +1,33 @@ +covariance model: SABER +saber central block: + saber block name: diffusion + read: + groups: + - variables: [mass_fraction_of_sulfate_in_air, + mass_fraction_of_hydrophobic_black_carbon_in_air, + mass_fraction_of_hydrophilic_black_carbon_in_air, + mass_fraction_of_hydrophobic_organic_carbon_in_air, + mass_fraction_of_hydrophilic_organic_carbon_in_air, + mass_fraction_of_dust001_in_air, mass_fraction_of_dust002_in_air, + mass_fraction_of_dust003_in_air, mass_fraction_of_dust004_in_air, + mass_fraction_of_dust005_in_air, mass_fraction_of_sea_salt001_in_air, + mass_fraction_of_sea_salt002_in_air, mass_fraction_of_sea_salt003_in_air, + mass_fraction_of_sea_salt004_in_air] + horizontal: + filepath: "{{ DATA }}/berror/diffusion_hz" + vertical: + levels: {{ npz_ges }} + filepath: "{{ DATA }}/berror/diffusion_vt" +saber outer blocks: +- saber block name: StdDev + read: + model file: + datetime: '{{ current_cycle | to_isotime }}' + set datetime on read: true + filetype: fms restart + psinfile: true + datapath: "{{ DATA }}/berror" + filename_core: '{{ current_cycle | to_fv3time }}.stddev.fv_core.res.nc' + filename_trcr: '{{ current_cycle | to_fv3time }}.stddev.fv_tracer.res.nc' + filename_cplr: '{{ current_cycle | to_fv3time }}.stddev.coupler.res' + date: '{{ current_cycle | to_isotime }}' diff --git a/parm/aero/variational/3dvar_fgat_gfs_aero.yaml.j2 b/parm/aero/variational/3dvar_fgat_gfs_aero.yaml.j2 index 3dff3763e..751cbdf53 100644 --- a/parm/aero/variational/3dvar_fgat_gfs_aero.yaml.j2 +++ b/parm/aero/variational/3dvar_fgat_gfs_aero.yaml.j2 @@ -96,6 +96,8 @@ variational: final: diagnostics: departures: anlmob + prints: + frequency: PT3H increment: geometry: fms initialization: @@ -120,3 +122,13 @@ final: state variables: [t,delp,sphum,so4,bc1,bc2,oc1,oc2, dust1,dust2,dust3,dust4,dust5, seas1,seas2,seas3,seas4] + increment to structured grid: + grid type: regular gaussian + local interpolator type: atlas interpolator + interpolation method: + type: finite-element + number of latitude gridpoints: {{ npy_ges - 1 }} + variables to output: *3dvars + all model levels: true + datapath: ./anl + prefix: aeroinc_gauss diff --git a/parm/aero/variational/3dvar_gfs_aero.yaml.j2 b/parm/aero/variational/3dvar_gfs_aero.yaml.j2 index 356eb721f..905d991e3 100644 --- a/parm/aero/variational/3dvar_gfs_aero.yaml.j2 +++ b/parm/aero/variational/3dvar_gfs_aero.yaml.j2 @@ -87,6 +87,8 @@ variational: final: diagnostics: departures: anlmob + prints: + frequency: PT3H increment: geometry: fms initialization: @@ -111,3 +113,13 @@ final: state variables: [t,delp,sphum,so4,bc1,bc2,oc1,oc2, dust1,dust2,dust3,dust4,dust5, seas1,seas2,seas3,seas4] + increment to structured grid: + grid type: regular gaussian + local interpolator type: atlas interpolator + interpolation method: + type: finite-element + number of latitude gridpoints: {{ npy_ges - 1 }} + variables to output: *3dvars + all model levels: true + datapath: ./anl + prefix: aeroinc_gauss diff --git a/parm/atm/jcb-base.yaml.j2 b/parm/atm/jcb-base.yaml.j2 index c8b85d564..6387fffbb 100644 --- a/parm/atm/jcb-base.yaml.j2 +++ b/parm/atm/jcb-base.yaml.j2 @@ -10,65 +10,59 @@ app_path_observation_chronicle: "{{PARMgfs}}/gdas/jcb-gdas/observation_chronicle # Places where we deviate from the generic file name of a yaml # ------------------------------------------------------------ #final_increment_file: final_increment_gaussian -final_increment_file: final_increment_cubed_sphere -output_ensemble_increments_file: output_ensemble_increments_cubed_sphere -model_file: model_pseudo -initial_condition_file: background # Initial conditions for 4D apps is background - +final_increment_file: atmosphere_final_increment_cubed_sphere +output_ensemble_increments_file: atmosphere_output_ensemble_increments_cubed_sphere +model_file: atmosphere_model_pseudo +initial_condition_file: atmosphere_background # Initial conditions for 4D apps is background +background_error_file: "{{BERROR_YAML}}" -# Assimilation window -# ------------------- +# Assimilation standard things (not prepended with model choice) +# ---------------------------- window_begin: "{{ ATM_WINDOW_BEGIN | to_isotime }}" window_length: "{{ ATM_WINDOW_LENGTH }}" bound_to_include: begin - -# Default background time is for 3D applications -atm_background_time_iso: "{{ current_cycle | to_isotime }}" - - -# Analysis standard things -# ------------------------ -analysis_variables: [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr] minimizer: DRPCG final_diagnostics_departures: anlmob - -cost_type: 3D-Var +final_prints_frequency: PT3H number_of_outer_loops: 2 +analysis_variables: [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr] # Model things # ------------ # Geometry -layout_x: {{ layout_x | default(1, true) }} -layout_y: {{ layout_y | default(1, true) }} -npx_ges: {{ npx_ges | default(49, true) }} -npy_ges: {{ npy_ges | default(49, true) }} -npz_ges: {{ npz_ges | default(127, true) }} -npx_anl: {{ npx_anl | default(49, true) }} -npy_anl: {{ npy_anl | default(49, true) }} -npz_anl: {{ npz_anl | default(127, true) }} +atmosphere_layout_x: {{ layout_x | default(1, true) }} +atmosphere_layout_y: {{ layout_y | default(1, true) }} +atmosphere_npx_ges: {{ npx_ges | default(49, true) }} +atmosphere_npy_ges: {{ npy_ges | default(49, true) }} +atmosphere_npz_ges: {{ npz_ges | default(127, true) }} +atmosphere_npx_anl: {{ npx_anl | default(49, true) }} +atmosphere_npy_anl: {{ npy_anl | default(49, true) }} +atmosphere_npz_anl: {{ npz_anl | default(127, true) }} -fv3jedi_files_path: ./fv3jedi # Ideally this would be {{DATA}}/fv3jedi but FMS +atmosphere_fv3jedi_files_path: ./fv3jedi # Ideally this would be {{DATA}}/fv3jedi but FMS # Background -background_path: ./bkg -background_ensemble_path: ./ens/mem%mem% +atmosphere_background_path: ./bkg +atmosphere_background_ensemble_path: ./ens/mem%mem% + +# Default background time is for 3D applications +atmosphere_background_time_iso: "{{ current_cycle | to_isotime }}" # Background error -bump_data_directory: "{{ DATA }}/berror" -gsibec_path: "{{ DATA }}/berror" -number_ensemble_members: {{ NMEM_ENS | default(1, true) }} -layout_gsib_x: {{ layout_gsib_x | default(1, true) }} -layout_gsib_y: {{ layout_gsib_y | default(1, true) }} +atmosphere_bump_data_directory: "{{ DATA }}/berror" +atmosphere_gsibec_path: "{{ DATA }}/berror" +atmosphere_number_ensemble_members: {{ NMEM_ENS | default(1, true) }} +atmosphere_layout_gsib_x: {{ layout_gsib_x | default(1, true) }} +atmosphere_layout_gsib_y: {{ layout_gsib_y | default(1, true) }} -background_error_file: "{{BERROR_YAML}}" # Forecasting -forecast_length: "{{ ATM_WINDOW_LENGTH }}" -forecast_timestep: "{{ BKG_TSTEP }}" +atmosphere_forecast_timestep: "{{ BKG_TSTEP }}" # Write final increment on Guassian grid in variational -final_increment_prefix: "./anl/atminc." +atmosphere_final_increment_prefix: "./anl/atminc." +atmosphere_variational_history_prefix: "{{GPREFIX}}" # Observation things # ------------------ @@ -77,35 +71,35 @@ observations: all_observations crtm_coefficient_path: "{{ DATA }}/crtm/" # Naming conventions for observational files -atm_obsdatain_path: "{{atm_obsdatain_path}}" -atm_obsdatain_prefix: "{{OPREFIX}}" -atm_obsdatain_suffix: ".tm00.nc" +atmosphere_obsdatain_path: "{{atm_obsdatain_path}}" +atmosphere_obsdatain_prefix: "{{OPREFIX}}" +atmosphere_obsdatain_suffix: ".tm00.nc" -atm_obsdataout_path: "{{atm_obsdataout_path}}" -atm_obsdataout_prefix: diag_ -atm_obsdataout_suffix: "_{{ current_cycle | to_YMDH }}.nc" +atmosphere_obsdataout_path: "{{atm_obsdataout_path}}" +atmosphere_obsdataout_prefix: diag_ +atmosphere_obsdataout_suffix: "_{{ current_cycle | to_YMDH }}.nc" # Naming conventions for bias correction files -atm_obsbiasin_path: "{{DATA}}/obs/" -atm_obsbiasin_prefix: "{{GPREFIX}}" -atm_obsbiasin_suffix: ".satbias.nc" -atm_obstlapsein_prefix: "{{GPREFIX}}" -atm_obstlapsein_suffix: ".tlapse.txt" -atm_obsbiascovin_prefix: "{{GPREFIX}}" -atm_obsbiascovin_suffix: ".satbias_cov.nc" +atmosphere_obsbiasin_path: "{{DATA}}/obs/" +atmosphere_obsbiasin_prefix: "{{GPREFIX}}" +atmosphere_obsbiasin_suffix: ".satbias.nc" +atmosphere_obstlapsein_prefix: "{{GPREFIX}}" +atmosphere_obstlapsein_suffix: ".tlapse.txt" +atmosphere_obsbiascovin_prefix: "{{GPREFIX}}" +atmosphere_obsbiascovin_suffix: ".satbias_cov.nc" -atm_obsbiasout_path: "{{DATA}}/bc/" -atm_obsbiasout_prefix: "{{APREFIX}}" -atm_obsbiasout_suffix: ".satbias.nc" -atm_obsbiascovout_prefix: "{{APREFIX}}" -atm_obsbiascovout_suffix: ".satbias_cov.nc" +atmosphere_obsbiasout_path: "{{DATA}}/bc/" +atmosphere_obsbiasout_prefix: "{{APREFIX}}" +atmosphere_obsbiasout_suffix: ".satbias.nc" +atmosphere_obsbiascovout_prefix: "{{APREFIX}}" +atmosphere_obsbiascovout_suffix: ".satbias_cov.nc" # Local Ensemble DA (LETKF) # ------------------------- local_ensemble_da_solver: GETKF -increment_variables: [ua,va,DZ,delp,t,ps,sphum,ice_wat,liq_wat,o3mr] +increment_variables: [ua,va,delz,delp,t,ps,sphum,ice_wat,liq_wat,o3mr] # Veritcal localization for GETKF vl_fraction_of_retained_variance: 0.750 @@ -123,6 +117,11 @@ driver_save_prior_mean: false driver_save_posterior_mean_increment: false driver_save_posterior_ensemble_increments: true +# Distribution type +distribution_type: Halo + # Diagnostics -ensemble_increment_prefix: "./anl/mem%{member}%/atminc." -posterior_output_gaussian: "./mem%{member}%/atmanl." +atmosphere_ensemble_increment_prefix: "./anl/mem%{member}%/atminc." +atmosphere_posterior_output_gaussian: "./mem%{member}%/atmanl." + +atmosphere_ensemble_history_prefix: "enkf{{GPREFIX}}" diff --git a/parm/atm/jcb-prototype_3dvar.yaml.j2 b/parm/atm/jcb-prototype_3dvar.yaml.j2 index c8fb9308f..7b6c80011 100644 --- a/parm/atm/jcb-prototype_3dvar.yaml.j2 +++ b/parm/atm/jcb-prototype_3dvar.yaml.j2 @@ -5,10 +5,27 @@ algorithm: 3dvar # Observation things # ------------------ observations: - - satwnd.abi_goes-16 +# - ADPSFC +# - ADPUPA +# - SFCSHP + - aircraft - ascatw.ascat_metop-b - #- conv_ps # Turned off until naming convention of obs files is resolved. - #- gnssro # Turned off until naming convention of obs files is resolved. +# - ascatw.ascat_metop-c + - atms_n20 +# - atms_npp + - conventional_ps + - gnssro +# - gpsro +# - mtiasi_metop-a +# - mtiasi_metop-b +# - ompsnp_n20 - ompsnp_npp +# - ompstc_n20 - ompstc_npp - - omi_aura + - satwnd.abi_goes-16 +# - satwnd.abi_goes-18 +# - satwnd.leogeo_multi +# - satwnd.viirs_n20 +# - satwnd.viirs_npp +# - scatwind_ascat_metop-a +# - snowcvr diff --git a/parm/atm/jcb-prototype_lgetkf.yaml.j2 b/parm/atm/jcb-prototype_lgetkf.yaml.j2 index 54600b7d1..a1b099bb6 100644 --- a/parm/atm/jcb-prototype_lgetkf.yaml.j2 +++ b/parm/atm/jcb-prototype_lgetkf.yaml.j2 @@ -1,7 +1,7 @@ # Use observations for lgetkf # --------------------------- app_path_observations: {{PARMgfs}}/gdas/jcb-gdas/observations/atmosphere-lgetkf -app_path_observation_chronicle: {{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/atmosphere-lgetkf +app_path_observation_chronicle: {{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/atmosphere # Algorithm # --------- @@ -9,12 +9,32 @@ algorithm: local_ensemble_da # Model things # ------------ -background_ensemble_path: ./bkg/mem%mem% +atmosphere_background_ensemble_path: ./bkg/mem%mem% # Observation things # ------------------ observations: - - satwnd.abi_goes-16 +# - ADPSFC +# - ADPUPA +# - SFCSHP + - aircraft - ascatw.ascat_metop-b - #- conv_ps # Turned off until naming convention of obs files is resolved. - #- gnssro # Turned off until naming convention of obs files is resolved. +# - ascatw.ascat_metop-c + - atms_n20 + - atms_npp + - conventional_ps + - gnssro +# - gpsro +# - mtiasi_metop-a +# - mtiasi_metop-b +# - ompsnp_n20 + - ompsnp_npp +# - ompstc_n20 + - ompstc_npp + - satwnd.abi_goes-16 + - satwnd.abi_goes-18 + - satwnd.leogeo_multi + - satwnd.viirs_n20 + - satwnd.viirs_npp +# - scatwind_ascat_metop-a +# - snowcvr diff --git a/parm/atm/jcb-prototype_lgetkf_observer.yaml.j2 b/parm/atm/jcb-prototype_lgetkf_observer.yaml.j2 new file mode 100644 index 000000000..26654b175 --- /dev/null +++ b/parm/atm/jcb-prototype_lgetkf_observer.yaml.j2 @@ -0,0 +1,46 @@ +# Use observations for lgetkf +# --------------------------- +app_path_observations: {{PARMgfs}}/gdas/jcb-gdas/observations/atmosphere-lgetkf +app_path_observation_chronicle: {{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/atmosphere + +# Algorithm +# --------- +algorithm: local_ensemble_da_observer + +# Model things +# ------------ +atmosphere_background_ensemble_path: ./bkg/mem%mem% + +# Observation things +# ------------------ +observations: +# - ADPSFC +# - ADPUPA +# - SFCSHP + - aircraft + - ascatw.ascat_metop-b +# - ascatw.ascat_metop-c + - atms_n20 +# - atms_npp + - conventional_ps + - gnssro +# - gpsro +# - mtiasi_metop-a +# - mtiasi_metop-b +# - ompsnp_n20 + - ompsnp_npp +# - ompstc_n20 + - ompstc_npp + - satwnd.abi_goes-16 +# - satwnd.abi_goes-18 +# - satwnd.leogeo_multi +# - satwnd.viirs_n20 +# - satwnd.viirs_npp +# - scatwind_ascat_metop-a +# - snowcvr + +# Naming conventions for observation files +atmosphere_obsdataout_prefix: diag_lobs_ + +# Distribution type +distribution_type: RoundRobin diff --git a/parm/atm/jcb-prototype_lgetkf_solver.yaml.j2 b/parm/atm/jcb-prototype_lgetkf_solver.yaml.j2 new file mode 100644 index 000000000..677934158 --- /dev/null +++ b/parm/atm/jcb-prototype_lgetkf_solver.yaml.j2 @@ -0,0 +1,49 @@ +# Use observations for lgetkf +# --------------------------- +app_path_observations: {{PARMgfs}}/gdas/jcb-gdas/observations/atmosphere-lgetkf +app_path_observation_chronicle: {{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/atmosphere + +# Algorithm +# --------- +algorithm: local_ensemble_da_solver + +# Model things +# ------------ +atmosphere_background_ensemble_path: ./bkg/mem%mem% + +# Observation things +# ------------------ +observations: +# - ADPSFC +# - ADPUPA +# - SFCSHP + - aircraft + - ascatw.ascat_metop-b +# - ascatw.ascat_metop-c + - atms_n20 +# - atms_npp + - conventional_ps + - gnssro +# - gpsro +# - mtiasi_metop-a +# - mtiasi_metop-b +# - ompsnp_n20 + - ompsnp_npp +# - ompstc_n20 + - ompstc_npp + - satwnd.abi_goes-16 +# - satwnd.abi_goes-18 +# - satwnd.leogeo_multi +# - satwnd.viirs_n20 +# - satwnd.viirs_npp +# - scatwind_ascat_metop-a +# - snowcvr + +# Naming conventions for observation files +atmosphere_obsdatain_path: "{{atm_obsdataout_path}}" +atmosphere_obsdatain_prefix: diag_lobs_ +atmosphere_obsdatain_suffix: "_{{ current_cycle | to_YMDH }}.nc" +atmosphere_obsdataout_prefix: diag_solv_ + +# Distribution type +distribution_type: Halo diff --git a/parm/atm/obs/config/satwind_modis_aqua.yaml.j2 b/parm/atm/obs/config/satwind_modis_aqua.yaml.j2 deleted file mode 100644 index df98cd4f5..000000000 --- a/parm/atm/obs/config/satwind_modis_aqua.yaml.j2 +++ /dev/null @@ -1,356 +0,0 @@ -- obs space: - name: satwind_modis_aqua - obsdatain: - engine: - type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}satwnd.modis_aqua.tm00.nc' - obsdataout: - engine: - type: H5File - obsfile: '{{ DATA }}/diags/diag_satwind_modis_aqua_{{ current_cycle | to_YMDH }}.nc' - io pool: - max pool size: 1 - simulated variables: [windEastward, windNorthward] - - obs operator: - name: VertInterp - hofx scaling field: SurfaceWindScalingPressure - hofx scaling field group: DerivedVariables - - linear obs operator: - name: VertInterp - - # NOTE: Tests using the Gaussian Thinning filter (below) to duplicate GSI's thinning of AHI/Himawari-8 satwinds - # results in more JEDI satwinds in the diag file than in GSI, but far fewer JEDI satwinds assimilated than - # GSI. JEDI under-counts assimilated winds by roughly 25-40%, relative to GSI, and this under-count is not - # even including the temporal thinning which is applied in GSI but not JEDI (by this filter below). See - # GDASApp Issue #741 for details: https://github.com/NOAA-EMC/GDASApp/issues/741 - #obs pre filters: - #- filter: Gaussian Thinning - # horizontal_mesh: 200 - # vertical_mesh: 10000 - # use_reduced_horizontal_grid: true - # round_horizontal_bin_count_to_nearest: true - # partition_longitude_bins_using_mesh: true - - obs prior filters: - # Apply variable changes needed for wind scaling - # For wind observations with pressure provided - - filter: Variable Transforms - Transform: SurfaceWindScalingPressure - SkipWhenNoObs: False - - # Calculate error inflation factor for duplicate observations - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windEastward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windEastward - - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windNorthward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windNorthward - - obs post filters: - # Assign the initial observation error, based on height/pressure - # Hard-wiring to prepobs_errtable.global by Type - # ObsError is currently not updating in diag file, but passes directly to EffectiveError when no inflation is specified in YAML - - # Type 257 (MODIS LWIR) - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 257 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,105000.,100000.,95000.,90000.,85000.,80000.,75000.,70000.,65000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.9,3.9,4.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # Type 258 (MODIS WVCT): Some levels assigned dummy values - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 258 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [1000000000.,1000000000.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # Type 259 (MODIS WVDL): Some levels assigned dummy values - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 259 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [1000000000.,1000000000.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # sanity-check criteria - # Observation Range Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - minvalue: -130. - maxvalue: 130. - action: - name: reject - - # Velocity Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/Velocity - maxvalue: 130. - action: - name: reject - - # MODIS-Aqua/Terra (257) and (259), reject when pressure less than 249 mb. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 257,259 - test variables: - - name: MetaData/pressure - minvalue: 24900. - action: - name: reject - - # MODIS-Aqua/Terra (258) and (259), reject when pressure greater than 600 mb. - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - # maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 258, 259 - test variables: - - name: MetaData/pressure - maxvalue: 60000. - action: - name: reject - - # Reject any observation with a /=0 surface type (non-water surface) within - # 200 hPa of the surface pressure (as part of the LNVD check). - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: - name: GeoVaLs/water_area_fraction - maxvalue: 0.99 - reference: GeoVaLs/surface_pressure - value: MetaData/pressure - maxvalue: -20000. # within 200 hPa above surface pressure, negative p-diff - action: - name: reject - - # LNVD check - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/SatWindsLNVDCheck - maxvalue: 3. - action: - name: reject - - # GSI setupw routine QC - # Reject any ob Type [240–260] when pressure greater than 950 mb. - # CLEARED: minvalue/maxvalue are >=/<=, not >/<, so editing range by 1 Pa - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 240-260 - test variables: - - name: MetaData/pressure - maxvalue: 95001. - action: - name: reject - - # Multiple satellite platforms, reject when pressure is more than 50 mb above tropopause. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - # Notes (eliu): This tropopause check reject too many obs; probably due to tropopause pressure estimation - # Turn this check off for now. - # Need to check if troposphere pressure was implemented correctly in fv3-jed - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - reference: GeoVaLs/tropopause_pressure - value: MetaData/pressure - minvalue: -5000. # 50 hPa above tropopause level, negative p-diff - action: - name: reject - - # All satwinds must adjust errors based on ObsErrorFactorPressureCheck - # prior to the SPDB check (i.e. the gross-error check). The gross-error - # check uses the adjusted errors for error-bound tightening and rejection, - # so this check has to come first. This check will inflate errors for obs - # that are too close to either the model top or bottom. - # Notes (eliu): GMAO added a required parameter: adjusted_error_name. - - filter: Perform Action - filter variables: - - name: windEastward - where: - - variable: - name: ObsType/windEastward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - surface_obs: false - variable: windEastward - inflation factor: 4.0 - - - filter: Perform Action - filter variables: - - name: windNorthward - where: - - variable: - name: ObsType/windNorthward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - variable: windNorthward - inflation factor: 4.0 - - # All satwinds subject to a gross-error check that contains significant - # modifiers for satwinds with a negative speed-bias. ALL wind gross-error - # checks are currently being done by the SatWindsSPDBCheck. - # CLEARED - - filter: Background Check - filter variables: - - name: windEastward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windEastward - action: - name: reject - - - filter: Background Check - filter variables: - - name: windNorthward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windNorthward - action: - name: reject - - # The last error inflation check is for duplicate observations. This one needs - # to come last, because we don't want to inflate errors for duplication if one - # of the duplicates should be rejected. - # Notes (eliu): ObsErrorFactorDuplicateCheck obsfunction requires PreUseFlag (usage parameter from read_satwnd.f90). - # : Turn off duplicate check for now. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windEastward - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windNorthward - - # We are extending this to an additional filter that inflates final ob-errors across-the-board by - # 1/0.8 = 1.25. This is caused by the GSI value of nvqc being set to .true. in the global operational - # configuration, see: https://github.com/NOAA-EMC/global-workflow/blob/d5ae3328fa4041b177357b1133f6b92e81c859d7/scripts/exglobal_atmos_analysis.sh#L750 - # This setting activates Line 1229 of setupw.f90 to scale ratio_errors by 0.8, which is applied in - # the denominator of the final ob-error, so 1/0.8 = 1.25 factor of ob-error inflation. - # - # If this nvqc functionality were to be switched off (i.e. if variational qc were to be turned off), - # you would want to remove this last inflation filter. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # where: - # - variable: ObsType/windEastward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # where: - # - variable: ObsType/windNorthward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - # End of Filters diff --git a/parm/atm/obs/config/satwind_modis_terra.yaml.j2 b/parm/atm/obs/config/satwind_modis_terra.yaml.j2 deleted file mode 100644 index ee50733b4..000000000 --- a/parm/atm/obs/config/satwind_modis_terra.yaml.j2 +++ /dev/null @@ -1,368 +0,0 @@ -- obs space: - name: satwind_modis_terra - obsdatain: - engine: - type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}satwnd.modis_terra.tm00.nc' - obsdataout: - engine: - type: H5File - obsfile: '{{ DATA }}/diags/diag_satwind_modis_terra_{{ current_cycle | to_YMDH }}.nc' - io pool: - max pool size: 1 - simulated variables: [windEastward, windNorthward] - - obs operator: - name: VertInterp - hofx scaling field: SurfaceWindScalingPressure - hofx scaling field group: DerivedVariables - - linear obs operator: - name: VertInterp - - # NOTE: Tests using the Gaussian Thinning filter (below) to duplicate GSI's thinning of AHI/Himawari-8 satwinds - # results in more JEDI satwinds in the diag file than in GSI, but far fewer JEDI satwinds assimilated than - # GSI. JEDI under-counts assimilated winds by roughly 25-40%, relative to GSI, and this under-count is not - # even including the temporal thinning which is applied in GSI but not JEDI (by this filter below). See - # GDASApp Issue #741 for details: https://github.com/NOAA-EMC/GDASApp/issues/741 - #obs pre filters: - #- filter: Gaussian Thinning - # horizontal_mesh: 200 - # vertical_mesh: 10000 - # use_reduced_horizontal_grid: true - # round_horizontal_bin_count_to_nearest: true - # partition_longitude_bins_using_mesh: true - - obs prior filters: - # Apply variable changes needed for wind scaling - # For wind observations with pressure provided - - filter: Variable Transforms - Transform: SurfaceWindScalingPressure - SkipWhenNoObs: False - - # Calculate error inflation factor for duplicate observations - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windEastward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windEastward - - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windNorthward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windNorthward - - obs post filters: - # Assign the initial observation error, based on height/pressure - # Hard-wiring to prepobs_errtable.global by Type - # ObsError is currently not updating in diag file, but passes directly to EffectiveError when no inflation is specified in YAML - - # Type 257 (MODIS LWIR) - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 257 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,105000.,100000.,95000.,90000.,85000.,80000.,75000.,70000.,65000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.9,3.9,4.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # Type 258 (MODIS WVCT): Some levels assigned dummy values - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 258 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [1000000000.,1000000000.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # Type 259 (MODIS WVDL): Some levels assigned dummy values - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 259 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] #Pressure (Pa) - errors: [1000000000.,1000000000.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # sanity-check criteria - # Observation Range Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - minvalue: -130. - maxvalue: 130. - action: - name: reject - - # Velocity Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/Velocity - maxvalue: 130. - action: - name: reject - - # MODIS-TERRA: reject any WVCT (258) or WVDL (259) satwind - # NOTE: This restriction does NOT apply to MODIS-AQUA - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 258,259 - action: - name: reject - - # MODIS-Aqua/Terra (257) and (259), reject when pressure less than 249 mb. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 257,259 - test variables: - - name: MetaData/pressure - minvalue: 24900. - action: - name: reject - - # MODIS-Aqua/Terra (258) and (259), reject when pressure greater than 600 mb. - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - # maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 258, 259 - test variables: - - name: MetaData/pressure - maxvalue: 60000. - action: - name: reject - - # Reject any observation with a /=0 surface type (non-water surface) within - # 200 hPa of the surface pressure (as part of the LNVD check). - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: - name: GeoVaLs/water_area_fraction - maxvalue: 0.99 - reference: GeoVaLs/surface_pressure - value: MetaData/pressure - maxvalue: -20000. # within 200 hPa above surface pressure, negative p-diff - action: - name: reject - - # LNVD check - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/SatWindsLNVDCheck - maxvalue: 3. - action: - name: reject - - # GSI setupw routine QC - # Reject any ob Type [240–260] when pressure greater than 950 mb. - # CLEARED: minvalue/maxvalue are >=/<=, not >/<, so editing range by 1 Pa - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 240-260 - test variables: - - name: MetaData/pressure - maxvalue: 95001. - action: - name: reject - - # Multiple satellite platforms, reject when pressure is more than 50 mb above tropopause. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - # Notes (eliu): This tropopause check reject too many obs; probably due to tropopause pressure estimation - # Turn this check off for now. - # Need to check if troposphere pressure was implemented correctly in fv3-jed - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - reference: GeoVaLs/tropopause_pressure - value: MetaData/pressure - minvalue: -5000. # 50 hPa above tropopause level, negative p-diff - action: - name: reject - - # All satwinds must adjust errors based on ObsErrorFactorPressureCheck - # prior to the SPDB check (i.e. the gross-error check). The gross-error - # check uses the adjusted errors for error-bound tightening and rejection, - # so this check has to come first. This check will inflate errors for obs - # that are too close to either the model top or bottom. - # Notes (eliu): GMAO added a required parameter: adjusted_error_name. - - filter: Perform Action - filter variables: - - name: windEastward - where: - - variable: - name: ObsType/windEastward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - surface_obs: false - variable: windEastward - inflation factor: 4.0 - - - filter: Perform Action - filter variables: - - name: windNorthward - where: - - variable: - name: ObsType/windNorthward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - variable: windNorthward - inflation factor: 4.0 - - # All satwinds subject to a gross-error check that contains significant - # modifiers for satwinds with a negative speed-bias. ALL wind gross-error - # checks are currently being done by the SatWindsSPDBCheck. - # CLEARED - - filter: Background Check - filter variables: - - name: windEastward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windEastward - action: - name: reject - - - filter: Background Check - filter variables: - - name: windNorthward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windNorthward - action: - name: reject - - # The last error inflation check is for duplicate observations. This one needs - # to come last, because we don't want to inflate errors for duplication if one - # of the duplicates should be rejected. - # Notes (eliu): ObsErrorFactorDuplicateCheck obsfunction requires PreUseFlag (usage parameter from read_satwnd.f90). - # : Turn off duplicate check for now. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windEastward - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windNorthward - - # We are extending this to an additional filter that inflates final ob-errors across-the-board by - # 1/0.8 = 1.25. This is caused by the GSI value of nvqc being set to .true. in the global operational - # configuration, see: https://github.com/NOAA-EMC/global-workflow/blob/d5ae3328fa4041b177357b1133f6b92e81c859d7/scripts/exglobal_atmos_analysis.sh#L750 - # This setting activates Line 1229 of setupw.f90 to scale ratio_errors by 0.8, which is applied in - # the denominator of the final ob-error, so 1/0.8 = 1.25 factor of ob-error inflation. - # - # If this nvqc functionality were to be switched off (i.e. if variational qc were to be turned off), - # you would want to remove this last inflation filter. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # where: - # - variable: ObsType/windEastward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # where: - # - variable: ObsType/windNorthward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - # End of Filters diff --git a/parm/atm/obs/config/satwind_viirs_n20.yaml.j2 b/parm/atm/obs/config/satwind_viirs_n20.yaml.j2 deleted file mode 100644 index 2a0c2258a..000000000 --- a/parm/atm/obs/config/satwind_viirs_n20.yaml.j2 +++ /dev/null @@ -1,289 +0,0 @@ -- obs space: - name: satwind_viirs_n20 - obsdatain: - engine: - type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}satwnd.viirs_n20.tm00.nc' - obsdataout: - engine: - type: H5File - obsfile: '{{ DATA }}/diags/diag_satwind_viirs_n20_{{ current_cycle | to_YMDH }}.nc' - io pool: - max pool size: 1 - simulated variables: [windEastward, windNorthward] - - obs operator: - name: VertInterp - hofx scaling field: SurfaceWindScalingPressure - hofx scaling field group: DerivedVariables - - linear obs operator: - name: VertInterp - - # NOTE: Tests using the Gaussian Thinning filter (below) to duplicate GSI's thinning of AHI/Himawari-8 satwinds - # results in more JEDI satwinds in the diag file than in GSI, but far fewer JEDI satwinds assimilated than - # GSI. JEDI under-counts assimilated winds by roughly 25-40%, relative to GSI, and this under-count is not - # even including the temporal thinning which is applied in GSI but not JEDI (by this filter below). See - # GDASApp Issue #741 for details: https://github.com/NOAA-EMC/GDASApp/issues/741 - #obs pre filters: - #- filter: Gaussian Thinning - # horizontal_mesh: 200 - # vertical_mesh: 10000 - # use_reduced_horizontal_grid: true - # round_horizontal_bin_count_to_nearest: true - # partition_longitude_bins_using_mesh: true - - obs prior filters: - # Apply variable changes needed for wind scaling - # For wind observations with pressure provided - - filter: Variable Transforms - Transform: SurfaceWindScalingPressure - SkipWhenNoObs: False - - # Calculate error inflation factor for duplicate observations - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windEastward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windEastward - - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windNorthward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windNorthward - - obs post filters: - # Assign the initial observation error, based on height/pressure - # Hard-wiring to prepobs_errtable.global by Type - # ObsError is currently not updating in diag file, but passes directly to EffectiveError when no inflation is specified in YAML - - # Type 260 (VIIRS LWIR) - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 260 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,105000.,100000.,95000.,90000.,85000.,80000.,75000.,70000.,65000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] - errors: [3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.9,3.9,4.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # sanity-check criteria - # Observation Range Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - minvalue: -130. - maxvalue: 130. - action: - name: reject - - # Velocity Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/Velocity - maxvalue: 130. - action: - name: reject - - # Reject any observation with a /=0 surface type (non-water surface) within - # 200 hPa of the surface pressure (as part of the LNVD check). - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: - name: GeoVaLs/water_area_fraction - maxvalue: 0.99 - reference: GeoVaLs/surface_pressure - value: MetaData/pressure - maxvalue: -20000. # within 200 hPa above surface pressure, negative p-diff - action: - name: reject - - # LNVD check - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/SatWindsLNVDCheck - maxvalue: 3. - action: - name: reject - - # GSI setupw routine QC - # Reject any ob Type [240–260] when pressure greater than 950 mb. - # CLEARED: minvalue/maxvalue are >=/<=, not >/<, so editing range by 1 Pa - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 240-260 - test variables: - - name: MetaData/pressure - maxvalue: 95001. - action: - name: reject - - # Multiple satellite platforms, reject when pressure is more than 50 mb above tropopause. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - # Notes (eliu): This tropopause check reject too many obs; probably due to tropopause pressure estimation - # Turn this check off for now. - # Need to check if troposphere pressure was implemented correctly in fv3-jed - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - reference: GeoVaLs/tropopause_pressure - value: MetaData/pressure - minvalue: -5000. # 50 hPa above tropopause level, negative p-diff - action: - name: reject - - # All satwinds must adjust errors based on ObsErrorFactorPressureCheck - # prior to the SPDB check (i.e. the gross-error check). The gross-error - # check uses the adjusted errors for error-bound tightening and rejection, - # so this check has to come first. This check will inflate errors for obs - # that are too close to either the model top or bottom. - # Notes (eliu): GMAO added a required parameter: adjusted_error_name. - - filter: Perform Action - filter variables: - - name: windEastward - where: - - variable: - name: ObsType/windEastward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - surface_obs: false - variable: windEastward - inflation factor: 4.0 - - - filter: Perform Action - filter variables: - - name: windNorthward - where: - - variable: - name: ObsType/windNorthward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - variable: windNorthward - inflation factor: 4.0 - - # All satwinds subject to a gross-error check that contains significant - # modifiers for satwinds with a negative speed-bias. ALL wind gross-error - # checks are currently being done by the SatWindsSPDBCheck. - # CLEARED - - filter: Background Check - filter variables: - - name: windEastward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windEastward - action: - name: reject - - - filter: Background Check - filter variables: - - name: windNorthward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windNorthward - action: - name: reject - - # The last error inflation check is for duplicate observations. This one needs - # to come last, because we don't want to inflate errors for duplication if one - # of the duplicates should be rejected. - # Notes (eliu): ObsErrorFactorDuplicateCheck obsfunction requires PreUseFlag (usage parameter from read_satwnd.f90). - # : Turn off duplicate check for now. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windEastward - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windNorthward - - # We are extending this to an additional filter that inflates final ob-errors across-the-board by - # 1/0.8 = 1.25. This is caused by the GSI value of nvqc being set to .true. in the global operational - # configuration, see: https://github.com/NOAA-EMC/global-workflow/blob/d5ae3328fa4041b177357b1133f6b92e81c859d7/scripts/exglobal_atmos_analysis.sh#L750 - # This setting activates Line 1229 of setupw.f90 to scale ratio_errors by 0.8, which is applied in - # the denominator of the final ob-error, so 1/0.8 = 1.25 factor of ob-error inflation. - # - # If this nvqc functionality were to be switched off (i.e. if variational qc were to be turned off), - # you would want to remove this last inflation filter. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # where: - # - variable: ObsType/windEastward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # where: - # - variable: ObsType/windNorthward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - # End of Filters diff --git a/parm/atm/obs/config/satwind_viirs_npp.yaml.j2 b/parm/atm/obs/config/satwind_viirs_npp.yaml.j2 deleted file mode 100644 index ce8a377a2..000000000 --- a/parm/atm/obs/config/satwind_viirs_npp.yaml.j2 +++ /dev/null @@ -1,289 +0,0 @@ -- obs space: - name: satwind_viirs_npp - obsdatain: - engine: - type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}satwnd.viirs_npp.tm00.nc' - obsdataout: - engine: - type: H5File - obsfile: '{{ DATA }}/diags/diag_satwind_viirs_npp_{{ current_cycle | to_YMDH }}.nc' - io pool: - max pool size: 1 - simulated variables: [windEastward, windNorthward] - - obs operator: - name: VertInterp - hofx scaling field: SurfaceWindScalingPressure - hofx scaling field group: DerivedVariables - - linear obs operator: - name: VertInterp - - # NOTE: Tests using the Gaussian Thinning filter (below) to duplicate GSI's thinning of AHI/Himawari-8 satwinds - # results in more JEDI satwinds in the diag file than in GSI, but far fewer JEDI satwinds assimilated than - # GSI. JEDI under-counts assimilated winds by roughly 25-40%, relative to GSI, and this under-count is not - # even including the temporal thinning which is applied in GSI but not JEDI (by this filter below). See - # GDASApp Issue #741 for details: https://github.com/NOAA-EMC/GDASApp/issues/741 - #obs pre filters: - #- filter: Gaussian Thinning - # horizontal_mesh: 200 - # vertical_mesh: 10000 - # use_reduced_horizontal_grid: true - # round_horizontal_bin_count_to_nearest: true - # partition_longitude_bins_using_mesh: true - - obs prior filters: - # Apply variable changes needed for wind scaling - # For wind observations with pressure provided - - filter: Variable Transforms - Transform: SurfaceWindScalingPressure - SkipWhenNoObs: False - - # Calculate error inflation factor for duplicate observations - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windEastward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windEastward - - #- filter: Variable Assignment - # assignments: - # - name: ObsErrorFactorDuplicateCheck/windNorthward - # type: float - # function: - # name: ObsFunction/ObsErrorFactorDuplicateCheck - # options: - # use_air_pressure: true - # variable: windNorthward - - obs post filters: - # Assign the initial observation error, based on height/pressure - # Hard-wiring to prepobs_errtable.global by Type - # ObsError is currently not updating in diag file, but passes directly to EffectiveError when no inflation is specified in YAML - - # Type 260 (VIIRS LWIR) - - filter: Perform Action - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 260 - action: - name: assign error - error function: - name: ObsFunction/ObsErrorModelStepwiseLinear - options: - xvar: - name: MetaData/pressure - xvals: [110000.,105000.,100000.,95000.,90000.,85000.,80000.,75000.,70000.,65000.,60000.,55000.,50000.,45000.,40000.,35000.,30000.,25000.,20000.,15000.,10000.,7500.,5000.,4000.,3000.,2000.,1000.,500.,400.,300.,200.,100.,0.] - errors: [3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.8,3.9,3.9,4.,4.,4.1,5.,6.,6.3,6.6,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - - # sanity-check criteria - # Observation Range Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - minvalue: -130. - maxvalue: 130. - action: - name: reject - - # Velocity Sanity Check - # NOT EXPLICITLY CLEARED: No obs in this range in file, so 0 Bounds Check rejects (which is correct) but essentially untested - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/Velocity - maxvalue: 130. - action: - name: reject - - # Reject any observation with a /=0 surface type (non-water surface) within - # 200 hPa of the surface pressure (as part of the LNVD check). - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: - name: GeoVaLs/water_area_fraction - maxvalue: 0.99 - reference: GeoVaLs/surface_pressure - value: MetaData/pressure - maxvalue: -20000. # within 200 hPa above surface pressure, negative p-diff - action: - name: reject - - # LNVD check - # CLEARED: maxvalue is rejecting >, not >= as per a Perform Action, so threshold is unchanged - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - test variables: - - name: ObsFunction/SatWindsLNVDCheck - maxvalue: 3. - action: - name: reject - - # GSI setupw routine QC - # Reject any ob Type [240–260] when pressure greater than 950 mb. - # CLEARED: minvalue/maxvalue are >=/<=, not >/<, so editing range by 1 Pa - - filter: Bounds Check - filter variables: - - name: windEastward - - name: windNorthward - where: - - variable: ObsType/windEastward - is_in: 240-260 - test variables: - - name: MetaData/pressure - maxvalue: 95001. - action: - name: reject - - # Multiple satellite platforms, reject when pressure is more than 50 mb above tropopause. - # CLEARED: minvalue is rejecting <, not <= as per a Perform Action, so threshold is unchanged - # Notes (eliu): This tropopause check reject too many obs; probably due to tropopause pressure estimation - # Turn this check off for now. - # Need to check if troposphere pressure was implemented correctly in fv3-jed - - filter: Difference Check - filter variables: - - name: windEastward - - name: windNorthward - reference: GeoVaLs/tropopause_pressure - value: MetaData/pressure - minvalue: -5000. # 50 hPa above tropopause level, negative p-diff - action: - name: reject - - # All satwinds must adjust errors based on ObsErrorFactorPressureCheck - # prior to the SPDB check (i.e. the gross-error check). The gross-error - # check uses the adjusted errors for error-bound tightening and rejection, - # so this check has to come first. This check will inflate errors for obs - # that are too close to either the model top or bottom. - # Notes (eliu): GMAO added a required parameter: adjusted_error_name. - - filter: Perform Action - filter variables: - - name: windEastward - where: - - variable: - name: ObsType/windEastward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - surface_obs: false - variable: windEastward - inflation factor: 4.0 - - - filter: Perform Action - filter variables: - - name: windNorthward - where: - - variable: - name: ObsType/windNorthward - is_in: 240-260 - action: - name: inflate error - inflation variable: - name: ObsFunction/ObsErrorFactorPressureCheck - options: - variable: windNorthward - inflation factor: 4.0 - - # All satwinds subject to a gross-error check that contains significant - # modifiers for satwinds with a negative speed-bias. ALL wind gross-error - # checks are currently being done by the SatWindsSPDBCheck. - # CLEARED - - filter: Background Check - filter variables: - - name: windEastward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windEastward - action: - name: reject - - - filter: Background Check - filter variables: - - name: windNorthward - function absolute threshold: - - name: ObsFunction/WindsSPDBCheck - options: - wndtype: [ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260] - cgross: [ 2.5, 2.5, 2.5, 1.5, 2.5, 1.3, 1.3, 2.5, 2.5, 2.5, 2.5, 1.3, 2.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5] - error_min: [1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4, 1.4] - error_max: [6.1, 6.1, 15.0, 15.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.1, 20.1, 20.1, 20.1, 20.1, 20.1] - variable: windNorthward - action: - name: reject - - # The last error inflation check is for duplicate observations. This one needs - # to come last, because we don't want to inflate errors for duplication if one - # of the duplicates should be rejected. - # Notes (eliu): ObsErrorFactorDuplicateCheck obsfunction requires PreUseFlag (usage parameter from read_satwnd.f90). - # : Turn off duplicate check for now. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windEastward - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # action: - # name: inflate error - # inflation variable: - # name: ObsErrorFactorDuplicateCheck/windNorthward - - # We are extending this to an additional filter that inflates final ob-errors across-the-board by - # 1/0.8 = 1.25. This is caused by the GSI value of nvqc being set to .true. in the global operational - # configuration, see: https://github.com/NOAA-EMC/global-workflow/blob/d5ae3328fa4041b177357b1133f6b92e81c859d7/scripts/exglobal_atmos_analysis.sh#L750 - # This setting activates Line 1229 of setupw.f90 to scale ratio_errors by 0.8, which is applied in - # the denominator of the final ob-error, so 1/0.8 = 1.25 factor of ob-error inflation. - # - # If this nvqc functionality were to be switched off (i.e. if variational qc were to be turned off), - # you would want to remove this last inflation filter. - #- filter: Perform Action - # filter variables: - # - name: windEastward - # where: - # - variable: ObsType/windEastward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - #- filter: Perform Action - # filter variables: - # - name: windNorthward - # where: - # - variable: ObsType/windNorthward - # is_in: 240-260 - # action: - # name: inflate error - # inflation factor: 1.25 - - # End of Filters diff --git a/parm/io/fv3jedi_fieldmetadata_history.yaml b/parm/io/fv3jedi_fieldmetadata_history.yaml index a36e9021c..a8532c32c 100644 --- a/parm/io/fv3jedi_fieldmetadata_history.yaml +++ b/parm/io/fv3jedi_fieldmetadata_history.yaml @@ -47,8 +47,9 @@ field metadata: - long name: surface_pressure io name: pressfc + io file: atmosphere -- long name: sfc_geopotential_height_times_grav +- long name: surface_geopotential_height io name: hgtsfc - long name: u_component_of_native_D_grid_wind @@ -82,7 +83,7 @@ field metadata: - long name: vfrac io name: veg -- long name: totalSnowDepth +- long name: totalSnowDepthMeters io name: snod - long name: surface_eastward_wind diff --git a/parm/ioda/bufr2ioda/bufr2ioda_gnssro_bufr.json b/parm/ioda/bufr2ioda/bufr2ioda_gnssro.json similarity index 100% rename from parm/ioda/bufr2ioda/bufr2ioda_gnssro_bufr.json rename to parm/ioda/bufr2ioda/bufr2ioda_gnssro.json diff --git a/parm/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.json b/parm/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.json deleted file mode 100644 index 067f92c28..000000000 --- a/parm/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "data_format" : "bufr_d", - "data_type" : "gpsro", - "cycle_type" : "{{ RUN }}", - "cycle_datetime" : "{{ current_cycle | to_YMDH }}", - "dump_directory" : "{{ DMPDIR }}", - "ioda_directory" : "{{ COM_OBS }}", - "subsets" : [ "NC003010" ], - "data_description" : "MSG TYPE 003-010 NESDIS GPS-RO: MetOp-A GRAS, MetOp-B GRAS, MetOp-C GRAS, TerraSAR-X IGOR, TanDEM-X IGOR, PAZ IGOR, CICERO-1 OP1 CION, COSMIC-2 E1-E6 Tri-G", - "data_provider" : "U.S. NOAA", -} diff --git a/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_ahi.json b/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_ahi.json index 964175368..269d45258 100644 --- a/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_ahi.json +++ b/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_ahi.json @@ -6,10 +6,11 @@ "dump_directory" : "{{ DMPDIR }}", "ioda_directory" : "{{ COM_OBS }}", "subsets" : [ "NC005044", "NC005045", "NC005046" ], - "data_description" : "NC005044 JMA SATWIND, AHI HIM8 IR(LW)/VIS/WV-CT/WV-CS; NC005045 JMA SATWIND, HIMAWARI-8 IR(LW)/VIS/WV-CT/WV-CS; NC005046 JMA SATWIND, HIMAWARI-8 IR(LW)/VIS/WV-CT/WV-CS", + "data_description" : "NC005044 JMA SATWIND, AHI HIMAWARI IR(LW)/VIS/WV-CT/WV-CS; NC005045 JMA SATWIND, AHI HIMAWARI IR(LW)/VIS/WV-CT/WV-CS; NC005046 JMA SATWIND, AHI HIMAWARI IR(LW)/VIS/WV-CT/WV-CS", "data_provider" : "JMA", "sensor_info" : { "sensor_name": "AHI", "sensor_full_name": "Advanced Himawari Imager", "sensor_id": 999 }, "satellite_info" : [ { "satellite_name": "H8", "satellite_full_name": "Himawari-8", "satellite_id": 173, "launch time": "YYYYMMDD" }, - ] + { "satellite_name": "H9", "satellite_full_name": "Himawari-9", "satellite_id": 174, "launch time": "YYYYMMDD" }, + ] } diff --git a/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_seviri.json b/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_seviri.json index 3fad3c258..6166f0b4b 100644 --- a/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_seviri.json +++ b/parm/ioda/bufr2ioda/bufr2ioda_satwnd_amv_seviri.json @@ -11,6 +11,8 @@ "sensor_info" : { "sensor_name": "SEVIRI", "sensor_full_name": "Spinning Enhanced Visible and InfraRed Imager", "sensor_id": 999 }, "satellite_info" : [ { "satellite_name": "M8", "satellite_full_name": "METEOSAT-8", "satellite_id": 55, "launch time": "YYYYMMDD" }, + { "satellite_name": "M9", "satellite_full_name": "METEOSAT-9", "satellite_id": 56, "launch time": "YYYYMMDD" }, + { "satellite_name": "M10", "satellite_full_name": "METEOSAT-10", "satellite_id": 57, "launch time": "YYYYMMDD" }, { "satellite_name": "M11", "satellite_full_name": "METEOSAT-11", "satellite_id": 70, "launch time": "YYYYMMDD" }, ] } diff --git a/parm/jcb-algorithms b/parm/jcb-algorithms index df03b11da..a6822d8c1 160000 --- a/parm/jcb-algorithms +++ b/parm/jcb-algorithms @@ -1 +1 @@ -Subproject commit df03b11da1701f1713959f9ffc29dd2ba66efe62 +Subproject commit a6822d8c1e72f6b1bf951e378b153cb6df1faee5 diff --git a/parm/jcb-gdas b/parm/jcb-gdas index 0d66231f3..661b51b3d 160000 --- a/parm/jcb-gdas +++ b/parm/jcb-gdas @@ -1 +1 @@ -Subproject commit 0d66231f35143d61a4dcca468945e8944bf1c3bc +Subproject commit 661b51b3d4eeed88f3157daeda37aca3cb3d963f diff --git a/parm/snow/hofx/hofx_nomodel.yaml.j2 b/parm/snow/hofx/hofx_nomodel.yaml.j2 index 9c7ef61e6..7a6cc8ab7 100644 --- a/parm/snow/hofx/hofx_nomodel.yaml.j2 +++ b/parm/snow/hofx/hofx_nomodel.yaml.j2 @@ -3,16 +3,16 @@ time window: length: {{ SNOW_WINDOW_LENGTH }} geometry: fms initialization: - namelist filename: '{{ DATA }}/fv3jedi/fmsmpp.nml' - field table filename: '{{ DATA }}/fv3jedi/field_table' - akbk: '{{ DATA }}/fv3jedi/akbk.nc4' + namelist filename: './fv3jedi/fmsmpp.nml' + field table filename: './fv3jedi/field_table' + akbk: './fv3jedi/akbk.nc4' layout: - {{ layout_x }} - {{ layout_y }} npx: {{ npx_ges }} npy: {{ npy_ges }} npz: {{ npz_ges }} - field metadata override: '{{ DATA }}/fv3jedi/fv3jedi_fieldmetadata_restart.yaml' + field metadata override: './fv3jedi/fv3jedi_fieldmetadata_restart.yaml' time invariant fields: state fields: datetime: '{{ SNOW_WINDOW_BEGIN | to_isotime }}' @@ -22,7 +22,7 @@ geometry: datapath: '{{ FIXgfs }}/fix_orog/{{ CASE }}/' filename_orog: '{{ CASE }}_oro_data.nc' state: - datapath: '{{ DATA }}/bkg' + datapath: './bkg' filetype: fms restart datetime: '{{ current_cycle | to_isotime }}' filename_sfcd: '{{ current_cycle | to_fv3time }}.sfc_data.nc' diff --git a/parm/snow/jcb-base.yaml.j2 b/parm/snow/jcb-base.yaml.j2 new file mode 100644 index 000000000..672b1bf8f --- /dev/null +++ b/parm/snow/jcb-base.yaml.j2 @@ -0,0 +1,137 @@ +# Search path for model and obs for JCB +# ------------------------------------- +algorithm_path: "{{PARMgfs}}/gdas/jcb-algorithms" +app_path_algorithm: "{{PARMgfs}}/gdas/jcb-gdas/algorithm/snow" +app_path_model: "{{PARMgfs}}/gdas/jcb-gdas/model/snow" +app_path_observations: "{{PARMgfs}}/gdas/jcb-gdas/observations/atmosphere" +app_path_observation_chronicle: "{{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/atmosphere" + + +# Places where we deviate from the generic file name of a yaml +# ------------------------------------------------------------ +#final_increment_file: final_increment_gaussian +final_increment_file: final_increment_cubed_sphere +output_ensemble_increments_file: output_ensemble_increments_gaussian +model_file: model_pseudo +initial_condition_file: background # Initial conditions for 4D apps is background + + +# Assimilation window +# ------------------- +window_begin: "{{ SNOW_WINDOW_BEGIN | to_isotime }}" +window_length: "{{ SNOW_WINDOW_LENGTH }}" +bound_to_include: begin + +# Default background time is for 3D applications +{% if DOIAU %} +{% set bkg_time_iso = SNOW_WINDOW_BEGIN | to_isotime %} +{% set bkg_time_fv3 = SNOW_WINDOW_BEGIN | to_fv3time %} +{% else %} +{% set bkg_time_iso = current_cycle | to_isotime %} +{% set bkg_time_fv3 = current_cycle | to_fv3time %} +{% endif %} +snow_background_time_iso: "{{ bkg_time_iso }}" +snow_increment_time_iso: "{{ bkg_time_iso }}" +snow_increment_time_fv3: "{{ bkg_time_fv3 }}" + + +# Analysis standard things +# ------------------------ +analysis_variables: [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr] +minimizer: DRPCG +final_diagnostics_departures: anlmob +final_prints_frequency: PT3H +cost_type: 3D-Var +number_of_outer_loops: 2 + +# Model things +# ------------ +# Geometry +layout_x: {{ layout_x | default(1, true) }} +layout_y: {{ layout_y | default(1, true) }} +npx_ges: {{ npx_ges | default(49, true) }} +npy_ges: {{ npy_ges | default(49, true) }} +npz_ges: {{ npz_ges | default(127, true) }} +npx_anl: {{ npx_anl | default(49, true) }} +npy_anl: {{ npy_anl | default(49, true) }} +npz_anl: {{ npz_anl | default(127, true) }} + +fv3jedi_files_path: ./fv3jedi # Ideally this would be {{DATA}}/fv3jedi but FMS + +# Background +background_path: ./bkg +background_ensemble_path: ./ens/mem%mem% + +# Background error +bump_data_directory: "{{ DATA }}/berror" +gsibec_path: "{{ DATA }}/berror" +number_ensemble_members: {{ NMEM_ENS | default(1, true) }} +layout_gsib_x: {{ layout_gsib_x | default(1, true) }} +layout_gsib_y: {{ layout_gsib_y | default(1, true) }} + +background_error_file: "{{BERROR_YAML}}" + +# Forecasting +forecast_length: "{{ ATM_WINDOW_LENGTH }}" +forecast_timestep: "{{ BKG_TSTEP }}" + +# Write final increment on Guassian grid in variational +final_increment_prefix: "./anl/atminc." + + +# Observation things +# ------------------ +observations: all_observations + +crtm_coefficient_path: "{{ DATA }}/crtm/" + +# Naming conventions for observational files +atm_obsdatain_path: "{{atm_obsdatain_path}}" +atm_obsdatain_prefix: "{{OPREFIX}}" +atm_obsdatain_suffix: ".tm00.nc" + +atm_obsdataout_path: "{{atm_obsdataout_path}}" +atm_obsdataout_prefix: diag_ +atm_obsdataout_suffix: "_{{ current_cycle | to_YMDH }}.nc" + +# Naming conventions for bias correction files +atm_obsbiasin_path: "{{DATA}}/obs/" +atm_obsbiasin_prefix: "{{GPREFIX}}" +atm_obsbiasin_suffix: ".satbias.nc" +atm_obstlapsein_prefix: "{{GPREFIX}}" +atm_obstlapsein_suffix: ".tlapse.txt" +atm_obsbiascovin_prefix: "{{GPREFIX}}" +atm_obsbiascovin_suffix: ".satbias_cov.nc" + +atm_obsbiasout_path: "{{DATA}}/bc/" +atm_obsbiasout_prefix: "{{APREFIX}}" +atm_obsbiasout_suffix: ".satbias.nc" +atm_obsbiascovout_prefix: "{{APREFIX}}" +atm_obsbiascovout_suffix: ".satbias_cov.nc" + + +# Local Ensemble DA (LETKF) +# ------------------------- +local_ensemble_da_solver: GETKF + +increment_variables: [ua,va,DZ,delp,t,ps,sphum,ice_wat,liq_wat,o3mr] + +# Veritcal localization for GETKF +vl_fraction_of_retained_variance: 0.750 +vl_lengthscale: 2.1 +vl_lengthscale_units: logp +inflation_rtps: 0.85 +inflation_rtpp: 0.0 +inflation_mult: 1.0 + +# Driver +driver_update_obs_config_with_geometry_info: true +driver_save_posterior_mean: false +driver_save_posterior_ensemble: false +driver_save_prior_mean: false +driver_save_posterior_mean_increment: false +driver_save_posterior_ensemble_increments: true + +# Diagnostics +ensemble_increment_prefix: "./anl/mem%{member}%/atminc." +#posterior_output_gaussian: "./mem%{member}%/atmanl." diff --git a/parm/snow/jcb-fv3jedi_land_ensrecenter.yaml.j2 b/parm/snow/jcb-fv3jedi_land_ensrecenter.yaml.j2 new file mode 100644 index 000000000..842352c93 --- /dev/null +++ b/parm/snow/jcb-fv3jedi_land_ensrecenter.yaml.j2 @@ -0,0 +1,7 @@ +# Algorithm +# --------- +algorithm: fv3jedi_land_ensrecenter + +# Observation things +# ------------------ +observations: [] diff --git a/parm/snow/letkfoi/apply_incr_nml.j2 b/parm/snow/letkfoi/apply_incr_nml.j2 index d12b00150..afc74fbbb 100644 --- a/parm/snow/letkfoi/apply_incr_nml.j2 +++ b/parm/snow/letkfoi/apply_incr_nml.j2 @@ -3,8 +3,8 @@ hour_str = "{{ current_cycle | strftime('%H') }}", res = {{ CASE[1:] }}, frac_grid = .true., - rst_path = "{{ DATA }}/anl", - inc_path = "{{ DATA }}/anl", + rst_path = "./anl", + inc_path = "./anl", orog_path = "{{ HOMEgfs }}/fix/orog/{{ CASE }}", otype = "{{ CASE }}.mx{{ OCNRES }}_oro_data" / diff --git a/parm/snow/letkfoi/ens_apply_incr_nml.j2 b/parm/snow/letkfoi/ens_apply_incr_nml.j2 new file mode 100644 index 000000000..edd4b116f --- /dev/null +++ b/parm/snow/letkfoi/ens_apply_incr_nml.j2 @@ -0,0 +1,10 @@ +&noahmp_snow + date_str = "{{ current_cycle | to_YMD }}", + hour_str = "{{ current_cycle | strftime('%H') }}", + res = {{ CASE_ENS[1:] }}, + frac_grid = .true., + rst_path = "{{ DATAROOT }}/anl/mem{{ MYMEM }}", + inc_path = "{{ DATAROOT }}/inc/ensmean", + orog_path = "{{ HOMEgfs }}/fix/orog/{{ CASE_ENS }}", + otype = "{{ CASE_ENS }}.mx{{ OCNRES }}_oro_data" +/ diff --git a/parm/snow/letkfoi/letkfoi.yaml.j2 b/parm/snow/letkfoi/letkfoi.yaml.j2 index 467c7805b..e96425581 100644 --- a/parm/snow/letkfoi/letkfoi.yaml.j2 +++ b/parm/snow/letkfoi/letkfoi.yaml.j2 @@ -1,15 +1,15 @@ geometry: fms initialization: - namelist filename: {{ DATA }}/fv3jedi/fmsmpp.nml - field table filename: {{ DATA }}/fv3jedi/field_table - akbk: {{ DATA }}/fv3jedi/akbk.nc4 + namelist filename: ./fv3jedi/fmsmpp.nml + field table filename: ./fv3jedi/field_table + akbk: ./fv3jedi/akbk.nc4 layout: - {{ layout_x }} - {{ layout_y }} npx: {{ npx_ges }} npy: {{ npy_ges }} npz: {{ npz_ges }} - field metadata override: {{ DATA }}/fv3jedi/fv3jedi_fieldmetadata_restart.yaml + field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml time invariant fields: state fields: datetime: '{{ SNOW_WINDOW_BEGIN | to_isotime }}' @@ -31,7 +31,7 @@ background: datetime: '{{ current_cycle | to_isotime }}' filetype: fms restart state variables: [snodl,vtype,slmsk] - datapath: {{ DATA }}/bkg/mem%mem%/RESTART + datapath: ./bkg/mem%mem%/RESTART filename_sfcd: '{{ current_cycle | to_fv3time }}.sfc_data.nc' filename_cplr: '{{ current_cycle | to_fv3time }}.coupler.res' pattern: '%mem%' @@ -57,7 +57,7 @@ local ensemble DA: mult: 1.0 output increment: - datapath: {{ DATA }}/anl + datapath: ./anl prefix: snowinc filetype: fms restart filename_sfcd: '{{ current_cycle | to_fv3time }}.sfc_data.nc' diff --git a/parm/snow/obs/config/adpsfc_snow.yaml.j2 b/parm/snow/obs/config/adpsfc_snow.yaml.j2 index 026f01fae..1ddcb7e21 100644 --- a/parm/snow/obs/config/adpsfc_snow.yaml.j2 +++ b/parm/snow/obs/config/adpsfc_snow.yaml.j2 @@ -6,11 +6,11 @@ obsdatain: engine: type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}adpsfc_snow.nc4' + obsfile: './obs/{{ OPREFIX }}adpsfc_snow.nc4' obsdataout: engine: type: H5File - obsfile: '{{ DATA }}/diags/diag_adpsfc_snow.nc4' + obsfile: './diags/diag_adpsfc_snow.nc4' simulated variables: [totalSnowDepth] obs operator: name: Composite diff --git a/parm/snow/obs/config/ghcn_snow.yaml.j2 b/parm/snow/obs/config/ghcn_snow.yaml.j2 index 2cfb08161..b2a037cf1 100644 --- a/parm/snow/obs/config/ghcn_snow.yaml.j2 +++ b/parm/snow/obs/config/ghcn_snow.yaml.j2 @@ -6,11 +6,11 @@ obsdatain: engine: type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' + obsfile: './obs/{{ OPREFIX }}ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' obsdataout: engine: type: H5File - obsfile: '{{ DATA }}/diags/diag_ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' + obsfile: './diags/diag_ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' obs operator: name: Identity diff --git a/parm/snow/obs/config/ims_snow.yaml.j2 b/parm/snow/obs/config/ims_snow.yaml.j2 index 6fa427be7..c222d0dfe 100644 --- a/parm/snow/obs/config/ims_snow.yaml.j2 +++ b/parm/snow/obs/config/ims_snow.yaml.j2 @@ -6,11 +6,11 @@ obsdatain: engine: type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}ims_snow.nc4' + obsfile: './obs/{{ OPREFIX }}ims_snow.nc4' obsdataout: engine: type: H5File - obsfile: '{{ DATA }}/diags/diag_ims_snow.nc4' + obsfile: './diags/diag_ims_snow.nc4' simulated variables: [totalSnowDepth] obs operator: name: Identity diff --git a/parm/snow/obs/config/sfcsno_snow.yaml.j2 b/parm/snow/obs/config/sfcsno_snow.yaml.j2 new file mode 100644 index 000000000..443915b34 --- /dev/null +++ b/parm/snow/obs/config/sfcsno_snow.yaml.j2 @@ -0,0 +1,109 @@ +- obs space: + name: sfcsno_snow + distribution: + name: Halo + halo size: 250e3 + obsdatain: + engine: + type: H5File + obsfile: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno_snow.nc4' + obsdataout: + engine: + type: H5File + obsfile: '{{ DATA }}/diags/diag_sfcsno_snow.nc4' + simulated variables: [totalSnowDepth] + obs operator: + name: Composite + components: + - name: Identity + - name: BackgroundErrorIdentity + obs error: + covariance model: diagonal + obs localizations: + - localization method: Horizontal SOAR + lengthscale: 250e3 + soar horizontal decay: 0.000021 + max nobs: 50 + - localization method: Vertical Brasnett + vertical lengthscale: 700 + obs pre filters: + - filter: Perform Action + filter variables: + - name: totalSnowDepth + action: + name: assign error + error parameter: 40.0 + - filter: Variable Assignment + assignments: + - name: GrossErrorProbability/totalSnowDepth + type: float + value: 0.02 + - name: BkgError/totalSnowDepth_background_error + type: float + value: 30.0 + obs prior filters: + - filter: Bounds Check + filter variables: + - name: totalSnowDepth + minvalue: 0.0 + maxvalue: 2000.0 + action: + name: reject + - filter: Domain Check + where: + - variable: + name: MetaData/stationElevation + minvalue: -999.0 + - filter: Domain Check # land only + where: + - variable: + name: GeoVaLs/slmsk + minvalue: 0.5 + maxvalue: 1.5 + - filter: RejectList # no land-ice + where: + - variable: + name: GeoVaLs/vtype + minvalue: 14.5 + maxvalue: 15.5 + - filter: BlackList + where: + - variable: + name: MetaData/stationIdentification + is_in: [71120,71397,71621,71727,71816] + size where true: 5 + obs post filters: + - filter: Background Check # gross error check + filter variables: + - name: totalSnowDepth + threshold: 6.25 + action: + name: reject + - filter: Temporal Thinning + min_spacing: '{{ SNOW_WINDOW_LENGTH }}' + seed_time: '{{ current_cycle | to_isotime }}' + category_variable: + name: MetaData/stationIdentification + - filter: Met Office Buddy Check + filter variables: + - name: totalSnowDepth + rejection_threshold: 0.5 + traced_boxes: # trace all observations + min_latitude: -90 + max_latitude: 90 + min_longitude: -180 + max_longitude: 180 + search_radius: 150 # km + station_id_variable: + name: MetaData/stationIdentification + num_zonal_bands: 24 + sort_by_pressure: false + max_total_num_buddies: 15 + max_num_buddies_from_single_band: 10 + max_num_buddies_with_same_station_id: 5 + use_legacy_buddy_collector: false + horizontal_correlation_scale: { "-90": 150, "90": 150 } + temporal_correlation_scale: PT6H + damping_factor_1: 1.0 + damping_factor_2: 1.0 + background_error_group: BkgError diff --git a/parm/snow/obs/config/snocvr_snow.yaml.j2 b/parm/snow/obs/config/snocvr_snow.yaml.j2 index c6b872a48..45a361f32 100644 --- a/parm/snow/obs/config/snocvr_snow.yaml.j2 +++ b/parm/snow/obs/config/snocvr_snow.yaml.j2 @@ -6,11 +6,11 @@ obsdatain: engine: type: H5File - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}snocvr_snow.nc4' + obsfile: './obs/{{ OPREFIX }}snocvr_snow.nc4' obsdataout: engine: type: H5File - obsfile: '{{ DATA }}/diags/diag_snocvr_snow.nc4' + obsfile: './diags/diag_snocvr_snow.nc4' simulated variables: [totalSnowDepth] obs operator: name: Composite diff --git a/parm/snow/obs/lists/gdas_snow.yaml.j2 b/parm/snow/obs/lists/gdas_snow.yaml.j2 index 5be543389..0bbeb0e72 100644 --- a/parm/snow/obs/lists/gdas_snow.yaml.j2 +++ b/parm/snow/obs/lists/gdas_snow.yaml.j2 @@ -1,9 +1,9 @@ observers: {% filter indent(width=2) %} -{% include 'snow/obs/config/adpsfc_snow.yaml.j2' %} +{% include 'snow/obs/config/sfcsno_snow.yaml.j2' %} {% include 'snow/obs/config/snocvr_snow.yaml.j2' %} {% set cycle = current_cycle | strftime("t%Hz") %} -{% if cycle in ['t18z'] %} +{% if cycle in ['t00z'] %} {% include 'snow/obs/config/ims_snow.yaml.j2' %} {% endif %} {% endfilter %} diff --git a/parm/snow/prep/fims.nml.j2 b/parm/snow/prep/fims.nml.j2 index 6f0c0efb6..9b8408b32 100644 --- a/parm/snow/prep/fims.nml.j2 +++ b/parm/snow/prep/fims.nml.j2 @@ -4,9 +4,9 @@ otype = "{{ CASE }}_oro_data", jdate = "{{ current_cycle | to_julian }}", yyyymmddhh = "{{ current_cycle | to_YMD }}.{{ current_cycle.strftime('%H') }}", - imsformat = 2, + imsformat = 1, imsversion = "1.3", - fcst_path = "{{ DATA }}/bkg/" - IMS_OBS_PATH = "{{ DATA }}/obs/", - IMS_IND_PATH = "{{ DATA }}/obs/" + fcst_path = "./bkg/" + IMS_OBS_PATH = "./obs/", + IMS_IND_PATH = "./obs/" / diff --git a/parm/snow/prep/prep_gts.yaml.j2 b/parm/snow/prep/prep_gts.yaml.j2 index a5e4915a3..f91bb21e0 100644 --- a/parm/snow/prep/prep_gts.yaml.j2 +++ b/parm/snow/prep/prep_gts.yaml.j2 @@ -2,9 +2,9 @@ gtsbufr: mkdir: - '{{ DATA }}/obs' copy: - - ['{{ COM_OBS }}/{{ OPREFIX }}adpsfc.tm00.bufr_d', '{{ DATA }}/obs/'] + - ['{{ COM_OBS }}/{{ OPREFIX }}sfcsno.tm00.bufr_d', '{{ DATA }}/obs/'] gtsioda: copy: - - ['{{ DATA }}/{{ OPREFIX }}adpsfc_snow.nc4', '{{ COM_OBS }}/{{ OPREFIX }}adpsfc_snow.nc4'] + - ['{{ DATA }}/{{ OPREFIX }}sfcsno_snow.nc4', '{{ COM_OBS }}/{{ OPREFIX }}sfcsno_snow.nc4'] bufr2ioda: - adpsfc: '{{ HOMEgfs }}/sorc/gdas.cd/test/testinput/bufr_adpsfc_snow.yaml' + sfcsno: '{{ HOMEgfs }}/sorc/gdas.cd/test/testinput/bufr_sfcsno_snow.yaml' diff --git a/parm/snow/prep/prep_ims.yaml.j2 b/parm/snow/prep/prep_ims.yaml.j2 index 2757f6f06..0c2bbc163 100644 --- a/parm/snow/prep/prep_ims.yaml.j2 +++ b/parm/snow/prep/prep_ims.yaml.j2 @@ -2,7 +2,7 @@ calcfims: mkdir: - '{{ DATA }}/obs' copy: - - ['{{ COM_OBS }}/{{ OPREFIX }}ims{{ current_cycle | to_julian }}_4km_v1.3.nc', '{{ DATA }}/obs/ims{{ current_cycle | to_julian }}_4km_v1.3.nc'] + - ['{{ COM_OBS }}/{{ OPREFIX }}imssnow96.asc', '{{ DATA }}/obs/ims{{ current_cycle | to_julian }}_4km_v1.3.asc'] - ['{{ FIXgfs }}/gdas/obs/ims/IMS_4km_to_{{ CASE }}.mx{{ OCNRES }}.nc', '{{ DATA }}/obs/IMS4km_to_FV3_mapping.{{ CASE }}_oro_data.nc'] ims2ioda: copy: diff --git a/parm/soca/berror/soca_bump_loc.yaml b/parm/soca/berror/obsolete/soca_bump_loc.yaml similarity index 100% rename from parm/soca/berror/soca_bump_loc.yaml rename to parm/soca/berror/obsolete/soca_bump_loc.yaml diff --git a/parm/soca/berror/soca_ensweights.yaml b/parm/soca/berror/obsolete/soca_ensweights.yaml similarity index 100% rename from parm/soca/berror/soca_ensweights.yaml rename to parm/soca/berror/obsolete/soca_ensweights.yaml diff --git a/parm/soca/berror/soca_parameters_diffusion_hz.yaml b/parm/soca/berror/obsolete/soca_parameters_diffusion_hz.yaml similarity index 100% rename from parm/soca/berror/soca_parameters_diffusion_hz.yaml rename to parm/soca/berror/obsolete/soca_parameters_diffusion_hz.yaml diff --git a/parm/soca/berror/soca_parameters_diffusion_vt.yaml b/parm/soca/berror/obsolete/soca_parameters_diffusion_vt.yaml similarity index 100% rename from parm/soca/berror/soca_parameters_diffusion_vt.yaml rename to parm/soca/berror/obsolete/soca_parameters_diffusion_vt.yaml diff --git a/parm/soca/berror/soca_setlocscales.yaml b/parm/soca/berror/obsolete/soca_setlocscales.yaml similarity index 100% rename from parm/soca/berror/soca_setlocscales.yaml rename to parm/soca/berror/obsolete/soca_setlocscales.yaml diff --git a/parm/soca/berror/old/parametric_stddev_b.yaml b/parm/soca/berror/old/parametric_stddev_b.yaml deleted file mode 100644 index a2052e8b1..000000000 --- a/parm/soca/berror/old/parametric_stddev_b.yaml +++ /dev/null @@ -1,58 +0,0 @@ -input geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -output geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -linear variable change: - input variables: [tocn, socn, ssh, cicen, hicen] - output variables: [tocn, socn, ssh, cicen, hicen] - linear variable changes: - - - linear variable change name: BkgErrGODAS - t_min: 0.1 - t_max: 2.0 - t_dz: 20.0 - t_efold: 500.0 - s_min: 0.0 - s_max: 0.25 - ssh_min: 0.0 # value at EQ - ssh_max: 0.1 # value in Extratropics - ssh_phi_ex: 20 # lat of transition from extratropics - cicen_min: 0.1 - cicen_max: 0.5 - hicen_min: 10.0 - hicen_max: 100.0 - - - linear variable change name: BkgErrFILT - ocean_depth_min: 1000 # [m] - rescale_bkgerr: 1.0 - efold_z: 2500.0 # [m] - - - linear variable change name: HorizFiltSOCA - niter: 3 - filter variables: [tocn, socn, ssh] - -increments: -- date: '{{ATM_WINDOW_BEGIN}}' - input variables: [tocn, socn, ssh, cicen, hicen] - input: - Identity: 1 - date: '{{ATM_WINDOW_BEGIN}}' - state variables: [ssh, tocn, socn, cicen, hicen] - trajectory: - read_from_file: 1 - basename: ./INPUT/ - ocn_filename: MOM.res.nc - ice_filename: cice.res.nc - date: '{{ATM_WINDOW_BEGIN}}' - state variables: [cicen, hicen, ssh, tocn, socn, hocn, layer_depth, mld] - output: - datadir: ./ - exp: bkgerr_stddev - type: incr - date: '{{ATM_WINDOW_BEGIN}}' diff --git a/parm/soca/berror/old/soca_apply_steric.yaml b/parm/soca/berror/old/soca_apply_steric.yaml deleted file mode 100644 index 5459a48ae..000000000 --- a/parm/soca/berror/old/soca_apply_steric.yaml +++ /dev/null @@ -1,50 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -date: '{{ATM_WINDOW_BEGIN}}' - -layers variable: [hocn] - -increment variables: [tocn, socn, uocn, vocn, ssh, hocn] - -set increment variables to zero: [ssh] - -vertical geometry: - read_from_file: 1 - basename: ./INPUT/ - ocn_filename: MOM.res.nc - date: '{{ATM_WINDOW_BEGIN}}' - -soca increments: - number of increments: ${CLIM_ENS_SIZE} - pattern: '%mem%' - template: - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./static_ens/ - ocn_filename: 'ocn.pert.ens.%mem%.{{ATM_WINDOW_BEGIN}}.PT0S.nc' - read_from_file: 1 - -linear variable change: - linear variable changes: - - linear variable change name: BkgErrFILT - ocean_depth_min: 500 # zero where ocean is shallower than 500m - rescale_bkgerr: 1.0 # rescale perturbation - efold_z: 2500.0 # Apply exponential decay - - linear variable change name: BalanceSOCA - -trajectory: - state variables: [tocn, socn, uocn, vocn, ssh, hocn, layer_depth, mld] - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./INPUT/ - ocn_filename: MOM.res.nc - read_from_file: 1 - -output increment: - datadir: ./static_ens/ - date: '{{ATM_WINDOW_BEGIN}}' - exp: tmp - type: incr - output file: 'ocn.pert.steric.%mem%.{{ATM_WINDOW_BEGIN}}.nc' - pattern: '%mem%' diff --git a/parm/soca/berror/old/soca_bump2d.yaml b/parm/soca/berror/old/soca_bump2d.yaml deleted file mode 100644 index 93e1fb7f0..000000000 --- a/parm/soca/berror/old/soca_bump2d.yaml +++ /dev/null @@ -1,53 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -background: - read_from_file: 1 - date: &date '{{ATM_WINDOW_BEGIN}}' - basename: ./INPUT/ - ocn_filename: MOM.res.nc - ice_filename: cice.res.nc - state variables: [cicen, hicen, hsnon, ssh] - -background error: - covariance model: SABER - saber central block: - saber block name: BUMP_NICAS - calibration: - io: - data directory: bump - drivers: - multivariate strategy: univariate - compute nicas: true - write local nicas: true - write nicas grids: true - model: - do not cross mask boundaries: false - nicas: - resolution: !ENV ${NICAS_RESOL} - max horizontal grid size: ${NICAS_GRID_SIZE} - grids: - - model: - variables: [cicen, hicen, hsnon, ssh] - io: - files prefix: bump2d - input model files: - - parameter: rh - file: - read_from_file: 1 - date: *date - basename: ./ - ocn_filename: ocn.cor_rh.incr.0001-01-01T00:00:00Z.nc - ice_filename: ice.cor_rh.incr.0001-01-01T00:00:00Z.nc - state variables: [cicen, hicen, hsnon, ssh] - - parameter: rv - file: - read_from_file: 1 - date: *date - basename: ./ - ocn_filename: ocn.cor_rv.incr.0001-01-01T00:00:00Z.nc - ice_filename: ice.cor_rv.incr.0001-01-01T00:00:00Z.nc - state variables: [cicen, hicen, hsnon, ssh] - diff --git a/parm/soca/berror/old/soca_bump_split.yaml b/parm/soca/berror/old/soca_bump_split.yaml deleted file mode 100644 index 51bade388..000000000 --- a/parm/soca/berror/old/soca_bump_split.yaml +++ /dev/null @@ -1,57 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -background: - read_from_file: 1 - date: &date '{{ATM_WINDOW_BEGIN}}' - basename: ./INPUT/ - ocn_filename: MOM.res.nc - ice_filename: cice.res.nc - state variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] - -background error: - covariance model: SABER - saber central block: - saber block name: BUMP_NICAS - calibration: - io: - data directory: !ENV ${BUMPDIR} - drivers: - multivariate strategy: univariate - compute nicas: true - write local nicas: true - write nicas grids: true - model: - do not cross mask boundaries: false - nicas: - resolution: !ENV ${NICAS_RESOL} - max horizontal grid size: ${NICAS_GRID_SIZE} - grids: - - model: - variables: - - !ENV ${CVAR} - io: - files prefix: !ENV ${CVAR} - - input model files: - - parameter: rh - file: - read_from_file: 1 - date: *date - basename: ./ - ocn_filename: ocn.cor_rh.incr.0001-01-01T00:00:00Z.nc - ice_filename: ice.cor_rh.incr.0001-01-01T00:00:00Z.nc - state variables: - - !ENV ${CVAR} - - parameter: rv - file: - read_from_file: 1 - date: *date - basename: ./ - ocn_filename: ocn.cor_rv.incr.0001-01-01T00:00:00Z.nc - ice_filename: ice.cor_rv.incr.0001-01-01T00:00:00Z.nc - state variables: - - !ENV ${CVAR} - diff --git a/parm/soca/berror/old/soca_clim_ens_moments.yaml b/parm/soca/berror/old/soca_clim_ens_moments.yaml deleted file mode 100644 index df43fc516..000000000 --- a/parm/soca/berror/old/soca_clim_ens_moments.yaml +++ /dev/null @@ -1,28 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -ensemble: - members from template: - template: - read_from_file: 1 - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./static_ens/ - ocn_filename: ocn.%mem%.nc - ice_filename: ice.%mem%.nc - state variables: [tocn, socn, ssh, uocn, vocn, hocn, cicen, hicen, hsnon] - pattern: '%mem%' - nmembers: ${CLIM_ENS_SIZE} - -mean output: - datadir: ./static_ens/ - exp: orig_ens_mean - type: incr - date: '{{ATM_WINDOW_BEGIN}}' - -standard deviation output: - datadir: ./static_ens/ - exp: orig_ens_stddev - type: incr - date: '{{ATM_WINDOW_BEGIN}}' diff --git a/parm/soca/berror/old/soca_clim_ens_perts.yaml b/parm/soca/berror/old/soca_clim_ens_perts.yaml deleted file mode 100644 index 83ef4996d..000000000 --- a/parm/soca/berror/old/soca_clim_ens_perts.yaml +++ /dev/null @@ -1,34 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -recenter variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh, hocn, mld, layer_depth] - -zero center: True - -center: - read_from_file: 1 - basename: ./INPUT/ - ocn_filename: MOM.res.nc - ice_filename: cice.res.nc - date: '{{ATM_WINDOW_BEGIN}}' - state variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh, hocn, mld, layer_depth] - -ensemble: - members from template: - template: - read_from_file: 1 - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./static_ens/ - ocn_filename: ocn.%mem%.nc - ice_filename: ice.%mem%.nc - state variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh, hocn, mld, layer_depth] - pattern: '%mem%' - nmembers: ${CLIM_ENS_SIZE} - -recentered output: - datadir: ./static_ens - exp: pert - type: ens - date: '{{ATM_WINDOW_BEGIN}}' diff --git a/parm/soca/berror/old/soca_postproc_stddev.yaml b/parm/soca/berror/old/soca_postproc_stddev.yaml deleted file mode 100644 index 6720e1b5a..000000000 --- a/parm/soca/berror/old/soca_postproc_stddev.yaml +++ /dev/null @@ -1,31 +0,0 @@ -geometry: - geom_grid_file: soca_gridspec.nc - mom6_input_nml: mom_input.nml - fields metadata: fields_metadata.yaml - -date: '{{ATM_WINDOW_BEGIN}}' - -layers variable: [hocn] - -increment variables: [tocn, socn, uocn, vocn, ssh, hocn] - -set increment variables to zero: [ssh] - -vertical geometry: - read_from_file: 1 - basename: ./INPUT/ - ocn_filename: MOM.res.nc - date: '{{ATM_WINDOW_BEGIN}}' - -soca increment: - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./static_ens/ - ocn_filename: 'ocn.orig_ens_stddev.incr.{{ATM_WINDOW_BEGIN}}.nc' - read_from_file: 1 - -output increment: - datadir: ./ - date: '{{ATM_WINDOW_BEGIN}}' - exp: filtered - type: incr - output file: 'ocn.orig_ens_stddev.incr.{{ATM_WINDOW_BEGIN}}.nc' diff --git a/parm/soca/berror/soca_diagb.yaml.j2 b/parm/soca/berror/soca_diagb.yaml.j2 index 767b41f92..1493ea1d4 100644 --- a/parm/soca/berror/soca_diagb.yaml.j2 +++ b/parm/soca/berror/soca_diagb.yaml.j2 @@ -2,18 +2,18 @@ geometry: mom6_input_nml: mom_input.nml fields metadata: ./fields_metadata.yaml -date: '{{ ATM_WINDOW_MIDDLE }}' +date: '{{ MARINE_WINDOW_END | to_isotime }}' background: - date: '{{ ATM_WINDOW_MIDDLE }}' + date: '{{ MARINE_WINDOW_END | to_isotime }}' basename: ./bkg/ - ocn_filename: 'gdas.ocean.t{{ gcyc }}z.inst.f009.nc' - ice_filename: 'gdas.agg_ice.t{{ gcyc }}z.inst.f009.nc' + ocn_filename: 'ocean.bkg.f009.nc' + ice_filename: 'ice.bkg.f009.nc' read_from_file: 1 background error: - datadir: ./ - date: '{{ ATM_WINDOW_MIDDLE }}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_MIDDLE | to_isotime }}' exp: bkgerr_stddev type: incr @@ -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/berror/soca_ensb.yaml b/parm/soca/berror/soca_ensb.yaml.j2 similarity index 59% rename from parm/soca/berror/soca_ensb.yaml rename to parm/soca/berror/soca_ensb.yaml.j2 index 7def815c4..48bc494f4 100644 --- a/parm/soca/berror/soca_ensb.yaml +++ b/parm/soca/berror/soca_ensb.yaml.j2 @@ -1,8 +1,9 @@ +# Configuration for the recentering and re-balancing of the ensemble members geometry: mom6_input_nml: mom_input.nml fields metadata: ./fields_metadata.yaml -date: '{{ATM_WINDOW_BEGIN}}' +date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' layers variable: [hocn] @@ -11,7 +12,7 @@ increment variables: [tocn, socn, uocn, vocn, ssh, hocn, cicen, hicen, hsnon] set increment variables to zero: [ssh] vertical geometry: - date: '{{ATM_WINDOW_BEGIN}}' + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' basename: ./INPUT/ ocn_filename: MOM.res.nc read_from_file: 3 @@ -19,11 +20,11 @@ vertical geometry: add recentering increment: false soca increments: # Could also be states, but they are read as increments - number of increments: ${ENS_SIZE} + number of increments: {{ NMEM_ENS }} pattern: '%mem%' template: - date: '{{ATM_WINDOW_BEGIN}}' - basename: ./static_ens/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' + basename: '{{ ENSPERT_RELPATH }}/ens/' ocn_filename: 'ocean.%mem%.nc' ice_filename: 'ice.%mem%.nc' read_from_file: 3 @@ -33,67 +34,64 @@ steric height: - linear variable change name: BalanceSOCA # Only the steric balance is applied ensemble mean output: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: ens_mean type: incr ssh output: unbalanced: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: ssh_unbal_stddev type: incr steric: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: ssh_steric_stddev type: incr total: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: ssh_total_stddev type: incr explained variance: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: steric_explained_variance type: incr recentering error: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: ssh_recentering_error type: incr background error output: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + datadir: ./diagb/ + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: bkgerr_stddev type: incr linear variable change: linear variable changes: -# - linear variable change name: BkgErrFILT -# ocean_depth_min: 500 # zero where ocean is shallower than 500m -# rescale_bkgerr: 1.0 # rescale perturbation -# efold_z: 1500.0 # Apply exponential decay - linear variable change name: BalanceSOCA trajectory: state variables: [tocn, socn, uocn, vocn, ssh, hocn, layer_depth, mld, cicen, hicen, hsnon] - date: '{{ATM_WINDOW_BEGIN}}' + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' basename: ./INPUT/ ocn_filename: MOM.res.nc ice_filename: cice.res.nc read_from_file: 1 output increment: - datadir: ./static_ens - date: '{{ATM_WINDOW_BEGIN}}' + # TODO: Revert this when fms can take more than 128 charactres file names + datadir: '{{ ENSPERT_RELPATH }}/ens/' + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' exp: trash type: incr output file: 'ocn.pert.steric.%mem%.nc' diff --git a/parm/soca/berror/soca_ensweights.yaml.j2 b/parm/soca/berror/soca_ensweights.yaml.j2 new file mode 100644 index 000000000..f677d2a8d --- /dev/null +++ b/parm/soca/berror/soca_ensweights.yaml.j2 @@ -0,0 +1,37 @@ +geometry: + mom6_input_nml: mom_input.nml + fields metadata: ./fields_metadata.yaml + +date: '{{ MARINE_WINDOW_MIDDLE | to_isotime }}' + +variables: + ice: [cicen, hicen, hsnon] + ocean: [tocn, socn, uocn, vocn, ssh] + +background: + date: '{{ MARINE_WINDOW_BEGIN | to_isotime }}' + basename: ./INPUT/ + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + read_from_file: 1 + +weights: + # Need to provide weights^2 when reading from file + ice: 0.0025 # 5% of original variance + ocean: 0.0625 # 25% " " + # Apply localized weights to the ocean ens. B + ocean local weights: + - lon: -172.0 + lat: 11.0 + amplitude: -1.0 + length scale: 700.0 + - lon: -160.0 + lat: 12.0 + amplitude: -1.0 + length scale: 700.0 + +output: + datadir: ./ + date: '{{ MARINE_WINDOW_MIDDLE | to_isotime }}' + exp: ens_weights + type: incr diff --git a/parm/soca/berror/soca_hybrid_bmat.yaml b/parm/soca/berror/soca_hybrid_bmat.yaml index 6e3d35351..302cb6441 100644 --- a/parm/soca/berror/soca_hybrid_bmat.yaml +++ b/parm/soca/berror/soca_hybrid_bmat.yaml @@ -34,8 +34,8 @@ components: model file: date: '{{ATM_WINDOW_MIDDLE}}' basename: ./ - ocn_filename: 'ocn.bkgerr_stddev.incr.{{ATM_WINDOW_MIDDLE}}.nc' - ice_filename: 'ice.bkgerr_stddev.incr.{{ATM_WINDOW_MIDDLE}}.nc' + ocn_filename: 'ocean.bkgerr_stddev.nc' + ice_filename: 'ice.bkgerr_stddev.nc' read_from_file: 3 linear variable change: @@ -53,7 +53,7 @@ components: template: read_from_file: 1 date: '{{ATM_WINDOW_MIDDLE}}' - basename: ./static_ens/ + basename: ./ens/ ocn_filename: 'ocn.pert.steric.%mem%.nc' ice_filename: 'ice.%mem%.nc' state variables: [tocn, socn, ssh, uocn, vocn, cicen, hicen, hsnon] @@ -87,6 +87,6 @@ components: weight: read_from_file: 3 basename: ./ - ocn_filename: 'ocn.ens_weights.incr.{{ATM_WINDOW_MIDDLE}}.nc' - ice_filename: 'ice.ens_weights.incr.{{ATM_WINDOW_MIDDLE}}.nc' + ocn_filename: 'ocean.ens_weights.nc' + ice_filename: 'ice.ens_weights.nc' date: '{{ATM_WINDOW_MIDDLE}}' diff --git a/parm/soca/berror/soca_parameters_diffusion_hz.yaml.j2 b/parm/soca/berror/soca_parameters_diffusion_hz.yaml.j2 new file mode 100644 index 000000000..759a0ed03 --- /dev/null +++ b/parm/soca/berror/soca_parameters_diffusion_hz.yaml.j2 @@ -0,0 +1,37 @@ +geometry: &geom + mom6_input_nml: mom_input.nml + fields metadata: ./fields_metadata.yaml + +background: + read_from_file: 1 + basename: ./INPUT/ + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + date: '{{ MARINE_WINDOW_END | to_isotime }}' + state variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] + +background error: + covariance model: SABER + saber central block: + saber block name: EXPLICIT_DIFFUSION + geometry: *geom + calibration: + normalization: + method: randomization + iterations: 10000 + + groups: + - name: ocean + horizontal: + from file: + filename: ocn.cor_rh.incr.0001-01-01T00:00:00Z.nc + variable name: ave_ssh + write: + filename: hz_ocean.nc + + - name: ice + horizontal: + as gaussian: true + fixed value: 50000.0 + write: + filename: hz_ice.nc diff --git a/parm/soca/berror/soca_parameters_diffusion_vt.yaml.j2 b/parm/soca/berror/soca_parameters_diffusion_vt.yaml.j2 new file mode 100644 index 000000000..c740b37a7 --- /dev/null +++ b/parm/soca/berror/soca_parameters_diffusion_vt.yaml.j2 @@ -0,0 +1,32 @@ +geometry: &geom + mom6_input_nml: mom_input.nml + fields metadata: ./fields_metadata.yaml + +background: + read_from_file: 1 + basename: ./INPUT/ + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + date: '{{ MARINE_WINDOW_MIDDLE | to_isotime }}' + state variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] + +background error: + covariance model: SABER + saber central block: + saber block name: EXPLICIT_DIFFUSION + geometry: *geom + calibration: + normalization: + # NOTE, not actually used here, since the normalization spec is only used for hz + method: randomization #< other option is "brute force" + iterations: 1000 #< in the real world you'll want to use 1e4 or so + + groups: + - name: vt_ocean + vertical: + as gaussian: true + from file: + filename: vt_scales.nc + variable name: vt + write: + filename: vt_ocean.nc diff --git a/parm/soca/berror/soca_static_bmat.yaml b/parm/soca/berror/soca_static_bmat.yaml index 36e9274a7..640af506c 100644 --- a/parm/soca/berror/soca_static_bmat.yaml +++ b/parm/soca/berror/soca_static_bmat.yaml @@ -31,8 +31,8 @@ saber outer blocks: model file: date: '{{ATM_WINDOW_MIDDLE}}' basename: ./ - ocn_filename: 'ocn.bkgerr_stddev.incr.{{ATM_WINDOW_MIDDLE}}.nc' - ice_filename: 'ice.bkgerr_stddev.incr.{{ATM_WINDOW_MIDDLE}}.nc' + ocn_filename: 'ocean.bkgerr_stddev.nc' + ice_filename: 'ice.bkgerr_stddev.nc' read_from_file: 3 linear variable change: diff --git a/parm/soca/berror/soca_vtscales.yaml.j2 b/parm/soca/berror/soca_vtscales.yaml.j2 index bad7d623f..0b5d7a104 100644 --- a/parm/soca/berror/soca_vtscales.yaml.j2 +++ b/parm/soca/berror/soca_vtscales.yaml.j2 @@ -1,6 +1,6 @@ gridspec_filename: soca_gridspec.nc restart_filename: ./INPUT/MOM.res.nc -mld_filename: 'ocn.bkgerr_stddev.incr.{{ ATM_WINDOW_MIDDLE }}.nc' +mld_filename: './diagb/ocn.bkgerr_stddev.incr.{{ MARINE_WINDOW_END | to_isotime }}.nc' output_filename: ./vt_scales.nc output_variable_vt: vt output_variable_hz: hz diff --git a/parm/soca/ensda/stage_ens_mem.yaml.j2 b/parm/soca/ensda/stage_ens_mem.yaml.j2 new file mode 100644 index 000000000..e30a337e7 --- /dev/null +++ b/parm/soca/ensda/stage_ens_mem.yaml.j2 @@ -0,0 +1,27 @@ +###################################### +# set some variables +###################################### +{% set gPDY = previous_cycle | to_YMD %} +{% set gcyc = previous_cycle | strftime("%H") %} +{% set PDY = current_cycle | to_YMD %} +{% set cyc = current_cycle | strftime("%H") %} +###################################### +# create working directories +###################################### +mkdir: +- "{{ DATAenspert }}/ens" + +###################################### +# copy ensemble background files +###################################### +copy: +{% for mem in range(1, NMEM_ENS + 1) %} + # define variables used in the history template + {% set tmpl_dict = {'${ROTDIR}':ROTDIR, + '${RUN}': GDUMP_ENS, + '${YMD}':gPDY, + '${HH}':gcyc, + '${MEMDIR}':"mem" + '%03d' % mem} %} + - ["{{ COM_OCEAN_HISTORY_TMPL | replace_tmpl(tmpl_dict) }}/{{ GDUMP_ENS }}.ocean.t{{ gcyc }}z.inst.f006.nc", "{{ DATAenspert }}/ens/ocean.{{ mem }}.nc"] + - ["{{ COM_ICE_HISTORY_TMPL | replace_tmpl(tmpl_dict) }}/{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc", "{{ DATAenspert }}/ens/ice.{{ mem }}.nc"] +{% endfor %} 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/letkf/letkf.yaml.j2 b/parm/soca/letkf/letkf.yaml.j2 index 9cb7821ca..f4c4d4875 100644 --- a/parm/soca/letkf/letkf.yaml.j2 +++ b/parm/soca/letkf/letkf.yaml.j2 @@ -11,8 +11,8 @@ background: members from template: template: date: '{{ WINDOW_MIDDLE | to_isotime }}' - ocn_filename: "{{ GDUMP_ENS }}.ocean.t{{ gcyc }}z.inst.f006.nc" - ice_filename: "{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc" + ocn_filename: "{{ RUN }}.ocean.t{{ gcyc }}z.inst.f006.nc" + ice_filename: "{{ RUN }}.ice.t{{ gcyc }}z.inst.f006.nc" read_from_file: 1 basename: ./ens/mem%mem% state variables: [socn, tocn, ssh, uocn, vocn, cicen] diff --git a/parm/soca/letkf/letkf_stage.yaml.j2 b/parm/soca/letkf/letkf_stage.yaml.j2 index 58db4ef50..019e1ba37 100644 --- a/parm/soca/letkf/letkf_stage.yaml.j2 +++ b/parm/soca/letkf/letkf_stage.yaml.j2 @@ -1,49 +1,11 @@ ###################################### -# set some variables -###################################### -{% set gPDY = previous_cycle | to_YMD %} -{% set gcyc = previous_cycle | strftime("%H") %} -{% set PDY = current_cycle | to_YMD %} -{% set cyc = current_cycle | strftime("%H") %} -###################################### # create working directories ###################################### mkdir: - "{{ DATA }}/Data" - "{{ DATA }}/obs" -- "{{ DATA }}/INPUT" -{% for mem in range(1, NMEM_ENS + 1) %} -- "{{ DATA }}/ens/mem{{ '%03d' % mem }}" -{% endfor %} copy: ###################################### # copy mom input template ###################################### - ["{{ PARMgfs }}/gdas/soca/fms/input.nml", "{{ DATA }}/mom_input.nml.tmpl"] -###################################### -# copy ensemble background files -###################################### -{% for mem in range(1, NMEM_ENS + 1) %} -# define variables -# Declare a dict of search and replace terms to GDUMP on each template -{% set tmpl_dict = {'ROTDIR':ROTDIR, - 'RUN': GDUMP_ENS, - 'YMD':gPDY, - 'HH':gcyc, - 'MEMDIR':"mem" + '%03d' % mem} %} - -# Replace template variables with tmpl_dict, one key at a time -# This must be done in a namespace to overcome jinja scoping -# Variables set inside of a for loop are lost at the end of the loop -# unless they are part of a namespace -{% set com_prev_ocn = namespace(COM_OCEAN_HISTORY_MEM = COM_OCEAN_HISTORY_TMPL) %} -{% set com_prev_ice = namespace(COM_ICE_HISTORY_MEM = COM_ICE_HISTORY_TMPL) %} -{% for key in tmpl_dict.keys() %} -{% set search_term = '${' + key + '}' %} -{% set replace_term = tmpl_dict[key] %} -{% set com_prev_ocn.COM_OCEAN_HISTORY_MEM = com_prev_ocn.COM_OCEAN_HISTORY_MEM.replace(search_term, replace_term) %} -{% set com_prev_ice.COM_ICE_HISTORY_MEM = com_prev_ice.COM_ICE_HISTORY_MEM.replace(search_term, replace_term) %} -{% endfor %} -- ["{{ com_prev_ocn.COM_OCEAN_HISTORY_MEM }}/{{ GDUMP_ENS }}.ocean.t{{ gcyc }}z.inst.f006.nc", "{{ DATA }}/ens/mem{{ '%03d' % mem }}/{{ GDUMP_ENS }}.ocean.t{{ gcyc }}z.inst.f006.nc"] -- ["{{ com_prev_ice.COM_ICE_HISTORY_MEM }}/{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc", "{{ DATA }}/ens/mem{{ '%03d' % mem }}/{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc"] -{% endfor %} diff --git a/parm/soca/marine-jcb-3dfgat.yaml.j2 b/parm/soca/marine-jcb-3dfgat.yaml.j2 new file mode 100644 index 000000000..acdfa002d --- /dev/null +++ b/parm/soca/marine-jcb-3dfgat.yaml.j2 @@ -0,0 +1,5 @@ +# JEDI algorithm being invoked +algorithm: 3dfgat + +# Observations +observations: !INC ${OBS_LIST_SHORT} diff --git a/parm/soca/marine-jcb-base.yaml b/parm/soca/marine-jcb-base.yaml new file mode 100644 index 000000000..fd14f0dbb --- /dev/null +++ b/parm/soca/marine-jcb-base.yaml @@ -0,0 +1,73 @@ +# Search path for model and obs for JCB +# ------------------------------------- +algorithm_path: '{{PARMgfs}}/gdas/jcb-algorithms' +app_path_algorithm: '{{PARMgfs}}/gdas/jcb-gdas/algorithm/marine' +app_path_model: '{{PARMgfs}}/gdas/jcb-gdas/model/marine' +app_path_observations: '{{PARMgfs}}/gdas/jcb-gdas/observations/marine' +app_path_observation_chronicle: '{{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/marine' + + +# Places where we deviate from the generic file name of a yaml +# ------------------------------------------------------------ +model_file: marine_model_pseudo +initial_condition_file: marine_background # Initial conditions for 4D apps is background +output_file: marine_output +final_increment_file: marine_final_increment + + +# Assimilation standard things (not prepended with model choice) +# ---------------------------- +window_begin: '{{ATM_WINDOW_BEGIN}}' +window_length: '{{ATM_WINDOW_LENGTH}}' +bound_to_include: begin +minimizer: RPCG +final_diagnostics_departures: oman +final_prints_frequency: PT3H +number_of_outer_loops: 1 +analysis_variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] + + +# Model things +# ------------ +marine_window_begin: '{{ATM_WINDOW_BEGIN}}' +marine_window_middle: '{{ATM_WINDOW_MIDDLE}}' + +# Geometry +marine_soca_files_path: . + +# Background +marine_background_path: ./INPUT/ +marine_background_time: '{{ATM_WINDOW_BEGIN}}' + +# Pseudo model +marine_forecast_timestep: PT3H +marine_pseudo_model_states: !INC ${BKG_LIST} + +# Background error model +background_error_file: '{{berror_model}}' +marine_number_ensemble_members: '{{nmem_ens}}' +marine_stddev_time: '{{ATM_WINDOW_MIDDLE}}' + +# Observations +observations: all_observations + +marine_obsdatain_path: '{{DATA}}/obs' +marine_obsdatain_prefix: '{{OPREFIX}}' +marine_obsdatain_suffix: '.{{PDY}}{{cyc}}.nc4' +marine_obsdataout_path: '{{DATA}}/diags' +marine_obsdataout_prefix: '' +marine_obsdataout_suffix: '.{{PDY}}{{cyc}}.nc4' + +# Outer loops +marine_ninner_1: '{{SOCA_NINNER}}' +marine_grad_red_1: 1e-7 + +# Output +marine_output_dir: Data +marine_output_exp: 3dvarfgat_pseudo +marine_output_freq: PT3H # can only writes out the analysis at the middle of the window + # when using 3D-FGAT as cost function + +# Final increment +marine_final_increment_dir: Data +marine_final_increment_exp: 3dvarfgat_pseudo 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_det_bkg_stage.yaml.j2 b/parm/soca/soca_det_bkg_stage.yaml.j2 new file mode 100644 index 000000000..a0474ee59 --- /dev/null +++ b/parm/soca/soca_det_bkg_stage.yaml.j2 @@ -0,0 +1,23 @@ +###################################### +# set some variables +###################################### +{% set gPDY = previous_cycle | to_YMD %} +{% set gcyc = previous_cycle | strftime("%H") %} +###################################### +# create ens bkg directories +###################################### +mkdir: +- "{{ DATA }}/bkg" + +###################################### +# copy ensemble background files +###################################### +copy: +# stage initial conditions +- ["{{ COMIN_OCEAN_HISTORY_PREV }}/gdas.ocean.t{{ gcyc }}z.inst.f003.nc", "{{ DATA }}/INPUT/MOM.res.nc"] +- ["{{ COMIN_ICE_HISTORY_PREV }}/gdas.ice.t{{ gcyc }}z.inst.f003.nc", "{{ DATA }}/INPUT/cice.res.nc"] +# stage f006 and f009 backgrounds +{% for fcsth in ['f006', 'f009'] %} +- ["{{ COMIN_OCEAN_HISTORY_PREV }}/gdas.ocean.t{{ gcyc }}z.inst.{{ fcsth }}.nc", "{{ DATA }}/bkg/ocean.bkg.{{ fcsth }}.nc"] +- ["{{ COMIN_ICE_HISTORY_PREV }}/gdas.ice.t{{ gcyc }}z.inst.{{ fcsth }}.nc", "{{ DATA }}/bkg/ice.bkg.{{ fcsth }}.nc"] +{% endfor %} diff --git a/parm/soca/soca_ens_bkg_stage.yaml.j2 b/parm/soca/soca_ens_bkg_stage.yaml.j2 new file mode 100644 index 000000000..14cb641b4 --- /dev/null +++ b/parm/soca/soca_ens_bkg_stage.yaml.j2 @@ -0,0 +1,40 @@ +###################################### +# set some variables +###################################### +{% set gPDY = previous_cycle | to_YMD %} +{% set gcyc = previous_cycle | strftime("%H") %} +###################################### +# create ens bkg directories +###################################### +mkdir: +{% for mem in range(1, NMEM_ENS + 1) %} + - "{{ DATA }}/ens/mem{{ '%03d' % mem }}" +{% endfor %} +###################################### +# copy ensemble background files +###################################### +copy: +{% for mem in range(1, NMEM_ENS + 1) %} + # define variables + # Declare a dict of search and replace terms to GDUMP on each template + {% set tmpl_dict = {'ROTDIR':ROTDIR, + 'RUN': RUN, + 'YMD':gPDY, + 'HH':gcyc, + 'MEMDIR':"mem" + '%03d' % mem} %} + + # Replace template variables with tmpl_dict, one key at a time + # This must be done in a namespace to overcome jinja scoping + # Variables set inside of a for loop are lost at the end of the loop + # unless they are part of a namespace + {% set com_prev_ocn = namespace(COMIN_OCEAN_HISTORY_MEM = COM_OCEAN_HISTORY_TMPL) %} + {% set com_prev_ice = namespace(COMIN_ICE_HISTORY_MEM = COM_ICE_HISTORY_TMPL) %} + {% for key in tmpl_dict.keys() %} + {% set search_term = '${' + key + '}' %} + {% set replace_term = tmpl_dict[key] %} + {% set com_prev_ocn.COMIN_OCEAN_HISTORY_MEM = com_prev_ocn.COMIN_OCEAN_HISTORY_MEM.replace(search_term, replace_term) %} + {% set com_prev_ice.COMIN_ICE_HISTORY_MEM = com_prev_ice.COMIN_ICE_HISTORY_MEM.replace(search_term, replace_term) %} + {% endfor %} + - ["{{ com_prev_ocn.COMIN_OCEAN_HISTORY_MEM }}/{{ RUN }}.ocean.t{{ gcyc }}z.inst.f006.nc", "{{ DATA }}/ens/mem{{ '%03d' % mem }}/{{ RUN }}.ocean.t{{ gcyc }}z.inst.f006.nc"] + - ["{{ com_prev_ice.COMIN_ICE_HISTORY_MEM }}/{{ RUN }}.ice.t{{ gcyc }}z.inst.f006.nc", "{{ DATA }}/ens/mem{{ '%03d' % mem }}/{{ RUN }}.ice.t{{ gcyc }}z.inst.f006.nc"] +{% endfor %} diff --git a/parm/soca/soca_fix_stage_025.yaml.j2 b/parm/soca/soca_fix_stage_025.yaml.j2 new file mode 100644 index 000000000..2c41dcad4 --- /dev/null +++ b/parm/soca/soca_fix_stage_025.yaml.j2 @@ -0,0 +1,25 @@ +# TODO(AFE): make resolution dependent +mkdir: +- "{{ DATA }}/INPUT" +###################################### +# 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 }}/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"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/ocean_mosaic.nc", "{{ DATA }}/INPUT/ocean_mosaic.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/ocean_topog.nc", "{{ DATA }}/INPUT/ocean_topog.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/tidal_amplitude.v20140616.nc", "{{ DATA }}/INPUT/tidal_amplitude.v20140616.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/interpolate_zgrid_40L.nc", "{{ DATA }}/INPUT/interpolate_zgrid_40L.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/All_edits.nc", "{{ DATA }}/INPUT/All_edits.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/MOM_channels_global_025", "{{ DATA }}/INPUT/MOM_channels_global_025"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/seawifs-clim-1997-2010.1440x1080.v20180328.nc", "{{ DATA }}/INPUT/seawifs-clim-1997-2010.1440x1080.v20180328.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/geothermal_davies2013_v1.nc", "{{ DATA }}/INPUT/geothermal_davies2013_v1.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/interpolate_zgrid_46L.nc", "{{ DATA }}/INPUT/interpolate_zgrid_46L.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/C384_mosaic.nc", "{{ DATA }}/INPUT/C384_mosaic.nc"] diff --git a/parm/soca/soca_fix_stage_100.yaml.j2 b/parm/soca/soca_fix_stage_100.yaml.j2 new file mode 100644 index 000000000..0869f7d34 --- /dev/null +++ b/parm/soca/soca_fix_stage_100.yaml.j2 @@ -0,0 +1,25 @@ +# TODO(AFE): make resolution dependent +mkdir: +- "{{ DATA }}/INPUT" +###################################### +# 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 }}/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"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/ocean_mosaic.nc", "{{ DATA }}/INPUT/ocean_mosaic.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/topog.nc", "{{ DATA }}/INPUT/topog.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/vgrid_75_2m.nc", "{{ DATA }}/INPUT/vgrid_75_2m.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/KH_background_2d.nc", "{{ DATA }}/INPUT/KH_background_2d.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/tidal_amplitude.nc", "{{ DATA }}/INPUT/tidal_amplitude.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/interpolate_zgrid_40L.nc", "{{ DATA }}/INPUT/interpolate_zgrid_40L.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/interpolate_zgrid_46L.nc", "{{ DATA }}/INPUT/interpolate_zgrid_46L.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/topo_edits_011818.nc", "{{ DATA }}/INPUT/topo_edits_011818.nc"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/MOM_channels_SPEAR", "{{ DATA }}/INPUT/MOM_channels_SPEAR"] +- ["{{ SOCA_INPUT_FIX_DIR }}/INPUT/seawifs_1998-2006_smoothed_2X.nc", "{{ DATA }}/INPUT/seawifs_1998-2006_smoothed_2X.nc"] diff --git a/parm/soca/letkf/soca_fix_stage.yaml.j2 b/parm/soca/soca_fix_stage_500.yaml.j2 similarity index 94% rename from parm/soca/letkf/soca_fix_stage.yaml.j2 rename to parm/soca/soca_fix_stage_500.yaml.j2 index 50a61133a..0b25073ba 100644 --- a/parm/soca/letkf/soca_fix_stage.yaml.j2 +++ b/parm/soca/soca_fix_stage_500.yaml.j2 @@ -1,3 +1,6 @@ +# TODO(AFE): make resolution dependent +mkdir: +- "{{ DATA }}/INPUT" ###################################### # fix files to copy ###################################### 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/parm/soca/varchange/soca_2cice_arctic.yaml b/parm/soca/varchange/soca_2cice_arctic.yaml index fa3b86439..075ee018c 100644 --- a/parm/soca/varchange/soca_2cice_arctic.yaml +++ b/parm/soca/varchange/soca_2cice_arctic.yaml @@ -10,7 +10,7 @@ variable change: variable change name: Soca2Cice do inverse: false seaice edge: 0.8 - shuffle: true + shuffle: false rescale prior: min hice: 0.5 min hsno: 0.1 diff --git a/parm/soca/variational/3dvarfgat.yaml b/parm/soca/variational/3dvarfgat.yaml index 344962f21..75af98617 100644 --- a/parm/soca/variational/3dvarfgat.yaml +++ b/parm/soca/variational/3dvarfgat.yaml @@ -51,6 +51,8 @@ output: final: diagnostics: departures: oman + prints: + frequency: PT3H increment: output: state component: diff --git a/scripts/exgdas_global_marine_analysis_bmat.sh b/scripts/exgdas_global_marine_analysis_bmat.sh deleted file mode 100755 index 315e9fdc7..000000000 --- a/scripts/exgdas_global_marine_analysis_bmat.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exgdas_global_marine_analysis_bmat.sh -# Script description: Performs calculations in preparation for the global -# marine analysis with SOCA -# -# Author: Andrew Eichamnn Org: NCEP/EMC Date: 2023-01-12 -# -# Abstract: This script does the follwing in preparation for creating the -# global model ocean sea-ice analysis using SOCA: -# - generates the DA grid -# - computes diagonal of B based on the background if a std. dev. file -# was not staged. TODO: Remove this option in the future -# - initialize the loacalization and correlation operator -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# Machine: Orion -# -################################################################################ - -# Set environment. -export VERBOSE=${VERBOSE:-"YES"} -if [ $VERBOSE = "YES" ]; then - echo $(date) EXECUTING $0 $* >&2 - set -x -fi - -# Directories -pwd=$(pwd) - -# Utilities -export NLN=${NLN:-"/bin/ln -sf"} - -function clean_yaml() -{ - mv $1 tmp_yaml; - sed -e "s/'//g" tmp_yaml > $1 -} - -################################################################################ -# Generate soca geometry if needed -if [[ -e 'soca_gridspec.nc' ]]; then - echo "soca_gridspc.nc already exists, skip the grid generation step" -else - # Run gdas_soca_gridgen.x if the grid was not staged - # TODO (Guillaume): Should not use all pe's for the grid generation - $APRUN_OCNANAL $JEDI_BIN/gdas_soca_gridgen.x gridgen.yaml - export err=$?; err_chk - if [ $err -gt 0 ]; then - exit $err - fi -fi - - -################################################################################ -# Ensemble processing -if [ "${NMEM_ENS}" -ge 3 ]; then - ################################################################################ - # Write ensemble weights for the hybrid envar - $APRUN_OCNANAL $JEDI_BIN/gdas_socahybridweights.x soca_ensweights.yaml - export err=$?; err_chk - if [ $err -gt 0 ]; then - exit $err - fi - - ################################################################################ - # Ensemble perturbations for the EnVAR - # Ensemble diagnostics: - # - Compute moments of original ensemble with the balanced ssh removed - # from the statistics - # - # Ensemble of perturbations: - # - apply the linear steric height balance to each members, using the - # deterministic for trajectory. - # - add the unblanced ssh to the steric ssh field - # Diagnostics: - # - variance explained by the steric heigh - # - moments - clean_yaml soca_clim_ens_moments.yaml - $APRUN_OCNANAL $JEDI_BIN/gdas_ens_handler.x soca_ensb.yaml - export err=$?; err_chk - if [ $err -gt 0 ]; then - exit $err - fi -fi - -################################################################################ -# Compute the parametric diag of B -$APRUN_OCNANAL $JEDI_BIN/gdas_soca_diagb.x soca_diagb.yaml -export err=$?; err_chk -if [ $err -gt 0 ]; then - exit $err -fi - -################################################################################ -# Horizontal diffusion -if [ ! -f "ocn.cor_rh.incr.0001-01-01T00:00:00Z.nc" ]; then - # Set decorrelation scales for the static B - $APRUN_OCNANAL $JEDI_BIN/gdas_soca_setcorscales.x soca_setcorscales.yaml - export err=$?; err_chk - if [ $err -gt 0 ]; then - exit $err - fi - # Initialize the horizontal diffusion block and normalize - clean_yaml soca_parameters_diffusion_hz.yaml - $APRUN_OCNANAL $JEDI_BIN/gdas_soca_error_covariance_toolbox.x soca_parameters_diffusion_hz.yaml - export err=$?; err_chk - if [ $err -gt 0 ]; then - exit $err - fi -else - echo "Diffusion weights already calculated, skipping the init of the horizontal diffusion" -fi - -################################################################################ -# Initialize the vertical diffusion block -# Compute the MLD dependent vertical scales -# TODO(G): Probably not the right way to execute this script -python ${HOMEgfs}/sorc/gdas.cd/sorc/soca/tools/calc_scales.py soca_vtscales.yaml -clean_yaml soca_parameters_diffusion_vt.yaml - -# Initialize the vertical diffusion block and normalize -$APRUN_OCNANAL $JEDI_BIN/gdas_soca_error_covariance_toolbox.x soca_parameters_diffusion_vt.yaml -export err=$?; err_chk -if [ $err -gt 0 ]; then - exit $err -fi - -################################################################################ -set +x -if [ $VERBOSE = "YES" ]; then - echo $(date) EXITING $0 with return code $err >&2 -fi -exit $err - -################################################################################ 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_post.py b/scripts/exgdas_global_marine_analysis_post.py index 119fed228..4d2d8e889 100755 --- a/scripts/exgdas_global_marine_analysis_post.py +++ b/scripts/exgdas_global_marine_analysis_post.py @@ -67,6 +67,7 @@ def list_all_files(dir_in, dir_out, wc='*', fh_list=[]): domains = ['ocn', 'ice'] for domain in domains: + ''' # Copy of the diagonal of the background error for the cycle post_file_list.append([os.path.join(anl_dir, f'{domain}.bkgerr_stddev.incr.{mdate}.nc'), os.path.join(com_ocean_analysis, f'{RUN}.t{cyc}z.{domain}.bkgerr_stddev.nc')]) @@ -75,6 +76,7 @@ def list_all_files(dir_in, dir_out, wc='*', fh_list=[]): if nmem_ens > 2: post_file_list.append([os.path.join(anl_dir, 'static_ens', f'{domain}.ssh_recentering_error.incr.{bdate}.nc'), os.path.join(com_ocean_analysis, f'{RUN}.t{cyc}z.{domain}.recentering_error.nc')]) + ''' # Copy the ice and ocean increments post_file_list.append([os.path.join(anl_dir, 'Data', f'{domain}.3dvarfgat_pseudo.incr.{mdate}.nc'), @@ -85,6 +87,7 @@ def list_all_files(dir_in, dir_out, wc='*', fh_list=[]): os.path.join(com_ocean_analysis, f'{RUN}.t{cyc}z.{domain}ana.nc')]) # Copy of the ssh diagnostics +''' if nmem_ens > 2: for string in ['ssh_steric_stddev', 'ssh_unbal_stddev', 'ssh_total_stddev', 'steric_explained_variance']: post_file_list.append([os.path.join(anl_dir, 'static_ens', f'ocn.{string}.incr.{bdate}.nc'), @@ -93,6 +96,7 @@ def list_all_files(dir_in, dir_out, wc='*', fh_list=[]): # Copy DA grid (computed for the start of the window) post_file_list.append([os.path.join(anl_dir, 'soca_gridspec.nc'), os.path.join(com_ocean_analysis, f'{RUN}.t{bcyc}z.ocngrid.nc')]) +''' # Copy the CICE analysis restart if os.getenv('DOIAU') == "YES": diff --git a/scripts/exgdas_global_marine_analysis_prep.py b/scripts/exgdas_global_marine_analysis_prep.py index 03ff7c018..532e52ad4 100755 --- a/scripts/exgdas_global_marine_analysis_prep.py +++ b/scripts/exgdas_global_marine_analysis_prep.py @@ -3,6 +3,7 @@ # Script description: Stages files and generates YAML for UFS Global Marine Analysis # import os to add ush to path +import copy import os import glob import dateutil.parser as dparser @@ -10,8 +11,12 @@ from soca import bkg_utils from datetime import datetime, timedelta import pytz +import re +import yaml + +from jcb import render from wxflow import (Logger, Template, TemplateConstants, - YAMLFile, FileHandler, AttrDict, parse_j2yaml) + YAMLFile, FileHandler) logger = Logger() @@ -59,12 +64,27 @@ def find_clim_ens(input_date): return nearest_date(dirs, input_date) +def parse_obs_list_file(): + # Get the list of observation types from the obs_list.yaml + obs_list_path = os.path.join(gdas_home, 'parm', 'soca', 'obs', 'obs_list.yaml') + obs_types = [] + with open(obs_list_path, 'r') as file: + for line in file: + # Remove leading/trailing whitespace and check if the line is uncommented + line = line.strip() + if line.startswith('- !INC') and not line.startswith('#'): + # Extract the type using regex + match = re.search(r'\$\{OBS_YAML_DIR\}/(.+)\.yaml', line) + if match: + obs_types.append(str(match.group(1))) + return obs_types + ################################################################################ # runtime environment variables, create directories + logger.info(f"---------------- Setup runtime environement") -comin_obs = os.getenv('COMIN_OBS') anl_dir = os.getenv('DATA') staticsoca_dir = os.getenv('SOCA_INPUT_FIX_DIR') nmem_ens = 0 @@ -141,127 +161,63 @@ def find_clim_ens(input_date): ################################################################################ # 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 -if dohybvar: - logger.info("---------------- Stage ensemble members") - ens_member_list = [] - for mem in range(1, nmem_ens+1): - for domain in ['ocean', 'ice']: - # TODO(Guillaume): make use and define ensemble COM in the j-job - ensroot = os.getenv('COM_OCEAN_HISTORY_PREV') - ensdir = os.path.join(os.getenv('COM_OCEAN_HISTORY_PREV'), '..', '..', '..', '..', '..', - f'enkf{RUN}.{PDY}', f'{gcyc}', f'mem{str(mem).zfill(3)}', - 'model_data', domain, 'history') - ensdir_real = os.path.realpath(ensdir) - f009 = f'enkfgdas.{domain}.t{gcyc}z.inst.f009.nc' - - fname_in = os.path.abspath(os.path.join(ensdir_real, f009)) - fname_out = os.path.realpath(os.path.join(static_ens, domain+"."+str(mem)+".nc")) - ens_member_list.append([fname_in, fname_out]) - FileHandler({'copy': ens_member_list}).sync() - - # reformat the cice history output - for mem in range(1, nmem_ens+1): - cice_fname = os.path.realpath(os.path.join(static_ens, "ice."+str(mem)+".nc")) - bkg_utils.cice_hist2fms(cice_fname, cice_fname) -else: - if nmem_ens >= 3: - logger.info("---------------- Stage offline ensemble members") - ens_member_list = [] - clim_ens_dir = find_clim_ens(pytz.utc.localize(window_begin, is_dst=None)) - list_of_members = glob.glob(os.path.join(clim_ens_dir, 'ocean.*.nc')) - nmem_ens = min(nmem_ens, len(list_of_members)) - for domain in ['ocean', 'ice']: - for mem in range(1, nmem_ens+1): - fname = domain+"."+str(mem)+".nc" - fname_in = os.path.join(clim_ens_dir, fname) - fname_out = os.path.join(static_ens, fname) - ens_member_list.append([fname_in, fname_out]) - FileHandler({'copy': ens_member_list}).sync() - -os.environ['ENS_SIZE'] = str(nmem_ens) +if dohybvar or nmem_ens >= 3: + # TODO: No symlink allowed but this script will be refactored soon + # Relative path to ensemble perturbations + ens_perturbations = os.path.join('..', f'gdasmarinebmat.{PDY}{cyc}', 'enspert', 'ens') + os.symlink(ens_perturbations, 'ens') ################################################################################ # prepare JEDI yamls - +os.environ['ENS_SIZE'] = str(nmem_ens) logger.info(f"---------------- Generate JEDI yaml files") ################################################################################ -# copy yaml for grid generation - -logger.info(f"---------------- generate gridgen.yaml") -gridgen_yaml_src = os.path.realpath(os.path.join(gdas_home, 'parm', 'soca', 'gridgen', 'gridgen.yaml')) -gridgen_yaml_dst = os.path.realpath(os.path.join(stage_cfg['stage_dir'], 'gridgen.yaml')) -FileHandler({'copy': [[gridgen_yaml_src, gridgen_yaml_dst]]}).sync() - -################################################################################ -# generate the YAML file for the post processing of the clim. ens. B -berror_yaml_dir = os.path.join(gdas_home, 'parm', 'soca', 'berror') - -logger.info(f"---------------- generate soca_diagb.yaml") -conf = parse_j2yaml(path=os.path.join(berror_yaml_dir, 'soca_diagb.yaml.j2'), - data=envconfig) -conf.save(os.path.join(anl_dir, 'soca_diagb.yaml')) - -logger.info(f"---------------- generate soca_ensb.yaml") -berr_yaml = os.path.join(anl_dir, 'soca_ensb.yaml') -berr_yaml_template = os.path.join(berror_yaml_dir, 'soca_ensb.yaml') -config = YAMLFile(path=berr_yaml_template) -config = Template.substitute_structure(config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) -config.save(berr_yaml) - -logger.info(f"---------------- generate soca_ensweights.yaml") -berr_yaml = os.path.join(anl_dir, 'soca_ensweights.yaml') -berr_yaml_template = os.path.join(berror_yaml_dir, 'soca_ensweights.yaml') -config = YAMLFile(path=berr_yaml_template) -config = Template.substitute_structure(config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) -config.save(berr_yaml) - -################################################################################ -# copy yaml for localization length scales - -logger.info(f"---------------- generate soca_setlocscales.yaml") -locscales_yaml_src = os.path.join(gdas_home, 'parm', 'soca', 'berror', 'soca_setlocscales.yaml') -locscales_yaml_dst = os.path.join(stage_cfg['stage_dir'], 'soca_setlocscales.yaml') -FileHandler({'copy': [[locscales_yaml_src, locscales_yaml_dst]]}).sync() +# Stage the soca grid +src = os.path.join(os.getenv('COMIN_OCEAN_BMATRIX'), 'soca_gridspec.nc') +dst = os.path.join(anl_dir, 'soca_gridspec.nc') +FileHandler({'copy': [[src, dst]]}).sync() ################################################################################ -# copy yaml for correlation length scales - -logger.info(f"---------------- generate soca_setcorscales.yaml") -corscales_yaml_src = os.path.join(gdas_home, 'parm', 'soca', 'berror', 'soca_setcorscales.yaml') -corscales_yaml_dst = os.path.join(stage_cfg['stage_dir'], 'soca_setcorscales.yaml') -FileHandler({'copy': [[corscales_yaml_src, corscales_yaml_dst]]}).sync() +# stage the static B-matrix +bmat_list = [] +# Diagonal of the B matrix +bmat_list.append([os.path.join(os.getenv('COMIN_OCEAN_BMATRIX'), f"{RUN}.t{cyc}z.ocean.bkgerr_stddev.nc"), + os.path.join(anl_dir, "ocean.bkgerr_stddev.nc")]) +bmat_list.append([os.path.join(os.getenv('COMIN_ICE_BMATRIX'), f"{RUN}.t{cyc}z.ice.bkgerr_stddev.nc"), + os.path.join(anl_dir, "ice.bkgerr_stddev.nc")]) +# Correlation operator +bmat_list.append([os.path.join(os.getenv('COMIN_ICE_BMATRIX'), f"{RUN}.t{cyc}z.hz_ice.nc"), + os.path.join(anl_dir, "hz_ice.nc")]) +bmat_list.append([os.path.join(os.getenv('COMIN_OCEAN_BMATRIX'), f"{RUN}.t{cyc}z.hz_ocean.nc"), + os.path.join(anl_dir, "hz_ocean.nc")]) +bmat_list.append([os.path.join(os.getenv('COMIN_OCEAN_BMATRIX'), f"{RUN}.t{cyc}z.vt_ocean.nc"), + os.path.join(anl_dir, "vt_ocean.nc")]) +FileHandler({'copy': bmat_list}).sync() ################################################################################ -# copy yaml for diffusion initialization - -logger.info(f"---------------- generate soca_parameters_diffusion_hz.yaml") -diffu_hz_yaml = os.path.join(anl_dir, 'soca_parameters_diffusion_hz.yaml') -diffu_hz_yaml_dir = os.path.join(gdas_home, 'parm', 'soca', 'berror') -diffu_hz_yaml_template = os.path.join(berror_yaml_dir, 'soca_parameters_diffusion_hz.yaml') -config = YAMLFile(path=diffu_hz_yaml_template) -config = Template.substitute_structure(config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) -config.save(diffu_hz_yaml) - -logger.info(f"---------------- generate soca_vtscales.yaml") -conf = parse_j2yaml(path=os.path.join(gdas_home, 'parm', 'soca', 'berror', 'soca_vtscales.yaml.j2'), - data=envconfig) -conf.save(os.path.join(anl_dir, 'soca_vtscales.yaml')) - -logger.info(f"---------------- generate soca_parameters_diffusion_vt.yaml") -diffu_vt_yaml = os.path.join(anl_dir, 'soca_parameters_diffusion_vt.yaml') -diffu_vt_yaml_dir = os.path.join(gdas_home, 'parm', 'soca', 'berror') -diffu_vt_yaml_template = os.path.join(berror_yaml_dir, 'soca_parameters_diffusion_vt.yaml') -config = YAMLFile(path=diffu_vt_yaml_template) -config = Template.substitute_structure(config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) -config.save(diffu_vt_yaml) +# stage the ens B-matrix weights +if dohybvar or nmem_ens >= 3: + ensbmat_list = [] + ensbmat_list.append([os.path.join(os.getenv('COMIN_OCEAN_BMATRIX'), f"{RUN}.t{cyc}z.ocean.ens_weights.nc"), + os.path.join(anl_dir, "ocean.ens_weights.nc")]) + ensbmat_list.append([os.path.join(os.getenv('COMIN_ICE_BMATRIX'), f"{RUN}.t{cyc}z.ice.ens_weights.nc"), + os.path.join(anl_dir, "ice.ens_weights.nc")]) + FileHandler({'copy': ensbmat_list}).sync() ################################################################################ # generate yaml for soca_var @@ -288,16 +244,62 @@ def find_clim_ens(input_date): os.environ['SABER_BLOCKS_YAML'] = os.path.join(gdas_home, 'parm', 'soca', 'berror', 'soca_static_bmat.yaml') # substitute templated variables in the var config -logger.info(f"{config}") +logger.info(f"{envconfig}") varconfig = YAMLFile(path=var_yaml_template) -varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOUBLE_CURLY_BRACES, config.get) -varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOLLAR_PARENTHESES, config.get) +varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) +varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOLLAR_PARENTHESES, envconfig.get) varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig.get) varconfig = Template.substitute_structure(varconfig, TemplateConstants.DOLLAR_PARENTHESES, envconfig.get) # Remove empty obs spaces in var_yaml ufsda.yamltools.save_check(varconfig, target=var_yaml, app='var') +# Produce JEDI YAML file using JCB (for demonstration purposes) +# ------------------------------------------------------------- +""" +# Make a copy of the env config before modifying to avoid breaking something else +envconfig_jcb = copy.deepcopy(envconfig) + +# Add the things to the envconfig in order to template JCB files +envconfig_jcb['PARMgfs'] = os.getenv('PARMgfs') +envconfig_jcb['nmem_ens'] = nmem_ens +envconfig_jcb['berror_model'] = 'marine_background_error_static_diffusion' +if nmem_ens > 3: + envconfig_jcb['berror_model'] = 'marine_background_error_hybrid_diffusion_diffusion' +envconfig_jcb['DATA'] = os.getenv('DATA') +envconfig_jcb['OPREFIX'] = os.getenv('OPREFIX') +envconfig_jcb['PDY'] = os.getenv('PDY') +envconfig_jcb['cyc'] = os.getenv('cyc') +envconfig_jcb['SOCA_NINNER'] = os.getenv('SOCA_NINNER') +envconfig_jcb['obs_list'] = ['adt_rads_all'] + +# Write obs_list_short +with open('obs_list_short.yaml', 'w') as file: + yaml.dump(parse_obs_list_file(), file, default_flow_style=False) +os.environ['OBS_LIST_SHORT'] = 'obs_list_short.yaml' + +# Render the JCB configuration files +jcb_base_yaml = os.path.join(gdas_home, 'parm', 'soca', 'marine-jcb-base.yaml') +jcb_algo_yaml = os.path.join(gdas_home, 'parm', 'soca', 'marine-jcb-3dfgat.yaml.j2') + +jcb_base_config = YAMLFile(path=jcb_base_yaml) +jcb_base_config = Template.substitute_structure(jcb_base_config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig_jcb.get) +jcb_base_config = Template.substitute_structure(jcb_base_config, TemplateConstants.DOLLAR_PARENTHESES, envconfig_jcb.get) +jcb_algo_config = YAMLFile(path=jcb_algo_yaml) +jcb_algo_config = Template.substitute_structure(jcb_algo_config, TemplateConstants.DOUBLE_CURLY_BRACES, envconfig_jcb.get) +jcb_algo_config = Template.substitute_structure(jcb_algo_config, TemplateConstants.DOLLAR_PARENTHESES, envconfig_jcb.get) + +# Override base with the application specific config +jcb_config = {**jcb_base_config, **jcb_algo_config} + +# Render the full JEDI configuration file using JCB +jedi_config = render(jcb_config) + +# Save the JEDI configuration file +var_yaml_jcb = os.path.join(anl_dir, 'var-jcb.yaml') +ufsda.yamltools.save_check(jedi_config, target=var_yaml_jcb, app='var') +""" + ################################################################################ # Prepare the yamls for the "checkpoint" jjob # prepare yaml and CICE restart for soca to cice change of variable diff --git a/scripts/exgdas_global_marine_analysis_vrfy.py b/scripts/exgdas_global_marine_analysis_vrfy.py index 36d00bdb6..cf818db7d 100755 --- a/scripts/exgdas_global_marine_analysis_vrfy.py +++ b/scripts/exgdas_global_marine_analysis_vrfy.py @@ -31,10 +31,11 @@ com_ocean_history = os.path.realpath(os.getenv('COM_OCEAN_HISTORY_PREV')) cyc = os.getenv('cyc') RUN = os.getenv('RUN') -gcyc = str((int(cyc) - 6) % 24).zfill(2) bcyc = str((int(cyc) - 3) % 24).zfill(2) +gcyc = str((int(cyc) - 6) % 24).zfill(2) grid_file = os.path.join(comout, f'{RUN}.t'+bcyc+'z.ocngrid.nc') +layer_file = os.path.join(comout, f'{RUN}.t'+cyc+'z.ocninc.nc') # for eva diagdir = os.path.join(comout, 'diags') @@ -76,6 +77,7 @@ def plot_marine_vrfy(config): colormap='seismic', comout=os.path.join(comout, 'vrfy', 'bkgerr', 'steric_explained_variance')), # steric explained variance plotConfig(grid_file=grid_file, + layer_file=layer_file, data_file=os.path.join(comout, f'{RUN}.t'+cyc+'z.ocn.bkgerr_stddev.nc'), lats=np.arange(-60, 60, 10), lons=np.arange(-280, 80, 30), @@ -95,6 +97,7 @@ def plot_marine_vrfy(config): colormap='jet', comout=os.path.join(comout, 'vrfy', 'bkgerr')), # ocn bkgerr stddev plotConfig(grid_file=grid_file, + layer_file=layer_file, data_file=os.path.join(comout, f'{RUN}.t'+cyc+'z.ocninc.nc'), lats=np.arange(-60, 60, 10), lons=np.arange(-280, 80, 30), @@ -137,14 +140,21 @@ def plot_marine_vrfy(config): variables_horiz={'ave_ssh': [-1.8, 1.3], 'Temp': [-1.8, 34.0], 'Salt': [30, 38]}, - colormap='jet', + colormap='nipy_spectral', comout=os.path.join(comout, 'vrfy', 'ana')), # ocean surface analysis plotConfig(grid_file=grid_file, + layer_file=layer_file, data_file=os.path.join(com_ocean_history, f'{RUN}.ocean.t{gcyc}z.inst.f006.nc'), + lats=np.arange(-60, 60, 10), + lons=np.arange(-280, 80, 30), + variables_zonal={'Temp': [-1.8, 34.0], + 'Salt': [30, 38]}, + variables_meridional={'Temp': [-1.8, 34.0], + 'Salt': [30, 38]}, variables_horiz={'ave_ssh': [-1.8, 1.3], 'Temp': [-1.8, 34.0], 'Salt': [30, 38]}, - colormap='jet', + colormap='nipy_spectral', comout=os.path.join(comout, 'vrfy', 'bkg'))] # ocean surface background # Number of processes diff --git a/sorc/bufr-query b/sorc/bufr-query new file mode 160000 index 000000000..97367fcd5 --- /dev/null +++ b/sorc/bufr-query @@ -0,0 +1 @@ +Subproject commit 97367fcd59adf4863aba1a52189e20f9f66451af diff --git a/sorc/da-utils b/sorc/da-utils new file mode 160000 index 000000000..a2da7a84c --- /dev/null +++ b/sorc/da-utils @@ -0,0 +1 @@ +Subproject commit a2da7a84c76c03cbede5aa13f25549417bd30c43 diff --git a/sorc/fms b/sorc/fms deleted file mode 160000 index 1f739141e..000000000 --- a/sorc/fms +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f739141ef8b000a0bd75ae8bebfadea340299ba diff --git a/sorc/fv3 b/sorc/fv3 index 47b766295..ab25dc09d 160000 --- a/sorc/fv3 +++ b/sorc/fv3 @@ -1 +1 @@ -Subproject commit 47b766295682df2e53b59d0dd07b5c511b84dd67 +Subproject commit ab25dc09d955271f34ca6a3fa83af1093c85d9f7 diff --git a/sorc/fv3-jedi b/sorc/fv3-jedi index b5dd092e2..00173d7b0 160000 --- a/sorc/fv3-jedi +++ b/sorc/fv3-jedi @@ -1 +1 @@ -Subproject commit b5dd092e22a1ec8efdddc2bfbd58628b695ad1c4 +Subproject commit 00173d7b0162c3c0d2c583032b8dbd4a026e5220 diff --git a/sorc/fv3-jedi-lm b/sorc/fv3-jedi-lm index af67095ee..a6e97d76e 160000 --- a/sorc/fv3-jedi-lm +++ b/sorc/fv3-jedi-lm @@ -1 +1 @@ -Subproject commit af67095ee87ffb472218aa386e34c6bfe64ca424 +Subproject commit a6e97d76ed7c0b2a27cf97512893a93d7e2b44bc diff --git a/sorc/ioda b/sorc/ioda index d4dc2cdaa..b8281e5a9 160000 --- a/sorc/ioda +++ b/sorc/ioda @@ -1 +1 @@ -Subproject commit d4dc2cdaa944f2a8220fa5207968f0dab6c8b183 +Subproject commit b8281e5a9e04c07bd871a275eacd4ecd697b9434 diff --git a/sorc/iodaconv b/sorc/iodaconv index 7fb44969a..3c437f464 160000 --- a/sorc/iodaconv +++ b/sorc/iodaconv @@ -1 +1 @@ -Subproject commit 7fb44969a419348ba07abad1544b443212fc8d6c +Subproject commit 3c437f464572ce8d5ab076b4ad713f7f7f24dd04 diff --git a/sorc/jcb b/sorc/jcb new file mode 160000 index 000000000..8269ce474 --- /dev/null +++ b/sorc/jcb @@ -0,0 +1 @@ +Subproject commit 8269ce474fe864fdd6dc51913ccce9daca630ac2 diff --git a/sorc/land-imsproc b/sorc/land-imsproc index a3b233446..bbe3f311d 160000 --- a/sorc/land-imsproc +++ b/sorc/land-imsproc @@ -1 +1 @@ -Subproject commit a3b233446002af7643956bc31a7e68b89bf1a9d9 +Subproject commit bbe3f311dc310020319c313cde1a2ee8a3c47a36 diff --git a/sorc/mom6 b/sorc/mom6 deleted file mode 160000 index 51ec489ad..000000000 --- a/sorc/mom6 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 51ec489ad7d8a86762bef4c46eabd9af5fc41fa4 diff --git a/sorc/oops b/sorc/oops index db0fc43c7..e6485c0a6 160000 --- a/sorc/oops +++ b/sorc/oops @@ -1 +1 @@ -Subproject commit db0fc43c70f4b26b7e77782e8270a754d2a2aed7 +Subproject commit e6485c0a659103f0daa2b7e2cece39a15bfb0d60 diff --git a/sorc/saber b/sorc/saber index a2c8e1c78..bf5339c5f 160000 --- a/sorc/saber +++ b/sorc/saber @@ -1 +1 @@ -Subproject commit a2c8e1c78faf045613b7a5c15627e31fe947dc9f +Subproject commit bf5339c5ffe1828efab728e89bbc545ac22ddc88 diff --git a/sorc/soca b/sorc/soca index 98e2be9f8..92519ab72 160000 --- a/sorc/soca +++ b/sorc/soca @@ -1 +1 @@ -Subproject commit 98e2be9f83fe45453a34a24b6420b21a7cb6e0c5 +Subproject commit 92519ab72b89a4c3b802501e71b7b66349fc8cc8 diff --git a/sorc/ufo b/sorc/ufo index d90c514fd..cd6650500 160000 --- a/sorc/ufo +++ b/sorc/ufo @@ -1 +1 @@ -Subproject commit d90c514fdc1d1e5cd7a2a88384c0e634da78987f +Subproject commit cd66505007b1559d79cb158bd6dc018a3943c1e7 diff --git a/sorc/vader b/sorc/vader index 8210eccf7..c4df3182d 160000 --- a/sorc/vader +++ b/sorc/vader @@ -1 +1 @@ -Subproject commit 8210eccf77b80f51cce470ecdd5dd4cc2ec646bc +Subproject commit c4df3182de5c050b430250b5beae198af6eeb717 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c2fdf7b81..d04ec467c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -126,13 +126,14 @@ add_test(NAME test_gdasapp_jedi_increment_to_fv3 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/) # high level tests that require the global-workflow -if (WORKFLOW_TESTS) - - # test for creating an experiment directory within the global-workflow - add_test(NAME test_gdasapp_setup_cycled_exp - COMMAND ${PROJECT_SOURCE_DIR}/test/setup_workflow_exp.sh ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/testrun) -endif() +# TODO(AFE) see GDASApp issue #1213 +#if (WORKFLOW_TESTS) +# +# # test for creating an experiment directory within the global-workflow +# add_test(NAME test_gdasapp_setup_cycled_exp +# COMMAND ${PROJECT_SOURCE_DIR}/test/setup_workflow_exp.sh ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} +# WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/testrun) +#endif() if (${BUILD_GDASBUNDLE}) add_subdirectory(fv3jedi) # fv3jedi tests diff --git a/test/aero/genyaml_3dvar.sh b/test/aero/genyaml_3dvar.sh index 82363d15f..f8d3d23b4 100755 --- a/test/aero/genyaml_3dvar.sh +++ b/test/aero/genyaml_3dvar.sh @@ -24,6 +24,15 @@ export YAMLout=$DATA/3dvar_gfs_aero.yaml rm -rf $DATA mkdir -p $DATA +# Set g-w HOMEgfs +topdir=$(cd "$(dirname "$(readlink -f -n "${bindir}" )" )/../../.." && pwd -P) +export HOMEgfs=$topdir + +# Set python path for workflow utilities and tasks +wxflowPATH="${HOMEgfs}/ush/python" +PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${wxflowPATH}" +export PYTHONPATH + # run some python code to generate the YAML python3 - < $EXPDIR/config.base_lobsdiag_forenkf_false + exit $? diff --git a/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml b/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml index 185f8789c..41a761dee 100644 --- a/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml +++ b/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml @@ -1,6 +1,6 @@ variable change: variable change name: Model2GeoVaLs - input variables: &bkgvars [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr,phis] + input variables: &bkgvars [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr,surface_geopotential_height] output variables: &fv3incrvars [ua,va,t,sphum,ice_wat,liq_wat,o3mr,delp,hydrostatic_delz] jedi increment variables: [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr] fv3 increment variables: *fv3incrvars diff --git a/test/gw-ci/CMakeLists.txt b/test/gw-ci/CMakeLists.txt index dfd2a112f..357beaafe 100644 --- a/test/gw-ci/CMakeLists.txt +++ b/test/gw-ci/CMakeLists.txt @@ -46,8 +46,8 @@ set(pslot "WCDA-3DVAR-C48mx500") set(YAML_PATH ${HOMEgfs}/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml) set(TASK_LIST "gdasprepoceanobs" + "gdasmarinebmat" "gdasocnanalprep" - "gdasocnanalbmat" "gdasocnanalrun" "gdasocnanalchkpt" "gdasocnanalpost" diff --git a/test/snow/apply_jedi_incr.sh b/test/snow/apply_jedi_incr.sh index d00bcb2fc..d665a3c1c 100755 --- a/test/snow/apply_jedi_incr.sh +++ b/test/snow/apply_jedi_incr.sh @@ -16,7 +16,7 @@ GHR=$(date +%H -d "$YY$MM$DD $HH - 6 hours") EXECDIR=$project_source_dir/build/bin WORKDIR=$project_binary_dir/test/snow/apply_jedi_incr -RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model_data/atmos/restart +RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model/atmos/restart INCDIR=$GDASAPP_TESTDATA/snow/C${RES} export TPATH="$GDASAPP_TESTDATA/snow/C${RES}" diff --git a/test/snow/create_bkg_ens.sh b/test/snow/create_bkg_ens.sh index bc2232654..3d109605b 100755 --- a/test/snow/create_bkg_ens.sh +++ b/test/snow/create_bkg_ens.sh @@ -16,7 +16,7 @@ GYMD=$(date +%Y%m%d -d "$YY$MM$DD $HH - 6 hours") GHR=$(date +%H -d "$YY$MM$DD $HH - 6 hours") WORKDIR=$project_binary_dir/test/snow/create_jedi_ens -RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model_data/atmos/restart +RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model/atmos/restart GFSv17=NO DAtype=letkfoi_snow diff --git a/test/snow/letkfoi_snowda.sh b/test/snow/letkfoi_snowda.sh index 8b09ebca4..8e6cbdce0 100755 --- a/test/snow/letkfoi_snowda.sh +++ b/test/snow/letkfoi_snowda.sh @@ -16,7 +16,7 @@ GHR=$(date +%H -d "$YY$MM$DD $HH - 6 hours") EXECDIR=$project_source_dir/build/bin WORKDIR=$project_binary_dir/test/snow/letkfoi_snowda -RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model_data/atmos/restart +RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model/atmos/restart export OBSDIR=$GDASAPP_TESTDATA/snow GFSv17=${GFSv17:-"YES"} diff --git a/test/snow/test_imsproc.sh b/test/snow/test_imsproc.sh index 490c814c1..01cd6ec61 100755 --- a/test/snow/test_imsproc.sh +++ b/test/snow/test_imsproc.sh @@ -17,7 +17,7 @@ DOY=$(date +%j -d "$YY$MM$DD + 1 day") EXECDIR=$project_source_dir/build/bin WORKDIR=$project_binary_dir/test/snow/ims_proc -RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model_data/atmos/restart +RSTDIR=$GDASAPP_TESTDATA/lowres/gdas.$GYMD/$GHR/model/atmos/restart export OBSDIR=$GDASAPP_TESTDATA/snow/snow_ice_cover export TSTUB="oro_C${RES}.mx100" diff --git a/test/soca/gw/CMakeLists.txt b/test/soca/gw/CMakeLists.txt index e617b1156..1936ae994 100644 --- a/test/soca/gw/CMakeLists.txt +++ b/test/soca/gw/CMakeLists.txt @@ -7,12 +7,13 @@ add_test(NAME test_gdasapp_soca_prep WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/soca/gw) set_tests_properties(test_gdasapp_soca_prep PROPERTIES - ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/ush:${PROJECT_SOURCE_DIR}/../../ush/python/wxflow/src:$ENV{PYTHONPATH}") + ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/ush:${PROJECT_SOURCE_DIR}/../../ush/python/wxflow:$ENV{PYTHONPATH}") # Identify machine set(MACHINE "container") IF (IS_DIRECTORY /work2) - IF (IS_DIRECTORY /apps/other) + string(SUBSTRING $ENV{HOSTNAME} 0 8 HOST) + IF ("${HOST}" STREQUAL "hercules") set(MACHINE "hercules") set(PARTITION "hercules") ELSE() @@ -25,10 +26,6 @@ IF (IS_DIRECTORY /scratch2/NCEPDEV/) set(PARTITION "hera") ENDIF() -IF (IS_DIRECTORY /lfs/h2/) - set(MACHINE "wcoss2") -ENDIF() - # Clean-up add_test(NAME test_gdasapp_soca_run_clean COMMAND ${CMAKE_COMMAND} -E remove_directory ${PROJECT_BINARY_DIR}/test/soca/gw/testrun/testjjobs) @@ -46,10 +43,11 @@ add_test(NAME test_gdasapp_soca_setup_obsprep # Test JGDAS_GLOBAL_OCEAN_ANALYSIS_* set(jjob_list "JGLOBAL_PREP_OCEAN_OBS" + "JGLOBAL_MARINE_BMAT" "JGDAS_GLOBAL_OCEAN_ANALYSIS_PREP" - "JGDAS_GLOBAL_OCEAN_ANALYSIS_BMAT" +# "JGDAS_GLOBAL_OCEAN_ANALYSIS_BMAT" "JGDAS_GLOBAL_OCEAN_ANALYSIS_RUN" - "JGDAS_GLOBAL_OCEAN_ANALYSIS_ECEN" +# "JGDAS_GLOBAL_OCEAN_ANALYSIS_ECEN" # "JGDAS_GLOBAL_OCEAN_ANALYSIS_LETKF" "JGDAS_GLOBAL_OCEAN_ANALYSIS_CHKPT" "JGDAS_GLOBAL_OCEAN_ANALYSIS_POST") @@ -81,7 +79,7 @@ foreach(jjob ${jjob_list}) WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/soca/gw/testrun) set_tests_properties(${test_name} PROPERTIES - ENVIRONMENT "PYTHONPATH=${PROJECT_SOURCE_DIR}/ush/ioda/bufr2ioda::${PROJECT_SOURCE_DIR}/ush:${PROJECT_BINARY_DIR}/../lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}:$ENV{PYTHONPATH}:${PROJECT_SOURCE_DIR}/../../../../ush/python") + ENVIRONMENT "PYTHONPATH=${PROJECT_SOURCE_DIR}/ush/ioda/bufr2ioda::${PROJECT_SOURCE_DIR}/ush:${PROJECT_BINARY_DIR}/../lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}:${PROJECT_SOURCE_DIR}/ush/soca:${PROJECT_SOURCE_DIR}/../../../../ush/python:$ENV{PYTHONPATH}") set(setup "--skip") # Only run the setup of the first test, if not, it will hang @@ -89,7 +87,7 @@ foreach(jjob ${jjob_list}) endforeach() # Test gdas/oops applications -set(ctest_list "socahybridweights" "incr_handler" "ens_handler") +# add ens_handler back to the list when testing ensemble DA again foreach(ctest ${ctest_list}) set(TEST ${ctest}) set(EXEC ${PROJECT_BINARY_DIR}/../bin/gdas_${ctest}.x) diff --git a/test/soca/gw/prep.sh b/test/soca/gw/prep.sh index 2cefdc39d..c0717f243 100755 --- a/test/soca/gw/prep.sh +++ b/test/soca/gw/prep.sh @@ -11,29 +11,29 @@ ${project_source_dir}/test/soca/gw/static.sh $project_binary_dir $project_source COM=${project_binary_dir}/test/soca/gw/COM/gdas.20180415 -mkdir -p ${COM}/06/model_data/ice/history -mkdir -p ${COM}/06/model_data/ice/restart -mkdir -p ${COM}/06/model_data/ocean/history -mkdir -p ${COM}/06/model_data/atmos/analysis +mkdir -p ${COM}/06/model/ice/history +mkdir -p ${COM}/06/model/ice/restart +mkdir -p ${COM}/06/model/ocean/history +mkdir -p ${COM}/06/model/atmos/analysis # copy CICE6 restart ice_rst=${project_binary_dir}/test/testdata/iced.2019-04-15-43200.nc hist_icef=${project_binary_dir}/test/testdata/cice_hist.nc -cp ${ice_rst} ${COM}/06/model_data/ice/restart/20180415.120000.cice_model.res.nc +cp ${ice_rst} ${COM}/06/model/ice/restart/20180415.120000.cice_model.res.nc # invent MOM6 and CICE6 history files i=3 lof=`ls ${project_binary_dir}/test/testdata/ocn_da_*` for ocnf in $lof; do - cp $ocnf ${COM}/06/model_data/ocean/history/gdas.ocean.t06z.inst.f00$i.nc - cp $hist_icef ${COM}/06/model_data/ice/history/gdas.ice.t06z.inst.f00$i.nc + cp $ocnf ${COM}/06/model/ocean/history/gdas.ocean.t06z.inst.f00$i.nc + cp $hist_icef ${COM}/06/model/ice/history/gdas.ice.t06z.inst.f00$i.nc i=$(($i+1)) done # invent background error for day in $(seq 1 2 9); do - cp ${COM}/06/model_data/ocean/history/gdas.ocean.t06z.inst.f003.nc \ + cp ${COM}/06/model/ocean/history/gdas.ocean.t06z.inst.f003.nc \ ${project_binary_dir}/soca_static/bkgerr/stddev/ocn.ensstddev.fc.2019-04-0${day}T00:00:00Z.PT0S.nc cp ${project_source_dir}/sorc/soca/test/Data/72x35x25/ice.bkgerror.nc \ ${project_binary_dir}/soca_static/bkgerr/stddev/ice.ensstddev.fc.2019-04-0${day}T00:00:00Z.PT0S.nc @@ -43,7 +43,7 @@ done clim_ens_dir=${project_binary_dir}/soca_static/bkgerr/ens/2019-07-10T00Z mkdir -p ${clim_ens_dir} for domain in "ocean" "ice"; do - list_of_ocn_fcst=$(ls ${COM}/06/model_data/${domain}/history/gdas.${domain}.t06z.inst.f*.nc) + list_of_ocn_fcst=$(ls ${COM}/06/model/${domain}/history/gdas.${domain}.t06z.inst.f*.nc) counter=1 for file in ${list_of_ocn_fcst}; do file_name=${domain}.${counter}.nc @@ -65,13 +65,13 @@ for mem in {1..4} do echo "member: $mem" # ocean member - oceandir=${COMENS}/06/mem00${mem}/model_data/ocean/history + oceandir=${COMENS}/06/mem00${mem}/model/ocean/history mkdir -p $oceandir cp ${clim_ens_dir}/ocean.${mem}.nc $oceandir/enkfgdas.ocean.t06z.inst.f009.nc cp ${clim_ens_dir}/ocean.${mem}.nc $oceandir/enkfgdas.ocean.t06z.inst.f006.nc # ice member - icedir=${COMENS}/06/mem00${mem}/model_data/ice/history + icedir=${COMENS}/06/mem00${mem}/model/ice/history mkdir -p $icedir cp ${clim_ens_dir}/ice.${mem}.nc $icedir/enkfgdas.ice.t06z.inst.f009.nc cp ${clim_ens_dir}/ice.${mem}.nc $icedir/enkfgdas.ice.t06z.inst.f006.nc diff --git a/test/soca/gw/run_jjobs.yaml.test b/test/soca/gw/run_jjobs.yaml.test index f2331b07a..d8e4e6338 100644 --- a/test/soca/gw/run_jjobs.yaml.test +++ b/test/soca/gw/run_jjobs.yaml.test @@ -48,7 +48,7 @@ setup_expt config: DO_JEDIOCNVAR: "YES" DO_JEDISNOWDA: "NO" DO_MERGENSST: "NO" - NMEM_ENS: "4" + NMEM_ENS: "0" DOHYBVAR: "NO" ocnanal: SOCA_INPUT_FIX_DIR: @HOMEgfs@/sorc/gdas.cd/build/gdas/soca_static diff --git a/test/soca/socaincr2mom6.sh b/test/soca/socaincr2mom6.sh index 53add6284..3ce4b96cc 100755 --- a/test/soca/socaincr2mom6.sh +++ b/test/soca/socaincr2mom6.sh @@ -3,6 +3,15 @@ set -ex srcdir=$1 +# Set g-w HOMEgfs +topdir=$(cd "$(dirname "$(readlink -f -n "${srcdir}" )" )/.." && pwd -P) +export HOMEgfs=$topdir + +# Set python path for workflow utilities and tasks +wxflowPATH="${HOMEgfs}/ush/python" +PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${wxflowPATH}" +export PYTHONPATH + mom6_iau_incr="gdas.t12z.ocn.incr.nc" cat > nsst.yaml << EOF diff --git a/test/testinput/bufr_sfcsno_snow.yaml b/test/testinput/bufr_sfcsno_snow.yaml new file mode 100644 index 000000000..b1d663ae8 --- /dev/null +++ b/test/testinput/bufr_sfcsno_snow.yaml @@ -0,0 +1,83 @@ +# (C) Copyright 2021-2022 NOAA/NWS/NCEP/EMC +# + +observations: + - obs space: + name: bufr + + obsdatain: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno.tm00.bufr_d' + + exports: + variables: + # MetaData + timestamp: + datetime: + year: "*/YEAR[1]" + month: "*/MNTH[1]" + day: "*/DAYS[1]" + hour: "*/HOUR[1]" + minute: "*/MINU[1]" + latitude: + query: "[*/CLAT, */CLATH]" + longitude: + query: "[*/CLON, */CLONH]" + stationIdentification: + query: "*/RPID" + + stationElevation: + query: "[*/SELV, */HSMSL]" + + # ObsValue + totalSnowDepth: + query: "[*/SNWSQ1/TOSD, */MTRMSC/TOSD, */STGDSNDM/TOSD]" + transforms: + - scale: 1000.0 + filters: + - bounding: + variable: totalSnowDepth + upperBound: 10000000 + + ioda: + backend: netcdf + obsdataout: '{{ DATA }}/{{ OPREFIX }}sfcsno_snow.nc4' + + variables: + + # MetaData + - name: "MetaData/dateTime" + coordinates: "longitude latitude" + source: variables/timestamp + longName: "Datetime" + units: "seconds since 1970-01-01T00:00:00Z" + + - name: "MetaData/latitude" + coordinates: "longitude latitude" + source: variables/latitude + longName: "Latitude" + units: "degree_north" + range: [-90, 90] + + - name: "MetaData/longitude" + coordinates: "longitude latitude" + source: variables/longitude + longName: "Longitude" + units: "degree_east" + range: [-180, 180] + + - name: "MetaData/stationElevation" + coordinates: "longitude latitude" + source: variables/stationElevation + longName: "Height of Station" + + - name: "MetaData/stationIdentification" + coordinates: "longitude latitude" + source: variables/stationIdentification + longName: "Identification of Observing Location" + units: "m" + + # ObsValue + - name: "ObsValue/totalSnowDepth" + coordinates: "longitude latitude" + source: variables/totalSnowDepth + longName: "Total Snow Depth" + units: "mm" diff --git a/ush/eva/gen_eva_obs_yaml.py b/ush/eva/gen_eva_obs_yaml.py index 5ec301b09..9a500dd07 100755 --- a/ush/eva/gen_eva_obs_yaml.py +++ b/ush/eva/gen_eva_obs_yaml.py @@ -63,8 +63,8 @@ def gen_eva_obs_yaml(inputyaml, templateyaml, outputdir): os.makedirs(outputdir) # now loop over all observation spaces in input JEDI YAML file for obsspace in evaobs: - name = obsspace['name'] - cycle = obsspace['diagfile'].split('.')[-2] + name = obsspace['name'].replace(" ", "_").lower() + cycle = obsspace['diagfile'].split('_')[-1].split('.')[-2] logging.info(f'Now processing: {name}') # get the dictionary of replacements set up replacements = { diff --git a/ush/eva/marine_gdas_plots.yaml b/ush/eva/marine_gdas_plots.yaml index 9ad69d803..5bedd1f69 100644 --- a/ush/eva/marine_gdas_plots.yaml +++ b/ush/eva/marine_gdas_plots.yaml @@ -94,7 +94,7 @@ graphics: data: variable: experiment::OmBQC::${variable} @CHANNELKEY@ - markersize: 2 + markersize: 1 label: '$(variable)' colorbar: true # below may need to be edited/removed @@ -208,7 +208,7 @@ graphics: y: variable: experiment::hofx0::${variable} @CHANNELKEY@ - markersize: 5 + markersize: 1 color: 'black' label: 'JEDI h(x) versus obs (all obs)' - type: Scatter @@ -217,6 +217,6 @@ graphics: y: variable: experiment::hofxQC::${variable} @CHANNELKEY@ - markersize: 5 + markersize: 1 color: 'red' label: 'JEDI h(x) versus obs (passed QC in JEDI)' diff --git a/ush/examples/run_scripts/soca1deg.yaml b/ush/examples/run_scripts/soca1deg.yaml index 938160926..6ed4af7ac 100644 --- a/ush/examples/run_scripts/soca1deg.yaml +++ b/ush/examples/run_scripts/soca1deg.yaml @@ -31,8 +31,5 @@ jedi static: model background: ocn: /work2/noaa/da/gvernier/data/test_bkg/360x320x75/ -r2d2 options: - root: /work2/noaa/da/gvernier/data/static/r2d2-shared - fms: - domain_stack_size: 5832000 \ No newline at end of file + domain_stack_size: 5832000 diff --git a/ush/ioda/bufr2ioda/bufr2ioda_acft_profiles_prepbufr.py b/ush/ioda/bufr2ioda/bufr2ioda_acft_profiles_prepbufr.py index 8d4fa9974..53eda910e 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_acft_profiles_prepbufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_acft_profiles_prepbufr.py @@ -342,7 +342,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': np.arange(0, lat.shape[0])} - iodafile = f"{cycle_type}.t{hh}z.acft_profiles.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.aircraft.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_adpsfc_prepbufr.py b/ush/ioda/bufr2ioda/bufr2ioda_adpsfc_prepbufr.py index d23157605..5cffd940f 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_adpsfc_prepbufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_adpsfc_prepbufr.py @@ -232,7 +232,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': np.arange(0, lat.shape[0])} - iodafile = f"{cycle_type}.t{hh}z.{data_type}.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_adpupa.py b/ush/ioda/bufr2ioda/bufr2ioda_adpupa.py index 53dce26ad..5e282b376 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_adpupa.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_adpupa.py @@ -37,6 +37,21 @@ def Compute_WindComponents_from_WindDirection_and_WindSpeed(wdir, wspd): return uob, vob +def Compute_SpecificHumidity_from_dewPoint_and_Pressure(tmdp, prlc): + + # est is saturated vapor pressure in Mb + est = 6.1078 * np.exp((17.269 * (tmdp - 273.16))/((tmdp - 273.16)+237.3)) + # Change est from Mb to Pa + est = est*100. + + # specificHumidity (qob) is in kg/kg + qob = (0.622 * est)/(prlc - (0.378 * est)) + qob = ma.array(qob) + qob = ma.masked_values(qob, qob.fill_value) + + return qob + + def bufr_to_ioda(config, logger): subsets = config["subsets"] @@ -208,6 +223,10 @@ def bufr_to_ioda(config, logger): logger.debug(f' uob min/max = {uob.min()} {uob.max()}') logger.debug(f' vob min/max = {vob.min()} {vob.max()}') + qob = Compute_SpecificHumidity_from_dewPoint_and_Pressure(tmdp, prlc) + logger.debug(f' qob min/max = {qob.min()} {qob.max()}') + specificHumidityOE = np.float32(np.ma.masked_array(np.full((len(qob)), 0.0))) + end_time = time.time() running_time = end_time - start_time logger.info(f'Processing time for creating derived variables : {running_time} seconds') @@ -236,6 +255,7 @@ def bufr_to_ioda(config, logger): logger.debug(f' wspd shape = {wspd.shape}') logger.debug(f' uob shape = {uob.shape}') logger.debug(f' vob shape = {vob.shape}') + logger.debug(f' qob shape = {qob.shape}') logger.debug(f' qmpr shape = {qmpr.shape}') logger.debug(f' qmat shape = {qmat.shape}') @@ -264,6 +284,7 @@ def bufr_to_ioda(config, logger): logger.debug(f' wspd type = {wspd.dtype}') logger.debug(f' uob type = {uob.dtype}') logger.debug(f' vob type = {vob.dtype}') + logger.debug(f' qob type = {qob.dtype}') logger.debug(f' qmpr type = {qmpr.dtype}') logger.debug(f' qmat type = {qmat.dtype}') @@ -279,7 +300,7 @@ def bufr_to_ioda(config, logger): dims = {'Location': np.arange(0, clat.shape[0])} # Create IODA ObsSpace - iodafile = f"{cycle_type}.t{hh}z.{data_type}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.info(f"Create output file: {OUTPUT_PATH}") obsspace = ioda_ospace.ObsSpace(OUTPUT_PATH, mode='w', dim_dict=dims) @@ -365,6 +386,12 @@ def bufr_to_ioda(config, logger): .write_attr('long_name', 'Northward Wind') \ .write_data(vob) + # Specific Humidity + obsspace.create_var('ObsValue/specificHumidity', dtype=qob.dtype, fillval=qob.fill_value) \ + .write_attr('units', 'kg kg-1') \ + .write_attr('long_name', 'Specific Humidity') \ + .write_data(qob) + # Pressure Quality Marker obsspace.create_var('QualityMarker/pressure', dtype=qmpr.dtype, fillval=qmpr.fill_value) \ .write_attr('long_name', 'Pressure Quality Marker') \ @@ -420,6 +447,12 @@ def bufr_to_ioda(config, logger): .write_attr('long_name', 'Northward Wind Observation Error') \ .write_data(windNorthwardOE) + # Specific Humidity Observation Error + obsspace.create_var('ObsError/specificHumidity', dtype=qob.dtype, fillval=qob.fill_value) \ + .write_attr('units', 'kg kg-1') \ + .write_attr('long_name', 'Specific Humidity Observation Error') \ + .write_data(specificHumidityOE) + end_time = time.time() running_time = end_time - start_time logger.info(f"Running time for splitting and output IODA: {running_time} seconds") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_adpupa_prepbufr.py b/ush/ioda/bufr2ioda/bufr2ioda_adpupa_prepbufr.py index 05214f2fe..5518a992c 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_adpupa_prepbufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_adpupa_prepbufr.py @@ -352,7 +352,7 @@ def bufr_to_ioda(config, logger): dims = {'Location': np.arange(0, lat.shape[0])} # Create IODA ObsSpace - iodafile = f"{cycle_type}.t{hh}z.{data_type}.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.info(f"Create output file: {OUTPUT_PATH}") obsspace = ioda_ospace.ObsSpace(OUTPUT_PATH, mode='w', dim_dict=dims) diff --git a/ush/ioda/bufr2ioda/bufr2ioda_conventional_prepbufr_ps.py b/ush/ioda/bufr2ioda/bufr2ioda_conventional_prepbufr_ps.py index 55684cb56..790f41565 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_conventional_prepbufr_ps.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_conventional_prepbufr_ps.py @@ -864,7 +864,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': np.arange(0, lat.shape[0])} - iodafile = f"{cycle_type}.t{hh}z.{data_description}.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_description}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_gnssro_bufr.py b/ush/ioda/bufr2ioda/bufr2ioda_gnssro.py similarity index 99% rename from ush/ioda/bufr2ioda/bufr2ioda_gnssro_bufr.py rename to ush/ioda/bufr2ioda/bufr2ioda_gnssro.py index c200ea7dc..359c017d0 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_gnssro_bufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_gnssro.py @@ -403,7 +403,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': np.arange(0, clath.shape[0])} - iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.py b/ush/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.py deleted file mode 100755 index 698e5d422..000000000 --- a/ush/ioda/bufr2ioda/bufr2ioda_gpsro_bufr_combined.py +++ /dev/null @@ -1,593 +0,0 @@ -#!/usr/bin/env python3 -# (C) Copyright 2023 NOAA/NWS/NCEP/EMC -# -# This software is licensed under the terms of the Apache Licence Version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - -import sys -import os -import argparse -import json -import numpy as np -import numpy.ma as ma -import math -import calendar -import time -import datetime -from pyiodaconv import bufr -from collections import namedtuple -from pyioda import ioda_obs_space as ioda_ospace -from wxflow import Logger - -# ==================================================================== -# GPS-RO BUFR dump file -# ===================================================================== -# NC003010 | GPS-RO -# ==================================================================== - - -def Derive_stationIdentification(said, ptid): - - stid = [] - for i in range(len(said)): - newval = str(said[i]).zfill(4)+str(ptid[i]).zfill(4) - stid.append(str(newval)) - stid = np.array(stid).astype(dtype='str') - stid = ma.array(stid) - ma.set_fill_value(stid, "") - - return stid - - -def Compute_Grid_Location(degrees): - - for i in range(len(degrees)): - if degrees[i] <= 360 and degrees[i] >= -180: - degrees[i] = np.deg2rad(degrees[i]) - rad = degrees - - return rad - - -def Compute_imph(impp, elrc): - - imph = (impp - elrc).astype(np.float32) - - return imph - - -def bufr_to_ioda(config, logger): - - subsets = config["subsets"] - logger.debug(f"Checking subsets = {subsets}") - - # ========================================= - # Get parameters from configuration - # ========================================= - data_format = config["data_format"] - data_type = config["data_type"] - data_description = config["data_description"] - data_provider = config["data_provider"] - cycle_type = config["cycle_type"] - dump_dir = config["dump_directory"] - ioda_dir = config["ioda_directory"] - cycle = config["cycle_datetime"] - yyyymmdd = cycle[0:8] - hh = cycle[8:10] - - bufrfile = f"{cycle_type}.t{hh}z.{data_type}.tm00.{data_format}" - DATA_PATH = os.path.join(dump_dir, f"{cycle_type}.{yyyymmdd}", str(hh), - 'atmos', bufrfile) - if not os.path.isfile(DATA_PATH): - logger.info(f"DATA_PATH {DATA_PATH} does not exist") - return - logger.debug(f"The DATA_PATH is: {DATA_PATH}") - - # ============================================ - # Make the QuerySet for all the data we want - # ============================================ - start_time = time.time() - - logger.debug(f"Making QuerySet ...") - q = bufr.QuerySet(subsets) - - # MetaData - q.add('latitude', '*/ROSEQ1/CLATH') - q.add('longitude', '*/ROSEQ1/CLONH') - q.add('gridLatitude', '*/ROSEQ1/CLATH') - q.add('gridLongitude', '*/ROSEQ1/CLONH') - q.add('year', '*/YEAR') - q.add('year2', '*/YEAR') - q.add('month', '*/MNTH') - q.add('day', '*/DAYS') - q.add('hour', '*/HOUR') - q.add('minute', '*/MINU') - q.add('second', '*/SECO') - q.add('satelliteIdentifier', '*/SAID') - q.add('satelliteInstrument', '*/SIID') - q.add('satelliteConstellationRO', '*/SCLF') - q.add('satelliteTransmitterId', '*/PTID') - q.add('earthRadiusCurvature', '*/ELRC') -# q.add('observationSequenceNum', '*/SEQNUM') - q.add('geoidUndulation', '*/GEODU') - q.add('height', '*/ROSEQ3/HEIT') - q.add('impactParameterRO_roseq2repl1', '*/ROSEQ1/ROSEQ2{1}/IMPP') - q.add('impactParameterRO_roseq2repl3', '*/ROSEQ1/ROSEQ2{3}/IMPP') - q.add('frequency__roseq2repl1', '*/ROSEQ1/ROSEQ2{1}/MEFR') - q.add('frequency__roseq2repl3', '*/ROSEQ1/ROSEQ2{3}/MEFR') - q.add('pccf', '*/ROSEQ1/PCCF') - q.add('percentConfidence', '*/ROSEQ3/PCCF') - q.add('sensorAzimuthAngle', '*/BEARAZ') - - # Processing Center - q.add('dataProviderOrigin', '*/OGCE') - - # Quality Information - q.add('qualityFlags', '*/QFRO') - q.add('satelliteAscendingFlag', '*/QFRO') - - # ObsValue - q.add('bendingAngle_roseq2repl1', '*/ROSEQ1/ROSEQ2{1}/BNDA[1]') - q.add('bendingAngle_roseq2repl3', '*/ROSEQ1/ROSEQ2{3}/BNDA[1]') - q.add('atmosphericRefractivity', '*/ROSEQ3/ARFR[1]') - - # ObsError - q.add('obsErrorBendingAngle1', '*/ROSEQ1/ROSEQ2{1}/BNDA[2]') - q.add('obsErrorBendingAngle3', '*/ROSEQ1/ROSEQ2{3}/BNDA[2]') - q.add('obsErrorAtmosphericRefractivity', '*/ROSEQ3/ARFR[2]') - - # ObsType - q.add('obsTypeBendingAngle', '*/SAID') - q.add('obsTypeAtmosphericRefractivity', '*/SAID') - - end_time = time.time() - running_time = end_time - start_time - logger.debug(f"Running time for making QuerySet: {running_time} seconds") - - # ============================================================== - # Open the BUFR file and execute the QuerySet to get ResultSet - # Use the ResultSet returned to get numpy arrays of the data - # ============================================================== - start_time = time.time() - - logger.debug(f"Executing QuerySet to get ResultSet ...") - with bufr.File(DATA_PATH) as f: - try: - r = f.execute(q) - except Exception as err: - logger.info(f'Return with {err}') - return - - logger.debug(f" ... Executing QuerySet: get MetaData: basic ...") - # MetaData - clath = r.get('latitude', 'latitude') - clonh = r.get('longitude', 'latitude') - gclath = r.get('gridLatitude', 'latitude') - gclonh = r.get('gridLongitude', 'latitude') - year = r.get('year', 'latitude') - year2 = r.get('year2') - mnth = r.get('month', 'latitude') - days = r.get('day', 'latitude') - hour = r.get('hour', 'latitude') - minu = r.get('minute', 'latitude') - seco = r.get('second', 'latitude') - said = r.get('satelliteIdentifier', 'latitude') - siid = r.get('satelliteInstrument', 'latitude') - sclf = r.get('satelliteConstellationRO', 'latitude') - ptid = r.get('satelliteTransmitterId', 'latitude') - elrc = r.get('earthRadiusCurvature', 'latitude') -# seqnum = r.get('observationSequenceNum') - geodu = r.get('geoidUndulation', 'latitude') - heit = r.get('height', 'height', type='float32').astype(np.float32) - impp1 = r.get('impactParameterRO_roseq2repl1', 'latitude') - impp3 = r.get('impactParameterRO_roseq2repl3', 'latitude') - mefr1 = r.get('frequency__roseq2repl1', 'latitude', - type='float32').astype(np.float32) - mefr3 = r.get('frequency__roseq2repl3', 'latitude', - type='float32').astype(np.float32) - pccf = r.get('pccf', 'latitude', type='float32').astype(np.float32) - ref_pccf = r.get('percentConfidence', 'height') - bearaz = r.get('sensorAzimuthAngle', 'latitude') - - logger.debug(f" ... Executing QuerySet: get MetaData: processing center...") - # Processing Center - ogce = r.get('dataProviderOrigin', 'latitude') - - logger.debug(f" ... Executing QuerySet: get metadata: data quality \ - information ...") - # Quality Information - qfro = r.get('qualityFlags', 'latitude') - satasc = r.get('satelliteAscendingFlag', 'latitude') - - logger.debug(f" ... Executing QuerySet: get ObsValue: Bending Angle ...") - # ObsValue - # Bending Angle - bnda1 = r.get('bendingAngle_roseq2repl1', 'latitude') - bnda3 = r.get('bendingAngle_roseq2repl3', 'latitude') - arfr = r.get('atmosphericRefractivity', 'height') - - # ObsError - # Bending Angle - bndaoe1 = r.get('obsErrorBendingAngle1', 'latitude') - bndaoe3 = r.get('obsErrorBendingAngle3', 'latitude') - arfroe = r.get('obsErrorAtmosphericRefractivity', 'height') - - # ObsType - # Bending Angle - bndaot = r.get('obsTypeBendingAngle', 'latitude') - arfrot = r.get('obsTypeBendingAngle', 'latitude') - - logger.debug(f" ... Executing QuerySet: get datatime: observation time ...") - # DateTime: seconds since Epoch time - # IODA has no support for numpy datetime arrays dtype=datetime64[s] - timestamp = r.get_datetime('year', 'month', 'day', 'hour', 'minute', - 'second', 'latitude').astype(np.int64) - - logger.debug(f" ... Executing QuerySet: Done!") - - logger.debug(f" ... Executing QuerySet: Check BUFR variable generic \ - dimension and type ...") - # Check BUFR variable generic dimension and type - logger.debug(f" clath shape, type = {clath.shape}, {clath.dtype}") - logger.debug(f" clonh shape, type = {clonh.shape}, {clonh.dtype}") - logger.debug(f" gclath shape, type = {gclath.shape}, {gclath.dtype}") - logger.debug(f" gclonh shape, type = {gclonh.shape}, {gclonh.dtype}") - logger.debug(f" year shape, type = {year.shape}, {year.dtype}") - logger.debug(f" mnth shape, type = {mnth.shape}, {mnth.dtype}") - logger.debug(f" days shape, type = {days.shape}, {days.dtype}") - logger.debug(f" hour shape, type = {hour.shape}, {hour.dtype}") - logger.debug(f" minu shape, type = {minu.shape}, {minu.dtype}") - logger.debug(f" seco shape, type = {seco.shape}, {seco.dtype}") - logger.debug(f" said shape, type = {said.shape}, {said.dtype}") - logger.debug(f" siid shape, type = {siid.shape}, {siid.dtype}") - logger.debug(f" sclf shape, type = {sclf.shape}, {sclf.dtype}") - logger.debug(f" ptid shape, type = {ptid.shape}, {ptid.dtype}") - logger.debug(f" elrc shape, type = {elrc.shape}, {elrc.dtype}") - logger.debug(f" geodu shape, type = {geodu.shape}, {geodu.dtype}") - logger.debug(f" heit shape, type = {heit.shape}, {heit.dtype}") - logger.debug(f" impp1 shape, type = {impp1.shape}, {impp1.dtype}") - logger.debug(f" impp3 shape, type = {impp3.shape}, {impp3.dtype}") - logger.debug(f" mefr1 shape, type = {mefr1.shape}, {mefr1.dtype}") - logger.debug(f" mefr3 shape, type = {mefr3.shape}, {mefr3.dtype}") - logger.debug(f" pccf shape, type = {pccf.shape}, {pccf.dtype}") - logger.debug(f" ref_pccf shape, type = {ref_pccf.shape}, \ - {ref_pccf.dtype}") - logger.debug(f" bearaz shape, type = {bearaz.shape}, {bearaz.dtype}") - - logger.debug(f" ogce shape, type = {ogce.shape}, {ogce.dtype}") - - logger.debug(f" qfro shape, type = {qfro.shape}, {qfro.dtype}") - logger.debug(f" satasc shape, type = {satasc.shape}, {satasc.dtype}") - - logger.debug(f" bnda1 shape, type = {bnda1.shape}, {bnda1.dtype}") - logger.debug(f" bnda3 shape, type = {bnda3.shape}, {bnda3.dtype}") - logger.debug(f" arfr shape, type = {arfr.shape}, {arfr.dtype}") - - logger.debug(f" bndaoe1 shape, type = {bndaoe1.shape}, \ - {bndaoe1.dtype}") - logger.debug(f" bndaoe3 shape, type = {bndaoe3.shape}, \ - {bndaoe3.dtype}") - logger.debug(f" arfroe shape, type = {arfr.shape}, {arfr.dtype}") - - logger.debug(f" bndaot shape, type = {bndaot.shape}, {bndaot.dtype}") - - end_time = time.time() - running_time = end_time - start_time - logger.debug(f"Running time for executing QuerySet to get ResultSet: \ - {running_time} seconds") - - # ========================= - # Create derived variables - # ========================= - start_time = time.time() - - logger.debug(f"Creating derived variables - stationIdentification") - stid = Derive_stationIdentification(said, ptid) - - logger.debug(f" stid shape,type = {stid.shape}, {stid.dtype}") - - logger.debug(f"Creating derived variables - Grid Latitude / Longitude ...") - gclonh = Compute_Grid_Location(gclonh) - gclath = Compute_Grid_Location(gclath) - - logger.debug(f" gclonh shape,type = {gclonh.shape}, {gclonh.dtype}") - logger.debug(f" gclath shape,type = {gclath.shape}, {gclath.dtype}") - logger.debug(f" gclonh min/max = {gclonh.min()}, {gclonh.max()}") - logger.debug(f" gclath min/max = {gclath.min()}, {gclath.max()}") - - logger.debug(f"Creating derived variables - imph ...") - imph1 = Compute_imph(impp1, elrc) - imph3 = Compute_imph(impp3, elrc) - - logger.debug(f" imph1 shape,type = {imph1.shape}, {imph1.dtype}") - logger.debug(f" imph3 shape,type = {imph3.shape}, {imph3.dtype}") - logger.debug(f" imph1 min/max = {imph1.min()}, {imph1.max()}") - logger.debug(f" imph3 min/max = {imph3.min()}, {imph3.max()}") - - logger.debug(f"Editing some derived variables if SAID is not 44 or 825") - for i in range(len(said)): - if (said[i] != 44) or (said[i] != 825): - bnda1[i] = bnda3[i] - mefr1[i] = mefr3[i] - impp1[i] = impp3[i] - imph1[i] = imph3[i] - bndaoe1[i] = bndaoe3[i] - - logger.debug(f" new bnda1 shape, type, min/max {bnda1.shape}, \ - {bnda1.dtype}, {bnda1.min()}, {bnda1.max()}") - logger.debug(f" new mefr1 shape, type, min/max {mefr1.shape}, \ - {mefr1.dtype}, {mefr1.min()}, {mefr1.max()}") - logger.debug(f" new impp1 shape, type, min/max {impp1.shape}, \ - {impp1.dtype}, {impp1.min()}, {impp1.max()}") - logger.debug(f" new imph1 shape, type, min/max {imph1.shape}, \ - {imph1.dtype}, {imph1.min()}, {imph1.max()}") - logger.debug(f" new bndaoe1 shape, type, min/max {bndaoe1.shape}, \ - {bndaoe1.dtype}, {bndaoe1.min()}, {bndaoe1.max()}") - - end_time = time.time() - running_time = end_time - start_time - logger.debug(f"Running time for creating derived variables: {running_time} \ - seconds") - - # ===================================== - # Create IODA ObsSpace - # Write IODA output - # ===================================== - - # Find unique satellite identifiers in data to process - unique_satids = np.unique(said) - logger.debug(f" ... Number of Unique satellite identifiers: \ - {len(unique_satids)}") - logger.debug(f" ... Unique satellite identifiers: {unique_satids}") - - # Create the dimensions - dims = {'Location': np.arange(0, clath.shape[0])} - - iodafile = f"{cycle_type}.t{hh}z.{data_type}.{data_format}.nc" - OUTPUT_PATH = os.path.join(ioda_dir, iodafile) - logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") - - path, fname = os.path.split(OUTPUT_PATH) - if path and not os.path.exists(path): - os.makedirs(path) - - # Create IODA ObsSpace - obsspace = ioda_ospace.ObsSpace(OUTPUT_PATH, mode='w', dim_dict=dims) - - # Create Global attributes - logger.debug(f" ... ... Create global attributes") - obsspace.write_attr('data_format', data_format) - obsspace.write_attr('data_type', data_type) - obsspace.write_attr('subsets', subsets) - obsspace.write_attr('cycle_type', cycle_type) - obsspace.write_attr('cycle_datetime', cycle) - obsspace.write_attr('dataProviderOrigin', data_provider) - obsspace.write_attr('description', data_description) - obsspace.write_attr('converter', os.path.basename(__file__)) - - # Create IODA variables - logger.debug(f" ... ... Create variables: name, type, units, & attributes") - # Longitude - obsspace.create_var('MetaData/longitude', dtype=clonh.dtype, - fillval=clonh.fill_value) \ - .write_attr('units', 'degrees_east') \ - .write_attr('valid_range', np.array([-180, 180], dtype=np.float32)) \ - .write_attr('long_name', 'Longitude') \ - .write_data(clonh) - - # Latitude - obsspace.create_var('MetaData/latitude', dtype=clath.dtype, - fillval=clath.fill_value) \ - .write_attr('units', 'degrees_north') \ - .write_attr('valid_range', np.array([-90, 90], dtype=np.float32)) \ - .write_attr('long_name', 'Latitude') \ - .write_data(clath) - - # Grid Longitude - obsspace.create_var('MetaData/gridLongitude', dtype=gclonh.dtype, - fillval=gclonh.fill_value) \ - .write_attr('units', 'radians') \ - .write_attr('valid_range', np.array([-3.14159265, 3.14159265], - dtype=np.float32)) \ - .write_attr('long_name', 'Grid Longitude') \ - .write_data(gclonh) - - # Grid Latitude - obsspace.create_var('MetaData/gridLatitude', dtype=gclath.dtype, - fillval=gclath.fill_value) \ - .write_attr('units', 'radians') \ - .write_attr('valid_range', np.array([-1.570796325, 1.570796325], - dtype=np.float32)) \ - .write_attr('long_name', 'Grid Latitude') \ - .write_data(gclath) - - # Datetime - obsspace.create_var('MetaData/dateTime', dtype=np.int64, - fillval=timestamp.fill_value) \ - .write_attr('units', 'seconds since 1970-01-01T00:00:00Z') \ - .write_attr('long_name', 'Datetime') \ - .write_data(timestamp) - - # Station Identification - obsspace.create_var('MetaData/stationIdentification', dtype=stid.dtype, - fillval=stid.fill_value) \ - .write_attr('long_name', 'Station Identification') \ - .write_data(stid) - - # Satellite Identifier - obsspace.create_var('MetaData/satelliteIdentifier', dtype=said.dtype, - fillval=said.fill_value) \ - .write_attr('long_name', 'Satellite Identifier') \ - .write_data(said) - - # Satellite Instrument - obsspace.create_var('MetaData/satelliteInstrument', dtype=siid.dtype, - fillval=siid.fill_value) \ - .write_attr('long_name', 'Satellite Instrument') \ - .write_data(siid) - - # Satellite Constellation RO - obsspace.create_var('MetaData/satelliteConstellationRO', dtype=sclf.dtype, - fillval=sclf.fill_value) \ - .write_attr('long_name', 'Satellite Constellation RO') \ - .write_data(sclf) - - # Satellite Transmitter ID - obsspace.create_var('MetaData/satelliteTransmitterId', dtype=ptid.dtype, - fillval=ptid.fill_value) \ - .write_attr('long_name', 'Satellite Transmitter Id') \ - .write_data(ptid) - - # Earth Radius Curvature - obsspace.create_var('MetaData/earthRadiusCurvature', dtype=elrc.dtype, - fillval=elrc.fill_value) \ - .write_attr('units', 'm') \ - .write_attr('long_name', 'Earth Radius of Curvature') \ - .write_data(elrc) - - # Geoid Undulation - obsspace.create_var('MetaData/geoidUndulation', dtype=geodu.dtype, - fillval=geodu.fill_value) \ - .write_attr('units', 'm') \ - .write_attr('long_name', 'Geoid Undulation') \ - .write_data(geodu) - - # Height - obsspace.create_var('MetaData/height', dtype=heit.dtype, - fillval=heit.fill_value) \ - .write_attr('units', 'm') \ - .write_attr('long_name', 'Height') \ - .write_data(heit) - - # Impact Parameter RO - obsspace.create_var('MetaData/impactParameterRO', dtype=impp1.dtype, - fillval=impp1.fill_value) \ - .write_attr('units', 'm') \ - .write_attr('long_name', 'Impact Parameter RO') \ - .write_data(impp1) - - # Impact Height RO - obsspace.create_var('MetaData/impactHeightRO', dtype=imph1.dtype, - fillval=imph1.fill_value) \ - .write_attr('units', 'm') \ - .write_attr('long_name', 'Impact Height RO') \ - .write_data(imph1) - - # Impact Height RO - obsspace.create_var('MetaData/frequency', dtype=mefr1.dtype, - fillval=mefr1.fill_value) \ - .write_attr('units', 'Hz') \ - .write_attr('long_name', 'Frequency') \ - .write_data(mefr1) - - # PCCF Percent Confidence - obsspace.create_var('MetaData/pccf', dtype=pccf.dtype, - fillval=pccf.fill_value) \ - .write_attr('units', '%') \ - .write_attr('long_name', 'Percent Confidence') \ - .write_data(pccf) - - # PCCF Ref Percent Confidence - obsspace.create_var('MetaData/percentConfidence', dtype=ref_pccf.dtype, - fillval=ref_pccf.fill_value) \ - .write_attr('units', '%') \ - .write_attr('long_name', 'Ref Percent Confidence') \ - .write_data(ref_pccf) - - # Azimuth Angle - obsspace.create_var('MetaData/sensorAzimuthAngle', dtype=bearaz.dtype, - fillval=bearaz.fill_value) \ - .write_attr('units', 'degree') \ - .write_attr('long_name', 'Percent Confidence') \ - .write_data(bearaz) - - # Data Provider - obsspace.create_var('MetaData/dataProviderOrigin', dtype=ogce.dtype, - fillval=ogce.fill_value) \ - .write_attr('long_name', 'Identification of Originating Center') \ - .write_data(ogce) - - # Quality: Quality Flags - obsspace.create_var('MetaData/qualityFlags', dtype=qfro.dtype, - fillval=qfro.fill_value) \ - .write_attr('long_name', 'Quality Flags') \ - .write_data(qfro) - - # Quality: Satellite Ascending Flag - obsspace.create_var('MetaData/satelliteAscendingFlag', dtype=satasc.dtype, - fillval=satasc.fill_value) \ - .write_attr('long_name', 'Satellite Ascending Flag') \ - .write_data(satasc) - - # ObsValue: Bending Angle - obsspace.create_var('ObsValue/bendingAngle', dtype=bnda1.dtype, - fillval=bnda1.fill_value) \ - .write_attr('units', 'radians') \ - .write_attr('long_name', 'Bending Angle') \ - .write_data(bnda1) - - # ObsValue: Atmospheric Refractivity - obsspace.create_var('ObsValue/atmosphericRefractivity', dtype=arfr.dtype, - fillval=arfr.fill_value) \ - .write_attr('units', 'N-units') \ - .write_attr('long_name', 'Atmospheric Refractivity ObsError') \ - .write_data(arfr) - - # ObsError: Bending Angle - obsspace.create_var('ObsError/bendingAngle', dtype=bndaoe1.dtype, - fillval=bndaoe1.fill_value) \ - .write_attr('units', 'radians') \ - .write_attr('long_name', 'Bending Angle Obs Error') \ - .write_data(bndaoe1) - - # ObsError: Atmospheric Refractivity - obsspace.create_var('ObsError/atmosphericRefractivity', dtype=arfroe.dtype, - fillval=arfroe.fill_value) \ - .write_attr('units', 'N-units') \ - .write_attr('long_name', 'Atmospheric Refractivity ObsError') \ - .write_data(arfroe) - - # ObsType: Bending Angle - obsspace.create_var('ObsType/BendingAngle', dtype=bndaot.dtype, - fillval=bndaot.fill_value) \ - .write_attr('long_name', 'Bending Angle ObsType') \ - .write_data(bndaot) - - # ObsType: Atmospheric Refractivity - obsspace.create_var('ObsType/atmosphericRefractivity', dtype=arfrot.dtype, - fillval=arfrot.fill_value) \ - .write_attr('long_name', 'Atmospheric Refractivity ObsType') \ - .write_data(arfrot) - - end_time = time.time() - running_time = end_time - start_time - logger.debug(f"Running time for splitting and output IODA for gpsro bufr: \ - {running_time} seconds") - - logger.debug("All Done!") - - -if __name__ == '__main__': - - start_time = time.time() - - parser = argparse.ArgumentParser() - parser.add_argument('-c', '--config', type=str, - help='Input JSON configuration', required=True) - parser.add_argument('-v', '--verbose', - help='print debug logging information', - action='store_true') - args = parser.parse_args() - - log_level = 'DEBUG' if args.verbose else 'INFO' - logger = Logger('bufr2ioda_acft_profiles_prepbufr.py', level=log_level, - colored_log=True) - - with open(args.config, "r") as json_file: - config = json.load(json_file) - - bufr_to_ioda(config, logger) - - end_time = time.time() - running_time = end_time - start_time - logger.debug(f"Total running time: {running_time} seconds") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_sfcshp_prepbufr.py b/ush/ioda/bufr2ioda/bufr2ioda_sfcshp_prepbufr.py index ef1339818..36360d74e 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_sfcshp_prepbufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_sfcshp_prepbufr.py @@ -265,7 +265,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': np.arange(0, lat.shape[0])} - iodafile = f"{cycle_type}.t{hh}z.{data_type}.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.tm00.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/ioda/bufr2ioda/bufr2ioda_snocvr_bufr.py b/ush/ioda/bufr2ioda/bufr2ioda_snocvr_bufr.py index 6cf60ef6d..e0d2bfaea 100755 --- a/ush/ioda/bufr2ioda/bufr2ioda_snocvr_bufr.py +++ b/ush/ioda/bufr2ioda/bufr2ioda_snocvr_bufr.py @@ -131,7 +131,7 @@ def bufr_to_ioda(config, logger): # Create the dimensions dims = {'Location': snod.shape[0]} - iodafile = f"{cycle_type}.t{hh}z.{data_type}.{data_format}.nc" + iodafile = f"{cycle_type}.t{hh}z.{data_type}.nc" OUTPUT_PATH = os.path.join(ioda_dir, iodafile) logger.debug(f" ... ... Create OUTPUT file: {OUTPUT_PATH}") diff --git a/ush/run_satbias_conv.py b/ush/run_satbias_conv.py index aa749f322..1cb6166e6 100755 --- a/ush/run_satbias_conv.py +++ b/ush/run_satbias_conv.py @@ -101,7 +101,7 @@ def run_satbias_conv(config): f.write('output:\n') for sat in satlist: f.write(f'- sensor: {sat}\n') - f.write(f' output file: {sat}_satbias.nc4\n') + f.write(f' output file: {sat}_satbias.nc\n') f.write(' predictors: *default_preds\n') # run executable runcmd = f'./satbias2ioda.x satbias_converter.yaml' @@ -110,7 +110,7 @@ def run_satbias_conv(config): # copy output files to output directory outdir = os.path.join(ufo_bc_root, f'{cdump}.{pdy}', cyc, 'atmos') os.makedirs(outdir, exist_ok=True) - ncfiles = glob.glob(os.path.join(workdir, '*.nc4')) + ncfiles = glob.glob(os.path.join(workdir, '*.nc')) txtfiles = glob.glob(os.path.join(workdir, '*.txt')) allfiles = ncfiles + txtfiles for f in allfiles: 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/ush/soca/calc_scales.py b/ush/soca/calc_scales.py new file mode 100755 index 000000000..2ca6ce205 --- /dev/null +++ b/ush/soca/calc_scales.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# TODO: Copied/pasted from SOCA, point to the original one after we update the JEDI # + +import netCDF4 as nc +import numpy as np +import warnings +from scipy.ndimage import gaussian_filter, distance_transform_edt +import yaml +import argparse + + +def load_config(config_file): + with open(config_file, 'r') as stream: + config = yaml.safe_load(stream) + return config + + +def run(yaml_file): + config = load_config(yaml_file) + gridspec_filename = config.get('gridspec_filename', "./soca_gridspec.nc") + restart_filename = config.get('restart_filename', "./MOM.res.nc") + mld_filename = config.get('mld_filename', "./average_MLD.nc") + output_filename = config.get('output_filename', "./scales.nc") + output_variable_vt = config.get('output_variable_vt', 'vt') + output_variable_hz = config.get('output_variable_hz', 'hz') + + VT_MIN = float(config.get('VT_MIN', 1.5)) + VT_MAX = float(config.get('VT_MAX', 10)) + + HZ_ROSSBY_MULT = float(config.get('HZ_ROSSBY_MULT', 1.0)) + HZ_MAX = float(config.get('HZ_MAX', 200e3)) + HZ_MIN_GRID_MULT = float(config.get('HZ_MIN_GRID_MULT', 1.0)) + + # read input + with nc.Dataset(gridspec_filename, 'r') as src: + rossbyRadius = src.variables['rossby_radius'][0] + dx = src.variables['dx'][0] + dy = src.variables['dy'][0] + area = src.variables['area'][0] + mask = src.variables['mask2d'][0] + with nc.Dataset(restart_filename, 'r') as src: + h = src.variables['h'][0] + varType = src.variables['h'].datatype + with nc.Dataset(mld_filename, 'r') as src: + mld = src.variables['MLD'][0] + nz = h.shape[0] + + # calculate horizontal scales + hz_scales = rossbyRadius * HZ_ROSSBY_MULT + hz_scales = np.clip(hz_scales, a_min=dx*HZ_MIN_GRID_MULT, a_max=HZ_MAX) + hz_scales = np.clip(hz_scales, a_min=dy*HZ_MIN_GRID_MULT, a_max=HZ_MAX) + + # calculate hz smoothing scales for use inside this script. + # The scales (in units of # of grid cells) is zonally averaged, we assume hz scales + # do not vary as much with longitude as they do with latitude + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=RuntimeWarning) + smoothingScale = np.nanmean(np.where(mask, hz_scales/np.sqrt(area), np.NaN), axis=1) + smoothingScale[0] = smoothingScale[1] + smoothingScale[-1] = smoothingScale[-2] + + # smooth the horizontal scales WITH the horizontal scales. + hz_scales_orig = hz_scales.copy() + for j in range(hz_scales.shape[0]): # zonally for efficiency (otherwise it would be am i/j set of for loops) + hz_scales[j, :] = gaussian_filter(hz_scales_orig, sigma=smoothingScale[j], mode='nearest')[j, :] + hz_scales = np.where(mask, hz_scales, 0) + del hz_scales_orig + + # calculate vertical scales. + # --------------------------------------------------------- + + # initialize with zeros + vtScales = np.zeros_like(h) + + # smooth the MLD with the horizontal scales. + mld_orig = mld.copy() + # fill missing + mld_orig = mld[tuple(distance_transform_edt(mask == 0, return_distances=False, return_indices=True))] + for j in range(mld.shape[0]): # zonally for efficiency (otherwise it would be am i/j set of for loops) + mld[j, :] = gaussian_filter(mld_orig, sigma=smoothingScale[j], mode='nearest')[j, :] + mld = np.where(mask, mld, 0) + del mld_orig + + # calculate layer depths for use later + layerDepth = np.cumsum(h, axis=0) - h/2.0 + maxLevels = np.sum(np.where(h > 0.01, 1, 0), axis=0) # number of lvls before we hit bottom + + # find index of last level in the mixed layer + mlLastLevel = np.where(layerDepth < np.stack([mld]*nz, axis=0), 1, 0) + mlLastLevel[h <= 0.01] = 0 # don't count small bottom layers + mlLastLevel = np.clip(np.sum(mlLastLevel, axis=0)-1, a_min=0, a_max=nz-2) + + # add to that a fraction of layer at the bottom of the mixed layer + # for a total fractional number of levels in the ML + y_idx, x_idx = np.indices(mlLastLevel.shape) + depth1 = layerDepth[mlLastLevel, y_idx, x_idx] + depth2 = layerDepth[mlLastLevel+1, y_idx, x_idx] + mlLayers = mlLastLevel + (mld - depth1) / (depth2-depth1) + mlLayers = np.clip(mlLayers, a_min=1, a_max=maxLevels) + + # set the top to the number of levels in the ML, interpolate down to bottom of ML + # AND enforce a min/max value. The max value is important in order + # to keep the number of diffusion iterations in check. The resulting diracs + # are not quite the same... but close enough. + layer, _, _ = np.indices(h.shape) + mlLayers3D = np.stack([mlLayers]*nz, axis=0) + vtScales[:] = np.clip(mlLayers3D - layer, a_min=VT_MIN, a_max=VT_MAX) + + # ignore thin layers at the bottom + vtScales[h <= 0.01] = 0 + + # write output file + with nc.Dataset(output_filename, 'w') as dst: + dst.createDimension('Time', None) + dst.createDimension('z', vtScales.shape[0]) + dst.createDimension('y', vtScales.shape[1]) + dst.createDimension('x', vtScales.shape[2]) + + time = dst.createVariable('Time', varType, ('Time',)) + var_vt = dst.createVariable(output_variable_vt, varType, ('z', 'y', 'x')) + var_hz = dst.createVariable(output_variable_hz, varType, ('y', 'x')) + + var_vt[:] = vtScales + var_hz[:] = hz_scales + + +def main(): + parser = argparse.ArgumentParser(description='Process some netCDF files.') + parser.add_argument('config_file', help='Path to the YAML configuration file') + args = parser.parse_args() + + run(args.config_file) + + +if __name__ == "__main__": + main() diff --git a/ush/soca/examples/run_jjobs_container.yaml b/ush/soca/examples/run_jjobs_container.yaml deleted file mode 100644 index 92901fdc8..000000000 --- a/ush/soca/examples/run_jjobs_container.yaml +++ /dev/null @@ -1,45 +0,0 @@ -machine: container -resdetatmos: 48 - -jjobs: - - JGDAS_GLOBAL_OCEAN_ANALYSIS_PREP - - JGDAS_GLOBAL_OCEAN_ANALYSIS_RUN - - JGDAS_GLOBAL_OCEAN_ANALYSIS_POST - -gw environement: - experiment identifier: - PSLOT: gdas_test - HOMEgfs: /home/gvernier/wrk/gw - COMPONENT: ocean - CDUMP: gdas - - cycle info: - PDY: 20180415 - cyc: 12 - assym_freq: 6 - - backgrounds: - COMIN_GES: /home/gvernier/wrk/gw/sorc/gdas.cd/build/test/soca/bkg - - working directories: - ROTDIR: /home/gvernier/wrk/gw/sorc/gdas.cd/ush/soca/test/ROTDIRS - EXPDIRS: /home/gvernier/wrk/gw/sorc/gdas.cd/ush/soca/test/experiments - STMP: /home/gvernier/wrk/gw/sorc/gdas.cd/ush/soca/test - - jedi: - OOPS_TRACE: 1 - OOPS_DEBUG: 1 - OMP_NUM_THREADS: 1 - -setup_expt config: - ocnanal: - SOCA_INPUT_FIX_DIR: /home/gvernier/wrk/gw/sorc/gdas.cd/build/soca_static - CASE_ANL: C48 - SOCA_OBS_LIST: /home/gvernier/wrk/gw/sorc/gdas.cd/parm/soca/obs/obs_list.yaml - COMIN_OBS: /home/gvernier/wrk/gw/sorc/gdas.cd/build/test/soca/obs/r2d2-shared - SOCA_NINNER: 1 - R2D2_OBS_SRC: gdasapp - R2D2_OBS_DUMP: soca - SABER_BLOCKS_YAML: /home/gvernier/wrk/gw/sorc/gdas.cd/parm/soca/berror/saber_blocks.yaml - NICAS_RESOL: 1 - NICAS_GRID_SIZE: 15000 diff --git a/ush/soca/examples/run_jjobs_hera.yaml b/ush/soca/examples/run_jjobs_hera.yaml deleted file mode 100644 index 6b2edb863..000000000 --- a/ush/soca/examples/run_jjobs_hera.yaml +++ /dev/null @@ -1,50 +0,0 @@ -machine: hera -resdetatmos: 48 - -jjobs: - - JGDAS_GLOBAL_OCEAN_ANALYSIS_PREP - - JGDAS_GLOBAL_OCEAN_ANALYSIS_RUN - -gw environement: - experiment identifier: - PSLOT: gdas_test_5deg - HOMEgfs: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/sandboxes/gw-gdasapp - COMPONENT: ocean - CDUMP: gdas - - cycle info: - PDY: 20210323 - cyc: 18 - assym_freq: 6 - - backgrounds: - COMIN_GES: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/data/bkg/72x35x25/2021-03-23-12 - - working directories: - ROTDIR: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test/ROTDIRS - EXPDIRS: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test/experiments - STMP: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test - - jedi: - OOPS_TRACE: 1 - OOPS_DEBUG: 1 - OMP_NUM_THREADS: 1 - -setup_expt config: - ocnanal: - SOCA_INPUT_FIX_DIR: '/scratch2/NCEPDEV/ocean/Guillaume.Vernieres/data/static/72x35x25/soca' - CASE_ANL: 'C48' - SOCA_OBS_LIST: '' - COMIN_OBS: /scratch2/NCEPDEV/marineda/r2d2 - SOCA_NINNER: 3 - SABER_BLOCKS_YAML: '' - NICAS_RESOL: 1 - NICAS_GRID_SIZE: 15000 - -job options: - account: marine-cpu - qos: debug - output: gdas_test.out - nodes: 1 - partition: hera - time: 00:30:00 diff --git a/ush/soca/examples/run_jjobs_hera_025.yaml b/ush/soca/examples/run_jjobs_hera_025.yaml deleted file mode 100644 index 5686af150..000000000 --- a/ush/soca/examples/run_jjobs_hera_025.yaml +++ /dev/null @@ -1,50 +0,0 @@ -machine: hera -resdetatmos: 48 - -jjobs: - - JGDAS_GLOBAL_OCEAN_ANALYSIS_PREP - - JGDAS_GLOBAL_OCEAN_ANALYSIS_RUN - -gw environement: - experiment identifier: - PSLOT: gdas_test_025deg - HOMEgfs: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/sandboxes/gw-gdasapp - COMPONENT: ocean - CDUMP: gdas - - cycle info: - PDY: 20210701 - cyc: 12 - assym_freq: 6 - - backgrounds: - COMIN_GES: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/data/bkg/1440x1080x75/2021-07-01-12 - - working directories: - ROTDIR: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test/ROTDIRS - EXPDIRS: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test/experiments - STMP: /scratch2/NCEPDEV/ocean/Guillaume.Vernieres/runs/staticb-test - - jedi: - OOPS_TRACE: 1 - OOPS_DEBUG: 1 - OMP_NUM_THREADS: 1 - -setup_expt config: - ocnanal: - SOCA_INPUT_FIX_DIR: '/scratch2/NCEPDEV/ocean/Guillaume.Vernieres/data/static/1440x1080x75/soca' - CASE_ANL: 'C384' - SOCA_OBS_LIST: '' - COMIN_OBS: /scratch2/NCEPDEV/marineda/r2d2 - SOCA_NINNER: 1 - SABER_BLOCKS_YAML: '' - NICAS_RESOL: 1 - NICAS_GRID_SIZE: 15000 - -job options: - account: marine-cpu - qos: batch - output: gdas_test.out - nodes: 20 - partition: hera - time: 04:00:00 diff --git a/ush/soca/marine_recenter.py b/ush/soca/marine_recenter.py index fccacd7c6..5572e2c76 100644 --- a/ush/soca/marine_recenter.py +++ b/ush/soca/marine_recenter.py @@ -45,15 +45,15 @@ def __init__(self, config: Dict) -> None: # Variables of convenience # TODO (AFE) maybe the g- vars should be done in the jjob - PDY = self.runtime_config['PDY'] - cyc = self.runtime_config['cyc'] - DATA = self.runtime_config.DATA + PDY = self.task_config['PDY'] + cyc = self.task_config['cyc'] + DATA = self.task_config.DATA cdate = PDY + timedelta(hours=cyc) gdate = cdate - timedelta(hours=6) - self.runtime_config['gcyc'] = gdate.strftime("%H") - self.runtime_config['gPDY'] = datetime(gdate.year, - gdate.month, - gdate.day) + self.task_config['gcyc'] = gdate.strftime("%H") + self.task_config['gPDY'] = datetime(gdate.year, + gdate.month, + gdate.day) gdas_home = os.path.join(config['HOMEgfs'], 'sorc', 'gdas.cd') @@ -67,26 +67,26 @@ def __init__(self, config: Dict) -> None: 'ATM_WINDOW_BEGIN': window_begin_iso, 'ATM_WINDOW_MIDDLE': window_middle_iso, 'DATA': DATA, - 'dump': self.runtime_config.RUN, - 'fv3jedi_stage_files': self.config.FV3JEDI_STAGE_YAML, - 'fv3jedi_stage': self.config.FV3JEDI_STAGE_YAML, + 'dump': self.task_config.RUN, + 'fv3jedi_stage_files': self.task_config.FV3JEDI_STAGE_YAML, + 'fv3jedi_stage': self.task_config.FV3JEDI_STAGE_YAML, 'stage_dir': DATA, - 'soca_input_fix_dir': self.config.SOCA_INPUT_FIX_DIR, - 'NMEM_ENS': self.config.NMEM_ENS, + 'soca_input_fix_dir': self.task_config.SOCA_INPUT_FIX_DIR, + 'NMEM_ENS': self.task_config.NMEM_ENS, 'ATM_WINDOW_LENGTH': f"PT{config['assim_freq']}H"}) berror_yaml_dir = os.path.join(gdas_home, 'parm', 'soca', 'berror') - self.config['recen_yaml_template'] = os.path.join(berror_yaml_dir, 'soca_ensrecenter.yaml') - self.config['recen_yaml_file'] = os.path.join(DATA, 'soca_ensrecenter.yaml') - self.config['gridgen_yaml'] = os.path.join(gdas_home, 'parm', 'soca', 'gridgen', 'gridgen.yaml') - self.config['BKG_LIST'] = 'bkg_list.yaml' - self.config['window_begin'] = window_begin - self.config['mom_input_nml_src'] = os.path.join(gdas_home, 'parm', 'soca', 'fms', 'input.nml') - self.config['mom_input_nml_tmpl'] = os.path.join(DATA, 'mom_input.nml.tmpl') - self.config['mom_input_nml'] = os.path.join(DATA, 'mom_input.nml') - self.config['bkg_dir'] = os.path.join(DATA, 'bkg') - self.config['INPUT'] = os.path.join(DATA, 'INPUT') - self.config['ens_dir'] = os.path.join(DATA, 'ens') + self.task_config['recen_yaml_template'] = os.path.join(berror_yaml_dir, 'soca_ensrecenter.yaml') + self.task_config['recen_yaml_file'] = os.path.join(DATA, 'soca_ensrecenter.yaml') + self.task_config['gridgen_yaml'] = os.path.join(gdas_home, 'parm', 'soca', 'gridgen', 'gridgen.yaml') + self.task_config['BKG_LIST'] = 'bkg_list.yaml' + self.task_config['window_begin'] = window_begin + self.task_config['mom_input_nml_src'] = os.path.join(gdas_home, 'parm', 'soca', 'fms', 'input.nml') + self.task_config['mom_input_nml_tmpl'] = os.path.join(DATA, 'mom_input.nml.tmpl') + self.task_config['mom_input_nml'] = os.path.join(DATA, 'mom_input.nml') + self.task_config['bkg_dir'] = os.path.join(DATA, 'bkg') + self.task_config['INPUT'] = os.path.join(DATA, 'INPUT') + self.task_config['ens_dir'] = os.path.join(DATA, 'ens') @logit(logger) def initialize(self): @@ -100,57 +100,57 @@ def initialize(self): """ logger.info("initialize") - RUN = self.runtime_config.RUN - gcyc = self.runtime_config.gcyc + RUN = self.task_config.RUN + gcyc = self.task_config.gcyc ufsda.stage.soca_fix(self.recen_config) ################################################################################ # prepare input.nml - FileHandler({'copy': [[self.config.mom_input_nml_src, self.config.mom_input_nml_tmpl]]}).sync() + FileHandler({'copy': [[self.task_config.mom_input_nml_src, self.task_config.mom_input_nml_tmpl]]}).sync() # swap date and stack size - domain_stack_size = self.config.DOMAIN_STACK_SIZE - ymdhms = [int(s) for s in self.config.window_begin.strftime('%Y,%m,%d,%H,%M,%S').split(',')] - with open(self.config.mom_input_nml_tmpl, 'r') as nml_file: + domain_stack_size = self.task_config.DOMAIN_STACK_SIZE + ymdhms = [int(s) for s in self.task_config.window_begin.strftime('%Y,%m,%d,%H,%M,%S').split(',')] + with open(self.task_config.mom_input_nml_tmpl, 'r') as nml_file: nml = f90nml.read(nml_file) nml['ocean_solo_nml']['date_init'] = ymdhms nml['fms_nml']['domains_stack_size'] = int(domain_stack_size) - ufsda.disk_utils.removefile(self.config.mom_input_nml) - nml.write(self.config.mom_input_nml) + ufsda.disk_utils.removefile(self.task_config.mom_input_nml) + nml.write(self.task_config.mom_input_nml) - FileHandler({'mkdir': [self.config.bkg_dir]}).sync() - bkg_utils.gen_bkg_list(bkg_path=self.config.COM_OCEAN_HISTORY_PREV, - out_path=self.config.bkg_dir, - window_begin=self.config.window_begin, - yaml_name=self.config.BKG_LIST) + FileHandler({'mkdir': [self.task_config.bkg_dir]}).sync() + bkg_utils.gen_bkg_list(bkg_path=self.task_config.COM_OCEAN_HISTORY_PREV, + out_path=self.task_config.bkg_dir, + window_begin=self.task_config.window_begin, + yaml_name=self.task_config.BKG_LIST) ################################################################################ # Copy initial condition - bkg_utils.stage_ic(self.config.bkg_dir, self.runtime_config.DATA, gcyc) + bkg_utils.stage_ic(self.task_config.bkg_dir, self.task_config.DATA, gcyc) ################################################################################ # stage ensemble members logger.info("---------------- Stage ensemble members") - FileHandler({'mkdir': [self.config.ens_dir]}).sync() - nmem_ens = self.config.NMEM_ENS - gPDYstr = self.runtime_config.gPDY.strftime("%Y%m%d") + FileHandler({'mkdir': [self.task_config.ens_dir]}).sync() + nmem_ens = self.task_config.NMEM_ENS + gPDYstr = self.task_config.gPDY.strftime("%Y%m%d") ens_member_list = [] for mem in range(1, nmem_ens+1): for domain in ['ocean', 'ice']: - mem_dir = os.path.join(self.config.ROTDIR, + mem_dir = os.path.join(self.task_config.ROTDIR, f'enkf{RUN}.{gPDYstr}', f'{gcyc}', f'mem{str(mem).zfill(3)}', - 'model_data', + 'model', domain, 'history') mem_dir_real = os.path.realpath(mem_dir) f009 = f'enkf{RUN}.{domain}.t{gcyc}z.inst.f009.nc' fname_in = os.path.abspath(os.path.join(mem_dir_real, f009)) - fname_out = os.path.realpath(os.path.join(self.config.ens_dir, + fname_out = os.path.realpath(os.path.join(self.task_config.ens_dir, domain+"."+str(mem)+".nc")) ens_member_list.append([fname_in, fname_out]) @@ -161,8 +161,8 @@ def initialize(self): logger.info(f"---------------- generate soca_ensrecenter.yaml") - recen_yaml = parse_j2yaml(self.config.recen_yaml_template, self.recen_config) - recen_yaml.save(self.config.recen_yaml_file) + recen_yaml = parse_j2yaml(self.task_config.recen_yaml_template, self.recen_config) + recen_yaml.save(self.task_config.recen_yaml_file) @logit(logger) def run(self): @@ -177,12 +177,12 @@ def run(self): logger.info("run") - chdir(self.runtime_config.DATA) + chdir(self.task_config.DATA) - exec_cmd_gridgen = Executable(self.config.APRUN_OCNANALECEN) - exec_name_gridgen = os.path.join(self.config.JEDI_BIN, 'gdas_soca_gridgen.x') + exec_cmd_gridgen = Executable(self.task_config.APRUN_OCNANALECEN) + exec_name_gridgen = os.path.join(self.task_config.JEDI_BIN, 'gdas_soca_gridgen.x') exec_cmd_gridgen.add_default_arg(exec_name_gridgen) - exec_cmd_gridgen.add_default_arg(self.config.gridgen_yaml) + exec_cmd_gridgen.add_default_arg(self.task_config.gridgen_yaml) try: logger.debug(f"Executing {exec_cmd_gridgen}") @@ -193,10 +193,10 @@ def run(self): raise WorkflowException(f"An error occured during execution of {exec_cmd_gridgen}") pass - exec_cmd_recen = Executable(self.config.APRUN_OCNANALECEN) - exec_name_recen = os.path.join(self.config.JEDI_BIN, 'gdas_ens_handler.x') + exec_cmd_recen = Executable(self.task_config.APRUN_OCNANALECEN) + exec_name_recen = os.path.join(self.task_config.JEDI_BIN, 'gdas_ens_handler.x') exec_cmd_recen.add_default_arg(exec_name_recen) - exec_cmd_recen.add_default_arg(os.path.basename(self.config.recen_yaml_file)) + exec_cmd_recen.add_default_arg(os.path.basename(self.task_config.recen_yaml_file)) try: logger.debug(f"Executing {exec_cmd_recen}") @@ -220,16 +220,16 @@ def finalize(self): logger.info("finalize") - RUN = self.runtime_config.RUN - cyc = self.runtime_config.cyc + RUN = self.task_config.RUN + cyc = self.task_config.cyc incr_file = f'enkf{RUN}.t{cyc}z.ocninc.nc' - nmem_ens = self.config.NMEM_ENS - PDYstr = self.runtime_config.PDY.strftime("%Y%m%d") + nmem_ens = self.task_config.NMEM_ENS + PDYstr = self.task_config.PDY.strftime("%Y%m%d") mem_dir_list = [] copy_list = [] for mem in range(1, nmem_ens+1): - mem_dir = os.path.join(self.config.ROTDIR, + mem_dir = os.path.join(self.task_config.ROTDIR, f'enkf{RUN}.{PDYstr}', f'{cyc}', f'mem{str(mem).zfill(3)}', diff --git a/ush/soca/prep_ocean_obs.py b/ush/soca/prep_ocean_obs.py index 572b7349b..1d6b55e8e 100644 --- a/ush/soca/prep_ocean_obs.py +++ b/ush/soca/prep_ocean_obs.py @@ -37,20 +37,20 @@ def __init__(self, config: Dict) -> None: logger.info("init") super().__init__(config) - PDY = self.runtime_config['PDY'] - cyc = self.runtime_config['cyc'] + PDY = self.task_config['PDY'] + cyc = self.task_config['cyc'] cdate = PDY + timedelta(hours=cyc) - assim_freq = self.config['assim_freq'] + assim_freq = self.task_config['assim_freq'] half_assim_freq = assim_freq/2 - self.runtime_config['cdate'] = cdate + self.task_config['cdate'] = cdate window_begin_datetime = cdate - timedelta(hours=half_assim_freq) window_begin_datetime = cdate + timedelta(hours=half_assim_freq) self.window_begin = window_begin_datetime.strftime('%Y-%m-%dT%H:%M:%SZ') self.window_end = window_begin_datetime.strftime('%Y-%m-%dT%H:%M:%SZ') - self.config.conversion_list_file = 'conversion_list.yaml' - self.config.save_list_file = 'save_list.yaml' + self.task_config.conversion_list_file = 'conversion_list.yaml' + self.task_config.save_list_file = 'save_list.yaml' @logit(logger) def initialize(self): @@ -65,36 +65,36 @@ def initialize(self): logger.info("initialize") - cdate = self.runtime_config['cdate'] + cdate = self.task_config['cdate'] cdatestr = cdate.strftime('%Y%m%d%H') - RUN = self.runtime_config.RUN - cyc = self.runtime_config['cyc'] - assim_freq = self.config['assim_freq'] + RUN = self.task_config.RUN + cyc = self.task_config['cyc'] + assim_freq = self.task_config['assim_freq'] - SOCA_INPUT_FIX_DIR = self.config['SOCA_INPUT_FIX_DIR'] + SOCA_INPUT_FIX_DIR = self.task_config['SOCA_INPUT_FIX_DIR'] ocean_mask_src = os.path.join(SOCA_INPUT_FIX_DIR, 'RECCAP2_region_masks_all_v20221025.nc') - ocean_mask_dest = os.path.join(self.runtime_config.DATA, 'RECCAP2_region_masks_all_v20221025.nc') + ocean_mask_dest = os.path.join(self.task_config.DATA, 'RECCAP2_region_masks_all_v20221025.nc') try: FileHandler({'copy': [[ocean_mask_src, ocean_mask_dest]]}).sync() except OSError: logger.warning("Could not copy RECCAP2_region_masks_all_v20221025.nc") - OBS_YAML = self.config['OBS_YAML'] + OBS_YAML = self.task_config['OBS_YAML'] observer_config = YAMLFile(OBS_YAML) - OBSPREP_YAML = self.config['OBSPREP_YAML'] + OBSPREP_YAML = self.task_config['OBSPREP_YAML'] if os.path.exists(OBSPREP_YAML): obsprep_config = YAMLFile(OBSPREP_YAML) else: logger.critical(f"OBSPREP_YAML file {OBSPREP_YAML} does not exist") raise FileNotFoundError - JSON_TMPL_DIR = self.config.JSON_TMPL_DIR - BUFR2IODA_PY_DIR = self.config.BUFR2IODA_PY_DIR + JSON_TMPL_DIR = self.task_config.JSON_TMPL_DIR + BUFR2IODA_PY_DIR = self.task_config.BUFR2IODA_PY_DIR - COMIN_OBS = self.config.COMIN_OBS - COMOUT_OBS = self.config['COMOUT_OBS'] + COMIN_OBS = self.task_config.COMIN_OBS + COMOUT_OBS = self.task_config['COMOUT_OBS'] if not os.path.exists(COMOUT_OBS): os.makedirs(COMOUT_OBS) @@ -132,8 +132,8 @@ def initialize(self): interval = timedelta(hours=assim_freq * i) window_cdates.append(cdate + interval) - input_files = prep_ocean_obs_utils.obs_fetch(self.config, - self.runtime_config, + input_files = prep_ocean_obs_utils.obs_fetch(self.task_config, + self.task_config, obsprep_space, window_cdates) @@ -186,7 +186,7 @@ def initialize(self): # yes, there is redundancy between the yamls fed to the ioda converter and here, # this seems safer and easier than being selective about the fields - save_as_yaml({"observations": obsspaces_to_convert}, self.config.conversion_list_file) + save_as_yaml({"observations": obsspaces_to_convert}, self.task_config.conversion_list_file) @logit(logger) def run(self): @@ -201,9 +201,9 @@ def run(self): logger.info("run") - chdir(self.runtime_config.DATA) + chdir(self.task_config.DATA) - obsspaces_to_convert = YAMLFile(self.config.conversion_list_file) + obsspaces_to_convert = YAMLFile(self.task_config.conversion_list_file) processes = [] for observation in obsspaces_to_convert['observations']: @@ -213,7 +213,7 @@ def run(self): logger.info(f"Trying to convert {obtype} to IODA") if obs_space["type"] == "nc": process = Process(target=prep_ocean_obs_utils.run_netcdf_to_ioda, args=(obs_space, - self.config.OCNOBS2IODAEXEC)) + self.task_config.OCNOBS2IODAEXEC)) elif obs_space["type"] == "bufr": process = Process(target=prep_ocean_obs_utils.run_bufr_to_ioda, args=(obs_space,)) else: @@ -229,7 +229,7 @@ def run(self): process.join() completed.append(obs_space) - save_as_yaml({"observations": completed}, self.config.save_list_file) + save_as_yaml({"observations": completed}, self.task_config.save_list_file) @logit(logger) def finalize(self): @@ -244,11 +244,11 @@ def finalize(self): logger.info("finalize") - RUN = self.runtime_config.RUN - cyc = self.runtime_config.cyc - COMOUT_OBS = self.config.COMOUT_OBS + RUN = self.task_config.RUN + cyc = self.task_config.cyc + COMOUT_OBS = self.task_config.COMOUT_OBS - obsspaces_to_save = YAMLFile(self.config.save_list_file) + obsspaces_to_save = YAMLFile(self.task_config.save_list_file) for obsspace_to_save in obsspaces_to_save['observations']: diff --git a/ush/soca/prep_ocean_obs_utils.py b/ush/soca/prep_ocean_obs_utils.py index 7ba6e240b..11b18fd37 100755 --- a/ush/soca/prep_ocean_obs_utils.py +++ b/ush/soca/prep_ocean_obs_utils.py @@ -10,14 +10,14 @@ # copies them to DATA, and returns a list of the files so handled -def obs_fetch(config, runtime_config, obsprep_space, cycles): +def obs_fetch(config, task_config, obsprep_space, cycles): DMPDIR = config.DMPDIR COMIN_OBS = config.COMIN_OBS - RUN = runtime_config.RUN - PDY = runtime_config.PDY - cyc = runtime_config.cyc + RUN = task_config.RUN + PDY = task_config.PDY + cyc = task_config.cyc subdir = obsprep_space['dmpdir subdir'] dumpdir_regex = obsprep_space['dmpdir regex'] diff --git a/ush/soca/run_jjobs.py b/ush/soca/run_jjobs.py index 223ce0cc4..175262e0b 100755 --- a/ush/soca/run_jjobs.py +++ b/ush/soca/run_jjobs.py @@ -94,8 +94,8 @@ def export_env_vars_script(self): self.f.write(f"export gcyc='{gcyc}'\n") self.f.write(f"export CDATE='{CDATE}'\n") - # Add to python environement - self.f.write("PYTHONPATH=${HOMEgfs}/ush/python/wxflow/src:${PYTHONPATH}\n") + # Add to python environment + self.f.write("PYTHONPATH=${HOMEgfs}/ush/python:${PYTHONPATH}\n") def setupexpt(self): """ @@ -185,10 +185,10 @@ def copy_bkgs(self): self.f.write("mkdir -p ${COM_ICE_HISTORY_PREV}/\n") self.f.write("mkdir -p ${COM_ICE_RESTART_PREV}/\n") - model_data = os.path.join(self.com_src, f"{self.RUN}.{self.gPDY}", self.gcyc, "model_data") - com_ocean_history_src = os.path.join(model_data, 'ocean', 'history') - com_ice_history_src = os.path.join(model_data, 'ice', 'history') - com_ice_restart_src = os.path.join(model_data, 'ice', 'restart') + model = os.path.join(self.com_src, f"{self.RUN}.{self.gPDY}", self.gcyc, "model") + com_ocean_history_src = os.path.join(model, 'ocean', 'history') + com_ice_history_src = os.path.join(model, 'ice', 'history') + com_ice_restart_src = os.path.join(model, 'ice', 'restart') self.f.write(f"cp {com_ocean_history_src}/*.ocean.*.nc $COM_OCEAN_HISTORY_PREV \n") self.f.write(f"cp {com_ice_history_src}/*.ice.*.nc $COM_ICE_HISTORY_PREV \n") self.f.write(f"cp {com_ice_restart_src}/*cice_model*.nc $COM_ICE_RESTART_PREV \n") @@ -222,7 +222,6 @@ def fixconfigs(self): 'ROTDIR': self.rotdir, 'EXPDIRS': self.expdirs} - # needed for this ctest at least until R2D2 goes away if 'JGLOBAL_PREP_OCEAN_OBS' in self.config['jjobs']: dmpdir = self.config['setup_expt config']['prepoceanobs']['DMPDIR'] var2replace['DMPDIR'] = dmpdir diff --git a/ush/soca/soca_vrfy.py b/ush/soca/soca_vrfy.py index d80a7782e..854d7ab69 100755 --- a/ush/soca/soca_vrfy.py +++ b/ush/soca/soca_vrfy.py @@ -17,6 +17,7 @@ def plotConfig(grid_file=[], data_file=[], + layer_file=[], variable=[], PDY=os.getenv('PDY'), cyc=os.getenv('cyc'), @@ -44,6 +45,7 @@ def plotConfig(grid_file=[], config['comout'] = comout # output directory config['grid file'] = grid_file config['fields file'] = data_file + config['layer file'] = layer_file config['PDY'] = PDY config['cyc'] = cyc config['exp'] = exp @@ -67,7 +69,7 @@ def plotConfig(grid_file=[], def plotHorizontalSlice(config): """ - pcolormesh of a horizontal slice of an ocean field + Contourf of a horizontal slice of an ocean field """ grid = xr.open_dataset(config['grid file']) data = xr.open_dataset(config['fields file']) @@ -83,26 +85,43 @@ def plotHorizontalSlice(config): if variable in ['Temp', 'Salt', 'u', 'v']: level = config['levels'][0] slice_data = np.squeeze(data[variable])[level, :, :] - label_colorbar = variable+' Level '+str(level) - figname = os.path.join(dirname, variable+'_Level_'+str(level)) + label_colorbar = variable + ' Level ' + str(level) + figname = os.path.join(dirname, variable + '_Level_' + str(level)) title = f"{exp} {PDY} {cyc} {variable} Level {level}" else: slice_data = np.squeeze(data[variable]) label_colorbar = variable - figname = os.path.join(dirname, variable+'_'+config['proj']) + figname = os.path.join(dirname, variable + '_' + config['proj']) title = f"{exp} {PDY} {cyc} {variable}" - bounds = config['bounds'] + bounds = config['horiz variables'][variable] + slice_data = np.clip(slice_data, bounds[0], bounds[1]) fig, ax = plt.subplots(figsize=(8, 5), subplot_kw={'projection': projs[config['proj']]}) - plt.pcolormesh(np.squeeze(grid.lon), - np.squeeze(grid.lat), - slice_data, - vmin=bounds[0], vmax=bounds[1], - transform=ccrs.PlateCarree(), - cmap=config['colormap']) - - plt.colorbar(label=label_colorbar, shrink=0.5, orientation='horizontal') + + # Plot the filled contours + contourf_plot = ax.contourf(np.squeeze(grid.lon), + np.squeeze(grid.lat), + slice_data, + levels=100, + vmin=bounds[0], vmax=bounds[1], + transform=ccrs.PlateCarree(), + cmap=config['colormap']) + + # Add colorbar for filled contours + cbar = fig.colorbar(contourf_plot, ax=ax, shrink=0.75, orientation='horizontal') + cbar.set_label(label_colorbar) + + # Add contour lines with specified linewidths + contour_levels = np.linspace(bounds[0], bounds[1], 5) + ax.contour(np.squeeze(grid.lon), + np.squeeze(grid.lat), + slice_data, + levels=contour_levels, + colors='black', + linewidths=0.1, + transform=ccrs.PlateCarree()) + ax.coastlines() # TODO: make this work on hpc ax.set_title(title) if config['proj'] == 'South': @@ -116,7 +135,7 @@ def plotHorizontalSlice(config): def plotZonalSlice(config): """ - pcolormesh of a zonal slice of an ocean field + Contourf of a zonal slice of an ocean field """ variable = config['variable'] exp = config['exp'] @@ -125,32 +144,53 @@ def plotZonalSlice(config): lat = float(config['lat']) grid = xr.open_dataset(config['grid file']) data = xr.open_dataset(config['fields file']) - lat_index = np.argmin(np.array(np.abs(np.squeeze(grid.lat)[:, 0]-lat))) + layer = xr.open_dataset(config['layer file']) + lat_index = np.argmin(np.array(np.abs(np.squeeze(grid.lat)[:, 0] - lat))) slice_data = np.squeeze(np.array(data[variable]))[:, lat_index, :] - depth = np.squeeze(np.array(data['h']))[:, lat_index, :] + depth = np.squeeze(np.array(layer['h']))[:, lat_index, :] depth[np.where(np.abs(depth) > 10000.0)] = 0.0 depth = np.cumsum(depth, axis=0) - bounds = config['bounds'] + bounds = config['zonal variables'][variable] + slice_data = np.clip(slice_data, bounds[0], bounds[1]) x = np.tile(np.squeeze(grid.lon[:, lat_index]), (np.shape(depth)[0], 1)) + fig, ax = plt.subplots(figsize=(8, 5)) - plt.pcolormesh(x, -depth, slice_data, - vmin=bounds[0], vmax=bounds[1], - cmap=config['colormap']) - plt.colorbar(label=variable+' Lat '+str(lat), shrink=0.5, orientation='horizontal') + + # Plot the filled contours + contourf_plot = ax.contourf(x, -depth, slice_data, + levels=np.linspace(bounds[0], bounds[1], 100), + vmin=bounds[0], vmax=bounds[1], + cmap=config['colormap']) + + # Add contour lines with specified linewidths + contour_levels = np.linspace(bounds[0], bounds[1], 5) + ax.contour(x, -depth, slice_data, + levels=contour_levels, + colors='black', + linewidths=0.1) + + # Add colorbar for filled contours + cbar = fig.colorbar(contourf_plot, ax=ax, shrink=0.5, orientation='horizontal') + cbar.set_label(variable + ' Lat ' + str(lat)) + + # Set the colorbar ticks + cbar.set_ticks(contour_levels) + contourf_plot.set_clim(bounds[0], bounds[1]) + ax.set_ylim(-config['max depth'], 0) title = f"{exp} {PDY} {cyc} {variable} lat {int(lat)}" ax.set_title(title) - dirname = os.path.join(config['comout'], variable) + dirname = os.path.join(config['comout'], config['variable']) os.makedirs(dirname, exist_ok=True) - figname = os.path.join(dirname, variable + - 'zonal_lat_'+str(int(lat)) + '_' + str(int(config['max depth'])) + 'm') + figname = os.path.join(dirname, config['variable'] + + 'zonal_lat_' + str(int(lat)) + '_' + str(int(config['max depth'])) + 'm') plt.savefig(figname, bbox_inches='tight', dpi=600) plt.close(fig) def plotMeridionalSlice(config): """ - pcolormesh of a Meridional slice of an ocean field + Contourf of a Meridional slice of an ocean field """ variable = config['variable'] exp = config['exp'] @@ -159,25 +199,46 @@ def plotMeridionalSlice(config): lon = float(config['lon']) grid = xr.open_dataset(config['grid file']) data = xr.open_dataset(config['fields file']) - lon_index = np.argmin(np.array(np.abs(np.squeeze(grid.lon)[0, :]-lon))) + layer = xr.open_dataset(config['layer file']) + lon_index = np.argmin(np.array(np.abs(np.squeeze(grid.lon)[0, :] - lon))) slice_data = np.squeeze(np.array(data[config['variable']]))[:, :, lon_index] - depth = np.squeeze(np.array(data['h']))[:, :, lon_index] + depth = np.squeeze(np.array(layer['h']))[:, :, lon_index] depth[np.where(np.abs(depth) > 10000.0)] = 0.0 depth = np.cumsum(depth, axis=0) - bounds = config['bounds'] + bounds = config['meridional variables'][variable] + slice_data = np.clip(slice_data, bounds[0], bounds[1]) y = np.tile(np.squeeze(grid.lat)[:, lon_index], (np.shape(depth)[0], 1)) + fig, ax = plt.subplots(figsize=(8, 5)) - plt.pcolormesh(y, -depth, slice_data, - vmin=bounds[0], vmax=bounds[1], - cmap=config['colormap']) - plt.colorbar(label=config['variable']+' Lon '+str(lon), shrink=0.5, orientation='horizontal') + + # Plot the filled contours + contourf_plot = ax.contourf(y, -depth, slice_data, + levels=np.linspace(bounds[0], bounds[1], 100), + vmin=bounds[0], vmax=bounds[1], + cmap=config['colormap']) + + # Add contour lines with specified linewidths + contour_levels = np.linspace(bounds[0], bounds[1], 5) + ax.contour(y, -depth, slice_data, + levels=contour_levels, + colors='black', + linewidths=0.1) + + # Add colorbar for filled contours + cbar = fig.colorbar(contourf_plot, ax=ax, shrink=0.5, orientation='horizontal') + cbar.set_label(variable + ' Lon ' + str(lon)) + + # Set the colorbar ticks + cbar.set_ticks(contour_levels) + contourf_plot.set_clim(bounds[0], bounds[1]) + ax.set_ylim(-config['max depth'], 0) title = f"{exp} {PDY} {cyc} {variable} lon {int(lon)}" ax.set_title(title) dirname = os.path.join(config['comout'], config['variable']) os.makedirs(dirname, exist_ok=True) figname = os.path.join(dirname, config['variable'] + - 'meridional_lon_'+str(int(lon)) + '_' + str(int(config['max depth'])) + 'm') + 'meridional_lon_' + str(int(lon)) + '_' + str(int(config['max depth'])) + 'm') plt.savefig(figname, bbox_inches='tight', dpi=600) plt.close(fig) diff --git a/ush/ufoeval/run_ufo_hofx_test.sh b/ush/ufoeval/run_ufo_hofx_test.sh index 5cb77fb6e..8d685d231 100755 --- a/ush/ufoeval/run_ufo_hofx_test.sh +++ b/ush/ufoeval/run_ufo_hofx_test.sh @@ -28,7 +28,7 @@ usage() { # ============================================================================== -cycle=2021080100 +cycle=2024021900 run_filtering=YES run_eva=YES eva_stats_only=NO @@ -77,6 +77,8 @@ if [ $machine = orion ]; then workdir=/work2/noaa/da/$LOGNAME/ufoeval/$cycle/${obtype} fi GDASApp=${GDASApp:-/work2/noaa/da/$LOGNAME/git/GDASApp/} # Change this to your own branch + JCBinstall=${JCBinstall:-/work2/noaa/da/cmartin/CI/GDASApp/opt} + JCBpylib=$JCBinstall/lib/python3.7/site-packages elif [ $machine = hera ]; then if [ $run_filtering == NO ]; then workdir=/scratch1/NCEPDEV/stmp2/$LOGNAME/ufoeval/$cycle/${obtype}_noqc @@ -84,6 +86,8 @@ elif [ $machine = hera ]; then workdir=/scratch1/NCEPDEV/stmp2/$LOGNAME/ufoeval/$cycle/${obtype} fi GDASApp=${GDASApp:-/scratch1/NCEPDEV/da/$LOGNAME/git/GDASApp/} # Change this to your own branch + JCBinstall=${JCBinstall:-/scratch1/NCEPDEV/da/Cory.R.Martin/CI/GDASApp/opt} + JCBpylib=$JCBinstall/lib/python3.10/site-packages else echo "Machine " $machine "not found" exit 1 @@ -94,17 +98,12 @@ if [ $keep_output = YES ]; then workdir=${workdir}_datetime fi -if [ $run_filtering == NO ]; then - yamlpath=$GDASApp/parm/atm/obs/testing/${obtype}_noqc.yaml -else - yamlpath=$GDASApp/parm/atm/obs/testing/${obtype}.yaml -fi exename=test_ObsFilters.x #-------------- Do not modify below this line ---------------- # paths that should only be changed by an expert user -dataprocdate=20230811 # Production date of test data +dataprocdate=20240815 # Production date of test data obtype_short=${obtype:0:4} if [ $obtype_short = "cris" ] || [ $obtype_short = "iasi" ] || [ $obtype_short = "hirs" ] || [ $obtype_short = "sevi" ] || \ @@ -116,7 +115,7 @@ else fi if [ $machine = orion ]; then - export Datapath='/work2/noaa/da/eliu/UFO_eval/data/gsi_geovals_l127/nofgat_aug2021/'$dataprocdate + export Datapath='/work2/noaa/da/acollard/UFO_eval/data/gsi_geovals_l127/nofgat_feb2024/'$dataprocdate FixDir=/work2/noaa/da/cmartin/GDASApp/fix elif [ $machine = hera ]; then export Datapath='/scratch1/NCEPDEV/da/Emily.Liu/UFO_eval/data/gsi_geovals_l127/nofgat_aug2021/'$dataprocdate @@ -133,14 +132,29 @@ BCDir=$Datapath/bc/ # other variables that should not change often export CDATE=$cycle export assim_freq=6 +export half_assim_freq=$(($assim_freq / 2)) export GDATE=$(date +%Y%m%d%H -d "${CDATE:0:8} ${CDATE:8:2} - ${assim_freq} hours") +export BDATE=$(date +%Y%m%d%H -d "${CDATE:0:8} ${CDATE:8:2} - ${half_assim_freq} hours") export PDY=${CDATE:0:8} export cyc=${CDATE:8:2} +export YYYY=${CDATE:0:4} +export MM=${CDATE:4:2} +export DD=${CDATE:6:2} export gPDY=${GDATE:0:8} export gcyc=${GDATE:8:2} +export bPDY=${BDATE:0:8} +export bcyc=${BDATE:8:2} +export bYYYY=${BDATE:0:4} +export bMM=${BDATE:4:2} +export bDD=${BDATE:6:2} export CASE="C768" export CASE_ANL="C384" export LEVS="128" +export DATA=./ +export COMPONENT=atmos +export OPREFIX=gdas.t${cyc}z +export APREFIX=gdas.t${cyc}z +export GPREFIX=gdas.t${gcyc}z # Load Modules for GDASApp module use $GDASApp/modulefiles @@ -157,12 +171,13 @@ ln -sf $FixDir/crtm/2.4.0 $workdir/crtm # copy BC files if [ $radiance = "YES" ]; then - cp -rf $BCDir/${obtype}*${GDATE}* $workdir/. + cp -rf $BCDir/${GPREFIX}.${obtype}.tlapse.txt $workdir/${GPREFIX}.${obtype}.tlapse.txt + cp -rf $BCDir/${GPREFIX}.${obtype}.satbias.nc $workdir/${GPREFIX}.${obtype}.satbias.nc fi # Copy obs and geovals -cp -rf $GeoDir/${obtype}_geoval_${cycle}*.nc4 $workdir/. -cp -rf $ObsDir/${obtype}_obs_${cycle}*.nc4 $workdir/. +cp -rf $GeoDir/${obtype}_geoval_${cycle}.nc4 $workdir/${OPREFIX}.${obtype}_geoval.tm00.nc +cp -rf $ObsDir/${obtype}_obs_${cycle}.nc4 $workdir/${OPREFIX}.${obtype}.tm00.nc # Link executable ln -sf $GDASApp/build/bin/$exename $workdir/. @@ -170,22 +185,75 @@ ln -sf $GDASApp/build/bin/$exename $workdir/. echo "Generating YAML" # Copy/generate YAML for test executable -# First, create the input YAMLs for the genYAML script -export DATA=./ -export COMPONENT=atmos -export OPREFIX=gdas.t${cyc}z -export APREFIX=gdas.t${cyc}z -export GPREFIX=gdas.t${gcyc}z +# need to add JCB to PATH and PYTHONPATH +export PYTHONPATH=$PYTHONPATH:$JCBpylib +export PATH=$PATH:$JCBinstall/bin +# First, create the input file for JCB cat > $workdir/temp.yaml << EOF -time window: - begin: '{{ WINDOW_BEGIN | to_isotime }}' - end: '{{ WINDOW_END | to_isotime }}' - bound to include: begin -observations: -- !INC $yamlpath +# Search path for model and obs for JCB +# ------------------------------------- +algorithm_path: "$GDASApp/parm/jcb-algorithms" +app_path_algorithm: "$GDASApp/parm/jcb-gdas/algorithm/atmosphere" +app_path_model: "$GDASApp/parm/jcb-gdas/model/atmosphere" +app_path_observations: "$GDASApp/parm/jcb-gdas/observations/atmosphere" +app_path_observation_chronicle: "$GDASApp/parm/jcb-gdas/observation_chronicle/atmosphere" + + +# Places where we deviate from the generic file name of a yaml +# ------------------------------------------------------------ +#final_increment_file: final_increment_gaussian +final_increment_file: final_increment_cubed_sphere +output_ensemble_increments_file: output_ensemble_increments_cubed_sphere +model_file: model_pseudo +initial_condition_file: background # Initial conditions for 4D apps is background + + +# Assimilation window +# ------------------- +window_begin: "${bYYYY}-${bMM}-${bDD}T${bcyc}:00:00Z" +window_length: "PT${assim_freq}H" +bound_to_include: begin + +# Default background time is for 3D applications +atmosphere_background_time_iso: "${YYYY}-${MM}-${DD}T${cyc}:00:00Z" + +algorithm: test_obs_filters + +# Observation things +# ------------------ +observations: [${obtype}] + +crtm_coefficient_path: "$workdir/crtm/" + +# Naming conventions for observational files +atmosphere_obsdatain_path: "$workdir" +atmosphere_obsdatain_prefix: "$OPREFIX." +atmosphere_obsdatain_suffix: ".tm00.nc" + +atmosphere_obsdataout_path: "$workdir" +atmosphere_obsdataout_prefix: diag_ +atmosphere_obsdataout_suffix: "_${cycle}.nc" + +# Naming conventions for bias correction files +atmosphere_obsbiasin_path: "$workdir" +atmosphere_obsbiasin_prefix: "$GPREFIX." +atmosphere_obsbiasin_suffix: ".satbias.nc" +atmosphere_obstlapsein_prefix: "$GPREFIX." +atmosphere_obstlapsein_suffix: ".tlapse.txt" +atmosphere_obsbiascovin_prefix: "$GPREFIX." +atmosphere_obsbiascovin_suffix: ".satbias_cov.nc" + +atmosphere_obsbiasout_path: "$workdir" +atmosphere_obsbiasout_prefix: "$APREFIX." +atmosphere_obsbiasout_suffix: ".satbias.nc" +atmosphere_obsbiascovout_prefix: "$APREFIX." +atmosphere_obsbiascovout_suffix: ".satbias_cov.nc" EOF -$GDASApp/ush/genYAML --input $workdir/temp.yaml --output $workdir/${obtype}_${cycle}.yaml +# jcb render dictionary_of_templates.yaml jedi_config.yaml +echo "Calling JCB Render" +jcb render $workdir/temp.yaml $workdir/${obtype}_${cycle}.yaml +echo "Called JCB Render" if [ $? -ne 0 ]; then echo "YAML creation failed" diff --git a/ush/ufoeval/test_yamls.sh b/ush/ufoeval/test_yamls.sh index d46056bd8..4c721f9af 100755 --- a/ush/ufoeval/test_yamls.sh +++ b/ush/ufoeval/test_yamls.sh @@ -14,7 +14,7 @@ if [ $? -ne 0 ]; then fi # Process tests wiht QC -for file in `find ../../parm/atm/obs/testing/*.yaml -type f -not -name "*noqc*"`; do +for file in `find ../../parm/jcb-gdas/observations/atmosphere -type f`; do basefile=${file##*/} obtype="${basefile%.*}" ./run_ufo_hofx_test.sh -x $obtype > $WORKDIR/$obtype.log 2> $WORKDIR/$obtype.err @@ -26,7 +26,7 @@ for file in `find ../../parm/atm/obs/testing/*.yaml -type f -not -name "*noqc*"` done # Process tests without QC (HofX + Observation error assignment) -for file in `ls ../../parm/atm/obs/testing/*_noqc.yaml`; do +for file in `find ../../parm/jcb-gdas/observations/atmosphere -type f`; do basefile=${file##*/} obtype="${basefile%_noqc.*}" ./run_ufo_hofx_test.sh -x -q $obtype > $WORKDIR/${obtype}_noqc.log 2> $WORKDIR/${obtype}_noqc.err diff --git a/utils/chem/chem_diagb.h b/utils/chem/chem_diagb.h index b8bfcdae9..703d4841f 100644 --- a/utils/chem/chem_diagb.h +++ b/utils/chem/chem_diagb.h @@ -132,6 +132,7 @@ namespace gdasapp { // Loop through variables for (auto & var : chemVars.variables()) { + nodeColumns.haloExchange(xbFs[var]); oops::Log::info() << "====================== std dev for " << var << std::endl; auto bkg = atlas::array::make_view(xbFs[var]); auto stdDevBkg = atlas::array::make_view(bkgErrFs[var]); @@ -230,13 +231,67 @@ namespace gdasapp { } // Rescale - double rescale; - fullConfig.get("rescale", rescale); - util::multiplyFieldSet(bkgErrFs, rescale); + if (fullConfig.has("rescale")) { + double rescale; + fullConfig.get("rescale", rescale); + util::multiplyFieldSet(bkgErrFs, rescale); + } - // We want to write with fv3jedi, not atlas: Syncronize with fv3jedi Increment bkgErr.fromFieldSet(bkgErrFs); + // Hybrid B option + if (fullConfig.has("climate background error")) { + const eckit::LocalConfiguration ClimBConfig(fullConfig, "climate background error"); + // Hybrid diagb_weight coefficient + // std = diagb_weight*diagb_std + (1-diagb_weight)*Climat_std + double diagb_weight; + ClimBConfig.get("diagb weight", diagb_weight); + // Initialize and read the climatological background error standard deviation field + oops::Log::info() << "====================== read climat bkg error std dev" << std::endl; + const eckit::LocalConfiguration climBGeomConfig(ClimBConfig, "geometry"); + const fv3jedi::Geometry climBGeom(climBGeomConfig, this->getComm()); + fv3jedi::Increment ClimBkgErrorStdDevOrig(climBGeom, chemVars, cycleDate); + ClimBkgErrorStdDevOrig.zero(); + const eckit::LocalConfiguration ClimBkgErrorStdDevConfig(ClimBConfig, + "climate background error stddev"); + ClimBkgErrorStdDevOrig.read(ClimBkgErrorStdDevConfig); + // interpolate to background resolution + fv3jedi::Increment ClimBkgErrorStdDev(geom, ClimBkgErrorStdDevOrig); + atlas::FieldSet ClimBkgErrorStdDevFs; + ClimBkgErrorStdDev.toFieldSet(ClimBkgErrorStdDevFs); + + // Replace negative values with zeros + for (const auto &var : chemVars.variables()) { + auto ClimBkgErrView = atlas::array::make_view(ClimBkgErrorStdDevFs[var]); + for (atlas::idx_t jnode = 0; jnode < ClimBkgErrorStdDevFs[var].shape(0); ++jnode) { + for (atlas::idx_t level = 0; level < ClimBkgErrorStdDevFs[var].shape(1); ++level) { + ClimBkgErrView(jnode, level) = std::max(ClimBkgErrView(jnode, level), 0.0); + } + } + } + + // Staticb rescale + double rescale_staticb; + ClimBConfig.get("staticb rescaling factor", rescale_staticb); + + // Combine diagb and climatological background errors + fv3jedi::Increment stddev_hybrid(geom, chemVars, cycleDate); + stddev_hybrid.zero(); + + // Convert FieldSets to States for accumulation + fv3jedi::State bkgErrState(geom, chemVars, cycleDate); + bkgErrState.fromFieldSet(bkgErrFs); + + fv3jedi::State ClimBkgErrorStdDevState(geom, chemVars, cycleDate); + ClimBkgErrorStdDevState.fromFieldSet(ClimBkgErrorStdDevFs); + + // Accumulate the fields with the given weights + stddev_hybrid.accumul(diagb_weight, bkgErrState); + stddev_hybrid.accumul((1.0 - diagb_weight)*rescale_staticb, ClimBkgErrorStdDevState); + // Use the hybrid increment + bkgErr = stddev_hybrid; + } + // Save the background error const eckit::LocalConfiguration bkgErrorConfig(fullConfig, "background error"); bkgErr.write(bkgErrorConfig); diff --git a/utils/land/land_ensrecenter.h b/utils/land/land_ensrecenter.h index e67358288..6e14528f3 100644 --- a/utils/land/land_ensrecenter.h +++ b/utils/land/land_ensrecenter.h @@ -133,9 +133,10 @@ namespace gdasapp { incrMaskConfig.get("variable", maskvarname); double minvalue = incrMaskConfig.getDouble("minvalue", -9e36); double maxvalue = incrMaskConfig.getDouble("maxvalue", 9e36); + const eckit::LocalConfiguration maskBkgConfig(incrMaskConfig, "background"); oops::Variables maskVars(incrMaskConfig, "variable"); fv3jedi::State maskbkg(geom, maskVars, cycleDate); - maskbkg.read(bkgConfig); + maskbkg.read(maskBkgConfig); atlas::FieldSet xbFs; maskbkg.toFieldSet(xbFs); /// Create the atlas fieldset for the output increment @@ -144,7 +145,7 @@ namespace gdasapp { /// Loop over all points, if the mask is in range, zero out the increments auto bkgMask = atlas::array::make_view(xbFs[maskvarname]); for (atlas::idx_t jnode = 0; jnode < bkgMask.shape(0); ++jnode) { - if (bkgMask(jnode, 0) > minvalue && bkgMask(jnode, 0) < maxvalue) { + if (bkgMask(jnode, 0) < minvalue || bkgMask(jnode, 0) > maxvalue) { for (auto & var : varList.variables()) { auto inc = atlas::array::make_view(ensincFs[var]); for (atlas::idx_t level = 0; level < ensincFs[var].shape(1); ++level) { diff --git a/utils/obsproc/IcecJpssrr2Ioda.h b/utils/obsproc/IcecJpssrr2Ioda.h new file mode 100644 index 000000000..49a378a2d --- /dev/null +++ b/utils/obsproc/IcecJpssrr2Ioda.h @@ -0,0 +1,125 @@ +#pragma once + +#include +#include +#include +#include +#include // NOLINT (using C API) +#include +#include +#include + +#include "eckit/config/LocalConfiguration.h" + +#include // NOLINT + +#include "ioda/../../../../core/IodaUtils.h" +#include "ioda/Group.h" +#include "ioda/ObsGroup.h" + +#include "oops/util/dateFunctions.h" + +#include "NetCDFToIodaConverter.h" + +namespace gdasapp { + + class IcecJpssrr2Ioda : public NetCDFToIodaConverter { + public: + explicit IcecJpssrr2Ioda(const eckit::Configuration & fullConfig, const eckit::mpi::Comm & comm) + : NetCDFToIodaConverter(fullConfig, comm) { + variable_ = "seaIceFraction"; + } + + // Read netcdf file and populate iodaVars + gdasapp::obsproc::iodavars::IodaVars providerToIodaVars(const std::string fileName) final { + oops::Log::info() << "Processing files provided by the JPSSRR" << std::endl; + + // Open the NetCDF file in read-only mode + netCDF::NcFile ncFile(fileName, netCDF::NcFile::read); + oops::Log::info() << "Reading... " << fileName << std::endl; + + // Get the number of obs in the file + int dimxSize = ncFile.getDim("Columns").getSize(); + int dimySize = ncFile.getDim("Rows").getSize(); + int nobs = dimxSize * dimySize; + + // Set the int metadata names + std::vector intMetadataNames = {"oceanBasin"}; + + // Set the float metadata name + std::vector floatMetadataNames = {}; + + // Create instance of iodaVars object + gdasapp::obsproc::iodavars::IodaVars iodaVars(nobs, floatMetadataNames, intMetadataNames); + + oops::Log::debug() << "--- iodaVars.location_: " << iodaVars.location_ << std::endl; + + // Read non-optional metadata: longitude and latitude + std::vector oneDimLatVal(iodaVars.location_); + ncFile.getVar("Latitude").getVar(oneDimLatVal.data()); + + std::vector oneDimLonVal(iodaVars.location_); + ncFile.getVar("Longitude").getVar(oneDimLonVal.data()); + + // Create a vector to hold the Summary Qc variable + // User-level summary QC: 0=Normal, 1=Uncertain + std::vector oneDimFlagsVal(iodaVars.location_); + ncFile.getVar("SummaryQC_Ice_Concentration").getVar(oneDimFlagsVal.data()); + + // Get Ice_Concentration obs values + std::vector oneDimObsVal(iodaVars.location_); + ncFile.getVar("IceConc").getVar(oneDimObsVal.data()); + + // Read and process the starting and ending of dateTime + auto timeStartAttr = ncFile.getAtt("time_coverage_start"); + auto timeEndAttr = ncFile.getAtt("time_coverage_end"); + + // Extract attribute values as strings + std::string timeStartStr, timeEndStr; + timeStartAttr.getValues(timeStartStr); + timeEndAttr.getValues(timeEndStr); + + // Convert the extracted strings to util::DateTime objects + util::DateTime timeStartDtime(timeStartStr); + util::DateTime timeEndDtime(timeEndStr); + + // Create vectors of util::DateTime + std::vector timeStartVector = {timeStartDtime}; + std::vector timeEndVector = {timeEndDtime}; + + // Set epoch time for JPSSRR ICEC + util::DateTime epochDtime("1970-01-01T00:00:00Z"); + + // Convert Obs DateTime objects to epoch time offsets in seconds + int64_t timeStartOffsets + = ioda::convertDtimeToTimeOffsets(epochDtime, timeStartVector)[0]; + int64_t timeEndOffsets + = ioda::convertDtimeToTimeOffsets(epochDtime, timeEndVector)[0]; + + iodaVars.referenceDate_ = "seconds since 1970-01-01T00:00:00Z"; + + // Update non-optional Eigen arrays + for (int i = 0; i < iodaVars.location_; i++) { + iodaVars.longitude_(i) = oneDimLonVal[i]; + iodaVars.latitude_(i) = oneDimLatVal[i]; + iodaVars.obsVal_(i) = static_cast(oneDimObsVal[i]*0.01); + iodaVars.obsError_(i) = 0.1; // Do something for obs error + iodaVars.preQc_(i) = oneDimFlagsVal[i]; + iodaVars.datetime_(i) = + timeStartOffsets + (timeEndOffsets - timeStartOffsets) * 0.5; + // Store optional metadata, set ocean basins to -999 for now + iodaVars.intMetadata_.row(i) << -999; + } + + // basic test for iodaVars.trim + Eigen::Array mask = + ((iodaVars.obsVal_ >= 0.0 && iodaVars.obsVal_ <= 1.0) && + iodaVars.datetime_ > 0.0 && + (iodaVars.latitude_ <= -40.0 || iodaVars.latitude_ >= 40.0)); + iodaVars.trim(mask); + + return iodaVars; + }; + }; // class IcecMirs2Ioda +} // namespace gdasapp + diff --git a/utils/obsproc/IcecMirs2Ioda.h b/utils/obsproc/IcecMirs2Ioda.h new file mode 100644 index 000000000..b3f27e102 --- /dev/null +++ b/utils/obsproc/IcecMirs2Ioda.h @@ -0,0 +1,165 @@ +#pragma once + +#include +#include +#include +#include +#include // NOLINT (using C API) +#include +#include +#include + +#include "eckit/config/LocalConfiguration.h" + +#include // NOLINT + +#include "ioda/../../../../core/IodaUtils.h" +#include "ioda/Group.h" +#include "ioda/ObsGroup.h" + +#include "oops/util/dateFunctions.h" + +#include "NetCDFToIodaConverter.h" + +namespace gdasapp { + + class IcecMirs2Ioda : public NetCDFToIodaConverter { + public: + explicit IcecMirs2Ioda(const eckit::Configuration & fullConfig, const eckit::mpi::Comm & comm) + : NetCDFToIodaConverter(fullConfig, comm) { + variable_ = "seaIceFraction"; + } + + // Read netcdf file and populate iodaVars + gdasapp::obsproc::iodavars::IodaVars providerToIodaVars(const std::string fileName) final { + oops::Log::info() << "Processing files provided by the MIRS" << std::endl; + + // Open the NetCDF file in read-only mode + netCDF::NcFile ncFile(fileName, netCDF::NcFile::read); + oops::Log::info() << "Reading... " << fileName << std::endl; + + // Get the number of obs in the file + int dimxSize = ncFile.getDim("Scanline").getSize(); + int dimySize = ncFile.getDim("Field_of_view").getSize(); + int dimQcSize = ncFile.getDim("Qc_dim").getSize(); + int nobs = dimxSize * dimySize; + int nqcs = dimxSize * dimySize * dimQcSize; + + // Set the int metadata names + std::vector intMetadataNames = {"oceanBasin"}; + + // Set the float metadata name + std::vector floatMetadataNames = {}; + + // Create instance of iodaVars object + gdasapp::obsproc::iodavars::IodaVars iodaVars(nobs, floatMetadataNames, intMetadataNames); + + oops::Log::debug() << "--- iodaVars.location_: " << iodaVars.location_ << std::endl; + + // Read non-optional metadata: longitude and latitude + std::vector oneDimLatVal(iodaVars.location_); + ncFile.getVar("Latitude").getVar(oneDimLatVal.data()); + + std::vector oneDimLonVal(iodaVars.location_); + ncFile.getVar("Longitude").getVar(oneDimLonVal.data()); + + // Create a vector to hold the full Qc variable + std::vector fullQcVar(nqcs); + ncFile.getVar("Qc").getVar(fullQcVar.data()); + + // Read Quality Flags as a preQc + // Create a vector to hold the first slice + std::vector oneDimFlagsVal(nobs); + // Extract the first slice + for (int i = 0; i < nobs; ++i) { + oneDimFlagsVal[i] = fullQcVar[i * dimQcSize]; + } + + // Get Ice_Concentration obs values + std::vector oneDimObsVal(iodaVars.location_); + ncFile.getVar("SIce").getVar(oneDimObsVal.data()); + + // Read and process the dateTime + std::vector TimeYearVal(dimxSize); + ncFile.getVar("ScanTime_year").getVar(TimeYearVal.data()); + + std::vector TimeMonthVal(dimxSize); + ncFile.getVar("ScanTime_month").getVar(TimeMonthVal.data()); + + std::vector TimeDayVal(dimxSize); + ncFile.getVar("ScanTime_dom").getVar(TimeDayVal.data()); + + std::vector TimeHourVal(dimxSize); + ncFile.getVar("ScanTime_hour").getVar(TimeHourVal.data()); + + std::vector TimeMinuteVal(dimxSize); + ncFile.getVar("ScanTime_minute").getVar(TimeMinuteVal.data()); + + std::vector TimeSecondVal(dimxSize); + ncFile.getVar("ScanTime_second").getVar(TimeSecondVal.data()); + + iodaVars.referenceDate_ = "seconds since 1970-01-01T00:00:00Z"; + + for (int i = 0; i < dimxSize; i++) { + int year = TimeYearVal[i]; + int month = TimeMonthVal[i]; + int day = TimeDayVal[i]; + int hour = TimeHourVal[i]; + int minute = TimeMinuteVal[i]; + int second = TimeSecondVal[i]; + + // Avoid crash util in ioda::convertDtimeToTimeOffsets + if (year == -999 || month == -999 || day == -999 || + hour == -999 || minute == -999 || second == -999) { + year = month = day = hour = minute = second = 0; + } + + // Construct iso8601 string format for each dateTime + std::stringstream ss; + ss << std::setfill('0') + << std::setw(4) << year << '-' + << std::setw(2) << month << '-' + << std::setw(2) << day << 'T' + << std::setw(2) << hour << ':' + << std::setw(2) << minute << ':' + << std::setw(2) << second << 'Z'; + std::string formattedDateTime = ss.str(); + util::DateTime dateTime(formattedDateTime); + + // Set epoch time for MIRS_ICEC + util::DateTime epochDtime("1970-01-01T00:00:00Z"); + + // Convert Obs DateTime objects to epoch time offsets in seconds + // 0000-00-00T00:00:00Z will be converterd to negative seconds + int64_t timeOffsets + = ioda::convertDtimeToTimeOffsets(epochDtime, {dateTime})[0]; + + // Update non-optional Eigen arrays + for (int j = 0; j < dimySize; j++) { + int index = i * dimySize + j; + iodaVars.datetime_(index) = timeOffsets; + } + } + + // Update non-optional Eigen arrays + for (int i = 0; i < iodaVars.location_; i++) { + iodaVars.longitude_(i) = oneDimLonVal[i]; + iodaVars.latitude_(i) = oneDimLatVal[i]; + iodaVars.obsVal_(i) = static_cast(oneDimObsVal[i]*0.01); + iodaVars.obsError_(i) = 0.1; // Do something for obs error + iodaVars.preQc_(i) = oneDimFlagsVal[i]; + // Store optional metadata, set ocean basins to -999 for now + iodaVars.intMetadata_.row(i) << -999; + } + + // basic test for iodaVars.trim + Eigen::Array mask = + (iodaVars.obsVal_ >= 0.0 && + iodaVars.datetime_ > 0.0 && + (iodaVars.latitude_ <= -40.0 || iodaVars.latitude_ >= 40.0)); + iodaVars.trim(mask); + + return iodaVars; + }; + }; // class IcecMirs2Ioda +} // namespace gdasapp diff --git a/utils/obsproc/applications/gdas_obsprovider2ioda.h b/utils/obsproc/applications/gdas_obsprovider2ioda.h index ac08b19c6..a1a6fe6e3 100644 --- a/utils/obsproc/applications/gdas_obsprovider2ioda.h +++ b/utils/obsproc/applications/gdas_obsprovider2ioda.h @@ -8,6 +8,8 @@ #include "../Ghrsst2Ioda.h" #include "../IcecAmsr2Ioda.h" +#include "../IcecJpssrr2Ioda.h" +#include "../IcecMirs2Ioda.h" #include "../Rads2Ioda.h" #include "../RTOFSSalinity.h" #include "../RTOFSTemperature.h" @@ -50,6 +52,12 @@ namespace gdasapp { } else if (provider == "AMSR2") { IcecAmsr2Ioda conv2ioda(fullConfig, this->getComm()); conv2ioda.writeToIoda(); + } else if (provider == "MIRS") { + IcecMirs2Ioda conv2ioda(fullConfig, this->getComm()); + conv2ioda.writeToIoda(); + } else if (provider == "JPSSRR") { + IcecJpssrr2Ioda conv2ioda(fullConfig, this->getComm()); + conv2ioda.writeToIoda(); } else if (provider == "VIIRSAOD") { Viirsaod2Ioda conv2ioda(fullConfig, this->getComm()); conv2ioda.writeToIoda(); diff --git a/utils/soca/gdas_soca_diagb.h b/utils/soca/gdas_soca_diagb.h index c1e46c250..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" @@ -300,12 +299,12 @@ namespace gdasapp { } // Update the layer thickness halo - xbFs["hocn"].haloExchange(); + nodeColumns.haloExchange(xbFs["hocn"]); // Loop through variables for (auto & var : configD.socaVars.variables()) { // Update the halo - xbFs[var].haloExchange(); + nodeColumns.haloExchange(xbFs[var]); // Skip the layer thickness variable if (var == "hocn") { @@ -361,7 +360,7 @@ namespace gdasapp { // Horizontal averaging for (int iter = 0; iter < configD.niterHoriz; ++iter) { // Update the halo points - bkgErrFs[var].haloExchange(); + nodeColumns.haloExchange(bkgErrFs[var]); auto stdDevBkg = atlas::array::make_view(bkgErrFs[var]); // Loops through nodes and levels @@ -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 diff --git a/utils/soca/gdassoca_obsstats.h b/utils/soca/gdassoca_obsstats.h index 5f95574a1..010fe9ac0 100644 --- a/utils/soca/gdassoca_obsstats.h +++ b/utils/soca/gdassoca_obsstats.h @@ -81,6 +81,11 @@ namespace gdasapp { // ocean basin partitioning std::vector oceanBasins(nlocs); + if (!ospace.has("MetaData", "oceanBasin")) { + oops::Log::warning() << "Skipping obsspace" << obsFile + << ": oceanBasin does not exist." << std::endl; + continue; + } ospace.get_db("MetaData", "oceanBasin", oceanBasins); // Open an ofstream for output and write header diff --git a/utils/test/CMakeLists.txt b/utils/test/CMakeLists.txt index ce9eae1ba..3be6cd1c4 100644 --- a/utils/test/CMakeLists.txt +++ b/utils/test/CMakeLists.txt @@ -8,6 +8,8 @@ list( APPEND utils_test_input testinput/gdas_smap2ioda.yaml testinput/gdas_smos2ioda.yaml testinput/gdas_icecamsr2ioda.yaml + testinput/gdas_icecmirs2ioda.yaml + testinput/gdas_icecjpssrr2ioda.yaml testinput/gdas_viirsaod2ioda.yaml ) @@ -19,6 +21,8 @@ set( gdas_utils_test_ref testref/smap2ioda.test testref/smos2ioda.test testref/icecamsr2ioda.test + testref/icecmirs2ioda.test + testref/icecjpssrr2ioda.test testref/viirsaod2ioda.test ) @@ -145,3 +149,17 @@ ecbuild_add_test( TARGET test_gdasapp_util_icecamsr2ioda ARGS "../testinput/gdas_icecamsr2ioda.yaml" LIBS gdas-utils WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + +# Test the MIRS to IODA converter +ecbuild_add_test( TARGET test_gdasapp_util_icecmirs2ioda + COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x + ARGS "../testinput/gdas_icecmirs2ioda.yaml" + LIBS gdas-utils + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + + # Test the JPSSRR to IODA converter +ecbuild_add_test( TARGET test_gdasapp_util_icecjpssrr2ioda + COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x + ARGS "../testinput/gdas_icecjpssrr2ioda.yaml" + LIBS gdas-utils + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) diff --git a/utils/test/prepdata.sh b/utils/test/prepdata.sh index d7c917e93..4cb5b31a9 100755 --- a/utils/test/prepdata.sh +++ b/utils/test/prepdata.sh @@ -23,6 +23,10 @@ cdl2nc4 icec_amsr2_north_1.nc4 ${project_source_dir}/testdata/icec_amsr2_north_1 cdl2nc4 icec_amsr2_north_2.nc4 ${project_source_dir}/testdata/icec_amsr2_north_2.cdl cdl2nc4 icec_amsr2_south_1.nc4 ${project_source_dir}/testdata/icec_amsr2_south_1.cdl cdl2nc4 icec_amsr2_south_2.nc4 ${project_source_dir}/testdata/icec_amsr2_south_2.cdl +cdl2nc4 icec_mirs_snpp_1.nc4 ${project_source_dir}/testdata/icec_mirs_snpp_1.cdl +cdl2nc4 icec_mirs_snpp_2.nc4 ${project_source_dir}/testdata/icec_mirs_snpp_2.cdl +cdl2nc4 icec_jrr_n20_1.nc4 ${project_source_dir}/testdata/icec_jrr_n20_1.cdl +cdl2nc4 icec_jrr_n20_2.nc4 ${project_source_dir}/testdata/icec_jrr_n20_2.cdl cdl2nc4 sss_smap_1.nc4 ${project_source_dir}/testdata/sss_smap_1.cdl cdl2nc4 sss_smap_2.nc4 ${project_source_dir}/testdata/sss_smap_2.cdl cdl2nc4 sss_smos_1.nc4 ${project_source_dir}/testdata/sss_smos_1.cdl diff --git a/utils/test/testdata/icec_jrr_n20_1.cdl b/utils/test/testdata/icec_jrr_n20_1.cdl new file mode 100644 index 000000000..2aaf0393c --- /dev/null +++ b/utils/test/testdata/icec_jrr_n20_1.cdl @@ -0,0 +1,724 @@ +netcdf output_1 { +dimensions: + Rows = 15 ; + Columns = 45 ; +variables: + float IceConc(Rows, Columns) ; + IceConc:_FillValue = -999.f ; + IceConc:coordinates = "Longitude Latitude" ; + IceConc:long_name = "Ice Concentration" ; + IceConc:units = "%" ; + IceConc:valid_range = 0.f, 100.f ; + byte IceMap(Rows, Columns) ; + IceMap:_FillValue = -3b ; + IceMap:coordinates = "Longitude Latitude" ; + IceMap:long_name = "Ice Cover map codes" ; + IceMap:units = "1" ; + IceMap:valid_range = -2b, 2b ; + float IceRetrPct ; + IceRetrPct:long_name = "% of valid ice cover and concentration retrievals of all water pixels" ; + IceRetrPct:units = "%" ; + IceRetrPct:_FillValue = 0.f ; + IceRetrPct:valid_range = 0.f, 100.f ; + float IceSrfTemp(Rows, Columns) ; + IceSrfTemp:_FillValue = -999.f ; + IceSrfTemp:coordinates = "Longitude Latitude" ; + IceSrfTemp:long_name = "Ice Surface Temp" ; + IceSrfTemp:units = "Kelvin(K)" ; + IceSrfTemp:valid_range = 100.f, 390.f ; + float IceTermntPct ; + IceTermntPct:long_name = "% of terminated ice cover and concentration retrievals of all processed pixels" ; + IceTermntPct:units = "%" ; + IceTermntPct:_FillValue = 0.f ; + IceTermntPct:valid_range = 0.f, 100.f ; + float Latitude(Rows, Columns) ; + Latitude:long_name = "Latitude" ; + Latitude:_FillValue = -999.f ; + Latitude:units = "degrees_north" ; + Latitude:valid_range = -90.f, 90.f ; + Latitude:comments = "Pixel latitude in field Latitude (degree)" ; + float Longitude(Rows, Columns) ; + Longitude:long_name = "Longitude" ; + Longitude:_FillValue = -999.f ; + Longitude:units = "degrees_east" ; + Longitude:valid_range = -180.f, 180.f ; + Longitude:comments = "Pixel longitude in field Longitude (degree)" ; + float MaxIceConc ; + MaxIceConc:long_name = "Max ice concentration retrieval" ; + MaxIceConc:_FillValue = -999.f ; + MaxIceConc:units = "%" ; + float MeanIceConc ; + MeanIceConc:long_name = "Mean ice concentration retrieval" ; + MeanIceConc:_FillValue = -999.f ; + MeanIceConc:units = "%" ; + float MinIceConc ; + MinIceConc:long_name = "Min ice concentration retrieval" ; + MinIceConc:_FillValue = -999.f ; + MinIceConc:units = "%" ; + byte NumOfQACategories ; + NumOfQACategories:long_name = "Number of QA flag values" ; + NumOfQACategories:_FillValue = -128b ; + NumOfQACategories:units = "1" ; + int QCFlags(Rows, Columns) ; + QCFlags:_FillValue = -1 ; + QCFlags:coordinates = "Longitude Latitude" ; + QCFlags:long_name = "QCFlags" ; + QCFlags:units = "1" ; + float STDIceConc ; + STDIceConc:long_name = "Standard deviation of ice concentration retrievals" ; + STDIceConc:_FillValue = -999.f ; + STDIceConc:units = "%" ; + byte SearchWindowSize ; + SearchWindowSize:long_name = "Pixel size of search window to determine tie-point" ; + SearchWindowSize:_FillValue = -128b ; + SearchWindowSize:units = "1" ; + int StartColumn ; + StartColumn:long_name = "Start column index" ; + StartColumn:units = "1" ; + int StartRow ; + StartRow:long_name = "Start row index" ; + StartRow:units = "1" ; + byte SummaryQC_Ice_Concentration(Rows, Columns) ; + SummaryQC_Ice_Concentration:_FillValue = -128b ; + SummaryQC_Ice_Concentration:coordinates = "Longitude Latitude" ; + SummaryQC_Ice_Concentration:long_name = "User-level summary QC: 0=Normal, 1=Uncertain, 2=Non-Retrievable, 3=Bad" ; + SummaryQC_Ice_Concentration:units = "1" ; + SummaryQC_Ice_Concentration:valid_range = 0b, 3b ; + int TotDaytimePixs ; + TotDaytimePixs:long_name = "Total number of daytime valid retrievals" ; + TotDaytimePixs:_FillValue = 0 ; + TotDaytimePixs:units = "1" ; + int TotIceRetrvls ; + TotIceRetrvls:long_name = "Total number of valid ice cover and concentration retrievals" ; + TotIceRetrvls:_FillValue = 0 ; + TotIceRetrvls:units = "1" ; + int TotIceTermnt ; + TotIceTermnt:long_name = "Total number of terminated ice cover and concentration retrievals" ; + TotIceTermnt:_FillValue = 0 ; + TotIceTermnt:units = "1" ; + int TotNighttimePixs ; + TotNighttimePixs:long_name = "Total number of nighttime valid retrievals" ; + TotNighttimePixs:_FillValue = 0 ; + TotNighttimePixs:units = "1" ; + int TotWaterPixs ; + TotWaterPixs:long_name = "Total number of pixels w. water surface" ; + TotWaterPixs:_FillValue = 0 ; + TotWaterPixs:units = "1" ; + int Tot_QA_BadData ; + Tot_QA_BadData:long_name = "Total number of pixels with QA category 4 (Bad data)" ; + Tot_QA_BadData:_FillValue = 0 ; + Tot_QA_BadData:units = "1" ; + int Tot_QA_Nonretrievable ; + Tot_QA_Nonretrievable:long_name = "Total number of pixels with QA category 3 (Non-retrievable)" ; + Tot_QA_Nonretrievable:_FillValue = 0 ; + Tot_QA_Nonretrievable:units = "1" ; + int Tot_QA_Normal ; + Tot_QA_Normal:long_name = "Total number of pixels with QA category 1 (Normal of optimal)" ; + Tot_QA_Normal:_FillValue = 0 ; + Tot_QA_Normal:units = "1" ; + int Tot_QA_Uncertain ; + Tot_QA_Uncertain:long_name = "Total number of pixels with QA category 2 (Uncertain or suboptimal)" ; + Tot_QA_Uncertain:_FillValue = 0 ; + Tot_QA_Uncertain:units = "1" ; + +// global attributes: + :Conventions = "CF-1.6,ACDD 1.3" ; + :Metadata_Conventions = "CF-1.6, Unidata Dataset Discovery v1.0" ; + :standard_name_vocabulary = "CF Standard Name Table v76" ; + :institution = "DOC/NOAA/NESDIS/OSPO > Office of Satellite and Product Operations, NESDIS, NOAA, U.S. Department of Commerce." ; + :naming_authority = "gov.noaa.nesdis.ncei." ; + :processing_level = "NOAA Level 2" ; + :production_site = "NCCF" ; + :production_environment = "prod" ; + :sensor_band_identifier = "M3,M5,M7,M10,M15,M16" ; + :sensor_band_central_radiation_wavelength = "0.488um,0.672um,0.865um,1.61um,10.763um,12.013um" ; + :satellite_name = "NOAA-20" ; + :instrument = "VIIRS" ; + :project = "NESDIS Common Cloud Framework" ; + :summary = "Enterprise Ice Concentration/ Ice Mask/ Ice Surface Temperature Products" ; + :history = "Tue Aug 20 14:14:39 2024: ncks -d Columns,1,90,2 -d Rows,1,30,2 JRR-IceConcentration_v3r3_j01_s202406181055311_e202406181056538_c202406181202563.nc output_1.ncn\nEnterprise Ice Concentration Algorithm v1.1.0" ; + :references = "N/A" ; + :resolution = "750M" ; + :time_coverage_start = "2024-06-18T10:55:31Z" ; + :time_coverage_end = "2024-06-18T10:56:53Z" ; + :date_created = "2024-06-18T12:02:56Z" ; + :geospatial_lat_units = "degrees_north" ; + :geospatial_lon_units = "degrees_east" ; + :publisher_name = "DOC/NOAA/NESDIS/OSPO > Office of Satellite and Product Operations, NESDIS, NOAA, U.S. Department of Commerce." ; + :publisher_email = "espcoperations@noaa.gov" ; + :publisher_url = "http://www.ospo.noaa.gov" ; + :creator_email = "jkey@ssec.wisc.edu" ; + :creator_name = "DOC/NOAA/NESDIS/STAR > Cryosphere Team, Center for Satellite Applications and Research, NESDIS, NOAA, U.S. Department of Commerce" ; + :creator_url = "http://www.star.nesdis.noaa.gov" ; + :source = "L1b data, JRR-CloudMask, JRR-CloudHeight" ; + :keywords = "EARTH SCIENCE, CRYOSPHERE, SEA ICE, SEA ICE CONCENTRATION, ICE FRACTION, ICE EXTENT, ICE EDGES" ; + :cdm_data_type = "Swath" ; + :platform = "NOAA-20" ; + :title = "JRR_IceConcentration" ; + :metadata_link = "JRR-IceConcentration_v3r3_j01_s202406181055311_e202406181056538_c202406181202563.nc" ; + :history_package = "Delivery Package v3r3" ; + :product_version = "v3r3" ; + :keywords_vocabulary = "NASA Global Change Master Directory (GCMD) Science Keywords" ; + :geospatial_lat_max = 90.f ; + :geospatial_lat_min = -90.f ; + :geospatial_lat_resolution = "750 meters" ; + :geospatial_lon_max = 180.f ; + :geospatial_lon_min = -180.f ; + :geospatial_lon_resolution = "750 meters" ; + :id = "7c38eaa1-7e82-49dc-a00d-96fc30f77f4d" ; + :geospatial_bounds = "POLYGON((92.3739319 -62.2583618, 17.40835 -73.4811554, 20.670002 -68.7148819, 84.2927856 -59.1303825, 92.3739319 -62.2583618))" ; + :day_night_data_flag = "night" ; + :start_orbit_number = 34108 ; + :end_orbit_number = 34108 ; + :ascend_descend_data_flag = 0 ; + :geospatial_first_scanline_first_fov_lat = -62.25836f ; + :geospatial_first_scanline_last_fov_lat = -59.13038f ; + :geospatial_last_scanline_first_fov_lat = -73.48116f ; + :geospatial_last_scanline_last_fov_lat = -68.71488f ; + :geospatial_first_scanline_first_fov_lon = 92.37393f ; + :geospatial_first_scanline_last_fov_lon = 84.29279f ; + :geospatial_last_scanline_first_fov_lon = 17.40835f ; + :geospatial_last_scanline_last_fov_lon = 20.67f ; + :NCO = "netCDF Operators version 5.0.6 (Homepage = http://nco.sf.net, Code = http://github.com/nco/nco)" ; +data: + + IceConc = + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, 67.32343, 84.27617, 69.62304, 58.03904, _, + 75.2986, _, 93.43942, 89.14372, 90.32429, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, 69.33148, _, _, _, _, _, 92.32764, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, 100, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, 77.16252, _, 89.43716, _, + 96.34447, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, 93.09033, _, 68.65797, 72.14285, 72.15576, _, _, _, _, _, + 93.74178, _, 100, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 95.81432, _, _, _, + _, _, _, _, _, _, _, 83.46582, _, _, 70.99985, _, _, _, _, _, _, _, + 90.44588, _, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, _, _, + _, _, 100, 100, _, _, _, _, _, _, _, _, _, _, _, _, 98.98752, 100, _, _, + 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 87.24126, _, 100, _, + _, _, _, _, _, _, _, 88.74048, 91.04077, _, 73.66028, 77.14046, 72.86072, + _, 96.87101, _, 65.08202, _, 89.43575, _, 100, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, 69.14838, 74.81149, _, _, _, _, _, _, 92.22154, _, + 100, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, _, _, + _, _, 100, _, _, _, _, _, _, _, _, _, _, _, _, _, 99.45397, _, _, 100, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, _, _, + 100, _, _, 100, 100, 90.56665, _, _, _, _, _, 87.64484, _, _, 91.27245, + _, 100, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, _, _, _, 95.01587, _, 98.09937, 89.29044, _, _, _, 87.08566, + 96.69353, 94.27303, _, _, 100, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 100, _, + _, _, _, 100, 98.30614, 94.49585, _, 95.56421, _, _, 91.44451, 94.2695, + 93.61901, _, _, _, _, 100, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, _, _, 100, _, _, 97.12012, _, _, _, _, 96.67687, _, 91.58325, + _, _, _, _, _, _ ; + + IceMap = + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 0, 2, 2, 2, 0, 2, 0, 2, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 2, 2, 2, 0, 2, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0 ; + + IceRetrPct = 92.00418 ; + + IceSrfTemp = + _, _, _, _, _, _, _, _, _, _, _, _, _, _, 262.912, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, 262.748, 260.5441, 262.449, 263.9549, + _, 261.7112, _, 259.3529, 259.9113, 259.7578, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, 262.4869, _, _, _, _, _, 259.4974, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 258.0082, 258.4478, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, 261.4689, _, 259.8732, _, + 258.9752, 258.0523, 257.7929, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, 259.8637, _, 262.5745, 262.1214, 262.1198, _, _, _, _, _, + 259.3136, _, 258.0438, 257.6424, 257.6123, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 260.4814, _, _, _, + _, _, _, _, _, _, _, 261.0668, _, _, 262.27, _, _, _, _, _, _, _, + 259.742, _, 257.781, 257.7041, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 259.4695, _, + _, _, _, 258.8402, 258.6626, _, _, _, _, _, _, _, _, _, _, _, _, + 258.6316, 258.2289, _, _, 257.6414, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 257.6414, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 261.4673, _, + 259.9039, _, _, _, _, _, _, _, _, 260.4074, 260.1199, _, 261.9242, + 261.4717, 262.0281, _, 258.9068, _, 263.0393, _, 259.8734, _, 258.0083, + 257.6029, 257.8393, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, 262.5107, 261.7745, _, _, _, _, _, _, 259.5112, _, + 257.9245, 257.633, 257.3847, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 259.6055, _, + _, _, _, 258.671, _, _, _, _, _, _, _, _, _, _, _, _, _, 258.571, _, _, + 257.6851, 257.6045, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 259.8718, _, + _, 259.1182, _, _, 259.2526, 259.4372, 260.1792, _, _, _, _, _, 260.1062, + _, _, 259.6346, _, 258.4996, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 259.1245, 259.1255, _, _, _, 259.623, _, 259.2376, 259.8922, _, _, _, + 260.1789, 258.9298, 259.2445, _, _, 258.3249, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, 259.6207, + _, _, _, _, 259.3116, 260.1948, 259.688, _, 259.5545, _, _, 259.6122, + 259.245, 259.3295, _, _, _, _, 258.3306, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 259.3393, 259.3635, _, _, 259.6414, _, _, 259.36, _, _, _, _, 258.932, _, + 259.5942, _, _, _, _, _, _ ; + + IceTermntPct = 96.45524 ; + + Latitude = + -62.26201, -62.28693, -62.31173, -62.33637, -62.36088, -62.38528, + -62.40954, -62.43367, -62.45765, -62.48153, -62.50529, -62.52892, + -62.55244, -62.57583, -62.59911, -62.62225, -62.64531, -62.66823, + -62.69104, -62.71375, -62.73633, -62.7588, -62.78117, -62.80342, + -62.82558, -62.84762, -62.86955, -62.89139, -62.91312, -62.93473, + -62.95624, -62.97764, -62.99895, -63.02018, -63.04131, -63.06235, + -63.08331, -63.10412, -63.12487, -63.1455, -63.16606, -63.1865, + -63.20688, -63.22714, -63.24732, + -62.24429, -62.26923, -62.29401, -62.31867, -62.34322, -62.36762, -62.3919, + -62.41604, -62.44005, -62.46393, -62.48772, -62.51137, -62.53489, + -62.5583, -62.5816, -62.60479, -62.62783, -62.65078, -62.6736, -62.69632, + -62.71892, -62.7414, -62.76378, -62.78606, -62.80823, -62.83027, + -62.85222, -62.87408, -62.89582, -62.91745, -62.93898, -62.96041, + -62.98171, -63.00295, -63.02411, -63.04518, -63.06613, -63.08697, + -63.10772, -63.12837, -63.14893, -63.1694, -63.18978, -63.21006, -63.23025, + -62.22651, -62.25145, -62.27627, -62.30095, -62.32549, -62.34993, -62.3742, + -62.39836, -62.42241, -62.44631, -62.47009, -62.49377, -62.51731, + -62.54074, -62.56406, -62.58723, -62.61031, -62.63326, -62.65611, + -62.67884, -62.70145, -62.72396, -62.74635, -62.76864, -62.79083, + -62.81289, -62.83486, -62.85672, -62.87847, -62.90014, -62.92169, + -62.94311, -62.96445, -62.98568, -63.00685, -63.02795, -63.04889, + -63.06976, -63.09053, -63.11119, -63.13177, -63.15226, -63.17266, + -63.19294, -63.21315, + -62.20868, -62.23362, -62.25846, -62.28316, -62.30772, -62.33216, + -62.35647, -62.38065, -62.40471, -62.42862, -62.45242, -62.4761, + -62.49968, -62.52313, -62.54646, -62.56966, -62.59274, -62.6157, + -62.63857, -62.66131, -62.68395, -62.70645, -62.72887, -62.75117, + -62.77337, -62.79546, -62.81743, -62.83931, -62.86109, -62.88277, + -62.90434, -62.92577, -62.94712, -62.96838, -62.98954, -63.01065, + -63.03164, -63.05252, -63.07329, -63.09396, -63.11456, -63.13505, + -63.15548, -63.17579, -63.196, + -62.19078, -62.21574, -62.2406, -62.2653, -62.28989, -62.31435, -62.33867, + -62.36287, -62.38693, -62.41087, -62.4347, -62.45842, -62.48199, + -62.50544, -62.52879, -62.55201, -62.57511, -62.5981, -62.62097, + -62.64373, -62.66639, -62.68891, -62.71133, -62.73365, -62.75586, + -62.77798, -62.79998, -62.82188, -62.84368, -62.86536, -62.88693, + -62.90839, -62.92974, -62.95101, -62.97221, -62.99332, -63.01432, + -63.03521, -63.05601, -63.0767, -63.09731, -63.11782, -63.13824, + -63.15857, -63.17879, + -62.17282, -62.19782, -62.22268, -62.2474, -62.272, -62.29648, -62.32082, + -62.34503, -62.36912, -62.39308, -62.41693, -62.44065, -62.46425, + -62.48772, -62.51107, -62.5343, -62.55743, -62.58043, -62.60332, + -62.6261, -62.64875, -62.67131, -62.69375, -62.71609, -62.73832, + -62.76044, -62.78246, -62.80437, -62.8262, -62.8479, -62.86947, + -62.89095, -62.91233, -62.9336, -62.95482, -62.97595, -62.99697, + -63.01787, -63.03868, -63.05939, -63.08001, -63.10055, -63.12098, + -63.14132, -63.16157, + -62.15481, -62.17982, -62.20471, -62.22945, -62.25407, -62.27857, + -62.30292, -62.32715, -62.35126, -62.37523, -62.39909, -62.42284, + -62.44645, -62.46994, -62.4933, -62.51656, -62.5397, -62.56272, + -62.58563, -62.60842, -62.6311, -62.65367, -62.67613, -62.69849, + -62.72072, -62.74287, -62.76492, -62.78683, -62.80865, -62.83037, + -62.85198, -62.87346, -62.89486, -62.91616, -62.93738, -62.95853, + -62.97956, -63.00048, -63.02131, -63.04203, -63.06266, -63.08321, + -63.10367, -63.12402, -63.14428, + -62.13674, -62.16177, -62.18667, -62.21144, -62.23608, -62.26059, + -62.28497, -62.30923, -62.33334, -62.35735, -62.38122, -62.40496, + -62.4286, -62.4521, -62.47549, -62.49877, -62.52193, -62.54496, + -62.56787, -62.59069, -62.61338, -62.63597, -62.65845, -62.68083, + -62.70309, -62.72525, -62.7473, -62.76923, -62.79108, -62.81281, + -62.83443, -62.85594, -62.87734, -62.89866, -62.9199, -62.94106, + -62.9621, -62.98305, -63.00388, -63.02463, -63.04528, -63.06583, + -63.0863, -63.10668, -63.12696, + -62.20229, -62.22714, -62.25185, -62.27643, -62.3009, -62.32522, -62.34944, + -62.3735, -62.39744, -62.42127, -62.44497, -62.46856, -62.49202, + -62.51536, -62.53855, -62.56163, -62.58459, -62.60746, -62.63023, + -62.65292, -62.67546, -62.69792, -62.72024, -62.74243, -62.76454, + -62.78652, -62.80841, -62.83018, -62.85189, -62.87347, -62.89493, + -62.9163, -62.93758, -62.95876, -62.97982, -63.0008, -63.02162, + -63.04238, -63.06308, -63.08369, -63.1042, -63.1246, -63.14489, + -63.16511, -63.18526, + -62.18449, -62.20935, -62.23409, -62.25868, -62.28314, -62.30751, + -62.33173, -62.35582, -62.37976, -62.4036, -62.42735, -62.45093, + -62.47441, -62.49775, -62.52097, -62.54407, -62.56704, -62.58994, + -62.61273, -62.6354, -62.65798, -62.68045, -62.70278, -62.725, -62.7471, + -62.76911, -62.79102, -62.81282, -62.83453, -62.85612, -62.8776, + -62.89899, -62.92028, -62.94146, -62.96255, -62.98352, -63.00439, + -63.02516, -63.04585, -63.06648, -63.08701, -63.10742, -63.12773, + -63.14795, -63.16812, + -62.16662, -62.19151, -62.21626, -62.24088, -62.26535, -62.28973, + -62.31395, -62.33807, -62.36204, -62.38591, -62.40965, -62.43325, + -62.45674, -62.48012, -62.50335, -62.52645, -62.54944, -62.57235, + -62.59515, -62.61784, -62.64044, -62.66291, -62.68528, -62.7075, + -62.72963, -62.75167, -62.77359, -62.79539, -62.81711, -62.83872, + -62.86021, -62.88162, -62.90292, -62.92412, -62.94522, -62.96622, + -62.9871, -63.00787, -63.02859, -63.04924, -63.06976, -63.09018, + -63.11052, -63.13077, -63.15094, + -62.1487, -62.17361, -62.19837, -62.22301, -62.2475, -62.27188, -62.29613, + -62.32028, -62.34426, -62.36814, -62.39189, -62.41552, -62.43902, + -62.46241, -62.48566, -62.50877, -62.5318, -62.55471, -62.57752, + -62.60024, -62.62286, -62.64535, -62.66772, -62.68998, -62.71213, + -62.73416, -62.75609, -62.77792, -62.79966, -62.82127, -62.84279, + -62.86421, -62.88552, -62.90673, -62.92785, -62.94887, -62.96976, + -62.99055, -63.01128, -63.03194, -63.05248, -63.07293, -63.09328, + -63.11353, -63.13371, + -62.13073, -62.15564, -62.18042, -62.20507, -62.2296, -62.254, -62.27827, + -62.30242, -62.32643, -62.35032, -62.37409, -62.39773, -62.42126, + -62.44466, -62.46794, -62.49105, -62.51408, -62.53703, -62.55986, + -62.5826, -62.60523, -62.62773, -62.65012, -62.6724, -62.69455, + -62.71659, -62.73857, -62.7604, -62.78214, -62.80377, -62.82531, + -62.84675, -62.86807, -62.88932, -62.91044, -62.93147, -62.95238, + -62.97319, -62.99393, -63.01461, -63.03518, -63.05562, -63.07598, + -63.09626, -63.11648, + -62.1127, -62.13765, -62.16243, -62.1871, -62.21166, -62.23609, -62.26037, + -62.28451, -62.30855, -62.33246, -62.35624, -62.3799, -62.40345, + -62.42686, -62.45015, -62.4733, -62.49633, -62.51929, -62.54214, + -62.56489, -62.58754, -62.61006, -62.63247, -62.65477, -62.67694, + -62.69901, -62.72098, -62.74283, -62.76459, -62.78625, -62.80779, + -62.82923, -62.85059, -62.87182, -62.89297, -62.91403, -62.93495, + -62.95576, -62.97654, -62.99721, -63.0178, -63.03827, -63.05866, + -63.07895, -63.09917, + -62.0946, -62.11958, -62.1444, -62.16909, -62.19365, -62.21809, -62.24238, + -62.26656, -62.29061, -62.31452, -62.33832, -62.36201, -62.38557, + -62.40901, -62.43231, -62.45547, -62.47853, -62.5015, -62.52438, + -62.54714, -62.56981, -62.59236, -62.61476, -62.63708, -62.65927, + -62.68135, -62.70333, -62.7252, -62.74699, -62.76866, -62.79021, + -62.81168, -62.83305, -62.85431, -62.87547, -62.89653, -62.91748, + -62.93832, -62.95908, -62.97978, -63.00042, -63.0209, -63.04129, + -63.06158, -63.08181 ; + + Longitude = + 92.32836, 92.28934, 92.25043, 92.21167, 92.17303, 92.1345, 92.09612, + 92.05786, 92.01971, 91.9817, 91.9438, 91.906, 91.86833, 91.83078, + 91.79333, 91.75603, 91.7188, 91.68171, 91.64473, 91.60786, 91.57111, + 91.53446, 91.4979, 91.46147, 91.42513, 91.38892, 91.35278, 91.31676, + 91.28085, 91.24503, 91.20936, 91.17381, 91.13828, 91.10289, 91.06756, + 91.0323, 90.99715, 90.96214, 90.92722, 90.8924, 90.85765, 90.82302, + 90.78848, 90.75401, 90.71967, + 92.27644, 92.23746, 92.19865, 92.15996, 92.12137, 92.08293, 92.04461, + 92.0064, 91.96834, 91.93037, 91.89256, 91.85484, 91.81721, 91.77973, + 91.74236, 91.70508, 91.66795, 91.63094, 91.594, 91.5572, 91.52051, + 91.48391, 91.44743, 91.41106, 91.37479, 91.33862, 91.30257, 91.26662, + 91.23075, 91.19501, 91.15939, 91.12386, 91.08844, 91.05311, 91.01783, + 90.98264, 90.94756, 90.9126, 90.87774, 90.84296, 90.80829, 90.77373, + 90.73923, 90.70483, 90.67053, + 92.22459, 92.18573, 92.14696, 92.10833, 92.06983, 92.03144, 91.9932, + 91.95507, 91.91708, 91.87918, 91.84142, 91.80374, 91.7662, 91.72879, + 91.69146, 91.65427, 91.61721, 91.58024, 91.54339, 91.50665, 91.47001, + 91.43347, 91.39709, 91.36076, 91.32457, 91.28845, 91.25244, 91.21656, + 91.18079, 91.14509, 91.1095, 91.07404, 91.03868, 91.00343, 90.96821, + 90.93306, 90.89806, 90.86316, 90.82837, 90.79366, 90.75903, 90.7245, + 90.69007, 90.65573, 90.62152, + 92.17288, 92.13409, 92.09541, 92.05685, 92.01839, 91.98009, 91.9419, + 91.90384, 91.8659, 91.82809, 91.79037, 91.75279, 91.71529, 91.67793, + 91.64069, 91.60357, 91.56655, 91.52966, 91.49287, 91.45618, 91.41963, + 91.38317, 91.34682, 91.31057, 91.27442, 91.23837, 91.20243, 91.16661, + 91.13089, 91.09524, 91.05972, 91.02435, 90.98907, 90.95384, 90.91871, + 90.88361, 90.84867, 90.81384, 90.77909, 90.74442, 90.70988, 90.67542, + 90.64106, 90.60677, 90.5726, + 92.12129, 92.08257, 92.04397, 92.00547, 91.9671, 91.92885, 91.89072, + 91.85273, 91.81487, 91.77711, 91.73946, 91.70191, 91.6645, 91.62721, + 91.59003, 91.55297, 91.51604, 91.47919, 91.44247, 91.40585, 91.36934, + 91.33295, 91.29668, 91.26048, 91.22441, 91.18842, 91.15255, 91.11676, + 91.08108, 91.04552, 91.01008, 90.97475, 90.93951, 90.90437, 90.86929, + 90.83427, 90.79936, 90.76458, 90.72989, 90.69531, 90.66081, 90.62642, + 90.5921, 90.55789, 90.52377, + 92.06983, 92.03118, 91.99264, 91.95422, 91.91589, 91.87771, 91.83965, + 91.80173, 91.76392, 91.72619, 91.68861, 91.65117, 91.61382, 91.57659, + 91.53949, 91.5025, 91.46561, 91.42886, 91.39217, 91.35561, 91.31918, + 91.28284, 91.24663, 91.21049, 91.17448, 91.13857, 91.10273, 91.06703, + 91.03141, 90.9959, 90.96053, 90.92525, 90.89008, 90.855, 90.81996, + 90.785, 90.75018, 90.71545, 90.68082, 90.64629, 90.61185, 90.57751, + 90.54325, 90.50909, 90.47505, + 92.01849, 91.97987, 91.94141, 91.90305, 91.8648, 91.82668, 91.78869, + 91.75083, 91.71306, 91.67544, 91.63794, 91.60052, 91.56325, 91.52608, + 91.48905, 91.45212, 91.41531, 91.37858, 91.34199, 91.30551, 91.26913, + 91.23284, 91.19669, 91.16062, 91.12466, 91.08879, 91.05303, 91.01737, + 90.98183, 90.9464, 90.91106, 90.87588, 90.84076, 90.80573, 90.77076, + 90.73586, 90.70107, 90.66644, 90.63184, 90.59737, 90.56301, 90.52871, + 90.49451, 90.46043, 90.42643, + 91.96724, 91.92871, 91.8903, 91.85201, 91.81382, 91.77579, 91.73785, + 91.70002, 91.66235, 91.62477, 91.58734, 91.55, 91.51279, 91.47569, + 91.4387, 91.40185, 91.36508, 91.32845, 91.29192, 91.25548, 91.21917, + 91.18296, 91.14687, 91.11082, 91.07494, 91.03915, 91.00345, 90.96786, + 90.93236, 90.897, 90.86172, 90.82659, 90.79153, 90.75655, 90.72166, + 90.68684, 90.6521, 90.6175, 90.583, 90.54856, 90.51425, 90.48003, + 90.44591, 90.41185, 90.3779, + 92.14404, 92.10492, 92.06598, 92.02713, 91.98841, 91.94981, 91.91131, + 91.87297, 91.83474, 91.79664, 91.75866, 91.72073, 91.68298, 91.64534, + 91.60785, 91.5705, 91.53324, 91.49606, 91.45898, 91.42199, 91.3851, + 91.34834, 91.31168, 91.27516, 91.23875, 91.20244, 91.16624, 91.13013, + 91.0941, 91.05822, 91.02245, 90.98676, 90.95116, 90.91568, 90.88029, + 90.84501, 90.80988, 90.77483, 90.73982, 90.70487, 90.67006, 90.63535, + 90.60075, 90.56625, 90.5318, + 92.09234, 92.05331, 92.0144, 91.97564, 91.93698, 91.89843, 91.86002, + 91.82175, 91.78358, 91.74553, 91.70758, 91.66977, 91.63207, 91.59453, + 91.5571, 91.51981, 91.48261, 91.44552, 91.40848, 91.37154, 91.33472, + 91.29803, 91.26144, 91.22499, 91.18864, 91.15239, 91.11625, 91.08018, + 91.04424, 91.00842, 90.97269, 90.93704, 90.90154, 90.8661, 90.83077, + 90.79557, 90.76048, 90.7255, 90.69056, 90.65569, 90.62093, 90.58629, + 90.55173, 90.5173, 90.4829, + 92.04076, 92.00178, 91.96294, 91.92425, 91.88567, 91.8472, 91.80884, + 91.77063, 91.73253, 91.69452, 91.65667, 91.61892, 91.58129, 91.54379, + 91.50644, 91.46921, 91.4321, 91.39506, 91.35809, 91.32122, 91.28448, + 91.24783, 91.2113, 91.17491, 91.13863, 91.10241, 91.06633, 91.03037, + 90.99448, 90.9587, 90.92306, 90.88749, 90.85201, 90.81665, 90.78139, + 90.74622, 90.71122, 90.67628, 90.64142, 90.60658, 90.57188, 90.53731, + 90.50283, 90.46841, 90.43409, + 91.98926, 91.95037, 91.9116, 91.87297, 91.83447, 91.79605, 91.75777, + 91.71959, 91.68156, 91.64364, 91.60586, 91.56818, 91.53062, 91.49319, + 91.45589, 91.41873, 91.38167, 91.3447, 91.30782, 91.271, 91.23429, + 91.19772, 91.16128, 91.12493, 91.08869, 91.05257, 91.01655, 90.98064, + 90.94482, 90.90911, 90.8735, 90.83801, 90.8026, 90.7673, 90.73212, + 90.697, 90.66203, 90.62717, 90.59236, 90.55759, 90.52296, 90.48843, + 90.45401, 90.41969, 90.3854, + 91.93791, 91.89908, 91.8604, 91.82183, 91.78336, 91.74503, 91.70679, + 91.66869, 91.63074, 91.59288, 91.55516, 91.51756, 91.48006, 91.4427, + 91.40546, 91.36836, 91.33136, 91.29446, 91.25762, 91.22089, 91.18424, + 91.14773, 91.11131, 91.07504, 91.03889, 91.00284, 90.96686, 90.93102, + 90.89526, 90.85963, 90.82409, 90.78862, 90.75327, 90.71805, 90.68291, + 90.64787, 90.61298, 90.57815, 90.5434, 90.5087, 90.47413, 90.43966, + 90.40529, 90.37099, 90.33678, + 91.88667, 91.84789, 91.80927, 91.77076, 91.73237, 91.69408, 91.65593, + 91.61791, 91.58001, 91.54224, 91.50457, 91.46703, 91.42961, 91.39231, + 91.35513, 91.3181, 91.28117, 91.24432, 91.20754, 91.17088, 91.13429, + 91.09781, 91.06149, 91.02528, 90.98918, 90.95319, 90.9173, 90.88151, + 90.84582, 90.81021, 90.77474, 90.73937, 90.70409, 90.66892, 90.63383, + 90.59882, 90.56401, 90.52924, 90.49453, 90.45992, 90.42538, 90.39097, + 90.35665, 90.32244, 90.28828, + 91.83555, 91.79684, 91.75826, 91.71982, 91.6815, 91.64329, 91.60519, + 91.56725, 91.52942, 91.49169, 91.45412, 91.41662, 91.37926, 91.34202, + 91.30491, 91.26795, 91.23109, 91.19429, 91.15759, 91.12096, 91.08443, + 91.04803, 91.01178, 90.97562, 90.9396, 90.90366, 90.86784, 90.83211, + 90.79646, 90.76093, 90.72552, 90.69021, 90.65498, 90.61985, 90.58482, + 90.5499, 90.51514, 90.48046, 90.44579, 90.41122, 90.37672, 90.34238, + 90.30814, 90.27399, 90.23987 ; + + MaxIceConc = 100 ; + + MeanIceConc = 96.61342 ; + + MinIceConc = 7.335297 ; + + NumOfQACategories = 4 ; + + QCFlags = + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -18006798, -16958217, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -22201095, + -22201104, -22201095, -22201104, -16958217, -22201095, -16958209, + -22201104, -22201104, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958217, + -16958209, -22201095, -16958209, -16958209, -16958209, -16958209, + -16958217, -22201095, -16958217, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958217, -16958217, -16958217, -16958209, -16958217, -16958217, + -22201104, -22201095, -16958217, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958217, -16958209, -16958209, -16958209, -16958209, -16958217, + -16958209, -16958209, -22201095, -16958209, -22201104, -16958217, + -22201095, -22201095, -22201095, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958217, + -22201095, -16958217, -22201095, -22201104, -22201095, -16958217, + -16958217, -16958209, -16958209, -16958209, -22201095, -16958217, + -22201095, -22201104, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -22201095, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -22201095, -16958209, -16958217, -22201095, -16958209, -16958217, + -16958209, -16958209, -16958217, -16958209, -16958217, -22201095, + -16958209, -22201104, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958217, -22201095, -16958217, -16958209, + -16958209, -16958217, -22201095, -22201095, -16958209, -16958209, + -16958217, -16958217, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958217, -16958217, -16958217, -22201095, -22201095, + -16958209, -16958209, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958217, + -16958217, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958217, -16958209, + -16958209, -16958209, -22201095, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -22201095, -16958209, -22201095, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -22201104, + -22201104, -16958217, -22201104, -22201104, -22201095, -16958209, + -22201095, -16958209, -22201104, -16958209, -22201104, -16958217, + -22201104, -22201095, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958217, -22201095, -22201095, -16958217, -16958209, + -16958209, -16958209, -16958217, -16958209, -22201095, -16958217, + -22201095, -22201104, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958217, + -16958217, -16958209, -16958217, -22201095, -16958209, -16958209, + -16958209, -16958209, -22201095, -16958209, -16958209, -16958217, + -16958217, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -22201095, -16958217, + -16958209, -22201104, -22201104, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958217, -16958217, -16958209, + -16958209, -16958209, -16958209, -22201095, -16958217, -16958217, + -22201095, -16958217, -16958209, -22201095, -22201095, -22201095, + -16958217, -16958217, -16958217, -16958209, -16958209, -22201095, + -16958209, -16958217, -22201104, -16958217, -22201095, -16958209, + -16958209, -16958209, -16958217, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958217, -16958217, -16958217, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958217, -16958217, + -22201095, -22201095, -16958217, -16958217, -16958217, -22201095, + -16958217, -22201095, -22201095, -16958209, -16958217, -16958209, + -22201095, -22201095, -22201104, -16958217, -16958217, -22201095, + -16958217, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958217, -16958209, -16958217, -16958217, -16958209, + -16958209, -16958209, -16958209, -16958209, -22201095, -16958217, + -16958217, -16958209, -16958217, -22201095, -22201095, -22201095, + -16958217, -22201104, -16958217, -16958217, -22201104, -22201095, + -22201104, -16958217, -16958209, -16958217, -16958209, -22201095, + -16958217, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958209, + -16958209, -16958217, -16958217, -16958217, -16958217, -16958209, + -16958209, -16958209, -16958209, -16958209, -16958209, -16958217, + -22201095, -22201095, -16958217, -16958217, -22201095, -16958217, + -16958217, -22201095, -16958217, -16958217, -16958217, -16958217, + -22201095, -16958217, -22201095, -16958209, -16958217, -16958209, + -16958217, -16958209, -16958209 ; + + STDIceConc = 6.231885 ; + + SearchWindowSize = 50 ; + + StartColumn = 1 ; + + StartRow = 1 ; + + SummaryQC_Ice_Concentration = + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 1, 0, 3, 1, 3, 0, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 0, 3, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 1, 3, 1, 0, 1, 3, 3, 3, 3, 3, 1, 3, 1, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, 3, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, + 3, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 0, 3, 0, 0, 1, 3, 1, 3, 0, 3, 0, 3, 0, 1, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, 1, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, + 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 1, + 3, 3, 1, 1, 1, 3, 3, 3, 3, 3, 1, 3, 3, 0, 3, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, + 1, 3, 3, 3, 1, 3, 1, 1, 3, 3, 3, 1, 1, 0, 3, 3, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, + 3, 3, 1, 1, 1, 3, 0, 3, 3, 0, 1, 0, 3, 3, 3, 3, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, + 1, 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 3, 3, 3 ; + + TotDaytimePixs = _ ; + + TotIceRetrvls = 87116 ; + + TotIceTermnt = 2370484 ; + + TotNighttimePixs = 87116 ; + + TotWaterPixs = 94687 ; + + Tot_QA_BadData = 2362913 ; + + Tot_QA_Nonretrievable = 7571 ; + + Tot_QA_Normal = 37020 ; + + Tot_QA_Uncertain = 50096 ; +} diff --git a/utils/test/testdata/icec_jrr_n20_2.cdl b/utils/test/testdata/icec_jrr_n20_2.cdl new file mode 100644 index 000000000..a833e0495 --- /dev/null +++ b/utils/test/testdata/icec_jrr_n20_2.cdl @@ -0,0 +1,783 @@ +netcdf output_2 { +dimensions: + Rows = 15 ; + Columns = 50 ; +variables: + float IceConc(Rows, Columns) ; + IceConc:_FillValue = -999.f ; + IceConc:coordinates = "Longitude Latitude" ; + IceConc:long_name = "Ice Concentration" ; + IceConc:units = "%" ; + IceConc:valid_range = 0.f, 100.f ; + byte IceMap(Rows, Columns) ; + IceMap:_FillValue = -3b ; + IceMap:coordinates = "Longitude Latitude" ; + IceMap:long_name = "Ice Cover map codes" ; + IceMap:units = "1" ; + IceMap:valid_range = -2b, 2b ; + float IceRetrPct ; + IceRetrPct:long_name = "% of valid ice cover and concentration retrievals of all water pixels" ; + IceRetrPct:units = "%" ; + IceRetrPct:_FillValue = 0.f ; + IceRetrPct:valid_range = 0.f, 100.f ; + float IceSrfTemp(Rows, Columns) ; + IceSrfTemp:_FillValue = -999.f ; + IceSrfTemp:coordinates = "Longitude Latitude" ; + IceSrfTemp:long_name = "Ice Surface Temp" ; + IceSrfTemp:units = "Kelvin(K)" ; + IceSrfTemp:valid_range = 100.f, 390.f ; + float IceTermntPct ; + IceTermntPct:long_name = "% of terminated ice cover and concentration retrievals of all processed pixels" ; + IceTermntPct:units = "%" ; + IceTermntPct:_FillValue = 0.f ; + IceTermntPct:valid_range = 0.f, 100.f ; + float Latitude(Rows, Columns) ; + Latitude:long_name = "Latitude" ; + Latitude:_FillValue = -999.f ; + Latitude:units = "degrees_north" ; + Latitude:valid_range = -90.f, 90.f ; + Latitude:comments = "Pixel latitude in field Latitude (degree)" ; + float Longitude(Rows, Columns) ; + Longitude:long_name = "Longitude" ; + Longitude:_FillValue = -999.f ; + Longitude:units = "degrees_east" ; + Longitude:valid_range = -180.f, 180.f ; + Longitude:comments = "Pixel longitude in field Longitude (degree)" ; + float MaxIceConc ; + MaxIceConc:long_name = "Max ice concentration retrieval" ; + MaxIceConc:_FillValue = -999.f ; + MaxIceConc:units = "%" ; + float MeanIceConc ; + MeanIceConc:long_name = "Mean ice concentration retrieval" ; + MeanIceConc:_FillValue = -999.f ; + MeanIceConc:units = "%" ; + float MinIceConc ; + MinIceConc:long_name = "Min ice concentration retrieval" ; + MinIceConc:_FillValue = -999.f ; + MinIceConc:units = "%" ; + byte NumOfQACategories ; + NumOfQACategories:long_name = "Number of QA flag values" ; + NumOfQACategories:_FillValue = -128b ; + NumOfQACategories:units = "1" ; + int QCFlags(Rows, Columns) ; + QCFlags:_FillValue = -1 ; + QCFlags:coordinates = "Longitude Latitude" ; + QCFlags:long_name = "QCFlags" ; + QCFlags:units = "1" ; + float STDIceConc ; + STDIceConc:long_name = "Standard deviation of ice concentration retrievals" ; + STDIceConc:_FillValue = -999.f ; + STDIceConc:units = "%" ; + byte SearchWindowSize ; + SearchWindowSize:long_name = "Pixel size of search window to determine tie-point" ; + SearchWindowSize:_FillValue = -128b ; + SearchWindowSize:units = "1" ; + int StartColumn ; + StartColumn:long_name = "Start column index" ; + StartColumn:units = "1" ; + int StartRow ; + StartRow:long_name = "Start row index" ; + StartRow:units = "1" ; + byte SummaryQC_Ice_Concentration(Rows, Columns) ; + SummaryQC_Ice_Concentration:_FillValue = -128b ; + SummaryQC_Ice_Concentration:coordinates = "Longitude Latitude" ; + SummaryQC_Ice_Concentration:long_name = "User-level summary QC: 0=Normal, 1=Uncertain, 2=Non-Retrievable, 3=Bad" ; + SummaryQC_Ice_Concentration:units = "1" ; + SummaryQC_Ice_Concentration:valid_range = 0b, 3b ; + int TotDaytimePixs ; + TotDaytimePixs:long_name = "Total number of daytime valid retrievals" ; + TotDaytimePixs:_FillValue = 0 ; + TotDaytimePixs:units = "1" ; + int TotIceRetrvls ; + TotIceRetrvls:long_name = "Total number of valid ice cover and concentration retrievals" ; + TotIceRetrvls:_FillValue = 0 ; + TotIceRetrvls:units = "1" ; + int TotIceTermnt ; + TotIceTermnt:long_name = "Total number of terminated ice cover and concentration retrievals" ; + TotIceTermnt:_FillValue = 0 ; + TotIceTermnt:units = "1" ; + int TotNighttimePixs ; + TotNighttimePixs:long_name = "Total number of nighttime valid retrievals" ; + TotNighttimePixs:_FillValue = 0 ; + TotNighttimePixs:units = "1" ; + int TotWaterPixs ; + TotWaterPixs:long_name = "Total number of pixels w. water surface" ; + TotWaterPixs:_FillValue = 0 ; + TotWaterPixs:units = "1" ; + int Tot_QA_BadData ; + Tot_QA_BadData:long_name = "Total number of pixels with QA category 4 (Bad data)" ; + Tot_QA_BadData:_FillValue = 0 ; + Tot_QA_BadData:units = "1" ; + int Tot_QA_Nonretrievable ; + Tot_QA_Nonretrievable:long_name = "Total number of pixels with QA category 3 (Non-retrievable)" ; + Tot_QA_Nonretrievable:_FillValue = 0 ; + Tot_QA_Nonretrievable:units = "1" ; + int Tot_QA_Normal ; + Tot_QA_Normal:long_name = "Total number of pixels with QA category 1 (Normal of optimal)" ; + Tot_QA_Normal:_FillValue = 0 ; + Tot_QA_Normal:units = "1" ; + int Tot_QA_Uncertain ; + Tot_QA_Uncertain:long_name = "Total number of pixels with QA category 2 (Uncertain or suboptimal)" ; + Tot_QA_Uncertain:_FillValue = 0 ; + Tot_QA_Uncertain:units = "1" ; + +// global attributes: + :Conventions = "CF-1.6,ACDD 1.3" ; + :Metadata_Conventions = "CF-1.6, Unidata Dataset Discovery v1.0" ; + :standard_name_vocabulary = "CF Standard Name Table v76" ; + :institution = "DOC/NOAA/NESDIS/OSPO > Office of Satellite and Product Operations, NESDIS, NOAA, U.S. Department of Commerce." ; + :naming_authority = "gov.noaa.nesdis.ncei." ; + :processing_level = "NOAA Level 2" ; + :production_site = "NCCF" ; + :production_environment = "prod" ; + :sensor_band_identifier = "M3,M5,M7,M10,M15,M16" ; + :sensor_band_central_radiation_wavelength = "0.488um,0.672um,0.865um,1.61um,10.763um,12.013um" ; + :satellite_name = "NOAA-20" ; + :instrument = "VIIRS" ; + :project = "NESDIS Common Cloud Framework" ; + :summary = "Enterprise Ice Concentration/ Ice Mask/ Ice Surface Temperature Products" ; + :history = "Tue Aug 20 14:35:27 2024: ncks -d Columns,902,1000,2 -d Rows,422,451,2 JRR-IceConcentration_v3r3_j01_s202406180952557_e202406180954184_c202406181023196.nc output_2.nc\nEnterprise Ice Concentration Algorithm v1.1.0" ; + :references = "N/A" ; + :resolution = "750M" ; + :time_coverage_start = "2024-06-18T09:52:55Z" ; + :time_coverage_end = "2024-06-18T09:54:18Z" ; + :date_created = "2024-06-18T10:23:19Z" ; + :geospatial_lat_units = "degrees_north" ; + :geospatial_lon_units = "degrees_east" ; + :publisher_name = "DOC/NOAA/NESDIS/OSPO > Office of Satellite and Product Operations, NESDIS, NOAA, U.S. Department of Commerce." ; + :publisher_email = "espcoperations@noaa.gov" ; + :publisher_url = "http://www.ospo.noaa.gov" ; + :creator_email = "jkey@ssec.wisc.edu" ; + :creator_name = "DOC/NOAA/NESDIS/STAR > Cryosphere Team, Center for Satellite Applications and Research, NESDIS, NOAA, U.S. Department of Commerce" ; + :creator_url = "http://www.star.nesdis.noaa.gov" ; + :source = "L1b data, JRR-CloudMask, JRR-CloudHeight" ; + :keywords = "EARTH SCIENCE, CRYOSPHERE, SEA ICE, SEA ICE CONCENTRATION, ICE FRACTION, ICE EXTENT, ICE EDGES" ; + :cdm_data_type = "Swath" ; + :platform = "NOAA-20" ; + :title = "JRR_IceConcentration" ; + :metadata_link = "JRR-IceConcentration_v3r3_j01_s202406180952557_e202406180954184_c202406181023196.nc" ; + :history_package = "Delivery Package v3r3" ; + :product_version = "v3r3" ; + :keywords_vocabulary = "NASA Global Change Master Directory (GCMD) Science Keywords" ; + :geospatial_lat_max = 90.f ; + :geospatial_lat_min = -90.f ; + :geospatial_lat_resolution = "750 meters" ; + :geospatial_lon_max = 180.f ; + :geospatial_lon_min = -180.f ; + :geospatial_lon_resolution = "750 meters" ; + :id = "b8b29146-2936-461e-b20a-b9cf98790cbf" ; + :geospatial_bounds = "POLYGON((66.674118 64.1376266, 12.215044 56.018959, 5.55829859 59.631855, 68.5783844 68.9835892, 66.674118 64.1376266))" ; + :day_night_data_flag = "day" ; + :start_orbit_number = 34108 ; + :end_orbit_number = 34108 ; + :ascend_descend_data_flag = 0 ; + :geospatial_first_scanline_first_fov_lat = 64.13763f ; + :geospatial_first_scanline_last_fov_lat = 68.98359f ; + :geospatial_last_scanline_first_fov_lat = 56.01896f ; + :geospatial_last_scanline_last_fov_lat = 59.63186f ; + :geospatial_first_scanline_first_fov_lon = 66.67412f ; + :geospatial_first_scanline_last_fov_lon = 68.57838f ; + :geospatial_last_scanline_first_fov_lon = 12.21504f ; + :geospatial_last_scanline_last_fov_lon = 5.558299f ; + :NCO = "netCDF Operators version 5.0.6 (Homepage = http://nco.sf.net, Code = http://github.com/nco/nco)" ; +data: + + IceConc = + 98.34166, 92.57914, 100, 100, _, 92.13963, 100, 100, 100, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, + 100, 100, 100, _, 100, 100, 100, 100, 100, 100, 100, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, + _, _, _, 100, 100, _, 100, 100, 100, 100, 100, 100, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, + _, _, _, _, 100, _, _, _, _, 100, 100, _, 100, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, + _, _, _, _, 100, 89.48627, _, 98.89512, _, 100, 100, 100, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, + _, _, _, 100, 100, 84.68418, _, 77.50546, _, 100, 100, 100, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, + 100, _, _, _, 100, 86.11667, 93.27911, 100, _, 100, 100, 100, 100, _, 100, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, + _, 71.43365, 96.33943, _, _, 83.95166, _, 100, _, 100, _, 100, 100, 100, + 100, 100, 98.03237, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 94.22326, 100, 100, 85.10742, _, _, 100, 100, 100, 86.36085, _, _, 100, + 100, 100, 100, 100, 76.49621, 44.59078, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 85.69344, 91.635, 88.16773, 100, 100, _, 100, 100, _, _, _, _, _, 100, + 99.10674, 100, 100, 100, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, 100, 100, 100, 75.4544, 100, _, 100, 83.1703, _, _, 57.75991, + 93.47446, 100, 72.29642, _, 83.43076, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 92.31869, 89.60022, 100, 100, 100, 100, 100, _, _, 100, _, 47.09764, _, _, + 48.18828, 55.38328, 69.85468, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, 100, 97.60914, 95.65573, _, _, 71.58017, 70.78253, 100, 40.73283, + 52.17646, 53.28339, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, 100, 100, 90.26763, _, 74.51026, 81.88432, 96.97428, 96.958, + 43.06062, 52.76248, 43.79315, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 100, 100, 100, 99.22068, 100, 100, 72.88243, 72.11736, 57.14133, 74.96605, + 48.98592, _, 42.24671, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ ; + + IceMap = + 1, 1, 1, 1, -2, 1, 1, 1, 1, _, _, 0, -2, _, 0, 0, 0, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, -2, 1, 1, 1, 1, 1, 1, 1, _, 0, -2, _, 0, -2, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -2, 0, -2, 1, 1, 0, 1, 1, 1, 1, 1, 1, -2, -2, _, 0, -2, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 1, _, -2, -2, -2, 1, 1, _, 1, -2, -2, 0, 0, 0, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, -2, -2, 0, 1, 1, -2, 1, -2, 1, 1, 1, _, -2, -2, -2, _, _, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 1, 1, 1, -2, 1, -2, 1, 1, 1, _, -2, -2, -2, 0, 0, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 0, 0, 0, 1, 1, 1, 1, -2, 1, 1, 1, 1, -2, 1, -2, 0, 0, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + _, 1, 1, _, 0, 1, -2, 1, -2, 1, -2, 1, 1, 1, 1, 1, 1, -2, _, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, _, 0, 1, 1, 1, 1, -2, -2, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, _, 1, 1, 0, 0, -2, -2, -2, 1, 1, 1, 1, 1, -2, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, _, 1, 1, -2, 0, 1, 1, 1, 1, -2, 1, -2, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, _, _, 1, _, 1, -2, -2, 1, 1, 1, -2, 0, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 0, _, 1, 1, 1, 1, 1, 1, 0, 0, -2, _, -2, -2, -2, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -2, 0, -2, _, -2, -2, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, 1, 0, 0, 0, _, -2, -2, -2, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, + -1, -2, -1, -1, -1, -1, -1, -1, -1 ; + + IceRetrPct = 5.886314 ; + + IceSrfTemp = + 274.9209, 274.8062, 274.9214, 274.7943, _, 274.665, 274.5973, 274.4221, + 274.4603, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 274.8839, 274.9639, 274.973, _, 274.7099, 274.8377, 274.6533, 274.5237, + 274.4453, 274.4314, 274.6646, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, 274.7484, 274.8216, _, 274.8814, 274.5321, 274.5942, 274.8002, + 274.8478, 274.6158, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, 274.6919, _, _, _, _, 274.9737, 274.7827, _, 274.6674, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, + _, _, _, _, 274.8948, 274.651, _, 274.8407, _, 274.6422, 274.7932, + 274.6945, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, 274.7605, 274.6727, 274.6691, _, 274.7073, _, 274.5918, 274.5064, + 274.3907, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 274.7585, _, _, _, 274.6302, 274.7849, 274.9124, 274.6997, _, 274.7486, + 274.7006, 274.4442, 274.6088, _, 274.6678, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, 274.9928, 274.8151, _, _, 274.9085, _, 274.8958, _, 274.8481, _, + 274.5542, 274.5204, 274.8527, 274.6447, 274.6751, 274.5598, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, + 274.3351, 274.1571, 273.9791, 273.6346, _, _, 274.7652, 274.8819, 274.5946, + 274.8276, _, _, 274.6264, 274.7227, 274.9106, 274.631, 274.7617, + 274.9178, 274.7668, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, + 273.7129, 273.8175, 274.0147, 273.0873, 273.9924, _, 274.8008, 274.757, _, + _, _, _, _, 274.5397, 274.9979, 274.8029, 274.8488, 274.6307, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, + 273.3674, 273.1697, 273.3668, 272.9165, 273.2345, 273.8546, 274.9253, _, + 274.7198, 274.7643, _, _, 274.6973, 274.9601, 273.6242, 274.2138, _, + 274.8115, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, + 273.7788, 273.5576, 273.6622, 273.6536, 273.5914, 273.2065, 273.1289, _, _, + 274.2018, _, 274.1711, _, _, 274.4727, 273.6517, 273.9172, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, + 273.8614, 273.7878, 273.7272, 274.054, 274.0677, _, _, 274.4107, 274.4062, + 273.796, 274.48, 273.7475, 274.541, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + 273.7503, 273.7122, 273.7489, 273.8601, 274.3159, _, 273.7474, 274.2003, + 274.0799, 273.5551, 274.2413, 273.4915, 274.3263, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, + 274.0728, 274.0887, 273.7952, 274.0573, 273.9589, 273.7769, 274.1772, + 274.5915, 274.6418, 274.3053, 274.2776, _, 274.5207, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _ ; + + IceTermntPct = 99.72612 ; + + Latitude = + 66.94942, 66.94698, 66.94451, 66.94205, 66.93958, 66.93712, 66.93463, + 66.93217, 66.9297, 66.9272, 66.92471, 66.92223, 66.91973, 66.91723, + 66.91472, 66.91222, 66.90971, 66.9072, 66.90468, 66.90215, 66.89961, + 66.89709, 66.89456, 66.89201, 66.88949, 66.88696, 66.8844, 66.88187, + 66.87932, 66.87677, 66.8742, 66.87164, 66.86909, 66.86653, 66.86395, + 66.8614, 66.85883, 66.85624, 66.85367, 66.85108, 66.8485, 66.84592, + 66.84332, 66.84074, 66.83816, 66.83556, 66.83297, 66.83036, 66.82776, + 66.82515, + 66.96622, 66.96376, 66.96128, 66.9588, 66.95631, 66.95382, 66.95133, + 66.94884, 66.94633, 66.94383, 66.94132, 66.93882, 66.93629, 66.93378, + 66.93126, 66.92873, 66.92621, 66.92368, 66.92115, 66.9186, 66.91606, + 66.9135, 66.91095, 66.90839, 66.90585, 66.9033, 66.90073, 66.89816, + 66.89559, 66.89303, 66.89045, 66.88787, 66.88531, 66.88272, 66.88013, + 66.87756, 66.87496, 66.87238, 66.86978, 66.86718, 66.86458, 66.86198, + 66.85937, 66.85677, 66.85416, 66.85156, 66.84894, 66.84632, 66.8437, + 66.84108, + 66.98304, 66.98055, 66.97805, 66.97555, 66.97305, 66.97054, 66.96802, + 66.9655, 66.96297, 66.96046, 66.95794, 66.9554, 66.95287, 66.95033, + 66.94779, 66.94524, 66.9427, 66.94015, 66.9376, 66.93504, 66.93247, + 66.9299, 66.92734, 66.92477, 66.92221, 66.91962, 66.91705, 66.91445, + 66.91187, 66.9093, 66.90671, 66.90411, 66.90152, 66.89892, 66.89632, + 66.8937, 66.89111, 66.88851, 66.88589, 66.88328, 66.88065, 66.87804, + 66.87541, 66.8728, 66.87016, 66.86755, 66.86491, 66.86229, 66.85965, + 66.85701, + 66.99986, 66.99734, 66.99483, 66.99229, 66.98977, 66.98724, 66.9847, + 66.98218, 66.97964, 66.9771, 66.97455, 66.97199, 66.96944, 66.9669, + 66.96433, 66.96176, 66.95921, 66.95663, 66.95407, 66.95148, 66.94889, + 66.94631, 66.94373, 66.94114, 66.93855, 66.93595, 66.93336, 66.93076, + 66.92816, 66.92555, 66.92294, 66.92034, 66.91772, 66.9151, 66.91249, + 66.90989, 66.90726, 66.90462, 66.902, 66.89937, 66.89674, 66.89409, + 66.89145, 66.88882, 66.88617, 66.88354, 66.88089, 66.87823, 66.87559, + 66.87292, + 67.01666, 67.01414, 67.01159, 67.00905, 67.0065, 67.00396, 67.0014, + 66.99884, 66.99628, 66.99373, 66.99115, 66.98859, 66.98603, 66.98344, + 66.98088, 66.97829, 66.97571, 66.97312, 66.97053, 66.96793, 66.96531, + 66.96272, 66.96012, 66.95751, 66.95491, 66.9523, 66.94968, 66.94706, + 66.94445, 66.94183, 66.93921, 66.93656, 66.93394, 66.93131, 66.92867, + 66.92604, 66.92342, 66.92076, 66.91811, 66.91547, 66.91281, 66.91015, + 66.9075, 66.90485, 66.90219, 66.89954, 66.89687, 66.8942, 66.89153, + 66.88885, + 67.0026, 67.0002, 66.9978, 66.99538, 66.99297, 66.99055, 66.98813, + 66.98571, 66.98327, 66.98083, 66.9784, 66.97595, 66.9735, 66.97105, + 66.9686, 66.96615, 66.96368, 66.96121, 66.95875, 66.95628, 66.95377, + 66.95129, 66.94881, 66.94633, 66.94383, 66.94135, 66.93885, 66.93635, + 66.93385, 66.93134, 66.92883, 66.92632, 66.92381, 66.92129, 66.91876, + 66.91624, 66.91372, 66.91119, 66.90865, 66.90611, 66.90356, 66.90102, + 66.89848, 66.89594, 66.89339, 66.89084, 66.88828, 66.88571, 66.88316, + 66.88058, + 67.01941, 67.01699, 67.01456, 67.01212, 67.0097, 67.00726, 67.00482, + 67.00238, 66.99992, 66.99746, 66.995, 66.99255, 66.99008, 66.98761, + 66.98513, 66.98266, 66.98018, 66.9777, 66.97521, 66.97272, 66.9702, + 66.9677, 66.96519, 66.9627, 66.96019, 66.95768, 66.95516, 66.95265, + 66.95013, 66.94759, 66.94507, 66.94255, 66.94001, 66.93748, 66.93494, + 66.9324, 66.92985, 66.92731, 66.92477, 66.92221, 66.91962, 66.91707, + 66.91451, 66.91196, 66.90938, 66.90681, 66.90424, 66.90167, 66.89909, + 66.89652, + 67.03622, 67.03377, 67.03133, 67.02888, 67.02643, 67.02397, 67.02151, + 67.01904, 67.01656, 67.01408, 67.01161, 67.00914, 67.00665, 67.00417, + 67.00166, 66.99918, 66.99667, 66.99418, 66.99166, 66.98916, 66.98663, + 66.98411, 66.98159, 66.97906, 66.97653, 66.974, 66.97147, 66.96894, + 66.96642, 66.96387, 66.96133, 66.95877, 66.95621, 66.95367, 66.9511, + 66.94855, 66.94601, 66.94344, 66.94087, 66.9383, 66.9357, 66.93313, + 66.93055, 66.92797, 66.92538, 66.9228, 66.9202, 66.91762, 66.91502, + 66.91244, + 67.05302, 67.05056, 67.0481, 67.04563, 67.04316, 67.04068, 67.03819, + 67.03571, 67.03322, 67.03072, 67.02823, 67.02573, 67.02322, 67.02072, + 67.0182, 67.01569, 67.01318, 67.01066, 67.00813, 67.00561, 67.00307, + 67.00052, 66.99798, 66.99543, 66.99288, 66.99033, 66.98779, 66.98524, + 66.98269, 66.98013, 66.97757, 66.975, 66.97244, 66.96987, 66.96729, + 66.96472, 66.96214, 66.95957, 66.95699, 66.95439, 66.95178, 66.94919, + 66.94659, 66.94399, 66.94138, 66.93878, 66.93617, 66.93358, 66.93095, + 66.92834, + 67.06982, 67.06735, 67.06487, 67.06238, 67.05988, 67.05738, 67.05489, + 67.05238, 67.04987, 67.04736, 67.04484, 67.04231, 67.0398, 67.03728, + 67.03474, 67.03221, 67.02967, 67.02713, 67.02459, 67.02203, 67.01949, + 67.01694, 67.01437, 67.0118, 67.00925, 67.00668, 67.0041, 67.00155, + 66.99897, 66.99639, 66.9938, 66.99123, 66.98865, 66.98606, 66.98347, + 66.98088, 66.97829, 66.97568, 66.97308, 66.97044, 66.96785, 66.96523, + 66.96262, 66.96002, 66.9574, 66.95477, 66.95214, 66.94953, 66.9469, + 66.94427, + 67.08664, 67.08413, 67.08163, 67.07911, 67.07661, 67.07408, 67.07157, + 67.06905, 67.06651, 67.06398, 67.06146, 67.05891, 67.05637, 67.05383, + 67.05128, 67.04872, 67.04617, 67.04361, 67.04105, 67.03848, 67.03592, + 67.03333, 67.03077, 67.02819, 67.0256, 67.02301, 67.02043, 67.01785, + 67.01526, 67.01266, 67.01006, 67.00748, 67.00487, 67.00227, 66.99965, + 66.99704, 66.99442, 66.99181, 66.98918, 66.98654, 66.9839, 66.98129, + 66.97866, 66.97604, 66.9734, 66.97076, 66.96811, 66.96547, 66.96283, + 66.96019, + 67.10343, 67.10093, 67.09839, 67.09586, 67.09334, 67.0908, 67.08826, + 67.08571, 67.08316, 67.08061, 67.07806, 67.07551, 67.07294, 67.07039, + 67.06781, 67.06524, 67.06267, 67.06009, 67.05752, 67.05492, 67.05235, + 67.04974, 67.04716, 67.04457, 67.04196, 67.03937, 67.03677, 67.03416, + 67.03155, 67.02892, 67.02631, 67.0237, 67.02106, 67.01845, 67.01583, + 67.0132, 67.01056, 67.00793, 67.00529, 67.00265, 66.99999, 66.99734, + 66.99471, 66.99204, 66.98938, 66.98674, 66.98408, 66.98142, 66.97876, + 66.97612, + 67.12025, 67.11771, 67.11517, 67.11261, 67.11006, 67.10751, 67.10495, + 67.10239, 67.09982, 67.09725, 67.09467, 67.09209, 67.08952, 67.08694, + 67.08435, 67.08176, 67.07918, 67.07658, 67.07397, 67.07137, 67.06878, + 67.06616, 67.06355, 67.06094, 67.05833, 67.05569, 67.05307, 67.05046, + 67.04784, 67.04519, 67.04257, 67.03992, 67.03728, 67.03464, 67.032, + 67.02935, 67.0267, 67.02405, 67.02141, 67.01874, 67.01608, 67.01343, + 67.01076, 67.00809, 67.00542, 67.00274, 67.00006, 66.99738, 66.99471, + 66.99203, + 67.10621, 67.1038, 67.10139, 67.09898, 67.09655, 67.09411, 67.09168, + 67.08926, 67.08682, 67.08437, 67.08192, 67.07948, 67.07701, 67.07455, + 67.0721, 67.06963, 67.06716, 67.06468, 67.06221, 67.05972, 67.05724, + 67.05475, 67.05226, 67.04977, 67.04726, 67.04477, 67.04224, 67.03976, + 67.03725, 67.03473, 67.0322, 67.02968, 67.02715, 67.02464, 67.0221, + 67.01955, 67.01703, 67.01449, 67.01196, 67.0094, 67.00686, 67.00431, + 67.00174, 66.99918, 66.99662, 66.99406, 66.99149, 66.98891, 66.98636, + 66.98378, + 67.12302, 67.12059, 67.11815, 67.11572, 67.11327, 67.11083, 67.10838, + 67.10593, 67.10346, 67.101, 67.09853, 67.09606, 67.09359, 67.09111, + 67.08862, 67.08615, 67.08365, 67.08117, 67.07867, 67.07616, 67.07368, + 67.07117, 67.06865, 67.06613, 67.06362, 67.0611, 67.05857, 67.05605, + 67.05352, 67.05099, 67.04845, 67.0459, 67.04336, 67.04082, 67.03827, + 67.03573, 67.03318, 67.03061, 67.02805, 67.02549, 67.02293, 67.02036, + 67.01779, 67.01522, 67.01264, 67.01006, 67.00747, 67.00489, 67.0023, + 66.99971 ; + + Longitude = + 46.51716, 46.47765, 46.43822, 46.39891, 46.35968, 46.32058, 46.28156, + 46.24268, 46.20383, 46.16513, 46.12648, 46.08799, 46.04957, 46.01125, + 45.97302, 45.93488, 45.89684, 45.85889, 45.82104, 45.78316, 45.74537, + 45.70775, 45.67018, 45.63273, 45.59543, 45.55842, 45.52107, 45.48421, + 45.44712, 45.41035, 45.37339, 45.33672, 45.30018, 45.26367, 45.22721, + 45.19092, 45.15468, 45.11847, 45.08233, 45.0463, 45.0104, 44.97458, + 44.93879, 44.90312, 44.86756, 44.83205, 44.7967, 44.76129, 44.72601, + 44.69084, + 46.51044, 46.47093, 46.43146, 46.39213, 46.35291, 46.31378, 46.27477, + 46.23582, 46.19698, 46.15827, 46.1196, 46.08109, 46.04266, 46.00429, + 45.96606, 45.92792, 45.88983, 45.85188, 45.81401, 45.77608, 45.73838, + 45.70064, 45.66307, 45.6256, 45.58849, 45.55126, 45.51389, 45.47682, + 45.43988, 45.40301, 45.36617, 45.32946, 45.29288, 45.25637, 45.21996, + 45.18361, 45.14734, 45.11115, 45.07497, 45.03897, 45.00304, 44.96717, + 44.93139, 44.89571, 44.86007, 44.82462, 44.78921, 44.75384, 44.71856, + 44.68334, + 46.50376, 46.4642, 46.42477, 46.3854, 46.34613, 46.30702, 46.26795, + 46.22897, 46.19012, 46.15139, 46.11274, 46.07417, 46.03571, 45.99737, + 45.95909, 45.92092, 45.88286, 45.84486, 45.80696, 45.76916, 45.73118, + 45.69353, 45.656, 45.61853, 45.58119, 45.54401, 45.50673, 45.46965, + 45.4327, 45.39584, 45.35898, 45.32223, 45.28561, 45.2491, 45.21268, + 45.17628, 45.14002, 45.10387, 45.0677, 45.03166, 44.99564, 44.95973, + 44.92397, 44.88835, 44.85266, 44.81717, 44.78171, 44.74647, 44.71105, + 44.67587, + 46.49706, 46.4575, 46.41802, 46.37867, 46.33934, 46.3002, 46.26112, + 46.22216, 46.18331, 46.14454, 46.10584, 46.06729, 46.02881, 45.99043, + 45.95215, 45.91393, 45.87587, 45.83783, 45.79993, 45.76213, 45.72405, + 45.68644, 45.64888, 45.6114, 45.57404, 45.5368, 45.49961, 45.46247, + 45.42551, 45.38857, 45.35173, 45.315, 45.27835, 45.24184, 45.2054, + 45.16902, 45.1327, 45.09652, 45.06042, 45.02434, 44.98829, 44.95233, + 44.91651, 44.88089, 44.84529, 44.80976, 44.77428, 44.73893, 44.70355, + 44.66837, + 46.49037, 46.45079, 46.41129, 46.37187, 46.3326, 46.2934, 46.25431, + 46.21533, 46.17643, 46.13766, 46.09896, 46.06038, 46.0219, 45.98349, + 45.94519, 45.90698, 45.86888, 45.83084, 45.79289, 45.75507, 45.71702, + 45.6793, 45.64178, 45.60431, 45.56693, 45.52969, 45.49246, 45.45532, + 45.41832, 45.38138, 45.34452, 45.30773, 45.27111, 45.23458, 45.19812, + 45.16173, 45.12548, 45.08923, 45.05308, 45.01699, 44.98087, 44.94493, + 44.90912, 44.87342, 44.83788, 44.80236, 44.76681, 44.73148, 44.69611, + 44.66084, + 46.48796, 46.44836, 46.40884, 46.36943, 46.33012, 46.29089, 46.25177, + 46.21277, 46.17385, 46.135, 46.09629, 46.05765, 46.0191, 45.98069, + 45.94237, 45.90414, 45.86597, 45.8279, 45.78996, 45.75208, 45.71393, + 45.67624, 45.63869, 45.60113, 45.56373, 45.52641, 45.48923, 45.45203, + 45.41501, 45.37803, 45.34114, 45.30436, 45.26765, 45.23102, 45.19456, + 45.15812, 45.1218, 45.08555, 45.04933, 45.01323, 44.97704, 44.94106, + 44.90522, 44.86953, 44.8339, 44.79831, 44.76278, 44.72733, 44.69194, + 44.65674, + 46.48121, 46.44161, 46.40201, 46.36259, 46.32327, 46.28403, 46.24491, + 46.20587, 46.16694, 46.1281, 46.08931, 46.0507, 46.01215, 45.97369, + 45.93533, 45.8971, 45.85892, 45.82085, 45.78287, 45.74502, 45.70689, + 45.66911, 45.63155, 45.59402, 45.55653, 45.51917, 45.48196, 45.44482, + 45.40776, 45.37074, 45.33387, 45.29706, 45.26037, 45.22378, 45.18723, + 45.15082, 45.11447, 45.07821, 45.04203, 45.00587, 44.9696, 44.93362, + 44.89776, 44.862, 44.82638, 44.79074, 44.7552, 44.71975, 44.68435, + 44.64914, + 46.47445, 46.43481, 46.39523, 46.35578, 46.31645, 46.27718, 46.23805, + 46.19898, 46.16003, 46.12115, 46.0824, 46.04374, 46.00518, 45.96668, + 45.92833, 45.89005, 45.85187, 45.81379, 45.77577, 45.73788, 45.7, + 45.66203, 45.62439, 45.58674, 45.54924, 45.51189, 45.47466, 45.43754, + 45.4005, 45.36353, 45.32663, 45.28977, 45.25304, 45.21648, 45.17994, + 45.14348, 45.10715, 45.07089, 45.03468, 44.99853, 44.96211, 44.92618, + 44.89035, 44.85452, 44.81884, 44.78321, 44.74763, 44.71222, 44.67678, + 44.64156, + 46.46774, 46.42803, 46.38847, 46.349, 46.30959, 46.27036, 46.23119, + 46.1921, 46.15311, 46.11423, 46.07547, 46.03678, 45.99818, 45.95971, + 45.92131, 45.88303, 45.84484, 45.80672, 45.7687, 45.7308, 45.69297, + 45.65496, 45.61721, 45.57953, 45.54199, 45.50467, 45.4674, 45.43033, + 45.39324, 45.35626, 45.31938, 45.28255, 45.24584, 45.20921, 45.17266, + 45.13616, 45.09975, 45.06353, 45.02736, 44.99102, 44.95473, 44.91871, + 44.88289, 44.84711, 44.81134, 44.77565, 44.74007, 44.70466, 44.66924, + 44.63398, + 46.46096, 46.42129, 46.38168, 46.34217, 46.3028, 46.26353, 46.2243, + 46.18523, 46.14624, 46.10734, 46.06855, 46.0298, 45.99124, 45.95272, + 45.91432, 45.876, 45.83778, 45.79965, 45.76162, 45.72369, 45.68584, + 45.64791, 45.61023, 45.57264, 45.53516, 45.49773, 45.46037, 45.42318, + 45.38606, 45.34904, 45.31212, 45.27531, 45.23858, 45.20193, 45.16534, + 45.12879, 45.09252, 45.05608, 45.01977, 44.98337, 44.94724, 44.91127, + 44.87539, 44.8396, 44.80383, 44.76819, 44.73257, 44.69706, 44.66162, + 44.62637, + 46.45421, 46.41452, 46.37491, 46.33535, 46.29597, 46.25666, 46.21746, + 46.17834, 46.13935, 46.10041, 46.0616, 46.02287, 45.98426, 45.94574, + 45.90729, 45.86897, 45.83074, 45.79258, 45.75454, 45.71657, 45.67871, + 45.64074, 45.60308, 45.56553, 45.52799, 45.49059, 45.45332, 45.41608, + 45.37896, 45.34194, 45.30492, 45.26806, 45.23124, 45.19455, 45.15796, + 45.12145, 45.0851, 45.04873, 45.01234, 44.97583, 44.93963, 44.9036, + 44.86778, 44.83204, 44.79626, 44.76054, 44.72491, 44.68941, 44.65396, + 44.61865, + 46.44748, 46.40775, 46.36811, 46.32855, 46.28916, 46.24984, 46.21058, + 46.17145, 46.1324, 46.09347, 46.05466, 46.0159, 45.97726, 45.93874, + 45.90028, 45.86193, 45.82369, 45.78552, 45.74743, 45.70947, 45.67162, + 45.63373, 45.59599, 45.55838, 45.52083, 45.48341, 45.4461, 45.40893, + 45.37176, 45.33461, 45.29758, 45.26074, 45.22393, 45.18722, 45.15061, + 45.11406, 45.07758, 45.04121, 45.00496, 44.96866, 44.93242, 44.89632, + 44.86033, 44.82442, 44.78865, 44.75291, 44.71729, 44.68173, 44.6463, + 44.61107, + 46.44075, 46.40099, 46.36134, 46.32178, 46.28231, 46.24298, 46.20371, + 46.16458, 46.12554, 46.0866, 46.04771, 46.00896, 45.97029, 45.93174, + 45.89328, 45.8549, 45.81663, 45.77845, 45.74034, 45.70236, 45.66445, + 45.62667, 45.58892, 45.55122, 45.51371, 45.47617, 45.43881, 45.40163, + 45.3645, 45.32739, 45.2904, 45.2534, 45.21656, 45.17982, 45.14317, + 45.10662, 45.07013, 45.03378, 44.9975, 44.96126, 44.92519, 44.8891, + 44.85311, 44.81726, 44.78141, 44.74559, 44.70991, 44.67424, 44.63876, + 44.60345, + 46.43872, 46.39893, 46.35923, 46.31966, 46.28017, 46.24077, 46.2015, + 46.16228, 46.12324, 46.08423, 46.04535, 46.00655, 45.96787, 45.92928, + 45.89077, 45.85236, 45.81405, 45.77584, 45.73773, 45.69971, 45.66179, + 45.62389, 45.5861, 45.54845, 45.51088, 45.47339, 45.43597, 45.39874, + 45.36154, 45.32435, 45.28721, 45.25024, 45.21344, 45.17671, 45.14, + 45.10344, 45.06689, 45.03051, 44.99417, 44.9579, 44.92175, 44.88565, + 44.84954, 44.81355, 44.77764, 44.74189, 44.70619, 44.67055, 44.63511, + 44.5997, + 46.4319, 46.39211, 46.35241, 46.31281, 46.2733, 46.23388, 46.19458, + 46.1554, 46.11628, 46.07727, 46.03837, 45.99955, 45.96085, 45.92221, + 45.88371, 45.84529, 45.80696, 45.76873, 45.73058, 45.69256, 45.65462, + 45.61675, 45.5789, 45.54121, 45.50367, 45.46609, 45.4286, 45.39139, + 45.35415, 45.31709, 45.27998, 45.243, 45.20608, 45.16926, 45.13259, + 45.09597, 45.05947, 45.02301, 44.98663, 44.95044, 44.9143, 44.8782, + 44.84216, 44.80625, 44.77032, 44.73455, 44.69887, 44.66325, 44.62769, + 44.59214 ; + + MaxIceConc = 100 ; + + MeanIceConc = 88.47009 ; + + MinIceConc = 14.89622 ; + + NumOfQACategories = 4 ; + + QCFlags = + -20905760, -20905760, -20905760, -20905760, -17760030, -20905760, + -20905751, -20905751, -20905751, -16973662, -16973662, -16973594, + -17497878, -16973662, -16973594, -16973594, -16973594, -16908058, + -16908062, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908062, -16908054, -16908054, -16908054, -17301270, -16908054, + -16908054, -16908054, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908058, -16908058, -16908050, -16908050, + -16908050, -16908050, -16908050, -16908050, -16908050, -16908050, + -16908050, -16908050, + -20905751, -20905751, -20905751, -17760030, -20905760, -20905760, + -20905760, -20905760, -20905760, -20905760, -20905751, -16973662, + -16973594, -17760030, -16973662, -16973594, -17497878, -16908058, + -16908058, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908058, -16908058, + -16908058, -16908058, -16908050, -16908050, -16908050, -16908050, + -16908050, -16908050, + -17760022, -16973594, -17760022, -20905751, -20905760, -16973594, + -20905760, -20905760, -20905760, -20905760, -20905760, -20905760, + -17760022, -17760022, -16973662, -16973594, -17497878, -16908058, + -16908058, -16908058, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908126, -16908050, -16908050, -16908050, + -16908050, -16908050, + -16973594, -16973586, -16973594, -16973594, -20905751, -16973662, + -17760030, -17760030, -17760030, -20905751, -20905760, -16973662, + -20905760, -17760022, -17760030, -16973594, -16973594, -16973594, + -16908058, -16908058, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908126, -16908126, -16908058, -16908050, + -16908050, -16908050, + -16973586, -17760022, -17760022, -16973594, -20905760, -20905751, + -17760030, -20905760, -17760030, -20905760, -20905760, -20905760, + -16973662, -17760030, -17760030, -17497886, -16973662, -16973662, + -17497886, -16908062, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908062, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908126, -16908126, -16908054, -16908054, + -16908050, -16908050, + -16973594, -16973594, -16973594, -20905751, -20905751, -20905751, + -17760022, -20905760, -17497886, -20905760, -20905760, -20905760, + -16973662, -17760030, -17760022, -17497886, -16973594, -16973594, + -16908126, -16908126, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908062, -16908050, -16908126, + -16908050, -16908050, + -20905751, -16973594, -16973594, -16973594, -20905751, -20905751, + -20905760, -20905751, -17760030, -20905751, -20905751, -20905751, + -20905751, -17760030, -20905760, -17760030, -16973594, -16973594, + -16908058, -16908062, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908058, -16908054, -16908062, + -16908062, -16908062, -16908050, -16908062, -16908126, -16908126, + -16908050, -16908050, + -16973662, -20905751, -20905751, -16973662, -16973594, -20905751, + -17760022, -20905751, -17760030, -20905751, -17760030, -20905751, + -20905751, -20905751, -20905751, -20905760, -20905760, -17760030, + -16973662, -16908058, -16908054, -16908054, -16908054, -16908054, + -16908062, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908062, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908058, -16908054, + -16908054, -16908054, -16908050, -16908058, -16908050, -16908050, + -16908058, -16908058, + -20905760, -20905760, -20905760, -20905760, -16973662, -16973594, + -20905751, -20905760, -20905751, -20905760, -17760030, -17760030, + -20905760, -20905760, -20905751, -20905751, -20905760, -20905760, + -20905760, -16973594, -16908058, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908062, -16908062, + -16908062, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908050, -16908054, -16908054, -16908054, -16908050, + -16908058, -16908054, + -20905760, -20905760, -20905760, -20905760, -20905760, -16973662, + -20905751, -20905751, -16973586, -16973586, -17497878, -17760022, + -17760030, -20905760, -20905760, -20905760, -20905760, -20905760, + -17760030, -16908126, -16908058, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908062, -16908054, -16908054, -16908054, + -17039126, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908050, -16908050, -16908054, -16908054, -16908054, + -16908062, -16908054, + -20905760, -20905760, -20905760, -20905760, -20905760, -20905760, + -20905760, -16973662, -20905751, -20905760, -17497878, -16973586, + -20905760, -20905760, -20905760, -20905760, -17760030, -20905760, + -17497886, -16908062, -16908058, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908062, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908058, -16908054, -16908058, -16908058, + -16908054, -16908054, + -20905760, -20905760, -20905760, -20905760, -20905760, -20905760, + -20905760, -16973662, -16973662, -20905760, -16973662, -20905760, + -17497886, -17497886, -20905760, -20905760, -20905760, -17497886, + -16973594, -16973594, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908050, -16908050, + -20905760, -20905760, -20905760, -20905760, -20905760, -16973586, + -16973662, -20905760, -20905760, -20905760, -20905760, -20905760, + -20905760, -16973586, -16973586, -18546454, -16973662, -18546462, + -18546462, -17497886, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -17301270, -16908062, -16908062, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908126, + -16908050, -16908050, + -20905760, -20905760, -20905760, -20905760, -20905760, -16973594, + -20905760, -20905760, -20905760, -20905760, -20905760, -20905760, + -20905751, -17497878, -16973594, -18546462, -16973662, -17497886, + -18546462, -16908062, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908062, -16908062, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908126, + -16908050, -16908058, + -20905760, -20905760, -20905760, -20905760, -20905760, -20905751, + -20905760, -20905760, -20905760, -20905760, -20905760, -18546462, + -20905760, -16973586, -16973586, -16973594, -16973662, -17497886, + -18546462, -17497886, -16908062, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -16908054, -16908054, -16908054, + -16908054, -16908054, -16908054, -17301270, -17301270, -16908054, + -17039126, -16908054, -16908054, -16908054, -16908054, -16908062, + -16908054, -16908054 ; + + STDIceConc = 19.20647 ; + + SearchWindowSize = 50 ; + + StartColumn = 1 ; + + StartRow = 1 ; + + SummaryQC_Ice_Concentration = + 0, 0, 0, 0, 2, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 1, 2, 0, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 2, 0, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 1, 1, 0, 1, 2, 1, 1, 1, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 2, 2, 1, 0, 1, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; + + TotDaytimePixs = 6731 ; + + TotIceRetrvls = 6731 ; + + TotIceTermnt = 2450869 ; + + TotNighttimePixs = _ ; + + TotWaterPixs = 114350 ; + + Tot_QA_BadData = 55710 ; + + Tot_QA_Nonretrievable = 2395159 ; + + Tot_QA_Normal = 5596 ; + + Tot_QA_Uncertain = 1135 ; +} diff --git a/utils/test/testdata/icec_mirs_snpp_1.cdl b/utils/test/testdata/icec_mirs_snpp_1.cdl new file mode 100644 index 000000000..f63289bd2 --- /dev/null +++ b/utils/test/testdata/icec_mirs_snpp_1.cdl @@ -0,0 +1,961 @@ +netcdf output_1 { +dimensions: + Scanline = 6 ; + Field_of_view = 5 ; + Channel = 22 ; + Qc_dim = 4 ; +variables: + short Atm_type(Scanline, Field_of_view) ; + Atm_type:description = "type of atmosphere:currently missing" ; + Atm_type:coordinates = "Longitude Latitude" ; + short BT(Scanline, Field_of_view, Channel) ; + BT:long_name = "Channel Temperature (K)" ; + BT:units = "Kelvin" ; + BT:coordinates = "Longitude Latitude Freq" ; + BT:scale_factor = 0.01 ; + BT:_FillValue = -999s ; + BT:valid_range = 0, 50000 ; + short CLW(Scanline, Field_of_view) ; + CLW:long_name = "Cloud liquid Water (mm)" ; + CLW:units = "mm" ; + CLW:coordinates = "Longitude Latitude" ; + CLW:scale_factor = 0.01 ; + CLW:_FillValue = -999s ; + CLW:valid_range = 0, 10000 ; + short ChanSel(Scanline, Field_of_view, Channel) ; + ChanSel:long_name = "Channels Selection Used in Retrieval" ; + ChanSel:units = "1" ; + ChanSel:coordinates = "Longitude Latitude Freq" ; + ChanSel:_FillValue = -999s ; + ChanSel:valid_range = 0, 1 ; + float ChiSqr(Scanline, Field_of_view) ; + ChiSqr:description = "Convergence rate: <3-good,>10-bad" ; + ChiSqr:units = "1" ; + ChiSqr:coordinates = "Longitude Latitude" ; + ChiSqr:_FillValue = -999.f ; + ChiSqr:valid_range = 0.f, 1000.f ; + short CldBase(Scanline, Field_of_view) ; + CldBase:long_name = "Cloud Base Pressure" ; + CldBase:scale_factor = 0.1 ; + CldBase:coordinates = "Longitude Latitude" ; + short CldThick(Scanline, Field_of_view) ; + CldThick:long_name = "Cloud Thickness" ; + CldThick:scale_factor = 0.1 ; + CldThick:coordinates = "Longitude Latitude" ; + short CldTop(Scanline, Field_of_view) ; + CldTop:long_name = "Cloud Top Pressure" ; + CldTop:scale_factor = 0.1 ; + CldTop:coordinates = "Longitude Latitude" ; + short Emis(Scanline, Field_of_view, Channel) ; + Emis:long_name = "Channel Emissivity" ; + Emis:units = "1" ; + Emis:coordinates = "Longitude Latitude Freq" ; + Emis:scale_factor = 0.0001 ; + Emis:_FillValue = -999s ; + Emis:valid_range = 0, 10000 ; + float Freq(Channel) ; + Freq:description = "Central Frequencies (GHz)" ; + short GWP(Scanline, Field_of_view) ; + GWP:long_name = "Graupel Water Path (mm)" ; + GWP:units = "mm" ; + GWP:coordinates = "Longitude Latitude" ; + GWP:scale_factor = 0.01 ; + GWP:_FillValue = -999s ; + GWP:valid_range = 0, 10000 ; + short IWP(Scanline, Field_of_view) ; + IWP:long_name = "Ice Water Path (mm)" ; + IWP:units = "mm" ; + IWP:coordinates = "Longitude Latitude" ; + IWP:scale_factor = 0.01 ; + IWP:_FillValue = -999s ; + IWP:valid_range = 0, 10000 ; + short LWP(Scanline, Field_of_view) ; + LWP:long_name = "Liquid Water Path (mm)" ; + LWP:units = "mm" ; + LWP:coordinates = "Longitude Latitude" ; + LWP:scale_factor = 0.01 ; + LWP:_FillValue = -999s ; + LWP:valid_range = 0, 10000 ; + float LZ_angle(Scanline, Field_of_view) ; + LZ_angle:long_name = "Local Zenith Angle degree" ; + LZ_angle:units = "degrees" ; + LZ_angle:coordinates = "Longitude Latitude" ; + LZ_angle:_FillValue = -999.f ; + LZ_angle:valid_range = -70.f, 70.f ; + float Latitude(Scanline, Field_of_view) ; + Latitude:long_name = "Latitude of the view (-90,90)" ; + Latitude:units = "degrees" ; + Latitude:_FillValue = -999.f ; + Latitude:valid_range = -90.f, 90.f ; + float Longitude(Scanline, Field_of_view) ; + Longitude:long_name = "Longitude of the view (-180,180)" ; + Longitude:units = "degrees" ; + Longitude:_FillValue = -999.f ; + Longitude:valid_range = -180.f, 180.f ; + short Orb_mode(Scanline) ; + Orb_mode:description = "0-ascending,1-descending" ; + Orb_mode:units = "1" ; + Orb_mode:_FillValue = -999s ; + Orb_mode:valid_range = 0, 1 ; + short Polo(Channel) ; + Polo:description = "Polarizations" ; + short PrecipType(Scanline, Field_of_view) ; + PrecipType:long_name = "Precipitation Type (Frozen/Liquid)" ; + PrecipType:coordinates = "Longitude Latitude" ; + short Prob_SF(Scanline, Field_of_view) ; + Prob_SF:long_name = "Probability of falling snow (%)" ; + Prob_SF:units = "percent" ; + Prob_SF:coordinates = "Longitude Latitude" ; + Prob_SF:_FillValue = -999s ; + Prob_SF:valid_range = 0, 100 ; + short Qc(Scanline, Field_of_view, Qc_dim) ; + Qc:description = "Qc: 0-good, 1-usable with problem, 2-bad" ; + float RAzi_angle(Scanline, Field_of_view) ; + RAzi_angle:long_name = "Relative Azimuth Angle 0-360 degree" ; + RAzi_angle:coordinates = "Longitude Latitude" ; + short RFlag(Scanline, Field_of_view) ; + RFlag:long_name = "Rain Flag" ; + RFlag:coordinates = "Longitude Latitude" ; + short RR(Scanline, Field_of_view) ; + RR:long_name = "Rain Rate (mm/hr)" ; + RR:units = "mm/hr" ; + RR:coordinates = "Longitude Latitude" ; + RR:scale_factor = 0.1 ; + RR:_FillValue = -999s ; + RR:valid_range = 0, 1000 ; + short RWP(Scanline, Field_of_view) ; + RWP:long_name = "Rain Water Path (mm)" ; + RWP:units = "mm" ; + RWP:coordinates = "Longitude Latitude" ; + RWP:scale_factor = 0.01 ; + RWP:_FillValue = -999s ; + RWP:valid_range = 0, 10000 ; + short SFR(Scanline, Field_of_view) ; + SFR:long_name = "Snow Fall Rate in mm/hr" ; + SFR:units = "mm/hr" ; + SFR:coordinates = "Longitude Latitude" ; + SFR:scale_factor = 0.01 ; + SFR:_FillValue = -999s ; + SFR:valid_range = 0, 10000 ; + short SIce(Scanline, Field_of_view) ; + SIce:long_name = "Sea Ice Concentration (%)" ; + SIce:units = "percent" ; + SIce:coordinates = "Longitude Latitude" ; + SIce:_FillValue = -999s ; + SIce:valid_range = 0, 100 ; + short SIce_FY(Scanline, Field_of_view) ; + SIce_FY:long_name = "First-Year Sea Ice Concentration (%)" ; + SIce_FY:units = "percent" ; + SIce_FY:coordinates = "Longitude Latitude" ; + SIce_FY:_FillValue = -999s ; + SIce_FY:valid_range = 0, 100 ; + short SIce_MY(Scanline, Field_of_view) ; + SIce_MY:long_name = "Multi-Year Sea Ice Concentration (%)" ; + SIce_MY:units = "percent" ; + SIce_MY:coordinates = "Longitude Latitude" ; + SIce_MY:_FillValue = -999s ; + SIce_MY:valid_range = 0, 100 ; + short SWE(Scanline, Field_of_view) ; + SWE:long_name = "Snow Water Equivalent (cm)" ; + SWE:units = "cm" ; + SWE:coordinates = "Longitude Latitude" ; + SWE:scale_factor = 0.01 ; + SWE:_FillValue = -999s ; + SWE:valid_range = 0, 10000 ; + short SWP(Scanline, Field_of_view) ; + SWP:long_name = "Snow Water Path" ; + SWP:units = "mm" ; + SWP:coordinates = "Longitude Latitude" ; + SWP:scale_factor = 0.01 ; + SWP:_FillValue = -999s ; + SWP:valid_range = 0, 10000 ; + float SZ_angle(Scanline, Field_of_view) ; + SZ_angle:long_name = "Solar Zenith Angle (-90,90) degree" ; + SZ_angle:coordinates = "Longitude Latitude" ; + double ScanTime_UTC(Scanline) ; + ScanTime_UTC:long_name = "Number of seconds since 00:00:00 UTC" ; + ScanTime_UTC:units = "seconds" ; + ScanTime_UTC:_FillValue = -999. ; + ScanTime_UTC:valid_range = 0., 86400. ; + short ScanTime_dom(Scanline) ; + ScanTime_dom:long_name = "Calendar day of the month 1-31" ; + ScanTime_dom:units = "days" ; + ScanTime_dom:_FillValue = -999s ; + ScanTime_dom:valid_range = 1, 31 ; + short ScanTime_doy(Scanline) ; + ScanTime_doy:long_name = "julian day 1-366" ; + ScanTime_doy:units = "days" ; + ScanTime_doy:_FillValue = -999s ; + ScanTime_doy:valid_range = 1, 366 ; + short ScanTime_hour(Scanline) ; + ScanTime_hour:long_name = "hour of the day 0-23" ; + ScanTime_hour:units = "hours" ; + ScanTime_hour:_FillValue = -999s ; + ScanTime_hour:valid_range = 0, 23 ; + short ScanTime_minute(Scanline) ; + ScanTime_minute:long_name = "minute of the hour 0-59" ; + ScanTime_minute:units = "minutes" ; + ScanTime_minute:_FillValue = -999s ; + ScanTime_minute:valid_range = 0, 59 ; + short ScanTime_month(Scanline) ; + ScanTime_month:long_name = "Calendar month 1-12" ; + ScanTime_month:units = "months" ; + ScanTime_month:_FillValue = -999s ; + ScanTime_month:valid_range = 1, 12 ; + short ScanTime_second(Scanline) ; + ScanTime_second:long_name = "second of the minute 0-59" ; + ScanTime_second:units = "seconds" ; + ScanTime_second:_FillValue = -999s ; + ScanTime_second:valid_range = 0, 59 ; + short ScanTime_year(Scanline) ; + ScanTime_year:long_name = "Calendar Year 20XX" ; + ScanTime_year:units = "years" ; + ScanTime_year:_FillValue = -999s ; + ScanTime_year:valid_range = 2011, 2050 ; + short Sfc_type(Scanline, Field_of_view) ; + Sfc_type:description = "type of surface:0-ocean,1-sea ice,2-land,3-snow" ; + Sfc_type:units = "1" ; + Sfc_type:coordinates = "Longitude Latitude" ; + Sfc_type:_FillValue = -999s ; + Sfc_type:valid_range = 0, 3 ; + short Snow(Scanline, Field_of_view) ; + Snow:long_name = "Snow Cover" ; + Snow:units = "1" ; + Snow:coordinates = "Longitude Latitude" ; + Snow:_FillValue = -999s ; + Snow:valid_range = 0, 1 ; + short SnowGS(Scanline, Field_of_view) ; + SnowGS:long_name = "Snow Grain Size (mm)" ; + SnowGS:units = "mm" ; + SnowGS:coordinates = "Longitude Latitude" ; + SnowGS:scale_factor = 0.01 ; + SnowGS:_FillValue = -999s ; + SnowGS:valid_range = 0, 2000 ; + short SurfM(Scanline, Field_of_view) ; + SurfM:long_name = "Surface Moisture" ; + SurfM:scale_factor = 0.1 ; + SurfM:coordinates = "Longitude Latitude" ; + short SurfP(Scanline, Field_of_view) ; + SurfP:long_name = "Surface Pressure (mb)" ; + SurfP:units = "millibars" ; + SurfP:coordinates = "Longitude Latitude" ; + SurfP:scale_factor = 0.1 ; + SurfP:_FillValue = -999s ; + SurfP:valid_range = 0, 12000 ; + short TPW(Scanline, Field_of_view) ; + TPW:long_name = "Total Precipitable Water (mm)" ; + TPW:units = "mm" ; + TPW:coordinates = "Longitude Latitude" ; + TPW:scale_factor = 0.1 ; + TPW:_FillValue = -999s ; + TPW:valid_range = 0, 2000 ; + short TSkin(Scanline, Field_of_view) ; + TSkin:long_name = "Skin Temperature (K)" ; + TSkin:units = "Kelvin" ; + TSkin:coordinates = "Longitude Latitude" ; + TSkin:scale_factor = 0.01 ; + TSkin:_FillValue = -999s ; + TSkin:valid_range = 0, 40000 ; + short WindDir(Scanline, Field_of_view) ; + WindDir:long_name = "Wind Direction" ; + WindDir:scale_factor = 0.01 ; + WindDir:coordinates = "Longitude Latitude" ; + short WindSp(Scanline, Field_of_view) ; + WindSp:long_name = "Wind Speed (m/s)" ; + WindSp:scale_factor = 0.01 ; + WindSp:coordinates = "Longitude Latitude" ; + short WindU(Scanline, Field_of_view) ; + WindU:long_name = "U-direction Wind Speed (m/s)" ; + WindU:scale_factor = 0.01 ; + WindU:coordinates = "Longitude Latitude" ; + short WindV(Scanline, Field_of_view) ; + WindV:long_name = "V-direction Wind Speed (m/s)" ; + WindV:scale_factor = 0.01 ; + WindV:coordinates = "Longitude Latitude" ; + short YM(Scanline, Field_of_view, Channel) ; + YM:long_name = "Un-Corrected Channel Temperature (K)" ; + YM:units = "Kelvin" ; + YM:coordinates = "Longitude Latitude Freq" ; + YM:scale_factor = 0.01 ; + YM:_FillValue = -999s ; + YM:valid_range = 0, 50000 ; + +// global attributes: + :missing_value = -999 ; + :notretrievedproduct_value = -888 ; + :noretrieval_value = -99 ; + :cdf_version = 4. ; + :alg_version = 4201 ; + :dap_version = "v11r4" ; + :Conventions = "CF-1.5" ; + :Metadata_Conventions = "CF-1.5, Unidata Dataset Discovery v1.0" ; + :standard_name_vocabulary = "CF Standard Name Table (version 17, 24 March 2011)" ; + :project = "Microwave Integrated Retrieval System" ; + :title = "MIRS IMG" ; + :summary = "MIRS imaging products including surface emissivity, TPW, CLW, RWP, IWP, LST." ; + :date_created = "2021-06-30T02:01:08Z" ; + :institution = "DOC/NOAA/NESDIS/NDE > NPOESS Data Exploitation, NESDIS, NOAA, U.S. Department of Commerce" ; + :naming_authority = "gov.noaa.nesdis.nde" ; + :production_site = "NSOF" ; + :production_environment = "OE" ; + :satellite_name = "NPP" ; + :instrument_name = "ATMS" ; + :creator_name = "DOC/NOAA/NESDIS/STAR > MIRS TEAM, Center for Satellite Applications and Research, NESDIS, NOAA, U.S. Department of Commerce" ; + :creator_email = "Christopher.Grassotti@noaa.gov, Quanhua.Liu@noaa.gov, Shu-yan.Liu@noaa.gov, ryan.honeyager@noaa.gov, Yong-Keun.Lee@noaa.gov " ; + :creator_url = "http://www.star.nesdis.noaa.gov/mirs" ; + :publisher_name = "DOC/NOAA/NESDIS/NDE > NPOESS Data Exploitation, NESDIS, NOAA, U.S. Department of Commerce" ; + :publisher_email = "NDE_POC@noaa.gov" ; + :publisher_url = "http://projects.osd.noaa.gov/NDE" ; + :Metadata_Link = "NDE product-specific output file name" ; + :references = "http://www.star.nesdis.noaa.gov/mirs/documentation.php" ; + :history = "Tue Jul 30 17:48:05 2024: ncks -d Scanline,1,12,2 -d Field_of_view,86,94,2 NPR-MIRS-IMG_v11r4_npp_s202106300127066_e202106300127383_c202106300201000.nc output_1.nc\nCreated by MIRS Version 11.4" ; + :processing_level = "NOAA Level 2 data" ; + :source = "SATMS_npp_d20210630_t0127066_e0127383_b50120_c20210630015713485030_oebc_ops.h5" ; + :time_coverage_start = "2021-06-30T01:27:06Z" ; + :time_coverage_end = "2021-06-30T01:27:38Z" ; + :cdm_data_type = "Swath" ; + :geospatial_lat_units = "degrees_north" ; + :geospatial_lon_units = "degrees_east" ; + :geospatial_lat_resolution = "100" ; + :geospatial_lon_resolution = "100" ; + :geospatial_first_scanline_first_fov_lat = 61.18f ; + :geospatial_first_scanline_first_fov_lon = 135.75f ; + :geospatial_first_scanline_last_fov_lat = 69.42f ; + :geospatial_first_scanline_last_fov_lon = -171.14f ; + :geospatial_last_scanline_first_fov_lat = 62.38f ; + :geospatial_last_scanline_first_fov_lon = 133.09f ; + :geospatial_last_scanline_last_fov_lat = 71.1f ; + :geospatial_last_scanline_last_fov_lon = -170.7f ; + :total_number_retrievals = 1152 ; + :percentage_optimal_retrievals = 0.3125f ; + :percentage_suboptimal_retrievals = 0.6875f ; + :percentage_bad_retrievals = 0.f ; + :start_orbit_number = 50120 ; + :end_orbit_number = 50120 ; + :id = "ndepgsl-op-13_2021-06-30T02:01:08Z_0000001764860342_SATMS_npp_d20210630_t0127066_e0127383_b50120_c20210630015713485030_oebc_ops.h5" ; + :NCO = "netCDF Operators version 5.0.6 (Homepage = http://nco.sf.net, Code = http://github.com/nco/nco)" ; +data: + + Atm_type = + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999 ; + + BT = + 22327, 22553, 24584, 25405, 25405, 24477, 23433, 23044, 22874, 22877, + 23030, 23657, 24728, 25747, 26557, 24500, 26503, 26678, 26213, 25708, + 25076, 24388, + 21454, 21778, 24626, 25336, 25317, 24339, 23404, 22988, 22882, 22870, + 23110, 23650, 24616, 25911, 26815, 23579, 26248, 26653, 26262, 25888, + 25060, 24489, + 20583, 20703, 24778, 25420, 25275, 24254, 23307, 22967, 22884, 22926, + 23216, 23669, 24735, 26131, 27203, 23515, 26303, 26641, 26241, 25768, + 25210, 24617, + 18802, 18765, 24518, 25360, 25151, 24143, 23200, 22978, 22862, 22898, + 23093, 23794, 24742, 26033, 26623, 23113, 26509, 26614, 26200, 25725, + 25061, 24510, + 18595, 18017, 24687, 25325, 25048, 24009, 23120, 22939, 22865, 22946, + 23224, 23879, 24829, 26147, 27059, 22539, 26383, 26362, 25866, 25253, + 24545, 23854, + 20793, 21116, 23628, 24840, 25233, 24424, 23390, 23045, 22901, 22904, + 23094, 23688, 24648, 25831, 26676, 22575, 25726, 26585, 26195, 25717, + 25064, 24363, + 21377, 21586, 24734, 25380, 25331, 24369, 23401, 23045, 22868, 22934, + 23189, 23708, 24567, 25960, 26841, 23692, 26248, 26683, 26257, 25791, + 25193, 24557, + 21381, 21420, 25117, 25561, 25226, 24274, 23292, 22993, 22911, 22893, + 23138, 23665, 24838, 26055, 26847, 24056, 26334, 26585, 26140, 25814, + 25120, 24504, + 19667, 19643, 24743, 25396, 25127, 24148, 23195, 22934, 22871, 22917, + 23140, 23828, 24779, 26136, 27013, 23313, 26553, 26566, 26085, 25653, + 25054, 24377, + 18796, 18249, 24810, 25396, 25050, 24028, 23159, 22958, 22904, 22927, + 23254, 23769, 24910, 26096, 27232, 22485, 26377, 26435, 25985, 25404, + 24735, 24056, + 20498, 20619, 24167, 25066, 25273, 24456, 23441, 23055, 22845, 22994, + 23204, 23619, 24720, 25987, 26769, 23008, 26075, 26562, 26192, 25755, + 25061, 24573, + 21974, 22034, 24987, 25431, 25308, 24348, 23367, 23050, 22914, 22895, + 23120, 23721, 24623, 25823, 26791, 23833, 26149, 26594, 26254, 25766, + 25196, 24606, + 22286, 22455, 25270, 25612, 25241, 24266, 23347, 23022, 22882, 23061, + 23197, 23677, 24769, 25901, 26953, 24352, 26322, 26612, 26150, 25802, + 25136, 24695, + 20622, 20769, 25003, 25495, 25182, 24147, 23257, 23022, 22900, 23025, + 23304, 23842, 24848, 26110, 26759, 23649, 26478, 26571, 26192, 25728, + 25063, 24466, + 19327, 18919, 25100, 25537, 25062, 24009, 23201, 22992, 22929, 23026, + 23256, 23809, 24836, 26290, 27335, 23116, 26365, 26440, 25947, 25510, + 24884, 24272, + 21249, 21254, 24759, 25349, 25313, 24440, 23466, 23067, 22965, 23009, + 23255, 23621, 24619, 25850, 27194, 24105, 26399, 26501, 26057, 25603, + 24990, 24414, + 22658, 22722, 24961, 25453, 25265, 24357, 23360, 23024, 22940, 23014, + 23245, 23711, 24671, 25754, 27012, 23734, 26119, 26526, 26154, 25713, + 25146, 24615, + 22959, 23177, 25363, 25634, 25235, 24239, 23334, 23023, 22907, 23019, + 23186, 23742, 24777, 26127, 26904, 24337, 26303, 26572, 26112, 25707, + 25029, 24396, + 21486, 21662, 25154, 25560, 25188, 24203, 23268, 23049, 22949, 23043, + 23274, 23804, 24848, 26228, 27015, 24075, 26566, 26510, 26126, 25620, + 24987, 24489, + 19966, 19685, 25024, 25462, 25036, 24029, 23177, 23025, 22970, 23030, + 23250, 23833, 24928, 26123, 26876, 23233, 26472, 26459, 26075, 25576, + 25050, 24462, + 22101, 22142, 24626, 25300, 25300, 24421, 23492, 23108, 22989, 22996, + 23273, 23624, 24619, 26074, 26893, 23896, 26110, 26501, 26128, 25586, + 25049, 24481, + 22985, 23104, 25074, 25606, 25321, 24344, 23442, 23067, 22944, 22979, + 23243, 23825, 24698, 26006, 27066, 24230, 26434, 26519, 26068, 25716, + 25108, 24535, + 23325, 23451, 25676, 25810, 25325, 24232, 23370, 23076, 22937, 23023, + 23175, 23773, 24758, 26123, 26956, 25236, 26625, 26515, 26135, 25720, + 25029, 24403, + 22237, 22340, 25362, 25622, 25147, 24160, 23253, 23042, 22990, 22986, + 23282, 23852, 24876, 26304, 27106, 24686, 26632, 26416, 25971, 25497, + 24880, 24287, + 20683, 20418, 24990, 25420, 25000, 24034, 23200, 23015, 22971, 23025, + 23331, 23892, 24923, 26416, 26846, 23170, 26333, 26315, 25872, 25491, + 24835, 24308, + 22590, 22687, 24808, 25303, 25314, 24410, 23474, 23116, 22966, 23030, + 23196, 23638, 24636, 25891, 26881, 24034, 26215, 26377, 25982, 25584, + 24962, 24423, + 23025, 23150, 25193, 25587, 25349, 24383, 23407, 23090, 22970, 22979, + 23231, 23757, 24766, 26025, 26894, 24597, 26450, 26373, 25997, 25490, + 24876, 24390, + 23403, 23510, 25850, 25891, 25304, 24246, 23363, 23124, 22967, 23032, + 23266, 23794, 24782, 26245, 26928, 25768, 26897, 26420, 25934, 25489, + 24899, 24318, + 22797, 22937, 25424, 25596, 25175, 24149, 23293, 23056, 22994, 23090, + 23257, 23835, 24904, 25935, 27034, 24841, 26579, 26436, 25983, 25501, + 24902, 24358, + 21439, 21265, 25131, 25468, 25006, 23978, 23199, 23067, 23015, 23028, + 23336, 23936, 24811, 26224, 27077, 23546, 26454, 26276, 25912, 25458, + 24844, 24264 ; + + CLW = + 4, 0, 0, 2, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 2, 7, 5, 0 ; + + ChanSel = + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; + + ChiSqr = + 0.3278425, 0.1270331, 0.5191541, 0.1502331, 0.1583424, + 0.2056985, 0.09662999, 0.4452049, 0.1618346, 0.2081715, + 0.7202161, 0.7179015, 0.3983652, 0.2625816, 0.9757569, + 0.264237, 0.8345357, 0.2943406, 0.1115318, 0.5097764, + 0.169713, 0.409044, 0.1654734, 0.1077542, 0.3691869, + 0.6970016, 0.4721045, 0.4847079, 0.4702559, 0.4022827 ; + + CldBase = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + CldThick = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + CldTop = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + Emis = + 7664, 7844, 7419, 7437, 7450, 7460, 7470, 7477, 7483, 7503, 7503, 7503, + 7503, 7503, 7503, 8176, 8189, 8189, 8189, 8189, 8189, 8189, + 7207, 7421, 7496, 7509, 7519, 7526, 7533, 7537, 7542, 7557, 7557, 7557, + 7557, 7557, 7557, 7808, 8056, 8056, 8056, 8056, 8056, 8056, + 6756, 7105, 7499, 7507, 7513, 7517, 7522, 7524, 7527, 7535, 7535, 7535, + 7535, 7535, 7535, 7803, 7831, 7831, 7831, 7831, 7831, 7831, + 5775, 6024, 6681, 6711, 6732, 6748, 6764, 6774, 6785, 6819, 6819, 6819, + 6819, 6819, 6819, 7102, 7947, 8063, 8063, 8063, 8063, 8063, + 5670, 5923, 6789, 6820, 6841, 6857, 6873, 6883, 6895, 6928, 6928, 6928, + 6928, 6928, 6928, 7000, 8029, 8141, 8141, 8141, 8141, 8141, + 7151, 7229, 6826, 6859, 6882, 6899, 6916, 6927, 6939, 6975, 6975, 6975, + 6975, 6975, 6975, 7525, 8182, 8182, 8182, 8182, 8182, 8182, + 7152, 7402, 7560, 7571, 7579, 7584, 7590, 7593, 7597, 7609, 7609, 7609, + 7609, 7609, 7609, 7851, 8010, 8010, 8010, 8010, 8010, 8010, + 7142, 7510, 7958, 7957, 7956, 7955, 7955, 7954, 7953, 7952, 7952, 7952, + 7952, 7952, 7952, 8116, 7899, 7898, 7898, 7898, 7899, 7899, + 6216, 6461, 7131, 7159, 7178, 7193, 7207, 7217, 7227, 7258, 7258, 7258, + 7258, 7258, 7258, 7452, 8253, 8358, 8358, 8358, 8358, 8358, + 5806, 6037, 6985, 7012, 7032, 7046, 7060, 7069, 7080, 7111, 7111, 7111, + 7111, 7111, 7111, 7010, 8103, 8208, 8208, 8208, 8208, 8208, + 6895, 7148, 7235, 7256, 7270, 7281, 7291, 7298, 7305, 7328, 7328, 7328, + 7328, 7328, 7328, 7765, 8086, 8086, 8086, 8086, 8086, 8086, + 7574, 7861, 8078, 8077, 8077, 8077, 8077, 8076, 8076, 8075, 8075, 8075, + 8075, 8075, 8075, 8248, 8048, 8048, 8048, 8048, 8048, 8049, + 7592, 7901, 8200, 8197, 8194, 8192, 8190, 8188, 8187, 8183, 8183, 8183, + 8183, 8183, 8183, 8303, 8039, 8039, 8039, 8039, 8039, 8039, + 6567, 6941, 7499, 7501, 7503, 7504, 7504, 7505, 7505, 7507, 7507, 7507, + 7507, 7507, 7507, 7602, 7570, 7570, 7570, 7570, 7570, 7570, + 5890, 6418, 7360, 7359, 7359, 7358, 7357, 7357, 7356, 7355, 7355, 7355, + 7355, 7355, 7355, 7486, 7309, 7309, 7309, 7309, 7309, 7310, + 7080, 7410, 7679, 7692, 7701, 7708, 7714, 7718, 7723, 7737, 7737, 7737, + 7737, 7737, 7737, 8135, 8209, 8209, 8209, 8209, 8209, 8209, + 7903, 8112, 8143, 8142, 8141, 8140, 8140, 8139, 8138, 8137, 8137, 8137, + 8137, 8137, 8137, 8257, 8082, 8081, 8081, 8082, 8082, 8082, + 7913, 8168, 8362, 8354, 8349, 8345, 8341, 8338, 8335, 8326, 8326, 8326, + 8326, 8326, 8326, 8344, 8036, 8036, 8036, 8036, 8036, 8036, + 6944, 7284, 7726, 7726, 7726, 7726, 7726, 7725, 7725, 7725, 7725, 7725, + 7725, 7725, 7725, 7821, 7720, 7720, 7720, 7720, 7720, 7720, + 6145, 6574, 7317, 7317, 7317, 7316, 7316, 7315, 7315, 7315, 7315, 7315, + 7315, 7315, 7315, 7356, 7295, 7295, 7295, 7295, 7296, 7296, + 7584, 7766, 7681, 7696, 7706, 7713, 7720, 7724, 7729, 7745, 7745, 7745, + 7745, 7745, 7745, 8074, 8262, 8262, 8262, 8262, 8262, 8262, + 7987, 8130, 8038, 8046, 8052, 8056, 8062, 8065, 8068, 8077, 8077, 8077, + 8077, 8077, 8077, 8367, 8397, 8397, 8397, 8397, 8397, 8397, + 7878, 8192, 8503, 8494, 8487, 8482, 8477, 8474, 8470, 8460, 8460, 8460, + 8460, 8460, 8460, 8519, 8101, 8101, 8101, 8101, 8101, 8101, + 7298, 7641, 8057, 8054, 8052, 8050, 8048, 8047, 8045, 8042, 8042, 8042, + 8042, 8042, 8042, 8144, 7915, 7915, 7915, 7915, 7915, 7915, + 6567, 6916, 7470, 7467, 7465, 7463, 7462, 7460, 7459, 7455, 7455, 7455, + 7455, 7455, 7455, 7416, 7333, 7333, 7333, 7333, 7333, 7333, + 7840, 8059, 8034, 8041, 8045, 8049, 8052, 8054, 8056, 8064, 8064, 8064, + 8064, 8064, 8064, 8365, 8304, 8303, 8303, 8304, 8304, 8304, + 7912, 8034, 8095, 8105, 8113, 8118, 8124, 8127, 8132, 8143, 8143, 8143, + 8143, 8143, 8143, 8442, 8605, 8681, 8681, 8681, 8681, 8681, + 7838, 8000, 8345, 8351, 8356, 8359, 8364, 8366, 8368, 8376, 8376, 8376, + 8376, 8376, 8376, 8510, 8633, 8633, 8633, 8633, 8633, 8633, + 7797, 7948, 8188, 8201, 8210, 8217, 8224, 8228, 8234, 8249, 8249, 8249, + 8249, 8249, 8249, 8445, 8750, 8825, 8825, 8825, 8825, 8825, + 6896, 7206, 7683, 7675, 7670, 7666, 7662, 7659, 7657, 7648, 7648, 7648, + 7648, 7648, 7648, 7528, 7365, 7365, 7365, 7365, 7365, 7365 ; + + Freq = 23.8, 31.4, 50.3, 51.76, 52.8, 53.596, 54.4, 54.94, 55.5, 57.29, + 57.29, 57.29, 57.29, 57.29, 57.29, 88.2, 165.5, 183.31, 183.31, 183.31, + 183.31, 183.31 ; + + GWP = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + IWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + LWP = + 4, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, 0, -998, -998, -998, + -998, -998, 7, -998, -998 ; + + LZ_angle = + 50.15001, 53.07, 56.06001, 59.21, 62.46, + 50.15001, 53.07, 56.08001, 59.18999, 62.47999, + 50.16999, 53.05, 56.09, 59.18999, 62.46998, + 50.16999, 53.08001, 56.08001, 59.21, 62.45, + 50.15001, 53.08001, 56.07, 59.2, 62.47999, + 50.15999, 53.07, 56.09, 59.18001, 62.48999 ; + + Latitude = + 69.59, 69.64, 69.67, 69.67, 69.62, + 69.9, 69.95, 69.98, 69.98, 69.93, + 70.21, 70.26, 70.29, 70.29, 70.24, + 70.52, 70.57, 70.6, 70.6, 70.55, + 70.83, 70.88, 70.91, 70.91, 70.85, + 71.14, 71.2, 71.23, 71.22, 71.16 ; + + Longitude = + 177.29, 179.29, -178.47, -175.86, -172.85, + 177.19, 179.21, -178.5, -175.88, -172.78, + 177.1, 179.13, -178.52, -175.87, -172.75, + 177, 179.07, -178.57, -175.85, -172.71, + 176.88, 179, -178.61, -175.85, -172.63, + 176.78, 178.92, -178.63, -175.86, -172.56 ; + + Orb_mode = 0, 0, 0, 0, 0, 0 ; + + Polo = 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3 ; + + PrecipType = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + Prob_SF = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + Qc = + 0, 0, 160, 8192, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 32, 4096, + 0, 0, 0, 4096, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 0, 4096, + 0, 0, 0, 4096, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 8192, + 0, 0, 128, 0, + 0, 0, 128, 0, + 0, 0, 128, 0, + 1, 0, 144, 0, + 0, 0, 32, 4096, + 0, 0, 160, 8192, + 0, 0, 32, 4096, + 1, 0, 144, 0 ; + + RAzi_angle = + -95.03, -93.16, -91.06, -88.61, -85.79, + -95.07, -93.17, -91.02, -88.56, -85.65, + -95.09, -93.18, -90.97, -88.48, -85.54, + -95.12, -93.17, -90.95, -88.38, -85.42, + -95.18, -93.17, -90.92, -88.3, -85.27, + -95.21, -93.18, -90.86, -88.25, -85.12 ; + + RFlag = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + RR = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + RWP = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + SFR = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SIce = + _, 58, 52, 0, 0, + 52, 58, 62, 38, 0, + 52, 70, 72, 0, 0, + 60, 76, 78, 56, 0, + 68, _, 80, 66, 46, + 76, 76, _, 76, 0 ; + + SIce_FY = + _, 58, 52, 0, 0, + 52, 58, 62, 38, 0, + 52, 70, 72, 0, 0, + 60, 76, 78, 56, 0, + 68, _, 80, 66, 45, + 76, 76, _, 76, 0 ; + + SIce_MY = + _, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, _, 0, 0, 0, + 0, 0, _, 0, 0 ; + + SWE = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + SWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SZ_angle = + 47.68, 48.01, 48.39, 48.83, 49.36, + 47.95, 48.28, 48.66, 49.1, 49.63, + 48.23, 48.56, 48.93, 49.37, 49.9, + 48.51, 48.83, 49.21, 49.64, 50.16, + 48.78, 49.11, 49.48, 49.91, 50.43, + 49.06, 49.38, 49.76, 50.18, 50.7 ; + + ScanTime_UTC = 5229.00048828125, 5234.00048828125, 5240.00048828125, + 5245.00048828125, 5250.00048828125, 5256.00048828125 ; + + ScanTime_dom = 30, 30, 30, 30, 30, 30 ; + + ScanTime_doy = 181, 181, 181, 181, 181, 181 ; + + ScanTime_hour = 1, 1, 1, 1, 1, 1 ; + + ScanTime_minute = 27, 27, 27, 27, 27, 27 ; + + ScanTime_month = 6, 6, 6, 6, 6, 6 ; + + ScanTime_second = 9, 14, 20, 25, 30, 36 ; + + ScanTime_year = 2021, 2021, 2021, 2021, 2021, 2021 ; + + Sfc_type = + 2, 1, 1, 0, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, + 1, 2, 1, 1, 1, + 1, 1, 2, 1, 0 ; + + Snow = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + SnowGS = + 0, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, 0, _, _, _, + _, _, 0, _, _ ; + + SurfM = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + SurfP = + 10046, 9930, 9930, 9930, 9930, + 9930, 9930, 9930, 9930, 9930, + 9930, 9930, 9930, 9930, 9930, + 9930, 9930, 9930, 9930, 9930, + 9930, 10092, 9930, 9930, 9930, + 9930, 10084, 9796, 10084, 9930 ; + + TPW = + 109, 107, 108, 103, 101, + 89, 107, 110, 106, 96, + 111, 106, 108, 123, 116, + 122, 110, 108, 130, 123, + 103, 119, 128, 133, 124, + 126, 110, 124, 95, 130 ; + + TSkin = + 27460, 27593, 27982, 27901, 27718, + 27122, 27666, 27847, 27840, 27733, + 27385, 27513, 27718, 28090, 28389, + 27715, 27420, 27685, 27993, 28310, + 27460, 27463, 27945, 27978, 27967, + 27305, 27795, 28165, 27668, 28025 ; + + WindDir = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindSp = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindU = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindV = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + YM = + 22619, 22707, 24720, 25360, 25272, 24389, 23362, 22925, 22768, 22824, + 22970, 23608, 24653, 25651, 26487, 24562, 26332, 26521, 26087, 25591, + 24965, 24324, + 21757, 21949, 24710, 25252, 25172, 24250, 23328, 22866, 22775, 22816, + 23047, 23598, 24539, 25816, 26741, 23607, 26072, 26493, 26135, 25772, + 24947, 24425, + 20878, 20881, 24797, 25290, 25118, 24163, 23227, 22841, 22775, 22870, + 23150, 23614, 24653, 26029, 27129, 23483, 26110, 26471, 26109, 25648, + 25094, 24552, + 19142, 19003, 24470, 25177, 24984, 24043, 23117, 22850, 22750, 22842, + 23026, 23736, 24656, 25926, 26548, 23016, 26297, 26435, 26060, 25604, + 24942, 24440, + 19011, 18355, 24562, 25105, 24873, 23904, 23031, 22809, 22753, 22889, + 23157, 23818, 24738, 26038, 26982, 22368, 26160, 26176, 25724, 25128, + 24421, 23778, + 21085, 21270, 23764, 24795, 25100, 24336, 23319, 22926, 22795, 22851, + 23034, 23639, 24573, 25735, 26606, 22637, 25556, 26428, 26069, 25600, + 24952, 24299, + 21680, 21757, 24818, 25296, 25186, 24280, 23326, 22923, 22761, 22880, + 23126, 23656, 24490, 25865, 26768, 23720, 26072, 26523, 26131, 25675, + 25080, 24493, + 21676, 21598, 25136, 25431, 25069, 24183, 23212, 22868, 22802, 22837, + 23072, 23610, 24756, 25954, 26773, 24024, 26141, 26415, 26007, 25694, + 25004, 24440, + 20007, 19881, 24695, 25213, 24960, 24048, 23112, 22806, 22759, 22861, + 23073, 23770, 24693, 26029, 26938, 23216, 26341, 26387, 25946, 25533, + 24935, 24307, + 19212, 18587, 24685, 25176, 24875, 23923, 23070, 22828, 22792, 22870, + 23187, 23707, 24819, 25987, 27156, 22314, 26154, 26250, 25843, 25279, + 24611, 23980, + 20790, 20773, 24303, 25021, 25140, 24368, 23370, 22936, 22739, 22941, + 23144, 23570, 24645, 25891, 26698, 23070, 25904, 26404, 26066, 25638, + 24949, 24509, + 22277, 22205, 25071, 25347, 25163, 24259, 23291, 22928, 22807, 22841, + 23057, 23669, 24546, 25728, 26717, 23861, 25973, 26434, 26128, 25650, + 25083, 24542, + 22581, 22633, 25289, 25482, 25084, 24175, 23267, 22896, 22773, 23005, + 23131, 23622, 24687, 25800, 26879, 24320, 26129, 26442, 26018, 25682, + 25020, 24630, + 20962, 21007, 24955, 25312, 25015, 24047, 23174, 22894, 22788, 22969, + 23237, 23784, 24762, 26003, 26684, 23552, 26266, 26392, 26053, 25607, + 24944, 24396, + 19743, 19257, 24975, 25318, 24887, 23904, 23112, 22862, 22818, 22969, + 23189, 23747, 24745, 26181, 27259, 22945, 26142, 26254, 25804, 25385, + 24760, 24196, + 21541, 21408, 24895, 25304, 25180, 24352, 23395, 22948, 22859, 22956, + 23195, 23572, 24544, 25754, 27123, 24167, 26228, 26344, 25931, 25486, + 24879, 24350, + 22961, 22893, 25045, 25369, 25120, 24268, 23284, 22902, 22833, 22960, + 23182, 23659, 24594, 25659, 26938, 23762, 25943, 26366, 26028, 25598, + 25033, 24551, + 23254, 23355, 25382, 25504, 25078, 24148, 23254, 22897, 22798, 22963, + 23120, 23687, 24695, 26026, 26831, 24305, 26110, 26401, 25979, 25587, + 24913, 24331, + 21826, 21900, 25106, 25377, 25021, 24103, 23185, 22921, 22837, 22987, + 23206, 23746, 24762, 26121, 26940, 23978, 26354, 26331, 25987, 25500, + 24868, 24419, + 20382, 20023, 24899, 25243, 24861, 23924, 23088, 22895, 22858, 22973, + 23183, 23771, 24837, 26014, 26800, 23062, 26249, 26273, 25932, 25451, + 24926, 24386, + 22393, 22296, 24762, 25255, 25167, 24333, 23421, 22989, 22883, 22943, + 23213, 23575, 24544, 25978, 26822, 23958, 25940, 26344, 26001, 25469, + 24937, 24417, + 23288, 23275, 25158, 25522, 25176, 24255, 23366, 22945, 22837, 22926, + 23180, 23773, 24621, 25910, 26992, 24258, 26257, 26359, 25941, 25600, + 24995, 24471, + 23620, 23629, 25695, 25681, 25168, 24141, 23290, 22951, 22829, 22967, + 23109, 23718, 24676, 26022, 26882, 25204, 26432, 26345, 26003, 25600, + 24913, 24338, + 22577, 22578, 25315, 25439, 24980, 24060, 23170, 22914, 22879, 22930, + 23215, 23794, 24790, 26197, 27031, 24589, 26420, 26237, 25832, 25377, + 24761, 24218, + 21099, 20756, 24865, 25200, 24825, 23929, 23111, 22885, 22859, 22968, + 23264, 23830, 24832, 26307, 26770, 22999, 26110, 26129, 25729, 25366, + 24711, 24232, + 22882, 22841, 24944, 25258, 25181, 24322, 23403, 22997, 22860, 22977, + 23136, 23589, 24561, 25795, 26810, 24096, 26044, 26220, 25856, 25467, + 24851, 24359, + 23328, 23321, 25277, 25503, 25204, 24294, 23331, 22968, 22863, 22926, + 23168, 23705, 24689, 25929, 26821, 24625, 26274, 26213, 25870, 25374, + 24763, 24326, + 23698, 23688, 25869, 25762, 25147, 24155, 23283, 22998, 22858, 22976, + 23200, 23739, 24700, 26144, 26854, 25735, 26704, 26250, 25801, 25369, + 24783, 24253, + 23137, 23175, 25376, 25413, 25008, 24049, 23210, 22928, 22882, 23034, + 23189, 23777, 24818, 25828, 26959, 24744, 26368, 26257, 25844, 25381, + 24783, 24288, + 21855, 21603, 25006, 25248, 24831, 23873, 23110, 22937, 22903, 22971, + 23269, 23874, 24720, 26115, 27001, 23375, 26231, 26091, 25769, 25333, + 24720, 24188 ; +} diff --git a/utils/test/testdata/icec_mirs_snpp_2.cdl b/utils/test/testdata/icec_mirs_snpp_2.cdl new file mode 100644 index 000000000..fd540b192 --- /dev/null +++ b/utils/test/testdata/icec_mirs_snpp_2.cdl @@ -0,0 +1,961 @@ +netcdf output_2 { +dimensions: + Scanline = 6 ; + Field_of_view = 5 ; + Channel = 22 ; + Qc_dim = 4 ; +variables: + short Atm_type(Scanline, Field_of_view) ; + Atm_type:description = "type of atmosphere:currently missing" ; + Atm_type:coordinates = "Longitude Latitude" ; + short BT(Scanline, Field_of_view, Channel) ; + BT:long_name = "Channel Temperature (K)" ; + BT:units = "Kelvin" ; + BT:coordinates = "Longitude Latitude Freq" ; + BT:scale_factor = 0.01 ; + BT:_FillValue = -999s ; + BT:valid_range = 0, 50000 ; + short CLW(Scanline, Field_of_view) ; + CLW:long_name = "Cloud liquid Water (mm)" ; + CLW:units = "mm" ; + CLW:coordinates = "Longitude Latitude" ; + CLW:scale_factor = 0.01 ; + CLW:_FillValue = -999s ; + CLW:valid_range = 0, 10000 ; + short ChanSel(Scanline, Field_of_view, Channel) ; + ChanSel:long_name = "Channels Selection Used in Retrieval" ; + ChanSel:units = "1" ; + ChanSel:coordinates = "Longitude Latitude Freq" ; + ChanSel:_FillValue = -999s ; + ChanSel:valid_range = 0, 1 ; + float ChiSqr(Scanline, Field_of_view) ; + ChiSqr:description = "Convergence rate: <3-good,>10-bad" ; + ChiSqr:units = "1" ; + ChiSqr:coordinates = "Longitude Latitude" ; + ChiSqr:_FillValue = -999.f ; + ChiSqr:valid_range = 0.f, 1000.f ; + short CldBase(Scanline, Field_of_view) ; + CldBase:long_name = "Cloud Base Pressure" ; + CldBase:scale_factor = 0.1 ; + CldBase:coordinates = "Longitude Latitude" ; + short CldThick(Scanline, Field_of_view) ; + CldThick:long_name = "Cloud Thickness" ; + CldThick:scale_factor = 0.1 ; + CldThick:coordinates = "Longitude Latitude" ; + short CldTop(Scanline, Field_of_view) ; + CldTop:long_name = "Cloud Top Pressure" ; + CldTop:scale_factor = 0.1 ; + CldTop:coordinates = "Longitude Latitude" ; + short Emis(Scanline, Field_of_view, Channel) ; + Emis:long_name = "Channel Emissivity" ; + Emis:units = "1" ; + Emis:coordinates = "Longitude Latitude Freq" ; + Emis:scale_factor = 0.0001 ; + Emis:_FillValue = -999s ; + Emis:valid_range = 0, 10000 ; + float Freq(Channel) ; + Freq:description = "Central Frequencies (GHz)" ; + short GWP(Scanline, Field_of_view) ; + GWP:long_name = "Graupel Water Path (mm)" ; + GWP:units = "mm" ; + GWP:coordinates = "Longitude Latitude" ; + GWP:scale_factor = 0.01 ; + GWP:_FillValue = -999s ; + GWP:valid_range = 0, 10000 ; + short IWP(Scanline, Field_of_view) ; + IWP:long_name = "Ice Water Path (mm)" ; + IWP:units = "mm" ; + IWP:coordinates = "Longitude Latitude" ; + IWP:scale_factor = 0.01 ; + IWP:_FillValue = -999s ; + IWP:valid_range = 0, 10000 ; + short LWP(Scanline, Field_of_view) ; + LWP:long_name = "Liquid Water Path (mm)" ; + LWP:units = "mm" ; + LWP:coordinates = "Longitude Latitude" ; + LWP:scale_factor = 0.01 ; + LWP:_FillValue = -999s ; + LWP:valid_range = 0, 10000 ; + float LZ_angle(Scanline, Field_of_view) ; + LZ_angle:long_name = "Local Zenith Angle degree" ; + LZ_angle:units = "degrees" ; + LZ_angle:coordinates = "Longitude Latitude" ; + LZ_angle:_FillValue = -999.f ; + LZ_angle:valid_range = -70.f, 70.f ; + float Latitude(Scanline, Field_of_view) ; + Latitude:long_name = "Latitude of the view (-90,90)" ; + Latitude:units = "degrees" ; + Latitude:_FillValue = -999.f ; + Latitude:valid_range = -90.f, 90.f ; + float Longitude(Scanline, Field_of_view) ; + Longitude:long_name = "Longitude of the view (-180,180)" ; + Longitude:units = "degrees" ; + Longitude:_FillValue = -999.f ; + Longitude:valid_range = -180.f, 180.f ; + short Orb_mode(Scanline) ; + Orb_mode:description = "0-ascending,1-descending" ; + Orb_mode:units = "1" ; + Orb_mode:_FillValue = -999s ; + Orb_mode:valid_range = 0, 1 ; + short Polo(Channel) ; + Polo:description = "Polarizations" ; + short PrecipType(Scanline, Field_of_view) ; + PrecipType:long_name = "Precipitation Type (Frozen/Liquid)" ; + PrecipType:coordinates = "Longitude Latitude" ; + short Prob_SF(Scanline, Field_of_view) ; + Prob_SF:long_name = "Probability of falling snow (%)" ; + Prob_SF:units = "percent" ; + Prob_SF:coordinates = "Longitude Latitude" ; + Prob_SF:_FillValue = -999s ; + Prob_SF:valid_range = 0, 100 ; + short Qc(Scanline, Field_of_view, Qc_dim) ; + Qc:description = "Qc: 0-good, 1-usable with problem, 2-bad" ; + float RAzi_angle(Scanline, Field_of_view) ; + RAzi_angle:long_name = "Relative Azimuth Angle 0-360 degree" ; + RAzi_angle:coordinates = "Longitude Latitude" ; + short RFlag(Scanline, Field_of_view) ; + RFlag:long_name = "Rain Flag" ; + RFlag:coordinates = "Longitude Latitude" ; + short RR(Scanline, Field_of_view) ; + RR:long_name = "Rain Rate (mm/hr)" ; + RR:units = "mm/hr" ; + RR:coordinates = "Longitude Latitude" ; + RR:scale_factor = 0.1 ; + RR:_FillValue = -999s ; + RR:valid_range = 0, 1000 ; + short RWP(Scanline, Field_of_view) ; + RWP:long_name = "Rain Water Path (mm)" ; + RWP:units = "mm" ; + RWP:coordinates = "Longitude Latitude" ; + RWP:scale_factor = 0.01 ; + RWP:_FillValue = -999s ; + RWP:valid_range = 0, 10000 ; + short SFR(Scanline, Field_of_view) ; + SFR:long_name = "Snow Fall Rate in mm/hr" ; + SFR:units = "mm/hr" ; + SFR:coordinates = "Longitude Latitude" ; + SFR:scale_factor = 0.01 ; + SFR:_FillValue = -999s ; + SFR:valid_range = 0, 10000 ; + short SIce(Scanline, Field_of_view) ; + SIce:long_name = "Sea Ice Concentration (%)" ; + SIce:units = "percent" ; + SIce:coordinates = "Longitude Latitude" ; + SIce:_FillValue = -999s ; + SIce:valid_range = 0, 100 ; + short SIce_FY(Scanline, Field_of_view) ; + SIce_FY:long_name = "First-Year Sea Ice Concentration (%)" ; + SIce_FY:units = "percent" ; + SIce_FY:coordinates = "Longitude Latitude" ; + SIce_FY:_FillValue = -999s ; + SIce_FY:valid_range = 0, 100 ; + short SIce_MY(Scanline, Field_of_view) ; + SIce_MY:long_name = "Multi-Year Sea Ice Concentration (%)" ; + SIce_MY:units = "percent" ; + SIce_MY:coordinates = "Longitude Latitude" ; + SIce_MY:_FillValue = -999s ; + SIce_MY:valid_range = 0, 100 ; + short SWE(Scanline, Field_of_view) ; + SWE:long_name = "Snow Water Equivalent (cm)" ; + SWE:units = "cm" ; + SWE:coordinates = "Longitude Latitude" ; + SWE:scale_factor = 0.01 ; + SWE:_FillValue = -999s ; + SWE:valid_range = 0, 10000 ; + short SWP(Scanline, Field_of_view) ; + SWP:long_name = "Snow Water Path" ; + SWP:units = "mm" ; + SWP:coordinates = "Longitude Latitude" ; + SWP:scale_factor = 0.01 ; + SWP:_FillValue = -999s ; + SWP:valid_range = 0, 10000 ; + float SZ_angle(Scanline, Field_of_view) ; + SZ_angle:long_name = "Solar Zenith Angle (-90,90) degree" ; + SZ_angle:coordinates = "Longitude Latitude" ; + double ScanTime_UTC(Scanline) ; + ScanTime_UTC:long_name = "Number of seconds since 00:00:00 UTC" ; + ScanTime_UTC:units = "seconds" ; + ScanTime_UTC:_FillValue = -999. ; + ScanTime_UTC:valid_range = 0., 86400. ; + short ScanTime_dom(Scanline) ; + ScanTime_dom:long_name = "Calendar day of the month 1-31" ; + ScanTime_dom:units = "days" ; + ScanTime_dom:_FillValue = -999s ; + ScanTime_dom:valid_range = 1, 31 ; + short ScanTime_doy(Scanline) ; + ScanTime_doy:long_name = "julian day 1-366" ; + ScanTime_doy:units = "days" ; + ScanTime_doy:_FillValue = -999s ; + ScanTime_doy:valid_range = 1, 366 ; + short ScanTime_hour(Scanline) ; + ScanTime_hour:long_name = "hour of the day 0-23" ; + ScanTime_hour:units = "hours" ; + ScanTime_hour:_FillValue = -999s ; + ScanTime_hour:valid_range = 0, 23 ; + short ScanTime_minute(Scanline) ; + ScanTime_minute:long_name = "minute of the hour 0-59" ; + ScanTime_minute:units = "minutes" ; + ScanTime_minute:_FillValue = -999s ; + ScanTime_minute:valid_range = 0, 59 ; + short ScanTime_month(Scanline) ; + ScanTime_month:long_name = "Calendar month 1-12" ; + ScanTime_month:units = "months" ; + ScanTime_month:_FillValue = -999s ; + ScanTime_month:valid_range = 1, 12 ; + short ScanTime_second(Scanline) ; + ScanTime_second:long_name = "second of the minute 0-59" ; + ScanTime_second:units = "seconds" ; + ScanTime_second:_FillValue = -999s ; + ScanTime_second:valid_range = 0, 59 ; + short ScanTime_year(Scanline) ; + ScanTime_year:long_name = "Calendar Year 20XX" ; + ScanTime_year:units = "years" ; + ScanTime_year:_FillValue = -999s ; + ScanTime_year:valid_range = 2011, 2050 ; + short Sfc_type(Scanline, Field_of_view) ; + Sfc_type:description = "type of surface:0-ocean,1-sea ice,2-land,3-snow" ; + Sfc_type:units = "1" ; + Sfc_type:coordinates = "Longitude Latitude" ; + Sfc_type:_FillValue = -999s ; + Sfc_type:valid_range = 0, 3 ; + short Snow(Scanline, Field_of_view) ; + Snow:long_name = "Snow Cover" ; + Snow:units = "1" ; + Snow:coordinates = "Longitude Latitude" ; + Snow:_FillValue = -999s ; + Snow:valid_range = 0, 1 ; + short SnowGS(Scanline, Field_of_view) ; + SnowGS:long_name = "Snow Grain Size (mm)" ; + SnowGS:units = "mm" ; + SnowGS:coordinates = "Longitude Latitude" ; + SnowGS:scale_factor = 0.01 ; + SnowGS:_FillValue = -999s ; + SnowGS:valid_range = 0, 2000 ; + short SurfM(Scanline, Field_of_view) ; + SurfM:long_name = "Surface Moisture" ; + SurfM:scale_factor = 0.1 ; + SurfM:coordinates = "Longitude Latitude" ; + short SurfP(Scanline, Field_of_view) ; + SurfP:long_name = "Surface Pressure (mb)" ; + SurfP:units = "millibars" ; + SurfP:coordinates = "Longitude Latitude" ; + SurfP:scale_factor = 0.1 ; + SurfP:_FillValue = -999s ; + SurfP:valid_range = 0, 12000 ; + short TPW(Scanline, Field_of_view) ; + TPW:long_name = "Total Precipitable Water (mm)" ; + TPW:units = "mm" ; + TPW:coordinates = "Longitude Latitude" ; + TPW:scale_factor = 0.1 ; + TPW:_FillValue = -999s ; + TPW:valid_range = 0, 2000 ; + short TSkin(Scanline, Field_of_view) ; + TSkin:long_name = "Skin Temperature (K)" ; + TSkin:units = "Kelvin" ; + TSkin:coordinates = "Longitude Latitude" ; + TSkin:scale_factor = 0.01 ; + TSkin:_FillValue = -999s ; + TSkin:valid_range = 0, 40000 ; + short WindDir(Scanline, Field_of_view) ; + WindDir:long_name = "Wind Direction" ; + WindDir:scale_factor = 0.01 ; + WindDir:coordinates = "Longitude Latitude" ; + short WindSp(Scanline, Field_of_view) ; + WindSp:long_name = "Wind Speed (m/s)" ; + WindSp:scale_factor = 0.01 ; + WindSp:coordinates = "Longitude Latitude" ; + short WindU(Scanline, Field_of_view) ; + WindU:long_name = "U-direction Wind Speed (m/s)" ; + WindU:scale_factor = 0.01 ; + WindU:coordinates = "Longitude Latitude" ; + short WindV(Scanline, Field_of_view) ; + WindV:long_name = "V-direction Wind Speed (m/s)" ; + WindV:scale_factor = 0.01 ; + WindV:coordinates = "Longitude Latitude" ; + short YM(Scanline, Field_of_view, Channel) ; + YM:long_name = "Un-Corrected Channel Temperature (K)" ; + YM:units = "Kelvin" ; + YM:coordinates = "Longitude Latitude Freq" ; + YM:scale_factor = 0.01 ; + YM:_FillValue = -999s ; + YM:valid_range = 0, 50000 ; + +// global attributes: + :missing_value = -999 ; + :notretrievedproduct_value = -888 ; + :noretrieval_value = -99 ; + :cdf_version = 4. ; + :alg_version = 4201 ; + :dap_version = "v11r4" ; + :Conventions = "CF-1.5" ; + :Metadata_Conventions = "CF-1.5, Unidata Dataset Discovery v1.0" ; + :standard_name_vocabulary = "CF Standard Name Table (version 17, 24 March 2011)" ; + :project = "Microwave Integrated Retrieval System" ; + :title = "MIRS IMG" ; + :summary = "MIRS imaging products including surface emissivity, TPW, CLW, RWP, IWP, LST." ; + :date_created = "2021-06-30T02:00:45Z" ; + :institution = "DOC/NOAA/NESDIS/NDE > NPOESS Data Exploitation, NESDIS, NOAA, U.S. Department of Commerce" ; + :naming_authority = "gov.noaa.nesdis.nde" ; + :production_site = "NSOF" ; + :production_environment = "OE" ; + :satellite_name = "NPP" ; + :instrument_name = "ATMS" ; + :creator_name = "DOC/NOAA/NESDIS/STAR > MIRS TEAM, Center for Satellite Applications and Research, NESDIS, NOAA, U.S. Department of Commerce" ; + :creator_email = "Christopher.Grassotti@noaa.gov, Quanhua.Liu@noaa.gov, Shu-yan.Liu@noaa.gov, ryan.honeyager@noaa.gov, Yong-Keun.Lee@noaa.gov " ; + :creator_url = "http://www.star.nesdis.noaa.gov/mirs" ; + :publisher_name = "DOC/NOAA/NESDIS/NDE > NPOESS Data Exploitation, NESDIS, NOAA, U.S. Department of Commerce" ; + :publisher_email = "NDE_POC@noaa.gov" ; + :publisher_url = "http://projects.osd.noaa.gov/NDE" ; + :Metadata_Link = "NDE product-specific output file name" ; + :references = "http://www.star.nesdis.noaa.gov/mirs/documentation.php" ; + :history = "Tue Jul 30 17:46:22 2024: ncks -d Scanline,1,12,2 -d Field_of_view,86,94,2 NPR-MIRS-IMG_v11r4_npp_s202106300127386_e202106300128103_c202106300200370.nc output_2.nc\nCreated by MIRS Version 11.4" ; + :processing_level = "NOAA Level 2 data" ; + :source = "SATMS_npp_d20210630_t0127386_e0128103_b50120_c20210630015746003377_oebc_ops.h5" ; + :time_coverage_start = "2021-06-30T01:27:38Z" ; + :time_coverage_end = "2021-06-30T01:28:10Z" ; + :cdm_data_type = "Swath" ; + :geospatial_lat_units = "degrees_north" ; + :geospatial_lon_units = "degrees_east" ; + :geospatial_lat_resolution = "100" ; + :geospatial_lon_resolution = "100" ; + :geospatial_first_scanline_first_fov_lat = 62.49f ; + :geospatial_first_scanline_first_fov_lon = 132.83f ; + :geospatial_first_scanline_last_fov_lat = 71.26f ; + :geospatial_first_scanline_last_fov_lon = -170.69f ; + :geospatial_last_scanline_first_fov_lat = 63.63f ; + :geospatial_last_scanline_first_fov_lon = 129.95f ; + :geospatial_last_scanline_last_fov_lat = 72.94f ; + :geospatial_last_scanline_last_fov_lon = -170.12f ; + :total_number_retrievals = 1152 ; + :percentage_optimal_retrievals = 0.1458333f ; + :percentage_suboptimal_retrievals = 0.8541667f ; + :percentage_bad_retrievals = 0.f ; + :start_orbit_number = 50120 ; + :end_orbit_number = 50120 ; + :id = "ndepgsl-op-11_2021-06-30T02:00:45Z_0000001250129361_SATMS_npp_d20210630_t0127386_e0128103_b50120_c20210630015746003377_oebc_ops.h5" ; + :NCO = "netCDF Operators version 5.0.6 (Homepage = http://nco.sf.net, Code = http://github.com/nco/nco)" ; +data: + + Atm_type = + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999 ; + + BT = + 22783, 22912, 24930, 25389, 25295, 24405, 23436, 23130, 22971, 22998, + 23178, 23801, 24680, 25968, 27054, 24428, 26216, 26467, 26087, 25650, + 25099, 24580, + 22992, 23085, 24983, 25439, 25236, 24334, 23387, 23066, 22996, 23026, + 23185, 23865, 24766, 26000, 27006, 24436, 26241, 26340, 25957, 25657, + 25037, 24441, + 23321, 23444, 25322, 25579, 25174, 24247, 23290, 23073, 23045, 23014, + 23191, 23712, 24764, 26090, 27147, 24914, 26432, 26228, 25901, 25462, + 24894, 24415, + 23199, 23336, 25346, 25579, 25090, 24108, 23318, 23088, 23025, 23041, + 23299, 23765, 24783, 26229, 26996, 24576, 26309, 26194, 25833, 25357, + 24878, 24287, + 22249, 22106, 25388, 25571, 24992, 23990, 23220, 23078, 23009, 22982, + 23324, 23975, 24971, 26157, 27281, 24225, 26407, 26237, 25857, 25437, + 24821, 24308, + 22827, 22891, 24868, 25399, 25335, 24425, 23462, 23134, 23030, 23014, + 23121, 23723, 24459, 25950, 27069, 24455, 26191, 26468, 26123, 25730, + 25232, 24751, + 23020, 23075, 25014, 25446, 25230, 24284, 23418, 23143, 23034, 23032, + 23157, 23711, 24698, 26145, 27057, 24449, 26315, 26421, 26022, 25635, + 25144, 24591, + 23347, 23414, 25153, 25552, 25165, 24200, 23399, 23129, 23060, 23089, + 23288, 23803, 24655, 26258, 26956, 24516, 26282, 26280, 25889, 25591, + 24983, 24420, + 23534, 23589, 25400, 25562, 25084, 24114, 23281, 23107, 23060, 23030, + 23415, 23839, 24765, 26067, 27021, 24636, 26282, 26189, 25717, 25250, + 24707, 24212, + 22925, 22776, 25520, 25540, 24967, 23974, 23242, 23115, 23070, 23071, + 23293, 23953, 24891, 26166, 27121, 24662, 26313, 26044, 25612, 25224, + 24649, 24018, + 22785, 22913, 24856, 25357, 25224, 24406, 23493, 23177, 23077, 23039, + 23083, 23733, 24603, 25912, 26928, 24384, 26259, 26395, 26085, 25762, + 25154, 24650, + 23083, 23212, 25050, 25421, 25187, 24293, 23460, 23139, 23046, 23043, + 23277, 23701, 24610, 25956, 27076, 24439, 26240, 26384, 26018, 25718, + 25080, 24463, + 23522, 23547, 25328, 25526, 25120, 24219, 23399, 23167, 23048, 23032, + 23233, 23831, 24692, 25999, 27087, 24582, 26300, 26294, 25968, 25524, + 24912, 24278, + 23858, 23850, 25451, 25606, 25050, 24151, 23340, 23122, 23075, 23101, + 23232, 23764, 24926, 26166, 27335, 24755, 26276, 26145, 25769, 25431, + 24820, 24237, + 23351, 23287, 25614, 25582, 24953, 23988, 23273, 23125, 23073, 23111, + 23346, 23865, 24862, 26135, 27366, 24968, 26319, 26000, 25553, 25145, + 24514, 24150, + 22691, 22869, 24796, 25340, 25240, 24398, 23500, 23176, 23101, 23078, + 23158, 23842, 24623, 25941, 27191, 24309, 26150, 26386, 26043, 25697, + 25245, 24645, + 23145, 23292, 25106, 25498, 25198, 24335, 23482, 23226, 23056, 23043, + 23244, 23709, 24688, 25934, 27109, 24451, 26248, 26368, 25996, 25566, + 25043, 24566, + 23699, 23739, 25354, 25490, 25142, 24214, 23399, 23222, 23120, 23071, + 23290, 23844, 24789, 25938, 26644, 24535, 26147, 26292, 25906, 25503, + 24983, 24440, + 24080, 24060, 25434, 25530, 25012, 24117, 23351, 23210, 23079, 23063, + 23276, 23883, 24725, 25937, 27007, 24731, 26185, 26107, 25755, 25423, + 24828, 24292, + 23592, 23565, 25572, 25530, 24914, 24021, 23295, 23171, 23101, 23070, + 23301, 23926, 24976, 26226, 27186, 25033, 26302, 25956, 25573, 25149, + 24618, 24037, + 22604, 22792, 24887, 25370, 25212, 24392, 23513, 23224, 23081, 23038, + 23231, 23864, 24553, 25832, 27016, 24514, 26441, 26382, 26095, 25701, + 25101, 24472, + 23213, 23346, 25154, 25493, 25173, 24264, 23460, 23210, 23074, 23107, + 23115, 23794, 24659, 25703, 26934, 24801, 26347, 26313, 26041, 25570, + 25026, 24499, + 23844, 23908, 25314, 25601, 25137, 24194, 23408, 23197, 23094, 23045, + 23218, 23729, 24612, 26007, 26788, 24567, 26215, 26252, 25895, 25475, + 24857, 24326, + 24154, 24118, 25323, 25525, 25001, 24094, 23339, 23146, 23156, 23086, + 23317, 23821, 24937, 26126, 27279, 24417, 26060, 26175, 25758, 25295, + 24848, 24252, + 23680, 23622, 25445, 25471, 24904, 24010, 23310, 23164, 23151, 23082, + 23391, 23899, 25043, 26398, 27133, 24604, 26071, 26031, 25665, 25214, + 24555, 24192, + 22502, 22810, 24918, 25348, 25238, 24415, 23482, 23275, 23107, 23069, + 23266, 23749, 24689, 25772, 26984, 24746, 26381, 26425, 26097, 25654, + 25151, 24571, + 23142, 23370, 25183, 25482, 25159, 24305, 23498, 23258, 23099, 23090, + 23304, 23737, 24781, 25911, 27006, 24900, 26432, 26320, 25940, 25504, + 24911, 24411, + 23857, 23971, 25382, 25533, 25138, 24234, 23450, 23222, 23155, 23120, + 23308, 23834, 24697, 26135, 27103, 24674, 26057, 26237, 25884, 25434, + 24908, 24446, + 24157, 24150, 25336, 25505, 25033, 24131, 23380, 23230, 23167, 23140, + 23343, 23874, 24776, 26118, 27457, 24030, 25846, 26267, 25891, 25516, + 24950, 24552, + 23720, 23667, 25385, 25411, 24896, 23991, 23356, 23217, 23182, 23182, + 23423, 23942, 24912, 26132, 27319, 23902, 25670, 26015, 25648, 25242, + 24752, 24318 ; + + CLW = + 0, 2, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 2, 3, 0, 0, 0 ; + + ChanSel = + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; + + ChiSqr = + 0.7953712, 0.59142, 0.2517513, 0.2231312, 0.2901628, + 0.83801, 0.7016711, 0.3099987, 0.3094735, 0.2798543, + 0.5025061, 0.6696218, 0.2448571, 0.2615377, 0.1434069, + 0.7199245, 0.9713045, 0.2094672, 0.3212895, 0.1872596, + 0.6445412, 0.3647941, 0.2405015, 0.3071654, 0.4628202, + 0.4326323, 0.4469193, 0.2237365, 0.4775677, 0.4854324 ; + + CldBase = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + CldThick = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + CldTop = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + Emis = + 7900, 8038, 8016, 8028, 8037, 8044, 8050, 8054, 8060, 8073, 8073, 8073, + 8073, 8073, 8073, 8512, 8598, 8677, 8677, 8677, 8677, 8677, + 7963, 8068, 7996, 8004, 8011, 8016, 8021, 8024, 8028, 8038, 8038, 8038, + 8038, 8038, 8038, 8435, 8493, 8571, 8571, 8571, 8571, 8571, + 7999, 8254, 8379, 8373, 8369, 8365, 8362, 8360, 8357, 8350, 8350, 8350, + 8350, 8350, 8350, 8461, 8113, 8113, 8113, 8113, 8113, 8113, + 7962, 8214, 8414, 8402, 8393, 8386, 8379, 8374, 8370, 8355, 8355, 8355, + 8355, 8355, 8355, 8300, 7873, 7873, 7873, 7873, 7873, 7873, + 7351, 7699, 8199, 8184, 8173, 8165, 8157, 8151, 8146, 8129, 8129, 8129, + 8129, 8129, 8129, 8018, 7554, 7554, 7554, 7554, 7554, 7555, + 7898, 8027, 7927, 7939, 7947, 7954, 7960, 7963, 7969, 7982, 7982, 7982, + 7982, 7982, 7982, 8485, 8512, 8594, 8594, 8594, 8594, 8594, + 8003, 8131, 8112, 8122, 8130, 8136, 8142, 8145, 8150, 8162, 8162, 8162, + 8162, 8162, 8162, 8555, 8637, 8714, 8714, 8714, 8714, 8714, + 8096, 8287, 8291, 8286, 8282, 8279, 8277, 8274, 8272, 8267, 8267, 8267, + 8267, 8267, 8267, 8316, 8066, 8066, 8066, 8066, 8066, 8066, + 8140, 8362, 8497, 8483, 8474, 8467, 8460, 8455, 8450, 8435, 8435, 8435, + 8435, 8435, 8435, 8352, 7930, 7930, 7930, 7930, 7930, 7930, + 7763, 8105, 8563, 8542, 8528, 8517, 8506, 8498, 8490, 8467, 8467, 8467, + 8467, 8467, 8467, 8325, 7682, 7682, 7682, 7682, 7682, 7682, + 7887, 8009, 7952, 7963, 7971, 7977, 7983, 7986, 7991, 8003, 8003, 8003, + 8003, 8003, 8003, 8438, 8510, 8591, 8591, 8591, 8591, 8591, + 8099, 8224, 8247, 8257, 8264, 8270, 8275, 8278, 8283, 8294, 8294, 8294, + 8294, 8294, 8294, 8619, 8726, 8799, 8799, 8799, 8799, 8799, + 8227, 8432, 8531, 8521, 8514, 8509, 8504, 8500, 8496, 8485, 8485, 8485, + 8485, 8485, 8485, 8426, 8109, 8109, 8109, 8109, 8109, 8109, + 8360, 8576, 8694, 8677, 8665, 8656, 8647, 8641, 8635, 8616, 8616, 8616, + 8616, 8616, 8616, 8494, 7976, 7976, 7976, 7976, 7976, 7976, + 7969, 8301, 8708, 8687, 8673, 8662, 8651, 8644, 8636, 8613, 8613, 8613, + 8613, 8613, 8613, 8502, 7840, 7839, 7839, 7839, 7840, 7840, + 7890, 8017, 7942, 7953, 7962, 7968, 7974, 7977, 7983, 7996, 7996, 7996, + 7996, 7996, 7996, 8465, 8517, 8598, 8598, 8598, 8598, 8598, + 8123, 8254, 8310, 8320, 8328, 8333, 8339, 8342, 8347, 8358, 8358, 8358, + 8358, 8358, 8358, 8658, 8784, 8856, 8856, 8856, 8856, 8856, + 8341, 8534, 8596, 8582, 8573, 8565, 8558, 8553, 8548, 8533, 8533, 8533, + 8533, 8533, 8533, 8434, 8021, 8021, 8021, 8021, 8021, 8021, + 8579, 8781, 8864, 8845, 8831, 8821, 8811, 8804, 8796, 8775, 8775, 8775, + 8775, 8775, 8775, 8620, 8049, 8049, 8049, 8049, 8049, 8049, + 8177, 8492, 8840, 8819, 8805, 8794, 8783, 8775, 8768, 8745, 8745, 8745, + 8745, 8745, 8745, 8643, 7969, 7969, 7969, 7969, 7969, 7969, + 7773, 7931, 7968, 7982, 7993, 8001, 8009, 8013, 8020, 8036, 8036, 8036, + 8036, 8036, 8036, 8484, 8625, 8708, 8708, 8708, 8708, 8708, + 8087, 8316, 8371, 8372, 8372, 8372, 8372, 8371, 8371, 8371, 8371, 8371, + 8371, 8371, 8371, 8550, 8369, 8369, 8369, 8369, 8369, 8369, + 8361, 8528, 8523, 8512, 8504, 8498, 8492, 8488, 8483, 8471, 8471, 8471, + 8471, 8471, 8471, 8389, 8047, 8047, 8047, 8047, 8047, 8047, + 8572, 8705, 8646, 8630, 8618, 8609, 8600, 8594, 8588, 8569, 8569, 8569, + 8569, 8569, 8569, 8377, 7939, 7939, 7939, 7939, 7939, 7939, + 8341, 8582, 8778, 8757, 8742, 8731, 8719, 8711, 8704, 8680, 8680, 8680, + 8680, 8680, 8680, 8501, 7873, 7873, 7873, 7873, 7873, 7873, + 7735, 7906, 7915, 7931, 7943, 7952, 7960, 7965, 7972, 7990, 7990, 7990, + 7990, 7990, 7990, 8514, 8625, 8711, 8711, 8711, 8711, 8711, + 8038, 8195, 8277, 8290, 8299, 8306, 8313, 8317, 8323, 8338, 8338, 8338, + 8338, 8338, 8338, 8696, 8838, 8912, 8912, 8912, 8912, 8912, + 8463, 8662, 8709, 8695, 8685, 8677, 8670, 8664, 8659, 8643, 8643, 8643, + 8643, 8643, 8643, 8574, 8101, 8101, 8101, 8101, 8101, 8102, + 8699, 8838, 8796, 8776, 8762, 8751, 8741, 8733, 8726, 8704, 8704, 8704, + 8704, 8704, 8704, 8478, 7953, 7953, 7953, 7953, 7953, 7953, + 8548, 8757, 8934, 8904, 8884, 8868, 8852, 8842, 8831, 8798, 8798, 8798, + 8798, 8798, 8798, 8444, 7684, 7684, 7684, 7684, 7684, 7684 ; + + Freq = 23.8, 31.4, 50.3, 51.76, 52.8, 53.596, 54.4, 54.94, 55.5, 57.29, + 57.29, 57.29, 57.29, 57.29, 57.29, 88.2, 165.5, 183.31, 183.31, 183.31, + 183.31, 183.31 ; + + GWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + IWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + LWP = + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998, + -998, -998, -998, -998, -998 ; + + LZ_angle = + 50.16999, 53.05, 56.09, 59.2, 62.46, + 50.15999, 53.08001, 56.07, 59.21998, 62.46, + 50.14001, 53.08001, 56.08001, 59.2, 62.48999, + 50.15999, 53.06001, 56.09999, 59.18999, 62.46998, + 50.16999, 53.07, 56.08001, 59.21, 62.46, + 50.14001, 53.09001, 56.07, 59.21998, 62.46998 ; + + Latitude = + 71.45, 71.51, 71.54, 71.53, 71.47, + 71.76, 71.82, 71.85, 71.84, 71.78, + 72.07, 72.13, 72.16, 72.15, 72.08, + 72.38, 72.44, 72.47, 72.46, 72.39, + 72.69, 72.75, 72.78, 72.77, 72.7, + 73, 73.06, 73.09, 73.08, 73.01 ; + + Longitude = + 176.67, 178.83, -178.67, -175.83, -172.53, + 176.55, 178.78, -178.72, -175.8, -172.46, + 176.43, 178.7, -178.75, -175.81, -172.36, + 176.32, 178.6, -178.76, -175.8, -172.31, + 176.21, 178.53, -178.82, -175.76, -172.25, + 176.07, 178.46, -178.86, -175.74, -172.14 ; + + Orb_mode = 0, 0, 0, 0, 0, 0 ; + + Polo = 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3 ; + + PrecipType = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + Prob_SF = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + Qc = + 0, 0, 0, 4096, + 0, 0, 32, 4096, + 1, 0, 144, 0, + 1, 0, 144, 0, + 1, 0, 144, 0, + 0, 0, 0, 4096, + 0, 0, 0, 4096, + 1, 0, 144, 0, + 0, 0, 128, 0, + 1, 0, 144, 0, + 0, 0, 0, 4096, + 0, 0, 0, 4096, + 1, 0, 144, 0, + 1, 0, 144, 0, + 1, 0, 144, 0, + 0, 0, 0, 4096, + 0, 0, 0, 4096, + 1, 0, 144, 0, + 1, 0, 148, 0, + 1, 0, 156, 0, + 1, 0, 20, 4096, + 1, 0, 144, 0, + 1, 0, 144, 0, + 1, 0, 144, 0, + 1, 0, 144, 0, + 0, 0, 32, 4096, + 0, 0, 32, 4096, + 1, 0, 144, 0, + 1, 0, 144, 0, + 1, 0, 144, 0 ; + + RAzi_angle = + -95.24, -93.2, -90.83, -88.14, -85.01, + -95.3, -93.19, -90.81, -88.04, -84.86, + -95.35, -93.19, -90.76, -87.97, -84.69, + -95.4, -93.22, -90.71, -87.89, -84.56, + -95.44, -93.22, -90.69, -87.77, -84.42, + -95.51, -93.22, -90.66, -87.68, -84.24 ; + + RFlag = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + RR = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + RWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SFR = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SIce = + 76, 76, 80, 80, 66, + 76, 78, 80, 82, 78, + 76, 82, 84, 88, 82, + 76, 82, 88, 94, 88, + 74, 82, 86, 90, 88, + 74, 82, 90, 94, 92 ; + + SIce_FY = + 76, 76, 80, 80, 66, + 76, 78, 80, 82, 78, + 76, 82, 84, 88, 82, + 76, 82, 88, 94, 88, + 74, 82, 86, 90, 88, + 74, 82, 90, 94, 92 ; + + SIce_MY = + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ; + + SWE = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SWP = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SZ_angle = + 49.34, 49.66, 50.03, 50.46, 50.97, + 49.62, 49.94, 50.3, 50.73, 51.24, + 49.9, 50.22, 50.58, 51, 51.51, + 50.18, 50.49, 50.86, 51.27, 51.78, + 50.46, 50.77, 51.13, 51.55, 52.05, + 50.74, 51.05, 51.4, 51.82, 52.32 ; + + ScanTime_UTC = 5261.00048828125, 5266.00048828125, 5272.00048828125, + 5277.00048828125, 5282.00048828125, 5288.00048828125 ; + + ScanTime_dom = 30, 30, 30, 30, 30, 30 ; + + ScanTime_doy = 181, 181, 181, 181, 181, 181 ; + + ScanTime_hour = 1, 1, 1, 1, 1, 1 ; + + ScanTime_minute = 27, 27, 27, 27, 28, 28 ; + + ScanTime_month = 6, 6, 6, 6, 6, 6 ; + + ScanTime_second = 41, 46, 52, 57, 2, 8 ; + + ScanTime_year = 2021, 2021, 2021, 2021, 2021, 2021 ; + + Sfc_type = + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 ; + + Snow = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SnowGS = + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _, + _, _, _, _, _ ; + + SurfM = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + SurfP = + 10084, 10084, 9930, 9930, 9930, + 10084, 10084, 9930, 9930, 9930, + 10084, 10084, 9930, 9930, 9930, + 10084, 10084, 9930, 9930, 9930, + 10084, 9930, 9930, 9930, 9930, + 10084, 10084, 9930, 9930, 9930 ; + + TPW = + 96, 104, 134, 128, 130, + 100, 101, 123, 124, 131, + 103, 94, 125, 130, 132, + 99, 94, 115, 129, 138, + 116, 123, 119, 110, 113, + 104, 106, 111, 99, 103 ; + + TSkin = + 27765, 27612, 27572, 27487, 27762, + 27740, 27634, 27429, 27474, 27567, + 27662, 27494, 27256, 27280, 27575, + 27628, 27562, 27275, 26996, 27279, + 27697, 27310, 27381, 27248, 27204, + 27713, 27563, 27188, 27092, 26923 ; + + WindDir = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindSp = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindU = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + WindV = + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888, + -888, -888, -888, -888, -888 ; + + YM = + 23075, 23066, 25066, 25344, 25162, 24317, 23365, 23011, 22865, 22945, + 23118, 23752, 24605, 25872, 26984, 24490, 26046, 26310, 25960, 25533, + 24987, 24516, + 23295, 23256, 25067, 25355, 25091, 24245, 23311, 22944, 22889, 22972, + 23122, 23813, 24689, 25904, 26932, 24464, 26065, 26179, 25831, 25541, + 24924, 24377, + 23616, 23622, 25341, 25449, 25017, 24156, 23210, 22947, 22936, 22958, + 23125, 23657, 24682, 25989, 27074, 24882, 26239, 26057, 25769, 25342, + 24778, 24351, + 23539, 23574, 25298, 25396, 24923, 24008, 23235, 22960, 22913, 22985, + 23231, 23707, 24697, 26122, 26921, 24479, 26097, 26015, 25694, 25237, + 24759, 24218, + 22665, 22444, 25263, 25351, 24817, 23885, 23131, 22948, 22897, 22925, + 23257, 23913, 24880, 26048, 27204, 24054, 26184, 26051, 25715, 25312, + 24697, 24232, + 23119, 23045, 25004, 25354, 25202, 24337, 23391, 23015, 22924, 22961, + 23061, 23674, 24384, 25854, 26998, 24517, 26021, 26310, 25997, 25613, + 25120, 24687, + 23323, 23246, 25098, 25362, 25085, 24195, 23343, 23021, 22927, 22978, + 23094, 23659, 24621, 26050, 26984, 24477, 26139, 26260, 25895, 25520, + 25031, 24527, + 23642, 23592, 25172, 25422, 25008, 24109, 23319, 23004, 22951, 23033, + 23222, 23748, 24573, 26157, 26882, 24484, 26090, 26110, 25757, 25471, + 24867, 24355, + 23874, 23827, 25352, 25379, 24917, 24014, 23198, 22979, 22948, 22974, + 23348, 23781, 24679, 25960, 26946, 24539, 26071, 26010, 25578, 25130, + 24588, 24142, + 23341, 23114, 25395, 25320, 24792, 23869, 23153, 22985, 22958, 23014, + 23226, 23891, 24800, 26057, 27045, 24491, 26090, 25859, 25469, 25099, + 24525, 23942, + 23077, 23067, 24992, 25312, 25091, 24318, 23422, 23058, 22971, 22986, + 23023, 23684, 24528, 25816, 26857, 24446, 26088, 26238, 25959, 25645, + 25042, 24586, + 23386, 23383, 25134, 25337, 25042, 24204, 23384, 23017, 22939, 22989, + 23214, 23649, 24533, 25860, 27003, 24467, 26064, 26224, 25891, 25601, + 24967, 24399, + 23817, 23725, 25347, 25396, 24963, 24128, 23319, 23041, 22939, 22976, + 23167, 23776, 24610, 25898, 27013, 24550, 26107, 26124, 25835, 25404, + 24796, 24213, + 24198, 24088, 25403, 25423, 24883, 24051, 23257, 22994, 22963, 23045, + 23164, 23706, 24840, 26059, 27260, 24658, 26065, 25966, 25629, 25311, + 24701, 24167, + 23767, 23625, 25489, 25362, 24778, 23883, 23184, 22995, 22961, 23054, + 23279, 23803, 24771, 26026, 27290, 24797, 26096, 25815, 25410, 25020, + 24390, 24074, + 22983, 23023, 24932, 25295, 25107, 24310, 23429, 23057, 22995, 23025, + 23098, 23793, 24548, 25845, 27121, 24371, 25979, 26229, 25917, 25580, + 25133, 24581, + 23448, 23463, 25190, 25414, 25053, 24246, 23406, 23104, 22949, 22989, + 23181, 23657, 24611, 25839, 27035, 24479, 26072, 26207, 25869, 25450, + 24930, 24502, + 23994, 23917, 25373, 25360, 24985, 24123, 23319, 23096, 23011, 23015, + 23224, 23789, 24707, 25837, 26571, 24503, 25954, 26122, 25774, 25383, + 24867, 24375, + 24420, 24298, 25386, 25347, 24845, 24017, 23268, 23082, 22968, 23007, + 23208, 23825, 24639, 25829, 26932, 24634, 25974, 25928, 25616, 25303, + 24709, 24222, + 24008, 23903, 25447, 25310, 24739, 23916, 23206, 23041, 22989, 23013, + 23234, 23864, 24885, 26118, 27110, 24862, 26079, 25770, 25430, 25024, + 24494, 23962, + 22896, 22946, 25023, 25325, 25079, 24304, 23442, 23105, 22975, 22985, + 23171, 23815, 24478, 25737, 26945, 24576, 26270, 26225, 25969, 25584, + 24989, 24408, + 23516, 23517, 25238, 25409, 25028, 24175, 23384, 23088, 22967, 23054, + 23052, 23742, 24582, 25607, 26860, 24829, 26171, 26153, 25914, 25454, + 24913, 24435, + 24139, 24086, 25333, 25471, 24980, 24103, 23328, 23071, 22985, 22989, + 23152, 23674, 24530, 25906, 26715, 24535, 26022, 26082, 25763, 25355, + 24741, 24262, + 24494, 24356, 25275, 25342, 24834, 23994, 23256, 23018, 23044, 23030, + 23249, 23763, 24851, 26019, 27204, 24320, 25848, 25996, 25619, 25175, + 24729, 24182, + 24096, 23960, 25320, 25251, 24729, 23905, 23221, 23034, 23039, 23025, + 23324, 23837, 24952, 26289, 27057, 24433, 25848, 25845, 25522, 25089, + 24431, 24116, + 22794, 22964, 25054, 25303, 25105, 24327, 23411, 23156, 23001, 23016, + 23206, 23700, 24614, 25676, 26913, 24808, 26210, 26268, 25971, 25537, + 25039, 24507, + 23445, 23541, 25267, 25398, 25014, 24216, 23422, 23136, 22992, 23037, + 23241, 23685, 24704, 25816, 26932, 24928, 26256, 26160, 25813, 25388, + 24798, 24347, + 24152, 24149, 25401, 25403, 24981, 24143, 23370, 23096, 23046, 23064, + 23242, 23779, 24615, 26034, 27029, 24642, 25864, 26067, 25751, 25314, + 24792, 24381, + 24497, 24388, 25288, 25322, 24866, 24031, 23297, 23102, 23055, 23084, + 23276, 23816, 24690, 26010, 27382, 23933, 25634, 26088, 25751, 25396, + 24831, 24482, + 24136, 24005, 25260, 25191, 24721, 23886, 23267, 23087, 23070, 23125, + 23356, 23880, 24821, 26023, 27243, 23731, 25447, 25829, 25505, 25117, + 24628, 24242 ; +} diff --git a/utils/test/testinput/gdas_icecjpssrr2ioda.yaml b/utils/test/testinput/gdas_icecjpssrr2ioda.yaml new file mode 100644 index 000000000..49a757d35 --- /dev/null +++ b/utils/test/testinput/gdas_icecjpssrr2ioda.yaml @@ -0,0 +1,13 @@ +provider: JPSSRR +window begin: 2024-06-29T21:00:00Z +window end: 2024-06-30T03:00:00Z +output file: icec_jrr.ioda.nc +#ocean basin: RECCAP2_region_masks_all_v20221025.nc +input files: +- icec_jrr_n20_1.nc4 +- icec_jrr_n20_2.nc4 + +test: + reference filename: testref/icecjpssrr2ioda.test + test output filename: testoutput/icecjpssrr2ioda.test + float relative tolerance: 1e-6 diff --git a/utils/test/testinput/gdas_icecmirs2ioda.yaml b/utils/test/testinput/gdas_icecmirs2ioda.yaml new file mode 100644 index 000000000..5a2067f60 --- /dev/null +++ b/utils/test/testinput/gdas_icecmirs2ioda.yaml @@ -0,0 +1,13 @@ +provider: MIRS +window begin: 2024-06-29T21:00:00Z +window end: 2024-06-30T03:00:00Z +output file: icec_mirs.ioda.nc +#ocean basin: RECCAP2_region_masks_all_v20221025.nc +input files: +- icec_mirs_snpp_1.nc4 +- icec_mirs_snpp_2.nc4 + +test: + reference filename: testref/icecmirs2ioda.test + test output filename: testoutput/icecmirs2ioda.test + float relative tolerance: 1e-6 diff --git a/utils/test/testref/icecjpssrr2ioda.test b/utils/test/testref/icecjpssrr2ioda.test new file mode 100644 index 000000000..4fedc6299 --- /dev/null +++ b/utils/test/testref/icecjpssrr2ioda.test @@ -0,0 +1,26 @@ +Reading: [icec_jrr_n20_1.nc4,icec_jrr_n20_2.nc4] +seconds since 1970-01-01T00:00:00Z +obsVal: + Min: 0.407328 + Max: 1 + Sum: 225.641 +obsError: + Min: 0.1 + Max: 0.1 + Sum: 24.6 +preQc: + Min: 0 + Max: 1 + Sum: 104 +longitude: + Min: 45.7687 + Max: 91.459 + Sum: 15553.2 +latitude: + Min: -63.2473 + Max: 67.123 + Sum: 4270.1 +datetime: + Min: 1718704416 + Max: 1718708172 + Sum: 422801639400 diff --git a/utils/test/testref/icecmirs2ioda.test b/utils/test/testref/icecmirs2ioda.test new file mode 100644 index 000000000..b20faf036 --- /dev/null +++ b/utils/test/testref/icecmirs2ioda.test @@ -0,0 +1,26 @@ +Reading: [icec_mirs_snpp_1.nc4,icec_mirs_snpp_2.nc4] +seconds since 1970-01-01T00:00:00Z +obsVal: + Min: 0 + Max: 0.94 + Sum: 37.36 +obsError: + Min: 0.1 + Max: 0.1 + Sum: 5.7 +preQc: + Min: 0 + Max: 1 + Sum: 21 +longitude: + Min: -178.86 + Max: 179.29 + Sum: -2234.77 +latitude: + Min: 69.62 + Max: 73.09 + Sum: 4068.9 +datetime: + Min: 1625016429 + Max: 1625016488 + Sum: 92625938165