diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..04832590e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,24 @@ +# Description + + + +# Companion PRs + + + +# Issues + + + +# Automated CI tests to run in Global Workflow + +- [ ] atm_jjob +- [ ] C96C48_ufs_hybatmDA +- [ ] C96C48_hybatmaerosnowDA +- [ ] C48mx500_3DVarAOWCDA +- [ ] C48mx500_hybAOWCDA +- [ ] C96C48_hybatmDA diff --git a/ci/ci_tests.sh b/ci/ci_tests.sh new file mode 100644 index 000000000..43e8eb2fb --- /dev/null +++ b/ci/ci_tests.sh @@ -0,0 +1,6 @@ +CI_TESTS=("atm_jjob" + "C96C48_ufs_hybatmDA" + "C96C48_hybatmaerosnowDA" + "C48mx500_3DVarAOWCDA" + "C48mx500_hybAOWCDA" + "C96C48_hybatmDA") diff --git a/ci/driver.sh b/ci/driver.sh index 933b9223b..e66929350 100755 --- a/ci/driver.sh +++ b/ci/driver.sh @@ -1,6 +1,6 @@ #!/bin/bash --login -echo "Start at $(date)" +echo "Starting automated testing at $(date)" my_dir="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )" echo "Set my_dir ${my_dir}" @@ -13,6 +13,7 @@ usage() { echo echo " -t target/machine script is running on DEFAULT: $(hostname)" echo " -h display this message and quit" + echo " -w run workflow tests on $(hostname)" echo exit 1 } @@ -22,7 +23,8 @@ usage() { export TARGET="$(hostname)" -while getopts "t:h" opt; do +TEST_WORKFLOW=0 +while getopts "t:h:w" opt; do case $opt in t) TARGET=$OPTARG @@ -30,12 +32,16 @@ while getopts "t:h" opt; do h|\?|:) usage ;; + w) + TEST_WORKFLOW=1 + ;; esac done +echo "Running automated testing on $TARGET" + case ${TARGET} in - hera | orion) - echo "Running Automated Testing on $TARGET" + hera | orion | hercules) source $MODULESHOME/init/sh source $my_dir/${TARGET}.sh module purge @@ -49,106 +55,176 @@ case ${TARGET} in ;; esac +# ============================================================================== +# set list of available CI tests to run on the Global Workflow +source $my_dir/ci_tests.sh + +# ============================================================================== +# set things that depend on whether running workflow tests or not +gdasapp_url="https://github.com/NOAA-EMC/GDASApp.git" +if [[ $TEST_WORKFLOW == 1 ]]; then + echo "Testing GDASApp inside the Global Workflow" + + CI_LABEL="${GDAS_CI_HOST}-GW-RT" + OPEN_PR_LIST_DIR=$GDAS_CI_ROOT/open_pr_list_gw + PR_TEST_DIR=$GDAS_CI_ROOT/workflow/PR + BASE_REPO=global-workflow + + # Default Global Workflow repo and branch if no companion PR found + workflow_url="https://github.com/NOAA-EMC/global-workflow.git" + workflow_branch="develop" +else + echo "Testing stand-alone GDASApp" + + CI_LABEL="${GDAS_CI_HOST}-RT" + OPEN_PR_LIST_DIR=$GDAS_CI_ROOT/open_pr_list + PR_TEST_DIR=$GDAS_CI_ROOT/PR + BASE_REPO=GDASApp +fi + # ============================================================================== # pull on the repo and get list of open PRs + cd $GDAS_CI_ROOT/repo -CI_LABEL="${GDAS_CI_HOST}-RT" -gh pr list --label "$CI_LABEL" --state "open" | awk '{print $1;}' > $GDAS_CI_ROOT/open_pr_list -open_pr=`cat $GDAS_CI_ROOT/open_pr_list | wc -l` +gh pr list --label "$CI_LABEL" --state "open" | awk '{print $1;}' > $OPEN_PR_LIST_DIR + +open_pr=`cat $OPEN_PR_LIST_DIR | wc -l` if (( $open_pr == 0 )); then echo "No open PRs with ${CI_LABEL}, exit." - echo "Finish at $(date)" + echo "Finished automated testing at $(date)" exit fi -open_pr_list=$(cat $GDAS_CI_ROOT/open_pr_list) +open_pr_list=$(cat $OPEN_PR_LIST_DIR) # ============================================================================== # clone, checkout, build, test, etc. -repo_url="https://github.com/NOAA-EMC/GDASApp.git" # loop through all open PRs for pr in $open_pr_list; do echo " " - echo "Start processing Pull Request #${pr} at $(date)" + echo "Starting processing of pull request #${pr} at $(date)" # get the branch name used for the PR gdasapp_branch=$(gh pr view $pr --json headRefName -q ".headRefName") - # get additional branch information - branch_owner=$(gh pr view $pr --repo ${repo_url} --json headRepositoryOwner --jq '.headRepositoryOwner.login') - branch_name=$(gh pr view $pr --repo ${repo_url} --json headRepository --jq '.headRepository.name') - pr_assignees=$(gh pr view $pr --repo ${repo_url} --json assignees --jq '.assignees[].login') - + # get additional branch informatio + branch_owner=$(gh pr view $pr --repo ${gdasapp_url} --json headRepositoryOwner --jq '.headRepositoryOwner.login') + branch_name=$(gh pr view $pr --repo ${gdasapp_url} --json headRepository --jq '.headRepository.name') + pr_assignees=$(gh pr view $pr --repo ${gdasapp_url} --json assignees --jq '.assignees[].login') + # check if any assignee is authorized to run CI - authorized_by="" + rc=1 for str in ${pr_assignees[@]}; do - grep $str /scratch1/NCEPDEV/da/role.jedipara/CI/GDASApp/authorized_users - rc=$? + grep $str $AUTHORIZED_USERS_FILE > /dev/null + if (( rc != 0 )); then + rc=$? + fi if (( rc == 0 )); then - authorized_by=${str} - echo "FOUND MATCH $str, rc $rc" - break + echo "Authorized user $str assigned to this PR" fi done # Authorized to run CI if (( rc == 0 )); then - echo "Run CI" + echo "CI authorized. Running CI..." # update PR label gh pr edit $pr --remove-label $CI_LABEL --add-label ${CI_LABEL}-Running - - # construct the fork URL - gdasapp_url="https://github.com/$branch_owner/${branch_name}.git" - + echo "GDASApp URL: $gdasapp_url" echo "GDASApp branch Name: $gdasapp_branch" - echo "CI authorized by $authorized_by at $(date)" + + if [[ $TEST_WORKFLOW == 1 ]]; then + # 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 + branch_owner=$(gh pr view $companion_pr --repo $workflow_url --json headRepositoryOwner --jq '.headRepositoryOwner.login') + branch_name=$(gh pr view $companion_pr --repo $workflow_url --json headRepository --jq '.headRepository.name') + + # Construct fork URL. Update workflow branch name + workflow_url="https://github.com/$branch_owner/$branch_name.git" + workflow_branch=$gdasapp_branch + fi + + echo "Found companion Global Workflow PR #${companion_pr}!" + echo "Global Workflow URL: $workflow_url" + echo "Global Workflow branch name: $workflow_branch" + fi - # create PR specific directory - if [ -d $GDAS_CI_ROOT/PR/$pr ]; then - rm -rf $GDAS_CI_ROOT/PR/$pr + # create PR specific directory + if [ -d $PR_TEST_DIR/$pr ]; then + rm -rf $PR_TEST_DIR/$pr fi - mkdir -p $GDAS_CI_ROOT/PR/$pr - cd $GDAS_CI_ROOT/PR/$pr + mkdir -p $PR_TEST_DIR/$pr + cd $PR_TEST_DIR/$pr pwd # clone copy of repo - git clone --recursive --jobs 8 --branch $gdasapp_branch $gdasapp_url - cd GDASApp + if [[ $TEST_WORKFLOW == 1 ]]; then + echo "Cloning Global Workflow branch $workflow_branch from $workflow_url at $(date)" + git clone --recursive --jobs 8 --branch $workflow_branch $workflow_url + cd global-workflow/sorc/gdas.cd + else + echo "Cloning GDASApp branch $workflow_branch at $(date)" + git clone --recursive --jobs 8 --branch $gdasapp_branch $gdasapp_url + cd GDASApp + fi pwd # checkout GDASApp pull request - git pull gh pr checkout $pr git submodule update --init --recursive # get commit hash commit=$(git log --pretty=format:'%h' -n 1) - echo "$commit" > $GDAS_CI_ROOT/PR/$pr/commit + echo "$commit" > $PR_TEST_DIR/$pr/commit # run build and testing command - echo "Execute $my_dir/run_ci.sh for $GDAS_CI_ROOT/PR/$pr/GDASApp at $(date)" - $my_dir/run_ci.sh -d $GDAS_CI_ROOT/PR/$pr/GDASApp -o $GDAS_CI_ROOT/PR/$pr/output_${commit} + echo "Running run_ci.sh for $PR_TEST_DIR/$pr/$BASE_REPO at $(date)" + run_ci_cmd="$my_dir/run_ci.sh -d $PR_TEST_DIR/$pr/$BASE_REPO -o $PR_TEST_DIR/$pr/output_${commit}" + if [[ $TEST_WORKFLOW == 1 ]]; then + # get ci tests from PR description and convert into a regular expressions to be excluded + branch_body=$(gh pr view $pr --repo ${gdasapp_url} --json body --jq '.body') + ci_checklist=$(echo "$branch_body" | grep '\[x\]') + ctest_regex_exclude="" + for ci_test in ${CI_TESTS[@]}; do + if ! echo "$ci_checklist" | grep -q "$ci_test"; then + ctest_regex_exclude+="${ctest_regex_exclude:+|}$ci_test" + fi + done + + # setup run_ci.sh arguments to test in the Global Workflow and exclude chosen CI tests + run_ci_cmd+=" -w" + if [ -n "$ctest_regex_exclude" ]; then + run_ci_cmd+=" -E $ctest_regex_exclude" + fi + fi + $run_ci_cmd ci_status=$? - echo "After run_ci.sh with ci_status ${ci_status} at $(date)" - gh pr comment $pr --repo ${repo_url} --body-file $GDAS_CI_ROOT/PR/$pr/output_${commit} + echo "Finished running run_ci.sh with ci_status ${ci_status} at $(date)" + + gh pr comment $pr --repo ${gdasapp_url} --body-file $PR_TEST_DIR/$pr/output_${commit} if [ $ci_status -eq 0 ]; then - gh pr edit $pr --repo ${repo_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Passed + gh pr edit $pr --repo ${gdasapp_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Passed else - gh pr edit $pr --repo ${repo_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Failed + gh pr edit $pr --repo ${gdasapp_url} --remove-label ${CI_LABEL}-Running --add-label ${CI_LABEL}-Failed fi # Not authorized to run CI else - echo "Do NOT run CI" + echo "No authorized users assigned to this PR. Aborting CI..." fi - echo "Finish processing Pull Request #{pr} at $(date)" + echo "Finished processing Pull Request #${pr} at $(date)" done # ============================================================================== # scrub working directory for older files -find $GDAS_CI_ROOT/PR/* -maxdepth 1 -mtime +3 -exec rm -rf {} \; -echo "Finish at $(date)" +find $PR_TEST_DIR/* -maxdepth 1 -mtime +3 -exec rm -rf {} \; +echo "Finished automated testing at $(date)" diff --git a/ci/gw_driver.sh b/ci/gw_driver.sh deleted file mode 100755 index c40ff4026..000000000 --- a/ci/gw_driver.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/bash --login - -echo "Start at $(date)" - -my_dir="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )" -echo "Set my_dir ${my_dir}" - -# ============================================================================== -usage() { - set +x - echo - echo "Usage: $0 -t -h" - echo - echo " -t target/machine script is running on DEFAULT: $(hostname)" - echo " -h display this message and quit" - echo - exit 1 -} - -# ============================================================================== -# First, set up runtime environment - -export TARGET="$(hostname)" - -while getopts "t:h" opt; do - case $opt in - t) - TARGET=$OPTARG - ;; - h|\?|:) - usage - ;; - esac -done - -case ${TARGET} in - hera | orion) - echo "Running Automated GW Testing on $TARGET" - source $MODULESHOME/init/sh - source $my_dir/${TARGET}.sh - module purge - module use $GDAS_MODULE_USE - module load GDAS/$TARGET - module list - ;; - *) - echo "Unsupported platform. Exiting with error." - exit 1 - ;; -esac - -# ============================================================================== -# pull on the repo and get list of open PRs -cd $GDAS_CI_ROOT/repo -CI_LABEL="${GDAS_CI_HOST}-GW-RT" -gh pr list --label "$CI_LABEL" --state "open" | awk '{print $1;}' > $GDAS_CI_ROOT/open_pr_list_gw - -open_pr=`cat $GDAS_CI_ROOT/open_pr_list_gw | wc -l` -if (( $open_pr == 0 )); then - echo "No open PRs with ${CI_LABEL}, exit." - echo "Finish at $(date)" - exit -fi - -open_pr_list=$(cat $GDAS_CI_ROOT/open_pr_list_gw) - -# ============================================================================== -# clone, checkout, build, test, etc. -repo_url="https://github.com/NOAA-EMC/GDASApp.git" -workflow_url="https://github.com/NOAA-EMC/global-workflow.git" -workflow_branch="develop" -# loop through all open PRs -for pr in $open_pr_list; do - echo " " - echo "Start processing Pull Request #${pr} at $(date)" - - # get the branch name used for the PR - gdasapp_branch=$(gh pr view $pr --json headRefName -q ".headRefName") - - # get additional branch information - branch_owner=$(gh pr view $pr --repo ${repo_url} --json headRepositoryOwner --jq '.headRepositoryOwner.login') - branch_name=$(gh pr view $pr --repo ${repo_url} --json headRepository --jq '.headRepository.name') - pr_assignees=$(gh pr view $pr --repo ${repo_url} --json assignees --jq '.assignees[].login') - - # check if any assignee is authorized to run CI - authorized_by="" - for str in ${pr_assignees[@]}; do - grep $str /scratch1/NCEPDEV/da/role.jedipara/CI/GDASApp/authorized_users - rc=$? - if (( rc == 0 )); then - authorized_by=${str} - echo "FOUND MATCH $str, rc $rc" - break - fi - done - - # Authorized to run CI - if (( rc == 0 )); then - echo "Run CI" - - # update PR label - gh pr edit $pr --remove-label $CI_LABEL --add-label ${CI_LABEL}-Running - - # 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 - branch_owner=$(gh pr view $companion_pr --repo $workflow_url --json headRepositoryOwner --jq '.headRepositoryOwner.login') - branch_name=$(gh pr view $companion_pr --repo $workflow_url --json headRepository --jq '.headRepository.name') - - # Construct fork URL. Update workflow branch name - workflow_url="https://github.com/$branch_owner/$branch_name.git" - workflow_branch=$gdasapp_branch - - fi - - echo "Workflow URL: $workflow_url" - echo "Workflow branch name: $workflow_branch" - echo "GDASApp branch name: $gdasapp_branch" - echo "CI authorized by $authorized_by at $(date)" - - # 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 - pwd - - # clone global workflow develop branch - git clone --recursive --jobs 8 --branch $workflow_branch $workflow_url - - # checkout GDASApp pull request - cd $GDAS_CI_ROOT/workflow/PR/$pr/global-workflow/sorc/gdas.cd - git pull - gh pr checkout $pr - git submodule update --init --recursive - - # get commit hash - commit=$(git log --pretty=format:'%h' -n 1) - echo "$commit" > $GDAS_CI_ROOT/workflow/PR/$pr/commit - - # run build and testing command - echo "Execute $my_dir/run_gw_ci.sh for $GDAS_CI_ROOT/PR/workflow/PR/$pr/global-workflow at $(date)" - $my_dir/run_gw_ci.sh -d $GDAS_CI_ROOT/workflow/PR/$pr/global-workflow -o $GDAS_CI_ROOT/workflow/PR/$pr/output_${commit} - ci_status=$? - echo "After run_gw_ci.sh with ci_status ${ci_status} at $(date)" - gh pr comment $pr --body-file $GDAS_CI_ROOT/workflow/PR/$pr/output_${commit} - if [ $ci_status -eq 0 ]; then - gh pr edit $pr --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 - fi - - # Not authorized to run CI - else - echo "Do NOT run CI" - fi - - echo "Finish processing Pull Request #{pr} at $(date)" -done - -# ============================================================================== -# scrub working directory for older files -find $GDAS_CI_ROOT/workflow/PR/* -maxdepth 1 -mtime +3 -exec rm -rf {} \; -echo "Finish at $(date)" diff --git a/ci/hera.sh b/ci/hera.sh index ec3858370..c9c5f892c 100644 --- a/ci/hera.sh +++ b/ci/hera.sh @@ -6,3 +6,5 @@ export SALLOC_ACCOUNT=$SLURM_ACCOUNT export SBATCH_ACCOUNT=$SLURM_ACCOUNT export SLURM_QOS=debug export PATH=$PATH:/home/role.jedipara/bin +export NTASKS_TESTS=12 +export AUTHORIZED_USERS_FILE=/scratch1/NCEPDEV/da/role.jedipara/CI/GDASApp/authorized_users diff --git a/ci/hercules.sh b/ci/hercules.sh new file mode 100644 index 000000000..663bc44c6 --- /dev/null +++ b/ci/hercules.sh @@ -0,0 +1,13 @@ +export GDAS_CI_ROOT=/work2/noaa/da/role-da/CI/hercules/GDASApp +export GDAS_CI_HOST='hercules' +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 SLURM_EXCLUSIVE=user +export OMP_NUM_THREADS=1 +ulimit -s unlimited +export PATH=$PATH:/home/role-da/bin +export NTASKS_TESTS=12 +export AUTHORIZED_USERS_FILE=$GDAS_CI_ROOT/authorized_users diff --git a/ci/orion.sh b/ci/orion.sh index 1232d2828..9d0674688 100644 --- a/ci/orion.sh +++ b/ci/orion.sh @@ -1,4 +1,4 @@ -export GDAS_CI_ROOT=/work2/noaa/stmp/cmartin/CI/GDASApp +export GDAS_CI_ROOT=/work2/noaa/da/role-da/CI/orion/GDASApp export GDAS_CI_HOST='orion' export GDAS_MODULE_USE=$GDAS_CI_ROOT/repo/modulefiles export SLURM_ACCOUNT=da-cpu @@ -8,3 +8,6 @@ export SLURM_QOS=debug export SLURM_EXCLUSIVE=user export OMP_NUM_THREADS=1 ulimit -s unlimited +export PATH=$PATH:/home/role-da/bin +export NTASKS_TESTS=12 +export AUTHORIZED_USERS_FILE=$GDAS_CI_ROOT/authorized_users diff --git a/ci/run_ci.sh b/ci/run_ci.sh index 1b5f27231..e92d943ae 100755 --- a/ci/run_ci.sh +++ b/ci/run_ci.sh @@ -9,13 +9,17 @@ usage() { echo echo " -d Run build and ctest for clone in " echo " -o Path to output message detailing results of CI tests" + echo " -w Test GDASApp within the Global Workflow" + echo " -E Regular expression of CTests to exclude" echo " -h display this message and quit" echo exit 1 } # ============================================================================== -while getopts "d:o:h" opt; do +TEST_WORKFLOW=0 +ctest_regex_exclude="" +while getopts "d:o:h:E:w" opt; do case $opt in d) repodir=$OPTARG @@ -23,26 +27,54 @@ while getopts "d:o:h" opt; do o) outfile=$OPTARG ;; + E) + ctest_regex_exclude+=$OPTARG + ;; + w) + TEST_WORKFLOW=1 + ;; h|\?|:) usage ;; esac done +if [[ $TEST_WORKFLOW == 1 ]]; then + export WORKFLOW_BUILD="ON" + + workflow_dir=$repodir + gdasapp_dir=$workflow_dir/sorc/gdas.cd + + build_cmd_dir=$workflow_dir/sorc + build_cmd="./build_all.sh -ug &>> log.build" + build_dir=$workflow_dir/build +else + export BUILD_JOBS=8 + + gdasapp_dir=$repodir + + build_cmd_dir=$gdasapp_dir + build_cmd="./build.sh -t $TARGET &>> log.build" + build_dir=$gdasapp_dir/build +fi + # ============================================================================== # start output file -echo "Automated GDASApp Testing Results:" > $outfile +if [[ $TEST_WORKFLOW == 1 ]]; then + echo "Automated GW-GDASApp Testing Results:" > $outfile +else + echo "Automated GDASApp Testing Results:" > $outfile +fi echo "Machine: ${TARGET}" >> $outfile echo '```' >> $outfile echo "Start: $(date) on $(hostname)" >> $outfile echo "---------------------------------------------------" >> $outfile # ============================================================================== # run build script -cd $repodir +cd $build_cmd_dir module purge -export BUILD_JOBS=8 rm -rf log.build -./build.sh -t $TARGET &>> log.build +$build_cmd build_status=$? if [ $build_status -eq 0 ]; then echo "Build: *SUCCESS*" >> $outfile @@ -50,18 +82,27 @@ if [ $build_status -eq 0 ]; then else echo "Build: *FAILED*" >> $outfile echo "Build: Failed at $(date)" >> $outfile - echo "Build: see output at $repodir/log.build" >> $outfile + echo "Build: see output at $build_cmd_dir/log.build" >> $outfile echo '```' >> $outfile exit $build_status fi +if [[ $TEST_WORKFLOW == 1 ]]; then + ./link_workflow.sh +fi # ============================================================================== # run ctests -cd $repodir/build -module use $GDAS_MODULE_USE +cd $gdasapp_dir/build +module use $gdasapp_dir/modulefiles module load GDAS/$TARGET echo "---------------------------------------------------" >> $outfile rm -rf log.ctest -ctest -R gdasapp --output-on-failure &>> log.ctest +ctest_cmd="ctest -j${NTASKS_TESTS} -R gdasapp" +if [ -n "$ctest_regex_exclude" ]; then + ctest_cmd+=" -E $ctest_regex_exclude" +fi +pwd +echo "Tests: $ctest_cmd" >> $outfile +$ctest_cmd --timeout 7200 --output-on-failure &>> log.ctest ctest_status=$? npassed=$(cat log.ctest | grep "tests passed") if [ $ctest_status -eq 0 ]; then @@ -73,7 +114,8 @@ else echo "Tests: Failed at $(date)" >> $outfile echo "Tests: $npassed" >> $outfile cat log.ctest | grep "(Failed)" >> $outfile - echo "Tests: see output at $repodir/build/log.ctest" >> $outfile + cat log.ctest | grep "(Timeout)" >> $outfile + echo "Tests: see output at $gdasapp_dir/build/log.ctest" >> $outfile fi echo '```' >> $outfile exit $ctest_status diff --git a/ci/run_gw_ci.sh b/ci/run_gw_ci.sh deleted file mode 100755 index ba1874107..000000000 --- a/ci/run_gw_ci.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -set -u - -# ============================================================================== -usage() { - set +x - echo - echo "Usage: $0 -d -o -h" - echo - echo " -d Run build and ctest for clone in " - echo " -o Path to output message detailing results of CI tests" - echo " -h display this message and quit" - echo - exit 1 -} - -# ============================================================================== -while getopts "d:o:h" opt; do - case $opt in - d) - repodir=$OPTARG - ;; - o) - outfile=$OPTARG - ;; - h|\?|:) - usage - ;; - esac -done - -# ============================================================================== -# start output file -echo "Automated GW GDASApp Testing Results:" > $outfile -echo "Machine: ${TARGET}" >> $outfile -echo '```' >> $outfile -echo "Start: $(date) on $(hostname)" >> $outfile -echo "---------------------------------------------------" >> $outfile -# ============================================================================== -# run build and link as part of the workflow -export WORKFLOW_BUILD="ON" -cd $repodir/sorc -module purge -rm -rf log.build -./build_all.sh -u &>> log.build -build_status=$? -if [ $build_status -eq 0 ]; then - echo "Build: *SUCCESS*" >> $outfile - echo "Build: Completed at $(date)" >> $outfile -else - echo "Build: *FAILED*" >> $outfile - echo "Build: Failed at $(date)" >> $outfile - echo "Build: see output at $repodir/sorc/log.build" >> $outfile - echo '```' >> $outfile - exit $build_status -fi -./link_workflow.sh -# ============================================================================== -# run ctests -cd $repodir/sorc/gdas.cd/build -module use $repodir/sorc/gdas.cd/modulefiles -module load GDAS/$TARGET -echo "---------------------------------------------------" >> $outfile -rm -rf log.ctest -ctest -R gdasapp --output-on-failure &>> log.ctest -ctest_status=$? -npassed=$(cat log.ctest | grep "tests passed") -if [ $ctest_status -eq 0 ]; then - echo "Tests: *SUCCESS*" >> $outfile - echo "Tests: Completed at $(date)" >> $outfile - echo "Tests: $npassed" >> $outfile -else - echo "Tests: *Failed*" >> $outfile - echo "Tests: Failed at $(date)" >> $outfile - echo "Tests: $npassed" >> $outfile - cat log.ctest | grep "(Failed)" >> $outfile - echo "Tests: see output at $repodir/sorc/gdas.cd/build/log.ctest" >> $outfile -fi -echo '```' >> $outfile -exit $ctest_status diff --git a/ci/stable_driver.sh b/ci/stable_driver.sh index 4172d6659..ca51f6f7c 100755 --- a/ci/stable_driver.sh +++ b/ci/stable_driver.sh @@ -53,6 +53,7 @@ repo_url="https://github.com/NOAA-EMC/GDASApp.git" workflow_url="https://github.com/NOAA-EMC/global-workflow.git" stableroot=$GDAS_CI_ROOT/stable +[[ -d $stableroot/$datestr ]] && rm -rf $stableroot/$datestr mkdir -p $stableroot/$datestr cd $stableroot/$datestr @@ -63,15 +64,21 @@ git clone --recursive $workflow_url cd $stableroot/$datestr/global-workflow/sorc/gdas.cd git checkout develop git pull +git submodule update --init --recursive # ============================================================================== # update the hashes to the most recent gdasdir=$stableroot/$datestr/global-workflow/sorc/gdas.cd -$my_dir/../ush/submodules/update_develop.sh $gdasdir +$gdasdir/ush/submodules/update_develop.sh $gdasdir + +# ============================================================================== +# email information +PEOPLE="Cory.R.Martin@noaa.gov Russ.Treadon@noaa.gov Guillaume.Vernieres@noaa.gov David.New@noaa.gov" +BODY=$stableroot/$datestr/stable_nightly # ============================================================================== # run the automated testing -$my_dir/run_gw_ci.sh -d $stableroot/$datestr/global-workflow -o $stableroot/$datestr/output +$my_dir/run_ci.sh -d $stableroot/$datestr/global-workflow -o $stableroot/$datestr/output -w ci_status=$? total=0 if [ $ci_status -eq 0 ]; then @@ -106,7 +113,6 @@ if [ $ci_status -eq 0 ]; then fi git diff-index --quiet HEAD || git commit -m "Update to new stable build on $datestr" total=$(($total+$?)) - caution="" if [ $total -ne 0 ]; then echo "Unable to commit" >> $stableroot/$datestr/output fi @@ -116,22 +122,30 @@ if [ $ci_status -eq 0 ]; then echo "Unable to push" >> $stableroot/$datestr/output fi if [ $total -ne 0 ]; then - echo "Issue merging with develop. please manually fix" - PEOPLE="Cory.R.Martin@noaa.gov Russ.Treadon@noaa.gov Guillaume.Vernieres@noaa.gov" SUBJECT="Problem updating feature/stable-nightly branch of GDASApp" - BODY=$stableroot/$datestr/output_stable_nightly cat > $BODY << EOF -Problem updating feature/stable-nightly branch of GDASApp. Please check $stableroot/$datestr/GDASApp +Problem updating feature/stable-nightly branch of GDASApp. Please check $stableroot/$datestr/global-workflow EOF - mail -r "Darth Vader - NOAA Affiliate " -s "$SUBJECT" "$PEOPLE" < $BODY + else - echo "Stable branch updated" + SUBJECT="Success updating feature/stable-nightly branch of GDASApp" + cat > $BODY << EOF +feature/stable-nightly branch of GDASApp updated successfully. See $stableroot/$datestr/global-workflow for details. + +EOF + fi else # do nothing - echo "Testing failed, stable branch will not be updated" + SUBJECT="Testing or building of feature/stable-nightly branch of GDASApp failed" + cat > $BODY << EOF +Testing or building of feature/stable-nightly branch of GDASApp failed. Please check $stableroot/$datestr/global-workflow. + +EOF fi +echo $SUBJECT +mail -r "Darth Vader - NOAA Affiliate " -s "$SUBJECT" "$PEOPLE" < $BODY # ============================================================================== # publish some information to RZDM for quick viewing # THIS IS A TODO FOR NOW diff --git a/parm/aero/berror/aero_diagb.yaml.j2 b/parm/aero/berror/aero_diagb.yaml.j2 index c62947f1e..95be9e474 100644 --- a/parm/aero/berror/aero_diagb.yaml.j2 +++ b/parm/aero/berror/aero_diagb.yaml.j2 @@ -76,25 +76,25 @@ variables: - mass_fraction_of_sea_salt003_in_air - mass_fraction_of_sea_salt004_in_air -#global rescale: -# 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_rescale }} -# npy: {{ npy_rescale }} -# npz: {{ npz_ges }} -# field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml -# rescale stddev: -# filetype: fms restart -# skip coupler file: true -# dateapath: ./stddev -# filename_trcr: rescale.fv_tracer.res.nc -# filename_cplr: rescale.coupler.res +global rescale: + 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_rescale }} + npy: {{ npy_rescale }} + npz: {{ npz_ges }} + field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_restart.yaml + rescale stddev: + filetype: fms restart + skip coupler file: true + dateapath: ./stddev + filename_trcr: rescale.fv_tracer.res.nc + filename_cplr: rescale.coupler.res number of halo points: {{ aero_diagb_n_halo }} number of neighbors: {{ aero_diagb_n_neighbors }} diff --git a/parm/aero/jcb-base.yaml.j2 b/parm/aero/jcb-base.yaml.j2 index 86988206d..6d1cf7b7f 100644 --- a/parm/aero/jcb-base.yaml.j2 +++ b/parm/aero/jcb-base.yaml.j2 @@ -74,19 +74,22 @@ aero_background_error_time_fv3: "{{ background_time | to_fv3time }}" # Background error aero_berror_data_directory: "{{ DATA }}/berror" aero_berror_diffusion_directory: "{{ DATA }}/diffusion" -aero_standard_devation_path: ./stddev +aero_standard_deviation_path: ./stddev aero_climatological_b_path: ./clm_stddev +aero_rescale_b_path: ./rescale aero_diagb_weight: {{ aero_diagb_weight | default(1.0, true) }} aero_diagb_static_rescale_factor: {{aero_staticb_rescaling_factor | default(1.0, true) }} -aero_diagb_rescale_factor: {{aero_diagb_rescale | default(1.0, true) }} -aero_diagb_n_halo: {{ aero_diagb_n_halo | default(1, true) }} -aero_diagb_n_neighbors: {{ aero_diagb_n_neighbors | default(1, true) }} -aero_diagb_smooth_horiz_iter: {{ aero_diagb_smooth_horiz_iter | default(1, true) }} -aero_diagb_smooth_vert_iter: {{ aero_diagb_smooth_vert_iter | default(1, true) }} -aero_diffusion_iter: {{ aero_diffusion_iter | default(1, true) }} +aero_diagb_n_halo: {{ aero_diagb_n_halo | default(0) }} +aero_diagb_n_neighbors: {{ aero_diagb_n_neighbors | default(0) }} +aero_diagb_smooth_horiz_iter: {{ aero_diagb_smooth_horiz_iters | default(0) }} +aero_diagb_smooth_vert_iter: {{ aero_diagb_smooth_vert_iters | default(0) }} +aero_diffusion_iter: {{ aero_diffusion_iter | default(0) }} aero_diffusion_horiz_len: {{ aero_diffusion_horiz_len | default(1.0, true)}} aero_diffusion_fixed_val: {{ aero_diffusion_fixed_val | default(1.0, true)}} +# Analysis +aero_analysis_path: ./anl + # Forecasting aero_forecast_timestep: "{{ BKG_TSTEP }}" diff --git a/parm/atm/jcb-prototype_3dvar-fv3inc.yaml.j2 b/parm/atm/jcb-prototype_3dvar-fv3inc.yaml.j2 new file mode 100644 index 000000000..1263650d6 --- /dev/null +++ b/parm/atm/jcb-prototype_3dvar-fv3inc.yaml.j2 @@ -0,0 +1,3 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_variational diff --git a/parm/atm/jcb-prototype_lgetkf-fv3inc.yaml.j2 b/parm/atm/jcb-prototype_lgetkf-fv3inc.yaml.j2 new file mode 100644 index 000000000..82f02f4d6 --- /dev/null +++ b/parm/atm/jcb-prototype_lgetkf-fv3inc.yaml.j2 @@ -0,0 +1,3 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_lgetkf diff --git a/parm/jcb-algorithms b/parm/jcb-algorithms index 43d8ff6ba..e854bd87f 160000 --- a/parm/jcb-algorithms +++ b/parm/jcb-algorithms @@ -1 +1 @@ -Subproject commit 43d8ff6ba14baf9402ee58d0f3351a143c21211b +Subproject commit e854bd87ff18ca053b2fe558b57b212ff159fe72 diff --git a/parm/jcb-gdas b/parm/jcb-gdas index 77fdc329d..8ee71d261 160000 --- a/parm/jcb-gdas +++ b/parm/jcb-gdas @@ -1 +1 @@ -Subproject commit 77fdc329d45b54529499f4033851e50e1dee0697 +Subproject commit 8ee71d26111a46d01f0dc9796d49e19fdcf2cf4f diff --git a/parm/snow/letkfoi/apply_incr_nml.j2 b/parm/snow/apply_incr_nml.j2 similarity index 100% rename from parm/snow/letkfoi/apply_incr_nml.j2 rename to parm/snow/apply_incr_nml.j2 diff --git a/parm/snow/letkfoi/ens_apply_incr_nml.j2 b/parm/snow/ens_apply_incr_nml.j2 similarity index 74% rename from parm/snow/letkfoi/ens_apply_incr_nml.j2 rename to parm/snow/ens_apply_incr_nml.j2 index edd4b116f..4a85b8416 100644 --- a/parm/snow/letkfoi/ens_apply_incr_nml.j2 +++ b/parm/snow/ens_apply_incr_nml.j2 @@ -3,8 +3,8 @@ hour_str = "{{ current_cycle | strftime('%H') }}", res = {{ CASE_ENS[1:] }}, frac_grid = .true., - rst_path = "{{ DATAROOT }}/anl/mem{{ MYMEM }}", - inc_path = "{{ DATAROOT }}/inc/ensmean", + rst_path = "{{ DATA }}/anl/mem{{ MYMEM }}", + inc_path = "{{ DATA }}/anl", orog_path = "{{ HOMEgfs }}/fix/orog/{{ CASE_ENS }}", otype = "{{ CASE_ENS }}.mx{{ OCNRES }}_oro_data" / diff --git a/parm/snow/jcb-base.yaml.j2 b/parm/snow/jcb-base.yaml.j2 index 672b1bf8f..69e097d74 100644 --- a/parm/snow/jcb-base.yaml.j2 +++ b/parm/snow/jcb-base.yaml.j2 @@ -3,15 +3,13 @@ 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" +app_path_observations: "{{PARMgfs}}/gdas/jcb-gdas/observations/snow" +app_path_observation_chronicle: "{{PARMgfs}}/gdas/jcb-gdas/observation_chronicle/snow" # 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 +final_increment_file: snow_final_increment_fms model_file: model_pseudo initial_condition_file: background # Initial conditions for 4D apps is background @@ -23,60 +21,52 @@ 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_background_time_fv3: "{{ bkg_time_fv3 }}" 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] +analysis_variables: [totalSnowDepth] minimizer: DRPCG final_diagnostics_departures: anlmob final_prints_frequency: PT3H cost_type: 3D-Var -number_of_outer_loops: 2 +number_of_outer_loops: 1 # 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 +snow_layout_x: {{ layout_x | default(1, true) }} +snow_layout_y: {{ layout_y | default(1, true) }} +snow_npx_ges: {{ npx_ges | default(49, true) }} +snow_npy_ges: {{ npy_ges | default(49, true) }} +snow_npz_ges: {{ npz_ges | default(127, true) }} +snow_npx_anl: {{ npx_ges | default(49, true) }} +snow_npy_anl: {{ npy_ges | default(49, true) }} +snow_npz_anl: {{ npz_ges | default(127, true) }} + +snow_fv3jedi_files_path: ./fv3jedi # Ideally this would be {{DATA}}/fv3jedi but FMS +snow_orog_files_path: "{{ FIXgfs }}/orog/{{ CASE }}" +snow_orog_prefix: "{{ CASE }}.mx{{ OCNRES }}" # Background -background_path: ./bkg +snow_background_path: {{snow_bkg_path}} background_ensemble_path: ./ens/mem%mem% # Background error -bump_data_directory: "{{ DATA }}/berror" -gsibec_path: "{{ DATA }}/berror" +snow_bump_data_directory: "{{ 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}}" +snow_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." +snow_forecast_length: "{{ SNOW_WINDOW_LENGTH }}" +snow_forecast_timestep: "{{ BKG_TSTEP }}" # Observation things @@ -86,29 +76,32 @@ 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" +snow_obsdataroot_path: "{{COMIN_OBS}}" +snow_obsdatain_path: "{{snow_obsdatain_path}}" +snow_obsdatain_prefix: "{{OPREFIX}}" +snow_obsdatain_suffix: ".tm00.bufr_d" -atm_obsdataout_path: "{{atm_obsdataout_path}}" -atm_obsdataout_prefix: diag_ -atm_obsdataout_suffix: "_{{ current_cycle | to_YMDH }}.nc" +snow_obsdataout_path: "{{snow_obsdataout_path}}" +snow_obsdataout_prefix: diag_ +snow_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" - +snow_obsbiasin_path: "{{DATA}}/obs/" +snow_obsbiasin_prefix: "{{GPREFIX}}" +snow_obsbiasin_suffix: ".satbias.nc" +snow_obstlapsein_prefix: "{{GPREFIX}}" +snow_obstlapsein_suffix: ".tlapse.txt" +snow_obsbiascovin_prefix: "{{GPREFIX}}" +snow_obsbiascovin_suffix: ".satbias_cov.nc" + +snow_obsbiasout_path: "{{DATA}}/bc/" +snow_obsbiasout_prefix: "{{APREFIX}}" +snow_obsbiasout_suffix: ".satbias.nc" +snow_obsbiascovout_prefix: "{{APREFIX}}" +snow_obsbiascovout_suffix: ".satbias_cov.nc" + +# Ensemble mean things +snow_number_ensemble_members: {{NMEM_ENS}} # Local Ensemble DA (LETKF) # ------------------------- @@ -133,5 +126,5 @@ 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." +ensemble_increment_prefix: "./anl/mem%{member}%/snowinc." +#posterior_output_gaussian: "./mem%{member}%/snowanl." diff --git a/parm/snow/jcb-prototype_2dvar.yaml.j2 b/parm/snow/jcb-prototype_2dvar.yaml.j2 new file mode 100644 index 000000000..5fb43600c --- /dev/null +++ b/parm/snow/jcb-prototype_2dvar.yaml.j2 @@ -0,0 +1,12 @@ +# Algorithm +# --------- +algorithm: 3dvar + +# Observation things +# ------------------ +observations: +# - adpsfc_snow + - ims_snow +# - ghcn_snow + - sfcsno + - snocvr_snow diff --git a/parm/snow/letkfoi/letkfoi.yaml.j2 b/parm/snow/letkfoi/letkfoi.yaml.j2 deleted file mode 100644 index e96425581..000000000 --- a/parm/snow/letkfoi/letkfoi.yaml.j2 +++ /dev/null @@ -1,66 +0,0 @@ -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 - time invariant fields: - state fields: - datetime: '{{ SNOW_WINDOW_BEGIN | to_isotime }}' - filetype: fms restart - skip coupler file: true - state variables: [orog_filt] - datapath: {{ FIXgfs }}/orog/{{ CASE }}/ - filename_orog: {{ CASE }}.mx{{ OCNRES }}_oro_data.nc - -time window: - begin: '{{ SNOW_WINDOW_BEGIN | to_isotime }}' - length: {{ SNOW_WINDOW_LENGTH }} - bound to include: begin - -background: - datetime: '{{ current_cycle | to_isotime }}' - members from template: - template: - datetime: '{{ current_cycle | to_isotime }}' - filetype: fms restart - state variables: [snodl,vtype,slmsk] - datapath: ./bkg/mem%mem%/RESTART - filename_sfcd: '{{ current_cycle | to_fv3time }}.sfc_data.nc' - filename_cplr: '{{ current_cycle | to_fv3time }}.coupler.res' - pattern: '%mem%' - nmembers: 2 - zero padding: 3 - -observations: -{% filter indent(width=2) %} -{% set snow_obs_list = 'OBS_LIST' | getenv('snow/obs/lists/obs_list.yaml.j2') %} -{% include snow_obs_list %} -{% endfilter %} - -driver: - save posterior mean: false - save posterior ensemble: false - save posterior mean increment: true - -local ensemble DA: - solver: LETKF - inflation: - rtps: 0.0 - rtpp: 0.0 - mult: 1.0 - -output increment: - datapath: ./anl - prefix: snowinc - filetype: fms restart - filename_sfcd: '{{ current_cycle | to_fv3time }}.sfc_data.nc' - filename_cplr: '{{ current_cycle | to_fv3time }}.coupler.res' - state variables: [snodl,vtype,slmsk] - diff --git a/parm/snow/obs/config/adpsfc_snow.yaml.j2 b/parm/snow/obs/config/adpsfc_snow.yaml.j2 deleted file mode 100644 index 1ddcb7e21..000000000 --- a/parm/snow/obs/config/adpsfc_snow.yaml.j2 +++ /dev/null @@ -1,109 +0,0 @@ -- obs space: - name: adpsfc_snow - distribution: - name: Halo - halo size: 250e3 - obsdatain: - engine: - type: H5File - obsfile: './obs/{{ OPREFIX }}adpsfc_snow.nc4' - obsdataout: - engine: - type: H5File - obsfile: './diags/diag_adpsfc_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/ghcn_snow.yaml.j2 b/parm/snow/obs/config/ghcn_snow.yaml.j2 deleted file mode 100644 index b2a037cf1..000000000 --- a/parm/snow/obs/config/ghcn_snow.yaml.j2 +++ /dev/null @@ -1,53 +0,0 @@ -- obs space: - name: ghcn_snow - distribution: - name: Halo - simulated variables: [totalSnowDepth] - obsdatain: - engine: - type: H5File - obsfile: './obs/{{ OPREFIX }}ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' - obsdataout: - engine: - type: H5File - obsfile: './diags/diag_ghcn_snow_{{ current_cycle | to_YMDH }}.nc4' - - obs operator: - name: Identity - 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 filters: - - filter: Bounds Check - filter variables: - - name: totalSnowDepth - minvalue: 0.0 - - filter: Domain Check - where: - - variable: - name: MetaData/height - 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: Background Check - filter variables: - - name: totalSnowDepth - threshold: 6.25 - action: - name: reject diff --git a/parm/snow/obs/config/ims_snow.yaml.j2 b/parm/snow/obs/config/ims_snow.yaml.j2 deleted file mode 100644 index c222d0dfe..000000000 --- a/parm/snow/obs/config/ims_snow.yaml.j2 +++ /dev/null @@ -1,46 +0,0 @@ -- obs space: - name: ims_snow - distribution: - name: Halo - halo size: 250e3 - obsdatain: - engine: - type: H5File - obsfile: './obs/{{ OPREFIX }}ims_snow.nc4' - obsdataout: - engine: - type: H5File - obsfile: './diags/diag_ims_snow.nc4' - simulated variables: [totalSnowDepth] - obs operator: - name: Identity - obs error: - covariance model: diagonal - obs localizations: - - localization method: Horizontal SOAR - lengthscale: 250e3 - soar horizontal decay: 0.000021 - max nobs: 1 - obs filters: - - filter: Bounds Check - filter variables: - - name: totalSnowDepth - minvalue: 0.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: Background Check # gross error check - filter variables: - - name: totalSnowDepth - threshold: 6.25 - action: - name: reject diff --git a/parm/snow/obs/config/sfcsno_snow.yaml.j2 b/parm/snow/obs/config/sfcsno_snow.yaml.j2 deleted file mode 100644 index 947d6340e..000000000 --- a/parm/snow/obs/config/sfcsno_snow.yaml.j2 +++ /dev/null @@ -1,113 +0,0 @@ -- obs space: - name: sfcsno_snow - distribution: - name: Halo - halo size: 250e3 - obsdatain: - engine: - type: script - script file: "{{ USHgfs }}/bufr2ioda_sfcsno_bufr_encoder.py" - args: - input_path: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno.tm00.bufr_d' - mapping_path: '{{ DATA }}/obs/bufr_sfcsno_mapping.yaml' - obsfile: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno.tm00.bufr_d' - 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 - maxvalue: 999999999.9 - - 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 deleted file mode 100644 index 45a361f32..000000000 --- a/parm/snow/obs/config/snocvr_snow.yaml.j2 +++ /dev/null @@ -1,103 +0,0 @@ -- obs space: - name: snocvr_snow - distribution: - name: Halo - halo size: 250e3 - obsdatain: - engine: - type: H5File - obsfile: './obs/{{ OPREFIX }}snocvr_snow.nc4' - obsdataout: - engine: - type: H5File - obsfile: './diags/diag_snocvr_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 - 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/prep/fims.nml.j2 b/parm/snow/prep/fims.nml.j2 index 9b8408b32..b9a8ded59 100644 --- a/parm/snow/prep/fims.nml.j2 +++ b/parm/snow/prep/fims.nml.j2 @@ -6,7 +6,7 @@ yyyymmddhh = "{{ current_cycle | to_YMD }}.{{ current_cycle.strftime('%H') }}", imsformat = 1, imsversion = "1.3", - fcst_path = "./bkg/" + fcst_path = "{{ ims_fcst_path }}" IMS_OBS_PATH = "./obs/", IMS_IND_PATH = "./obs/" / diff --git a/parm/snow/prep/prep_ims.yaml.j2 b/parm/snow/prep/prep_ims.yaml.j2 index 0c2bbc163..938d0503c 100644 --- a/parm/snow/prep/prep_ims.yaml.j2 +++ b/parm/snow/prep/prep_ims.yaml.j2 @@ -2,9 +2,9 @@ calcfims: mkdir: - '{{ DATA }}/obs' copy: - - ['{{ COM_OBS }}/{{ OPREFIX }}imssnow96.asc', '{{ DATA }}/obs/ims{{ current_cycle | to_julian }}_4km_v1.3.asc'] + - ['{{ COMIN_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: - - ['{{ DATA }}/ims_snow_{{ current_cycle | to_YMDH }}.nc4', '{{ COM_OBS }}/{{ OPREFIX }}ims_snow.nc4'] + - ['{{ DATA }}/ims_snow_{{ current_cycle | to_YMDH }}.nc4', '{{ DATA }}/obs/{{ OPREFIX }}ims_snow.tm00.nc'] diff --git a/parm/soca/berror/soca_ensrecenter.yaml b/parm/soca/berror/soca_ensrecenter.yaml index e3e63b7a1..b70060140 100644 --- a/parm/soca/berror/soca_ensrecenter.yaml +++ b/parm/soca/berror/soca_ensrecenter.yaml @@ -4,104 +4,60 @@ geometry: mom6_input_nml: mom_input.nml fields metadata: ./fields_metadata.yaml -date: '{{ ATM_WINDOW_BEGIN }}' +date: '{{ MARINE_WINDOW_END_ISO }}' -layers variable: [hocn] +layers variable: [sea_water_cell_thickness] # TODO(AFE) fix ice recentering in cycled da -#increment variables: [tocn, socn, uocn, vocn, ssh, hocn, cicen, hicen, hsnon] -increment variables: [tocn, socn, uocn, vocn, ssh, hocn] - -set increment variables to zero: [ssh] +increment variables: +- sea_water_potential_temperature +- sea_water_salinity +- eastward_sea_water_velocity +- northward_sea_water_velocity +set increment variables to zero: +- eastward_sea_water_velocity +- northward_sea_water_velocity vertical geometry: - date: '{{ ATM_WINDOW_BEGIN }}' + date: '{{ MARINE_WINDOW_BEGIN_ISO }}' basename: ./INPUT/ ocn_filename: MOM.res.nc read_from_file: 3 -add recentering increment: false +add recentering increment: true +recentering around deterministic: true soca increments: # Could also be states, but they are read as increments number of increments: {{ NMEM_ENS }} pattern: '%mem%' template: - date: '{{ ATM_WINDOW_BEGIN }}' + date: '{{ MARINE_WINDOW_END_ISO }}' basename: ./ens/ ocn_filename: 'ocean.%mem%.nc' -# TODO(AFE) fix ice recentering in cycled da + # TODO(AFE) fix ice recentering in cycled da # ice_filename: 'ice.%mem%.nc' read_from_file: 3 -steric height: - linear variable changes: - - linear variable change name: BalanceSOCA # Only the steric balance is applied - -#ensemble mean output: -# datadir: ./static_ens -# date: '{{ ATM_WINDOW_BEGIN }}' -# exp: ens_mean -# type: incr - -ssh output: - unbalanced: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - exp: ssh_unbal_stddev - type: incr - - steric: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - exp: ssh_steric_stddev - type: incr - - total: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - exp: ssh_total_stddev - type: incr - - explained variance: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - exp: steric_explained_variance - type: incr - - recentering error: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - exp: ssh_recentering_error - type: incr - -background error output: - datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' - 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: # TODO(AFE) fix ice recentering in cycled da - # state variables: [tocn, socn, uocn, vocn, ssh, hocn, layer_depth, mld, cicen, hicen, hsnon] - state variables: [tocn, socn, uocn, vocn, ssh, hocn, layer_depth, mld] - date: '{{ ATM_WINDOW_BEGIN }}' - basename: ./INPUT/ - ocn_filename: MOM.res.nc + state variables: + - sea_water_potential_temperature + - sea_water_salinity + - eastward_sea_water_velocity + - northward_sea_water_velocity + - sea_water_cell_thickness + - sea_water_depth + - ocean_mixed_layer_thickness + date: '{{ MARINE_WINDOW_END_ISO }}' + basename: ./bkg/ + ocn_filename: ocean.bkg.f009.nc # TODO(AFE) fix ice recentering in cycled da #ice_filename: cice.res.nc read_from_file: 1 output increment: datadir: ./ - date: '{{ ATM_WINDOW_BEGIN }}' + date: '{{ MARINE_WINDOW_END_ISO }}' exp: trash type: incr output file: 'ocn.recenter.incr.%mem%.nc' diff --git a/parm/soca/berror/soca_hybrid_bmat.yaml b/parm/soca/berror/soca_hybrid_bmat.yaml deleted file mode 100644 index 0e2340da8..000000000 --- a/parm/soca/berror/soca_hybrid_bmat.yaml +++ /dev/null @@ -1,92 +0,0 @@ -covariance model: hybrid -components: -- covariance: - covariance model: SABER - saber central block: - saber block name: diffusion - active variables: [tocn, socn, ssh, cicen] - geometry: - mom6_input_nml: mom_input.nml - fields metadata: ./fields_metadata.yaml - group mapping: - - name: ocean - variables: - - tocn - - socn - - ssh - - name: ice - variables: - - cicen - read: - groups: - - name: ocean - horizontal: - filename: hz_ocean.nc - vertical: - filename: vt_ocean.nc - - name: ice - horizontal: - filename: hz_ice.nc - - saber outer blocks: - - saber block name: StdDev - read: - model file: - date: '{{ATM_WINDOW_MIDDLE}}' - basename: ./ - ocn_filename: 'ocean.bkgerr_stddev.nc' - ice_filename: 'ice.bkgerr_stddev.nc' - read_from_file: 3 - - linear variable change: - input variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] - output variables: [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] - linear variable changes: - - linear variable change name: BalanceSOCA - - weight: - value: 1.00 - -- covariance: - covariance model: ensemble - members from template: - template: - read_from_file: 1 - date: '{{ATM_WINDOW_MIDDLE}}' - basename: ./ens/ - ocn_filename: 'ocn.pert.steric.%mem%.nc' - ice_filename: 'ice.%mem%.nc' - state variables: [tocn, socn, ssh, uocn, vocn, cicen, hicen, hsnon] - pattern: '%mem%' - nmembers: ${ENS_SIZE} - localization: - localization method: SABER - saber central block: - saber block name: diffusion - active variables: [tocn, socn, ssh] - geometry: - mom6_input_nml: mom_input.nml - fields metadata: ./fields_metadata.yaml - group mapping: - - name: ocean - variables: [tocn, socn, ssh, uocn, vocn] - - name: ice - variables: [cicen, hicen, hsnon] - read: - groups: - - name: ocean - multivariate strategy: duplicated - horizontal: - filename: hz_ocean.nc - vertical: - strategy: duplicated - - name: ice - horizontal: - filename: hz_ice.nc - - weight: - read_from_file: 3 - basename: ./ - ocn_filename: 'ocean.ens_weights.nc' - ice_filename: 'ice.ens_weights.nc' - date: '{{ATM_WINDOW_MIDDLE}}' diff --git a/parm/soca/ensda/stage_ens_mem.yaml.j2 b/parm/soca/ensda/stage_ens_mem.yaml.j2 index d0dca6e18..af47348a6 100644 --- a/parm/soca/ensda/stage_ens_mem.yaml.j2 +++ b/parm/soca/ensda/stage_ens_mem.yaml.j2 @@ -9,7 +9,8 @@ # create working directories ###################################### mkdir: - - "{{ ENSPERT_RELPATH }}/ens" +- "{{ DATAens }}/ens" + ###################################### # copy ensemble background files ###################################### @@ -21,6 +22,6 @@ copy: '${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", "{{ ENSPERT_RELPATH }}/ens/ocean.{{ mem }}.nc"] - - ["{{ COM_ICE_HISTORY_TMPL | replace_tmpl(tmpl_dict) }}/{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc", "{{ ENSPERT_RELPATH }}/ens/ice.{{ mem }}.nc"] + - ["{{ COM_OCEAN_HISTORY_TMPL | replace_tmpl(tmpl_dict) }}/{{ GDUMP_ENS }}.ocean.t{{ gcyc }}z.inst.f006.nc", "{{ DATAens }}/ens/ocean.{{ mem }}.nc"] + - ["{{ COM_ICE_HISTORY_TMPL | replace_tmpl(tmpl_dict) }}/{{ GDUMP_ENS }}.ice.t{{ gcyc }}z.inst.f006.nc", "{{ DATAens }}/ens/ice.{{ mem }}.nc"] {% endfor %} diff --git a/parm/soca/marine-jcb-base.yaml b/parm/soca/marine-jcb-base.yaml index 3a9d40223..5bbabe4c5 100644 --- a/parm/soca/marine-jcb-base.yaml +++ b/parm/soca/marine-jcb-base.yaml @@ -24,8 +24,15 @@ minimizer: RPCG final_diagnostics_departures: oman final_prints_frequency: PT3H number_of_outer_loops: 1 -analysis_variables: [sea_ice_area_fraction, sea_ice_thickness, sea_ice_snow_thickness, sea_water_salinity, sea_water_potential_temperature, eastward_sea_water_velocity, northward_sea_water_velocity, sea_surface_height_above_geoid] - +analysis_variables: +- sea_ice_area_fraction +- sea_ice_thickness +- sea_ice_snow_thickness +- sea_water_salinity +- sea_water_potential_temperature +#- eastward_sea_water_velocity +#- northward_sea_water_velocity +- sea_surface_height_above_geoid # Model things # ------------ @@ -50,7 +57,7 @@ marine_forecast_timestep: PT3H # Background error model background_error_file: '{{berror_model}}' marine_number_ensemble_members: '{{NMEM_ENS}}' -marine_stddev_time: '{{MARINE_WINDOW_MIDDLE}}' +marine_stddev_time: '{{ MARINE_WINDOW_MIDDLE | to_isotime }}' # Observations observations: all_observations diff --git a/parm/soca/obsprep/obsprep_config.yaml b/parm/soca/obsprep/obsprep_config.yaml index 0b3c56764..905f49be6 100644 --- a/parm/soca/obsprep/obsprep_config.yaml +++ b/parm/soca/obsprep/obsprep_config.yaml @@ -67,7 +67,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r9_ma1_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_ma1_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc - obs space: @@ -75,7 +75,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r9_n20_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_n20_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc - obs space: @@ -83,7 +83,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r9_n21_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_n21_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc - obs space: @@ -91,7 +91,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r4_npp_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_npp_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc - obs space: @@ -99,7 +99,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r9_gpm_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_gpm_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc - obs space: @@ -107,7 +107,7 @@ observations: provider: MIRS dmpdir subdir: ocean/icec type: nc - dmpdir regex: 'NPR-MIRS-IMG_v11r4_f17_s*.nc' + dmpdir regex: 'NPR-MIRS-IMG_v11r?_f17_s*.nc' ocean basin: RECCAP2_region_masks_all_v20221025.nc # SST @@ -160,7 +160,7 @@ observations: name: sst_viirs_npp_l3u provider: GHRSST dmpdir subdir: ocean/sst - type: nc + type: nc dmpdir regex: '*-L3U_GHRSST-SSTsubskin-VIIRS_NPP-ACSPO_V*.nc' bounds: units: C @@ -230,7 +230,7 @@ observations: stride: 15 min number of obs: 10 ocean basin: RECCAP2_region_masks_all_v20221025.nc - + # in situ: monthly - obs space: name: insitu_profile_bathy @@ -285,7 +285,7 @@ observations: name: insitu_surface_trkob provider: GTS dmpdir subdir: atmos - type: bufr + type: bufr dmpdir regex: 'gdas.*.trkob.*.bufr_d' # in situ: daily @@ -316,5 +316,3 @@ observations: dmpdir subdir: atmos type: bufr dmpdir regex: 'gdas.*.mbuoyb.*.bufr_d' - - diff --git a/sorc/land-imsproc b/sorc/land-imsproc index bbe3f311d..7ca1c7441 160000 --- a/sorc/land-imsproc +++ b/sorc/land-imsproc @@ -1 +1 @@ -Subproject commit bbe3f311dc310020319c313cde1a2ee8a3c47a36 +Subproject commit 7ca1c7441042558cf41a0753f80191a0026a1126 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cae0d55ec..a31f5443e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,7 +24,6 @@ file(ARCHIVE_EXTRACT INPUT ${CMAKE_CURRENT_BINARY_DIR}/${TAR} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # list of test binary/data files to install list(APPEND test_data - ${CMAKE_CURRENT_BINARY_DIR}/testdata/atminc_compress.nc4 ${CMAKE_CURRENT_BINARY_DIR}/testdata/adt.nc ${CMAKE_CURRENT_BINARY_DIR}/testdata/sst.nc ${CMAKE_CURRENT_BINARY_DIR}/testdata/sss.nc @@ -120,11 +119,6 @@ add_test(NAME test_gdasapp_check_yaml_keys # WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/) # commented out above test because it does not really do as advertised with all these templates which are not valid yaml -# test for ush/jediinc2fv3.py -add_test(NAME test_gdasapp_jedi_increment_to_fv3 - COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/ush/jediinc2fv3.py ${PROJECT_BINARY_DIR}/test/testdata/atmges_compress.nc4 ${PROJECT_BINARY_DIR}/test/testdata/atminc_compress.nc4 ${PROJECT_BINARY_DIR}/test/testoutput/fv_increment.nc - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/) - # high level tests that require the global-workflow # TODO(AFE) see GDASApp issue #1213 #if (WORKFLOW_TESTS) @@ -136,7 +130,6 @@ add_test(NAME test_gdasapp_jedi_increment_to_fv3 #endif() if (${BUILD_GDASBUNDLE}) - add_subdirectory(fv3jedi) # fv3jedi tests add_subdirectory(snow) # snow da tests add_subdirectory(gw-ci) # subset of the global-workflow ci tests endif() diff --git a/test/atm/global-workflow/CMakeLists.txt b/test/atm/global-workflow/CMakeLists.txt index 925a73677..1741a20f6 100644 --- a/test/atm/global-workflow/CMakeLists.txt +++ b/test/atm/global-workflow/CMakeLists.txt @@ -1,63 +1,86 @@ # test for creating an experiment directory within the global-workflow file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) -add_test(NAME test_gdasapp_setup_atm_cycled_exp - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/setup_workflow_exp.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_var_init - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_init.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_var_run - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_run.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_var_inc - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_inc.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_var_final - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_final.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_init - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_init.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_letkf - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_letkf.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_init_split - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_init_split.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_obs - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_obs.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_sol - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_sol.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) +ecbuild_add_test(TARGET test_gdasapp_setup_atm_jjob_cycled_exp + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/setup_workflow_exp.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_var_init + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_init.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_setup_atm_jjob_cycled_exp) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_var_run + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_run.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_var_init) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_var_inc + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_inc.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_var_run) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_var_final + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_var_final.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_var_inc) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_init + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_init.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_setup_atm_jjob_cycled_exp) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_letkf + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_letkf.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_init) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_init_split + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_init_split.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_letkf) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_obs + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_obs.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_init_split) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_sol + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_sol.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_obs) -add_test(NAME test_gdasapp_atm_jjob_ens_inc - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_inc.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) - -add_test(NAME test_gdasapp_atm_jjob_ens_final - COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_final.sh - ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun) +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_inc + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_inc.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_sol) + +ecbuild_add_test(TARGET test_gdasapp_atm_jjob_ens_final + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/atm/global-workflow/jjob_ens_final.sh + ARGS ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/atm/global-workflow/testrun + TEST_DEPENDS test_gdasapp_atm_jjob_ens_inc) diff --git a/test/atm/global-workflow/config.yaml b/test/atm/global-workflow/config.yaml index d8bf2e4c2..d6d4b0343 100644 --- a/test/atm/global-workflow/config.yaml +++ b/test/atm/global-workflow/config.yaml @@ -8,9 +8,11 @@ base: DUMPDIR: "@dumpdir@" STMP: "@bindir@/test/atm/global-workflow/testrun" PTMP: "@bindir@/test/atm/global-workflow/testrun" + DO_TEST_MODE: "YES" atmanl: JCB_ALGO_YAML_VAR: "@srcdir@/test/atm/global-workflow/jcb-prototype_3dvar.yaml.j2" + JCB_ALGO_YAML_FV3INC: "@srcdir@/test/atm/global-workflow/jcb-prototype_3dvar-fv3inc.yaml.j2" STATICB_TYPE: "identity" ATMRES_ANL: "C48" LAYOUT_X_ATMANL: 1 @@ -20,5 +22,6 @@ atmensanl: JCB_ALGO_YAML_LETKF: "@srcdir@/test/atm/global-workflow/jcb-prototype_lgetkf.yaml.j2" JCB_ALGO_YAML_OBS: "@srcdir@/test/atm/global-workflow/jcb-prototype_lgetkf_observer.yaml.j2" JCB_ALGO_YAML_SOL: "@srcdir@/test/atm/global-workflow/jcb-prototype_lgetkf_solver.yaml.j2" + JCB_ALGO_YAML_FV3INC: "@srcdir@/test/atm/global-workflow/jcb-prototype_lgetkf-fv3inc.yaml.j2" LAYOUT_X_ATMENSANL: 1 LAYOUT_Y_ATMENSANL: 1 diff --git a/test/atm/global-workflow/jcb-prototype_3dvar-fv3inc.yaml.j2 b/test/atm/global-workflow/jcb-prototype_3dvar-fv3inc.yaml.j2 new file mode 100644 index 000000000..1b7d705df --- /dev/null +++ b/test/atm/global-workflow/jcb-prototype_3dvar-fv3inc.yaml.j2 @@ -0,0 +1,13 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_variational + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'gdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_3dvar-fv3inc.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_3dvar-fv3inc.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/atm/global-workflow/jcb-prototype_3dvar.yaml.j2 b/test/atm/global-workflow/jcb-prototype_3dvar.yaml.j2 index e16f86ecc..2e0961b4f 100644 --- a/test/atm/global-workflow/jcb-prototype_3dvar.yaml.j2 +++ b/test/atm/global-workflow/jcb-prototype_3dvar.yaml.j2 @@ -17,7 +17,10 @@ atmosphere_obsdatain_suffix: ".{{ current_cycle | to_YMDH }}.nc" # Testing things # -------------- -test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/atm/global-workflow/3dvar.ref -test_output_filename: ./3dvar.out +{% if DO_TEST_MODE == true and RUN == 'gdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_3dvar.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_3dvar.test.out test_float_relative_tolerance: 1.0e-3 test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/atm/global-workflow/jcb-prototype_lgetkf-fv3inc.yaml.j2 b/test/atm/global-workflow/jcb-prototype_lgetkf-fv3inc.yaml.j2 new file mode 100644 index 000000000..0e6ce8358 --- /dev/null +++ b/test/atm/global-workflow/jcb-prototype_lgetkf-fv3inc.yaml.j2 @@ -0,0 +1,13 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_lgetkf + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_lgetkf-fv3inc.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_lgetkf-fv3inc.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/atm/global-workflow/jcb-prototype_lgetkf.yaml.j2 b/test/atm/global-workflow/jcb-prototype_lgetkf.yaml.j2 index b83b7d695..589e6b5c8 100644 --- a/test/atm/global-workflow/jcb-prototype_lgetkf.yaml.j2 +++ b/test/atm/global-workflow/jcb-prototype_lgetkf.yaml.j2 @@ -22,7 +22,10 @@ atmosphere_obsdatain_suffix: ".{{ current_cycle | to_YMDH }}.nc" # Testing things # -------------- -test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/atm/global-workflow/lgetkf.ref -test_output_filename: ./lgetkf.out +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_lgetkf.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_lgetkf.test.out test_float_relative_tolerance: 1.0e-3 test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/atm/global-workflow/jcb-prototype_lgetkf_observer.yaml.j2 b/test/atm/global-workflow/jcb-prototype_lgetkf_observer.yaml.j2 index ec1182019..1831ca4d2 100644 --- a/test/atm/global-workflow/jcb-prototype_lgetkf_observer.yaml.j2 +++ b/test/atm/global-workflow/jcb-prototype_lgetkf_observer.yaml.j2 @@ -28,7 +28,10 @@ distribution_type: RoundRobin # Testing things # -------------- -test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/atm/global-workflow/lgetkf_observer.ref -test_output_filename: ./lgetkf_observer.out +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_lgetkf_observer.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_lgetkf_observer.test.out test_float_relative_tolerance: 1.0e-3 test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/atm/global-workflow/jcb-prototype_lgetkf_solver.yaml.j2 b/test/atm/global-workflow/jcb-prototype_lgetkf_solver.yaml.j2 index a6ad34751..c2e644172 100644 --- a/test/atm/global-workflow/jcb-prototype_lgetkf_solver.yaml.j2 +++ b/test/atm/global-workflow/jcb-prototype_lgetkf_solver.yaml.j2 @@ -28,7 +28,10 @@ distribution_type: Halo # Testing things # -------------- -test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/atm/global-workflow/lgetkf_solver.ref -test_output_filename: ./lgetkf_solver.out +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2021032318' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/atm_jjob_lgetkf_solver.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/atm_jjob_lgetkf_solver.test.out test_float_relative_tolerance: 1.0e-3 test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/fv3jedi/CMakeLists.txt b/test/fv3jedi/CMakeLists.txt deleted file mode 100644 index 9b75510b9..000000000 --- a/test/fv3jedi/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Subdirectories -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/test/fv3jedi/testinput) -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/test/fv3jedi/testoutput) -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi) - -# Test YAMLs -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml ${PROJECT_BINARY_DIR}/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml SYMBOLIC) - -# Test reference files -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/test/fv3jedi/testoutput/gdasapp_fv3jedi_fv3inc.ref ${PROJECT_BINARY_DIR}/test/fv3jedi/testoutput/gdasapp_fv3jedi_fv3inc.ref SYMBOLIC) - -# FV3 files -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/parm/io/fv3jedi_fieldmetadata_fv3inc.yaml ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi/fv3jedi_fieldmetadata_fv3inc.yaml SYMBOLIC) -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/parm/io/fv3jedi_fieldmetadata_history.yaml ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi/fv3jedi_fieldmetadata_history.yaml SYMBOLIC) -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/sorc/fv3-jedi/test/Data/fv3files/akbk127.nc4 ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi/akbk127.nc4 SYMBOLIC) -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/sorc/fv3-jedi/test/Data/fv3files/fmsmpp.nml ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi/fmsmpp.nml SYMBOLIC) -file(CREATE_LINK ${PROJECT_SOURCE_DIR}/sorc/fv3-jedi/test/Data/fv3files/field_table_gfdl ${PROJECT_BINARY_DIR}/test/fv3jedi/fv3jedi/field_table_gfdl SYMBOLIC) - -# Tests -add_test(NAME test_gdasapp_fv3jedi_fv3inc - COMMAND srun -n6 ${CMAKE_BINARY_DIR}/bin/fv3jedi_fv3inc.x ${PROJECT_BINARY_DIR}/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/fv3jedi) - diff --git a/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml b/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml deleted file mode 100644 index 7ee403ccc..000000000 --- a/test/fv3jedi/testinput/gdasapp_fv3jedi_fv3inc.yaml +++ /dev/null @@ -1,65 +0,0 @@ -variable change: - variable change name: Model2GeoVaLs - input variables: &bkgvars [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr,hgtsfc] - output variables: &fv3incrvars [ua,va,t,sphum,ice_wat,liq_wat,o3mr,delp,delz] -jedi increment variables: [ua,va,t,ps,sphum,ice_wat,liq_wat,o3mr] -fv3 increment variables: *fv3incrvars -background geometry: - fms initialization: - namelist filename: ./fv3jedi/fmsmpp.nml - field table filename: ./fv3jedi/field_table_gfdl - akbk: ./fv3jedi/akbk127.nc4 - layout: - - '1' - - '1' - npx: '13' - npy: '13' - npz: '127' - field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_history.yaml -jedi increment geometry: - fms initialization: - namelist filename: ./fv3jedi/fmsmpp.nml - field table filename: ./fv3jedi/field_table_gfdl - akbk: ./fv3jedi/akbk127.nc4 - layout: - - '1' - - '1' - npx: '13' - npy: '13' - npz: '127' - field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_history.yaml -fv3 increment geometry: - fms initialization: - namelist filename: ./fv3jedi/fmsmpp.nml - field table filename: ./fv3jedi/field_table_gfdl - akbk: ./fv3jedi/akbk127.nc4 - layout: - - '1' - - '1' - npx: '13' - npy: '13' - npz: '127' - field metadata override: ./fv3jedi/fv3jedi_fieldmetadata_fv3inc.yaml -members: -- background input: - filetype: cube sphere history - datapath: ../testdata/ - provider: ufs - datetime: '2021-07-31T12:00:00Z' - filename: gdas.t06z.atmf006.nc - state variables: *bkgvars - jedi increment input: - filetype: cube sphere history - datapath: ../testdata/ - filename: atminc.20210731.120000.nc4 - provider: ufs - fv3 increment output: - filetype: cube sphere history - filename: atminc.20210731_120000.nc4 - provider: ufs - -test: - reference filename: testoutput/gdasapp_fv3jedi_fv3inc.ref - test output filename: testoutput/gdasapp_fv3jedi_fv3inc.test.out - float relative tolerance: 1.0e-3 - diff --git a/test/fv3jedi/testoutput/gdasapp_fv3jedi_fv3inc.ref b/test/fv3jedi/testoutput/gdasapp_fv3jedi_fv3inc.ref deleted file mode 100644 index a4be55d39..000000000 --- a/test/fv3jedi/testoutput/gdasapp_fv3jedi_fv3inc.ref +++ /dev/null @@ -1,41 +0,0 @@ -Background State: - ----------------------------------------------------------------------------------------------------- -State print | number of fields = 9 | cube sphere face size: C12 -eastward_wind | Min:-7.6655158996582031e+01 Max:+1.3484048461914062e+02 RMS:+2.4474819956360815e+01 -northward_wind | Min:-5.7591831207275391e+01 Max:+6.1521602630615234e+01 RMS:+9.0604680778982232e+00 -air_temperature | Min:+1.6467715454101562e+02 Max:+3.1937854003906250e+02 RMS:+2.5118590413162758e+02 -surface_pressure | Min:+5.6141089843750000e+04 Max:+1.0346660156250000e+05 RMS:+9.8890740204548158e+04 -specific_humidity | Min:+1.2364032020428795e-09 Max:+2.1250871941447258e-02 RMS:+5.1335857648077696e-03 -cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+5.9844314819201827e-04 RMS:+1.2911033014274613e-05 -cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.1054204078391194e-03 RMS:+3.7434027002184771e-05 -ozone_mass_mixing_ratio | Min:+8.6089233519714981e-09 Max:+1.6528036212548614e-05 RMS:+4.4014999048943556e-06 -sfc_geopotential_height_times_grav | Min:-3.9759671688079834e+00 Max:+4.8742519531250000e+03 RMS:+6.2112179267749525e+02 ----------------------------------------------------------------------------------------------------- -JEDI Increment: - ----------------------------------------------------------------------------------------------------- -Increment print | number of fields = 8 | cube sphere face size: C12 -eastward_wind | Min:-4.3422836419308410e+00 Max:+1.2320940067737499e+01 RMS:+3.0957235443709130e-01 -northward_wind | Min:-4.1090470888107049e+00 Max:+5.4552721209750796e+00 RMS:+3.1062842460180656e-01 -air_temperature | Min:-5.2980343087781989e-01 Max:+5.1811022097894011e-01 RMS:+3.5920751813835923e-02 -surface_pressure | Min:-1.3399192319669237e+02 Max:+6.8315024915413233e+01 RMS:+1.5538727344814935e+01 -specific_humidity | Min:-2.8092260972819617e-04 Max:+2.9434075393080551e-04 RMS:+1.6532405760382759e-05 -cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 -cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 -ozone_mass_mixing_ratio | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 ----------------------------------------------------------------------------------------------------- -FV3 Increment: - ----------------------------------------------------------------------------------------------------- -Increment print | number of fields = 9 | cube sphere face size: C12 -eastward_wind | Min:-4.3422836419308410e+00 Max:+1.2320940067737499e+01 RMS:+3.0957235443709130e-01 -northward_wind | Min:-4.1090470888107049e+00 Max:+5.4552721209750796e+00 RMS:+3.1062842460180656e-01 -air_temperature | Min:-5.2980343087781989e-01 Max:+5.1811022097894011e-01 RMS:+3.5920751813835923e-02 -specific_humidity | Min:-2.8092260972819617e-04 Max:+2.9434075393080551e-04 RMS:+1.6532405760382759e-05 -cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 -cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 -ozone_mass_mixing_ratio | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 -air_pressure_thickness | Min:-2.9992886080290191e+00 Max:+1.5291703492039233e+00 RMS:+1.7535872214547940e-01 -layer_thickness | Min:-4.6699236754648155e-01 Max:+7.4693987323735200e-01 RMS:+3.1162055487823255e-02 ----------------------------------------------------------------------------------------------------- diff --git a/test/gw-ci/CMakeLists.txt b/test/gw-ci/CMakeLists.txt index 4f1a969e3..35c66d0cd 100644 --- a/test/gw-ci/CMakeLists.txt +++ b/test/gw-ci/CMakeLists.txt @@ -1,11 +1,213 @@ +# Function that adds a test for a given GW task +function(add_task task_name test_prefix is_full_cycle HALF_CYCLE FULL_CYCLE pslot WORKING_DIRECTORY PROJECT_SOURCE_DIR) + + # Get subtask names if task is a metatask + if("${task_name}" STREQUAL "gdas_fcst") + set(subtask_names_list + "gdas_fcst_seg0") + elseif("${task_name}" STREQUAL "enkfgdas_fcst") + set(subtask_names_list + "enkfgdas_fcst_mem001" + "enkfgdas_fcst_mem002") + elseif("${task_name}" STREQUAL "gdas_atmos_prod") + set(subtask_names_list + "gdas_atmos_prod_f000" + "gdas_atmos_prod_f001" + "gdas_atmos_prod_f002" + "gdas_atmos_prod_f003" + "gdas_atmos_prod_f004" + "gdas_atmos_prod_f005" + "gdas_atmos_prod_f006" + "gdas_atmos_prod_f007" + "gdas_atmos_prod_f008" + "gdas_atmos_prod_f009") + elseif("${task_name}" STREQUAL "enkfgdas_epmn") + set(subtask_names_list + "enkfgdas_epos001" + "enkfgdas_epos002" + "enkfgdas_epos003" + "enkfgdas_epos004" + "enkfgdas_epos005" + "enkfgdas_epos006") + elseif("${task_name}" STREQUAL "enkfgdas_ecmn") + if ("${pslot}" STREQUAL "C96C48_ufs_hybatmDA") + set(subtask_names_list + "enkfgdas_ecen000") + else() + set(subtask_names_list + "enkfgdas_ecen000" + "enkfgdas_ecen001" + "enkfgdas_ecen002") + endif() + else() + set(subtask_names_list ${task_name}) + endif() + + # Convert list to comma-delimited string + string(JOIN "," subtask_names ${subtask_names_list}) + + # Get task dependencies + set(TEST_DEPENDS) + if(NOT ${is_full_cycle}) + if("${task_name}" STREQUAL "gdas_fcst") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_stage_ic_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_atmos_prod") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_fcst") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_stage_ic_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_echgres") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_fcst_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_epmn") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_fcst_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_aeroanlgenb") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}") + endif() + else() + if("${task_name}" STREQUAL "gdas_prep") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_atmos_prod_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_anal") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_epmn_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prep_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_prepatmiodaobs") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prep_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_atmanlinit") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_epmn_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prepatmiodaobs_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_atmanlvar") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_atmanlinit_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_atmanlfv3inc") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_atmanlvar_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_atmanlfinal") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_atmanlfv3inc_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_aeroanlinit") + list(APPEND TEST_DEPENDS "${test_prefix}_aeroanlgenb_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prep_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_aeroanlvar") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_aeroanlinit_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_aeroanlfinal") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_aeroanlvar_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_snowanl") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prep_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_sfcanl") + if("${pslot}" STREQUAL "C96C48_ufs_hybatmDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_atmanlfinal_${FULL_CYCLE}") + elseif("${pslot}" STREQUAL "C96C48_hybatmaerosnowDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_anal_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_snowanal_${FULL_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_anal_${FULL_CYCLE}") + endif() + elseif("${task_name}" STREQUAL "gdas_analcalc") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_echgres_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_sfcanl_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_fcst") + if("${pslot}" STREQUAL "C96C48_hybatmaerosnowDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_sfcanl_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_aeroanlfinal_${FULL_CYCLE}") + elseif("${pslot}" STREQUAL "C48mx500_3DVarAOWCDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_sfcanl_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_marineanlfinal_${FULL_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_sfcanl_${FULL_CYCLE}") + endif() + elseif("${task_name}" STREQUAL "enkfgdas_atmensanlinit") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_epmn_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prepatmiodaobs_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_atmensanlobs") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlinit_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_atmensanlsol") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlobs_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_atmensanlfv3inc") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlsol_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_atmensanlfinal") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlfv3inc_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_eobs") + set(TEST_DEPENDS) + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_epmn_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prep_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_ediag") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_eobs_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_eupd") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_ediag_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_ecmn") + if("${pslot}" STREQUAL "C96C48_ufs_hybatmDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_analcalc_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlfinal_${FULL_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_analcalc_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_eupd_${FULL_CYCLE}") + endif() + elseif("${task_name}" STREQUAL "enkfgdas_esnowrecen") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_epmn_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_snowanl_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "enkfgdas_esfc") + if("${pslot}" STREQUAL "C96C48_ufs_hybatmDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_analcalc_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_atmensanlfinal_${FULL_CYCLE}") + elseif("${pslot}" STREQUAL "C96C48_hybatmaerosnowDA") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_analcalc_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_eupd_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_esnowrecen_${FULL_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_analcalc_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_eupd_${FULL_CYCLE}") + endif() + elseif("${task_name}" STREQUAL "enkfgdas_fcst") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_ecmn_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_esfc_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_prepoceanobs") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marinebmat") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marineanlinit") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_fcst_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prepoceanobs_${FULL_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_marinebmat_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marineanlvar") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_marineanlinit_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marineanlchkpt") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_marineanlvar_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marineanlfinal") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_marineanlchkpt_${FULL_CYCLE}") + elseif("${task_name}" STREQUAL "gdas_marineanlletkf") + list(APPEND TEST_DEPENDS "${test_prefix}_enkfgdas_fcst_${HALF_CYCLE}") + list(APPEND TEST_DEPENDS "${test_prefix}_gdas_prepoceanobs_${FULL_CYCLE}") + else() + list(APPEND TEST_DEPENDS "${test_prefix}") + endif() + endif() + + # Set cycle + if(${is_full_cycle}) + set(cycle ${FULL_CYCLE}) + else() + set(cycle ${HALF_CYCLE}) + endif() + + # Add Task + set(test_name ${test_prefix}_${task_name}_${cycle}) + message(STATUS "preparing ${subtask_names} for ${test_prefix} ctest") + ecbuild_add_test(TARGET ${test_name} + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh + ARGS ${pslot} ${cycle} ${subtask_names} + WORKING_DIRECTORY ${WORKING_DIRECTORY} + TEST_DEPENDS ${TEST_DEPENDS}) +endfunction() + # Function that generates the 1/2 cycle forecast and DA tasks -function(add_cycling_tests pslot YAML_PATH HOMEgfs RUNTESTS PROJECT_SOURCE_DIR TASK_LIST) - set(test_name test_gdasapp_${pslot}) +function(add_cycling_tests pslot YAML_PATH HOMEgfs WORKING_DIRECTORY PROJECT_SOURCE_DIR HALF_CYCLE_TASKS FULL_CYCLE_TASKS) + set(test_prefix test_gdasapp_${pslot}) # Prepare the COMROOT and EXPDIR for the cycling ctests - add_test(NAME ${test_name} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/create_exp.sh ${YAML_PATH} ${pslot} ${HOMEgfs} ${RUNTESTS}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name} PROPERTIES LABELS "manual") + ecbuild_add_test(TARGET ${test_prefix} + TYPE SCRIPT + COMMAND ${PROJECT_SOURCE_DIR}/test/gw-ci/create_exp.sh + ARGS ${YAML_PATH} ${pslot} ${HOMEgfs} ${WORKING_DIRECTORY} + WORKING_DIRECTORY ${WORKING_DIRECTORY}) # Get the 1/2 cycle and full cycle's dates execute_process( @@ -18,121 +220,203 @@ function(add_cycling_tests pslot YAML_PATH HOMEgfs RUNTESTS PROJECT_SOURCE_DIR T list(GET DATES_LIST 0 HALF_CYCLE) list(GET DATES_LIST 1 FULL_CYCLE) - # stage IC's - message(STATUS "staging the 1/2 cycle IC's for ${pslot} ctest") - add_test(NAME ${test_name}_gdas_stage_ic_${HALF_CYCLE} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh ${pslot} gdas_stage_ic ${HALF_CYCLE}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name}_gdas_stage_ic_${HALF_CYCLE} PROPERTIES LABELS "manual") - - # stage ensemble ics - if (letkf) - message(STATUS "preparing enkfgdas_stage_ic for ${pslot} ctest") - add_test(NAME ${test_name}_enkfgdas_stage_ic_${HALF_CYCLE} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh ${pslot} enkfgdas_stage_ic ${HALF_CYCLE}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name}_enkfgdas_stage_ic_${HALF_CYCLE} PROPERTIES LABELS "manual") - endif() - - # 1/2 cycle gdas_fcst - message(STATUS "preparing 1/2 cycle gdas_fcst for ${pslot} ctest") - add_test(NAME ${test_name}_gdas_fcst_seg0_${HALF_CYCLE} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh ${pslot} gdas_fcst_seg0 ${HALF_CYCLE}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name}_gdas_fcst_seg0_${HALF_CYCLE} PROPERTIES LABELS "manual") - - # 1/2 cycle enkfgdas_fcst - if (letkf) - set(ENS_MEMS "mem001" "mem002" "mem003") - foreach(ENS_MEM ${ENS_MEMS}) - message(STATUS "preparing 1/2 cycle enkfgdas_fcst_${ENS_MEM} for ${pslot} ctest") - add_test(NAME ${test_name}_enkfgdas_fcst_${ENS_MEM}_${HALF_CYCLE} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh ${pslot} enkfgdas_fcst_${ENS_MEM} ${HALF_CYCLE}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name}_enkfgdas_fcst_${ENS_MEM}_${HALF_CYCLE} PROPERTIES LABELS "manual") - endforeach() - endif() + # Select the list of tasks to run for the half cycle + message(STATUS "Half-cycle tasks ${HALF_CYCLE_TASKS}") + set(is_full_cycle FALSE) + foreach(task_name ${HALF_CYCLE_TASKS}) + add_task(${task_name} ${test_prefix} ${is_full_cycle} ${HALF_CYCLE} ${FULL_CYCLE} ${pslot} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR}) + endforeach() # Select the list of tasks to run for the full cycle - message(STATUS "Tasks ${TASK_LIST}") - - foreach(task ${TASK_LIST}) - message(STATUS "preparing the full cycle ${task} for ${pslot} ctest") - add_test(NAME ${test_name}_${task}_${FULL_CYCLE} - COMMAND /bin/bash -c "${PROJECT_SOURCE_DIR}/test/gw-ci/run_exp.sh ${pslot} ${task} ${FULL_CYCLE}" - WORKING_DIRECTORY ${RUNTESTS}) - set_tests_properties(${test_name}_${task}_${FULL_CYCLE} PROPERTIES LABELS "manual") + message(STATUS "Full-cycle tasks ${FULL_CYCLE_TASKS}") + set(is_full_cycle TRUE) + foreach(task_name ${FULL_CYCLE_TASKS}) + add_task(${task_name} ${test_prefix} ${is_full_cycle} ${HALF_CYCLE} ${FULL_CYCLE} ${pslot} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR}) endforeach() endfunction() if (WORKFLOW_TESTS) + # List of tests to run + option(TEST_GSI "Enable the GFSv17 GSI tests" ON) + option(TEST_GFS18 "Enable the GFSv18 Atmos JEDI tests" ON) + option(TEST_AERO_LAND "Enable the GFSv17 Aero-Land JEDI tests" ON) + option(TEST_MARINE_VAR "Enable the GFSv17 Marine JEDI 3D VAR FGAT tests" ON) + option(TEST_MARINE_HYB "Enable the GFSv17 Marine JEDI 3d HYB VAR tests" ON) + option(TEST_GFS17 "Enable the GFSv17 WCDA tests" OFF) + # Setup the environement set(HOMEgfs ${CMAKE_SOURCE_DIR}/../../..) - set(RUNTESTS ${CMAKE_CURRENT_BINARY_DIR}/../../test/gw-ci) + set(WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../../test/gw-ci) + + if(${TEST_GSI}) + # GSI Atm DA C96/C48 + # ------------------ + set(pslot "C96C48_hybatmDA") + set(YAML_PATH ${HOMEgfs}/ci/cases/pr/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst" + "gdas_atmos_prod" + "enkfgdas_stage_ic" + "enkfgdas_fcst" + "enkfgdas_echgres" + "enkfgdas_epmn") + set(FULL_CYCLE_TASKS + "gdas_prep" + "gdas_anal" + "gdas_sfcanl" + "gdas_analcalc" + "gdas_fcst" + "enkfgdas_eobs" + "enkfgdas_ediag" + "enkfgdas_eupd" + "enkfgdas_ecmn" + "enkfgdas_esfc" + "enkfgdas_fcst" + ) + + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + endif() # TEST_GSI - # 3DVAR WCDA, low-res + # JEDI Atm DA C96/C48 # ------------------- - set(pslot "WCDA-3DVAR-C48mx500") - set(YAML_PATH ${HOMEgfs}/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml) - set(TASK_LIST - "gdas_prepoceanobs" - "gdas_marinebmat" - "gdas_marineanlinit" - "gdas_marineanlvar" - "gdas_marineanlchkpt" - "gdas_marineanlfinal" + if(${TEST_GFS18}) + set(pslot "C96C48_ufs_hybatmDA") + set(YAML_PATH ${HOMEgfs}/ci/cases/pr/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst" + "gdas_atmos_prod" + "enkfgdas_stage_ic" + "enkfgdas_fcst" + "enkfgdas_echgres" + "enkfgdas_epmn") + set(FULL_CYCLE_TASKS + "gdas_prep" + "gdas_prepatmiodaobs" + "gdas_atmanlinit" + "gdas_atmanlvar" + "gdas_atmanlfv3inc" + "gdas_atmanlfinal" + "gdas_sfcanl" + "gdas_analcalc" + "gdas_fcst" + "enkfgdas_atmensanlinit" + "enkfgdas_atmensanlobs" + "enkfgdas_atmensanlsol" + "enkfgdas_atmensanlfv3inc" + "enkfgdas_atmensanlfinal" + "enkfgdas_ecmn" + "enkfgdas_esfc" + "enkfgdas_fcst" ) - add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${RUNTESTS} ${PROJECT_SOURCE_DIR} "${TASK_LIST}") - - # WCDA, low-res, ensemble da - # ------------- - set(pslot "WCDA-hyb-C48mx500") - set(letkf TRUE) - set(YAML_PATH ${HOMEgfs}/ci/cases/pr/C48mx500_hybAOWCDA.yaml) - set(TASK_LIST - "gdas_prepoceanobs" - "gdas_marineanlletkf" - # TODO(AFE) waiting until these are working for hybrid - # "gdas_marinebmat" - # "gdas_marineanlinit" - # "gdas_marineanlvar" - # "gdas_marineanlchkpt" - # "gdas_marineanlfinal" + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + endif() # TEST_V18 + + # Aero-Land DA C96 + # ---------------- + if(${TEST_AERO_LAND}) + set(pslot "C96C48_hybatmaerosnowDA") + set(YAML_PATH ${HOMEgfs}/ci/cases/pr/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst" + "gdas_atmos_prod" + "gdas_aeroanlgenb" + "enkfgdas_stage_ic" + "enkfgdas_fcst" + "enkfgdas_echgres" + "enkfgdas_epmn") + set(FULL_CYCLE_TASKS + "gdas_prep" + "gdas_anal" + "gdas_aeroanlinit" + "gdas_aeroanlvar" + "gdas_aeroanlfinal" + "gdas_snowanl" + "gdas_sfcanl" + "gdas_analcalc" + "gdas_fcst" + "enkfgdas_eobs" + "enkfgdas_ediag" + "enkfgdas_eupd" + "enkfgdas_ecmn" + "enkfgdas_esnowrecen" + "enkfgdas_esfc" + "enkfgdas_fcst" ) - add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${RUNTESTS} ${PROJECT_SOURCE_DIR} "${TASK_LIST}") - set(letkf FALSE) -endif() + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + endif() # TEST_AERO_LAND + + if(${TEST_MARINE_VAR}) + # GSI Atm DA C48, JEDI Marine DA 500 + # ---------------------------------- + set(pslot "C48mx500_3DVarAOWCDA") + set(YAML_PATH ${HOMEgfs}/ci/cases/pr/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst") + set(FULL_CYCLE_TASKS + "gdas_prepoceanobs" + "gdas_marinebmat" + "gdas_marineanlinit" + "gdas_marineanlvar" + "gdas_marineanlchkpt" + "gdas_marineanlfinal" + # TODO: run the below task once we have a C24/C12 config + #"gdas_prep" + #"gdas_anal" + #"gdas_sfcanl" + #"gdas_fcst" + ) + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + endif() # TEST_MARINE_VAR -option(RUN_GW_CI "Enable the global-workflow CI tests" OFF) -if (RUN_GW_CI) - # Aero-Land DA, C96 - # ----------------- - set(pslot "Aero-Snow-3DVAR-C96") - set(YAML_PATH ${HOMEgfs}/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml) - set(TASK_LIST) # empty list for now - add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${RUNTESTS} ${PROJECT_SOURCE_DIR} "${TASK_LIST}") - - # Atm DA, C96/C48 - # --------------- - set(pslot "Atm-hyb-C96C48") - set(YAML_PATH ${HOMEgfs}/ci/cases/pr/C96C48_ufs_hybatmDA.yaml) - set(TASK_LIST) # empty list for now - add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${RUNTESTS} ${PROJECT_SOURCE_DIR} "${TASK_LIST}") + if(${TEST_MARINE_HYB}) + # WCDA, low-res, ensemble da + # ------------- + set(pslot "C48mx500_hybAOWCDA") + set(letkf TRUE) + set(YAML_PATH ${HOMEgfs}/ci/cases/pr/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst" + "enkfgdas_stage_ic" + "enkfgdas_fcst") + set(FULL_CYCLE_TASKS + "gdas_prepoceanobs" + "gdas_marineanlletkf" + "gdas_marinebmat" + "gdas_marineanlinit" + "gdas_marineanlvar" + "gdas_marineanlchkpt" + "gdas_marineanlfinal" + ) + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + set(letkf FALSE) + endif() # TEST_MARINE_HYB # GFSv17, 3DVAR prototype # ----------------------- - set(pslot "GFSv17-3DVAR-C384mx025") - set(YAML_PATH ${HOMEgfs}/ci/cases/gfsv17/C384mx025_3DVarAOWCDA.yaml) - set(TASK_LIST - "gdas_prepoceanobs" - "gdas_marinebmat" - "gdas_marineanlinit" - "gdas_marineanlvar" - "gdas_marineanlchkpt" - "gdas_marineanlfinal" - "gdas_ocnanalvrfy" - "gdas_prep" - "gdas_anal" - ) - add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${RUNTESTS} ${PROJECT_SOURCE_DIR} "${TASK_LIST}") + if(TEST_GFS17) + set(pslot "C384mx025_3DVarAOWCDA") + set(YAML_PATH ${HOMEgfs}/ci/cases/gfsv17/${pslot}.yaml) + set(HALF_CYCLE_TASKS + "gdas_stage_ic" + "gdas_fcst") + set(FULL_CYCLE_TASKS + "gdas_prepoceanobs" + "gdas_marinebmat" + "gdas_marineanlinit" + "gdas_marineanlvar" + "gdas_marineanlchkpt" + "gdas_marineanlfinal" + "gdas_ocnanalvrfy" + "gdas_prep" + "gdas_anal" + "gdas_sfcanl" + "gdas_fcst" + ) + add_cycling_tests(${pslot} ${YAML_PATH} ${HOMEgfs} ${WORKING_DIRECTORY} ${PROJECT_SOURCE_DIR} "${HALF_CYCLE_TASKS}" "${FULL_CYCLE_TASKS}") + endif() endif() diff --git a/test/gw-ci/atm/jcb-prototype_3dvar-fv3inc_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_3dvar-fv3inc_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..53e2fbe38 --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_3dvar-fv3inc_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,13 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_variational + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'gdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_3dvar-fv3inc.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_3dvar-fv3inc.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/atm/jcb-prototype_3dvar_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_3dvar_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..a3c63519b --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_3dvar_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,42 @@ +# Algorithm +# --------- +algorithm: 3dvar + +# Observation things +# ------------------ +observations: +# - ADPSFC +# - ADPUPA +# - SFCSHP + - aircraft + - ascatw.ascat_metop-b +# - ascatw.ascat_metop-c + - atms_n20 +# - atms_npp + - conventional_ps + - gnssro +# - gpsro +# - iasi_metop-a +# - iasi_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 +# - abi_g16 + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'gdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_3dvar.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_3dvar.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/atm/jcb-prototype_lgetkf-fv3inc_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_lgetkf-fv3inc_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..8aa124b8b --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_lgetkf-fv3inc_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,13 @@ +# Algorithm +# --------- +algorithm: fv3jedi_fv3inc_lgetkf + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf-fv3inc.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf-fv3inc.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/atm/jcb-prototype_lgetkf_observer_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_lgetkf_observer_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..5a8330587 --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_lgetkf_observer_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,56 @@ +# 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 +# - iasi_metop-a +# - iasi_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 + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf_observer.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf_observer.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/atm/jcb-prototype_lgetkf_solver_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_lgetkf_solver_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..fed452f20 --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_lgetkf_solver_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,59 @@ +# 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 +# - iasi_metop-a +# - iasi_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 + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf_solver.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf_solver.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/atm/jcb-prototype_lgetkf_ufs_hybatmDA.yaml.j2 b/test/gw-ci/atm/jcb-prototype_lgetkf_ufs_hybatmDA.yaml.j2 new file mode 100644 index 000000000..907cbbcd7 --- /dev/null +++ b/test/gw-ci/atm/jcb-prototype_lgetkf_ufs_hybatmDA.yaml.j2 @@ -0,0 +1,50 @@ +# 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 + +# 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 +# - iasi_metop-a +# - iasi_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 + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'enkfgdas' and current_cycle | to_YMDH == '2024022400' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: {{ HOMEgfs }}/sorc/gdas.cd/test/testreference/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf.ref +test_output_filename: {{ HOMEgfs }}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}{{ CASE_ENS }}_ufs_hybatmDA_lgetkf.test.out +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/gw-ci/run_exp.sh b/test/gw-ci/run_exp.sh index 8040860a0..3c02dbb1a 100755 --- a/test/gw-ci/run_exp.sh +++ b/test/gw-ci/run_exp.sh @@ -1,39 +1,55 @@ #!/bin/bash pslot=$1 -TASK_NAME=$2 -CYCLE=$3 +CYCLE=$2 +shift +shift +task_args=("$@") # Define the workflow XML and database files WORKFLOW_XML=${pslot}/EXPDIR/${pslot}/${pslot}.xml WORKFLOW_DB=${pslot}/EXPDIR/${pslot}/${pslot}.db # Boot the task -echo "booting $TASK_NAME for cycle $CYCLE" +echo "booting ${TASK_ARRAY[@]} for cycle $CYCLE" if [[ ! -e "$WORKFLOW_DB" ]]; then - rocotorun -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$TASK_NAME" -c "$CYCLE" + rocotorun -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task_args" -c "$CYCLE" fi -rocotoboot -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$TASK_NAME" -c "$CYCLE" +rocotoboot -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task_args" -c "$CYCLE" +# Loop through tasks +IFS=',' read -r -a TASK_ARRAY <<< "$task_args" +num_tasks=${#TASK_ARRAY[@]} while true; do # Update the status of the task - rocotorun -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$TASK_NAME" -c "$CYCLE" + rocotorun -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task_args" -c "$CYCLE" - # Check the task status - OUTPUT=$(rocotostat -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$TASK_NAME" -c "$CYCLE") - STATUS=$(echo "$OUTPUT" | awk '$2 == task {print $4}' task="$TASK_NAME") + num_succeeded=0 + for task in "${TASK_ARRAY[@]}"; do + + # Check the task status + OUTPUT=$(rocotostat -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task" -c "$CYCLE") + STATUS=$(echo "$OUTPUT" | awk '$2 == task {print $4}' task="$task") - if [[ "$STATUS" == "SUCCEEDED" ]]; then - echo "The task succeeded." + if [[ "$STATUS" == "SUCCEEDED" ]]; then + echo "$pslot"_"$task"_"$CYCLE"" succeeded." + num_succeeded=$((num_succeeded + 1)) + elif [[ "$STATUS" == "FAILED" ]]; then + echo "$pslot"_"$task"_"$CYCLE"" failed." + exit 1 + elif [[ "$STATUS" == "DEAD" ]]; then + echo "$pslot"_"$task"_"$CYCLE"" is dead." + exit 1 + elif [[ "$STATUS" == "SUBMITTING" ]] || [[ "$STATUS" == "QUEUED" ]] || [[ "$STATUS" == "RUNNING" ]]; then + echo "$pslot"_"$task"_"$CYCLE"" is in state: $STATUS" + else + echo "$pslot"_"$task"_"$CYCLE"" is in unrecognized state: $STATUS. Rewinding..." + rocotorewind -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task_args" -c "$CYCLE" + rocotoboot -w "$WORKFLOW_XML" -d "$WORKFLOW_DB" -t "$task_args" -c "$CYCLE" + fi + done + if [[ "$num_succeeded" == "$num_tasks" ]]; then exit 0 - elif [[ "$STATUS" == "FAILED" ]]; then - echo "The task failed." - exit 1 - elif [[ "$STATUS" == "DEAD" ]]; then - echo "The task is dead." - exit 1 - else - echo "The task is in state: $STATUS" fi sleep 10 done diff --git a/test/gw-ci/soca/jcb-prototype_3dfgat_3DVarAOWCDA.yaml.j2 b/test/gw-ci/soca/jcb-prototype_3dfgat_3DVarAOWCDA.yaml.j2 new file mode 100644 index 000000000..2e38b9872 --- /dev/null +++ b/test/gw-ci/soca/jcb-prototype_3dfgat_3DVarAOWCDA.yaml.j2 @@ -0,0 +1,15 @@ +# JEDI algorithm being invoked +algorithm: 3dfgat + +# Observations +observations: !INC ${OBS_LIST_SHORT} + +# Testing things +# -------------- +{% if DO_TEST_MODE == true and RUN == 'gdas' and current_cycle | to_YMDH == '2021032418' and machine != 'WCOSS2' %} +do_testing: true +test_reference_filename: '{{HOMEgfs}}/sorc/gdas.cd/test/testreference/{{ CASE }}mx{{ OCNRES }}_3DVarAOWCDA_3dfgat.ref' +test_output_filename: '{{HOMEgfs}}/sorc/gdas.cd/build/gdas/test/testoutput/{{ CASE }}mx{{ OCNRES }}_3DVarAOWCDA_3dfgat.test.out' +test_float_relative_tolerance: 1.0e-3 +test_float_absolute_tolerance: 1.0e-5 +{% endif %} diff --git a/test/testreference/C48mx500_3DVarAOWCDA_3dfgat.ref b/test/testreference/C48mx500_3DVarAOWCDA_3dfgat.ref new file mode 100644 index 000000000..da694e64f --- /dev/null +++ b/test/testreference/C48mx500_3DVarAOWCDA_3dfgat.ref @@ -0,0 +1,41 @@ +Norm of input parameter StdDev: 1.8173379285780410e+02 +CostJb : Nonlinear Jb = 0.0000000000000000e+00 +CostJo : Nonlinear Jo(adt_rads_all) = 8.9472206004908480e+02, nobs = 305088, Jo/n = 2.9326688039158695e-03, err = 3.6584285974238564e+00 +CostJo : Nonlinear Jo(sst_avhrr_ma_l3u) = 1.6529491726590766e+05, nobs = 75382, Jo/n = 2.1927637534943045e+00, err = 3.1025085244688677e-01 +CostJo : Nonlinear Jo(sst_avhrr_mb_l3u) = 2.0157960412025612e+05, nobs = 85824, Jo/n = 2.3487556408493675e+00, err = 2.9608803521703780e-01 +CostJo : Nonlinear Jo(sst_viirs_npp_l3u) = 2.5707963369798398e+05, nobs = 108952, Jo/n = 2.3595678252623538e+00, err = 2.7810665818752978e-01 +CostJo : Nonlinear Jo(sst_viirs_n20_l3u) = 2.1906632422822388e+05, nobs = 107011, Jo/n = 2.0471383710854387e+00, err = 2.8307574214768672e-01 +CostJo : Nonlinear Jo(sst_abi_g16_l3c) = 0.0000000000000000e+00 --- No Observations +CostJo : Nonlinear Jo(sst_abi_g17_l3c) = 0.0000000000000000e+00 --- No Observations +CostJo : Nonlinear Jo(sst_ahi_h08_l3c) = 0.0000000000000000e+00 --- No Observations +CostJo : Nonlinear Jo(icec_amsr2_north) = 4.5008964311717841e+05, nobs = 223886, Jo/n = 2.0103518894311319e+00, err = 1.1069397449281068e-01 +CostJo : Nonlinear Jo(icec_amsr2_south) = 2.0473344657993333e+06, nobs = 381832, Jo/n = 5.3618724093301067e+00, err = 1.5601541685395720e-01 +CostJo : Nonlinear Jo(insitu_profile_argo) = 1.0286658130801611e+03, nobs = 75513, Jo/n = 1.3622367182871308e-02, err = 1.0000000000000000e+01 +CostFunction: Nonlinear J = 3.3423679761020122e+06 +RPCGMinimizer: reduction in residual norm = 1.0352198587033008e+00 +CostFunction::addIncrement: Analysis: + Valid time: 2021-03-25T00:00:00Z + sea_ice_area_fraction min=-0.3375955741044348 max=1.0701686282805594 mean=0.1111281998821976 + sea_ice_thickness min=0.0000000000000000 max=48.1358184814453125 mean=0.2073979630505945 + sea_ice_snow_thickness min=0.0000000000000000 max=0.5993193387985229 mean=0.0200216847118031 + sea_water_salinity min=-0.0000000397062482 max=43.5831925004053033 mean=33.6886249686437580 +sea_water_potential_temperature min=-1.9124325513839722 max=30.8660448750331859 mean=11.7945041333814515 + eastward_sea_water_velocity min=-0.9171831607818604 max=1.5397396087646484 mean=-0.0003884267695896 + northward_sea_water_velocity min=-0.5532888770103455 max=1.0238031148910522 mean=0.0046988454914240 + sea_surface_height_above_geoid min=-11.2607626229298159 max=1.9775081835545605 mean=-0.3558952181999109 + sea_water_cell_thickness min=0.0000000000000000 max=5416.7958984375000000 mean=128.6249924829840268 + ocean_mixed_layer_thickness min=2.3822515010833740 max=2241.9723339080810547 mean=127.4101581065958015 + sea_water_depth min=2.3822515010833740 max=2949.8905668258666992 mean=150.4069206023627032 +CostJb : Nonlinear Jb = 1.8140984503493731 +CostJo : Nonlinear Jo(adt_rads_all) = 736.2157130227589050, nobs = 305088, Jo/n = 0.0024131257637887, err = 3.6584285974238564 +CostJo : Nonlinear Jo(sst_avhrr_ma_l3u) = 165802.2057433615264017, nobs = 75382, Jo/n = 2.1994933239150134, err = 0.3102508524468868 +CostJo : Nonlinear Jo(sst_avhrr_mb_l3u) = 199058.6476532369852066, nobs = 85824, Jo/n = 2.3193820802250769, err = 0.2960880352170378 +CostJo : Nonlinear Jo(sst_viirs_npp_l3u) = 257785.8077833042480052, nobs = 108952, Jo/n = 2.3660493408409597, err = 0.2781066581875298 +CostJo : Nonlinear Jo(sst_viirs_n20_l3u) = 230228.7910482294391841, nobs = 107011, Jo/n = 2.1514497672970951, err = 0.2830757421476867 +CostJo : Nonlinear Jo(sst_abi_g16_l3c) = 0.0000000000000000 --- No Observations +CostJo : Nonlinear Jo(sst_abi_g17_l3c) = 0.0000000000000000 --- No Observations +CostJo : Nonlinear Jo(sst_ahi_h08_l3c) = 0.0000000000000000 --- No Observations +CostJo : Nonlinear Jo(icec_amsr2_north) = 442351.0648206729674712, nobs = 223886, Jo/n = 1.9757870738709564, err = 0.1106939744928107 +CostJo : Nonlinear Jo(icec_amsr2_south) = 1688092.4695333424024284, nobs = 381832, Jo/n = 4.4210345637174004, err = 0.1560154168539572 +CostJo : Nonlinear Jo(insitu_profile_argo) = 1027.3563725773119586, nobs = 75513, Jo/n = 0.0136050265858503, err = 10.0000000000000000 +CostFunction: Nonlinear J = 2985084.3727661976590753 diff --git a/test/testreference/C96C48_ufs_hybatmDA_3dvar-fv3inc.ref b/test/testreference/C96C48_ufs_hybatmDA_3dvar-fv3inc.ref new file mode 100644 index 000000000..9f351467f --- /dev/null +++ b/test/testreference/C96C48_ufs_hybatmDA_3dvar-fv3inc.ref @@ -0,0 +1,41 @@ +Background State: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C96 +eastward_wind | Min:-8.7592636108398438e+01 Max:+1.1416704559326172e+02 RMS:+1.7446457173999249e+01 +northward_wind | Min:-9.0989822387695312e+01 Max:+8.9292556762695312e+01 RMS:+9.8047448525826173e+00 +air_temperature | Min:+1.7290489196777344e+02 Max:+3.1016726684570312e+02 RMS:+2.5022379933353739e+02 +air_pressure_at_surface | Min:+5.1309156250000000e+04 Max:+1.0433031250000000e+05 RMS:+9.8914639246899416e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+9.9999986069576607e-10 Max:+2.1401712670922279e-02 RMS:+5.0230810220772519e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+5.6316837435588241e-04 RMS:+9.4319632692495166e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.6321672592312098e-03 RMS:+3.7885306687823480e-05 +ozone_mass_mixing_ratio | Min:+3.6092406840992908e-10 Max:+1.7313830539933406e-05 RMS:+4.4655431091584869e-06 +geopotential_height_at_surface | Min:-2.9894643783569336e+01 Max:+5.3870561523437500e+03 RMS:+6.4442219321892003e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-2.1094110991271009e-07 Max:+1.1717330217209110e-07 RMS:+1.8406442199343545e-09 +northward_wind | Min:-1.0218003509976370e-07 Max:+2.6284932985731757e-07 RMS:+1.8321568102519878e-09 +air_temperature | Min:-5.2967720876040403e-08 Max:+6.6442652268960956e-08 RMS:+7.1529564595995224e-10 +air_pressure_at_surface | Min:-2.0471925381571054e-06 Max:+9.5464929472655058e-07 RMS:+4.2656890498660969e-08 +water_vapor_mixing_ratio_wrt_moist_air | Min:-3.5909499332409389e-11 Max:+2.5060615908845119e-11 RMS:+2.7346125979528040e-13 +cloud_liquid_ice | Min:-5.5298263899525562e-13 Max:+3.6544474506536037e-13 RMS:+3.3630266932071384e-15 +cloud_liquid_water | Min:-1.0711521106947577e-11 Max:+3.1052085273756969e-12 RMS:+1.7896344450957455e-14 +ozone_mass_mixing_ratio | Min:-1.0347839576407838e-06 Max:+1.3449736530190683e-06 RMS:+3.6860537521399650e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-2.1094110991271009e-07 Max:+1.1717330217209110e-07 RMS:+1.8406442199343545e-09 +northward_wind | Min:-1.0218003509976370e-07 Max:+2.6284932985731757e-07 RMS:+1.8321568102519878e-09 +air_temperature | Min:-5.2967720876040403e-08 Max:+6.6442652268960956e-08 RMS:+7.1529564595995224e-10 +water_vapor_mixing_ratio_wrt_moist_air | Min:-3.5909499332409389e-11 Max:+2.5060615908845119e-11 RMS:+2.7346125979528040e-13 +cloud_liquid_ice | Min:-5.5298263899525562e-13 Max:+3.6544474506536037e-13 RMS:+3.3630266932071384e-15 +cloud_liquid_water | Min:-1.0711521106947577e-11 Max:+3.1052085273756969e-12 RMS:+1.7896344450957455e-14 +ozone_mass_mixing_ratio | Min:-1.0347839576407838e-06 Max:+1.3449736530190683e-06 RMS:+3.6860537521399650e-08 +air_pressure_thickness | Min:-3.8967755244811997e-08 Max:+1.7229922377737239e-08 RMS:+4.3178264898018102e-10 +layer_thickness | Min:-1.9750632418435998e-07 Max:+1.8317587091587484e-07 RMS:+3.6300478031517017e-09 +---------------------------------------------------------------------------------------------------- diff --git a/test/testreference/C96C48_ufs_hybatmDA_3dvar.ref b/test/testreference/C96C48_ufs_hybatmDA_3dvar.ref new file mode 100644 index 000000000..06cb7c5c8 --- /dev/null +++ b/test/testreference/C96C48_ufs_hybatmDA_3dvar.ref @@ -0,0 +1,124 @@ +CostJb : Nonlinear Jb = 0.0000000000000000e+00 +CostJo : Nonlinear Jo(Aircraft) = 6.0586857580910716e+05, nobs = 504553, Jo/n = 1.2008026427533027e+00, err = 2.2437136734248115e+00 +CostJo : Nonlinear Jo(ascatw_ascat_metop-b) = 1.5969417839194493e+04, nobs = 26328, Jo/n = 6.0655643570322448e-01, err = 1.8362571773983374e+00 +CostJo : Nonlinear Jo(ATMS N20) = 4.8397895213825170e+04, nobs = 156648, Jo/n = 3.0895954760881195e-01, err = 5.2724142689429563e+00 +CostJo : Nonlinear Jo(surface_ps) = 2.6309839844535789e+04, nobs = 107320, Jo/n = 2.4515318528266669e-01, err = 5.9306444356854104e+02 +CostJo : Nonlinear Jo(gnssrobndnbam) = 6.1543420655506197e+05, nobs = 473850, Jo/n = 1.2987954132216144e+00, err = 3.2896403090661679e-04 +CostJo : Nonlinear Jo(ompsnp_npp) = 2.1270332920540864e+03, nobs = 3087, Jo/n = 6.8902924912668817e-01, err = 2.4001367423170068e+00 +CostJo : Nonlinear Jo(ompstc_npp) = 3.3787920743968766e+03, nobs = 3696, Jo/n = 9.1417534480434970e-01, err = 6.0000000000000000e+00 +CostJo : Nonlinear Jo(satwind_goes-16) = 6.9382686620861832e+03, nobs = 193152, Jo/n = 3.5921288219051231e-02, err = 1.1892539752006376e+01 +CostFunction: Nonlinear J = 1.3244240292902619e+06 +DRPCGMinimizer: reduction in residual norm = 2.8257030182760973e-01 +CostFunction::addIncrement: Analysis: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 22 | cube sphere face size: C96 +eastward_wind | Min:-8.7592636108385108e+01 Max:+1.1416704559315106e+02 RMS:+1.7446457173996492e+01 +northward_wind | Min:-9.0989822387686885e+01 Max:+8.9292556762725127e+01 RMS:+9.8047448525772207e+00 +air_temperature | Min:+1.7290489196777401e+02 Max:+3.1016726684575099e+02 RMS:+2.5022379933353719e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7837973632812500e+03 RMS:+9.5699713772439975e+02 +air_pressure_at_surface | Min:+5.1309156249999876e+04 Max:+1.0433031249999903e+05 RMS:+9.8914639246898892e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+9.9999986073430897e-10 Max:+2.1401712670923338e-02 RMS:+5.0230810220769934e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+5.6316837435572314e-04 RMS:+9.4319632692245291e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.6321672592384501e-03 RMS:+3.7885306687792885e-05 +ozone_mass_mixing_ratio | Min:+3.8830337803893365e-10 Max:+1.7313832023368078e-05 RMS:+4.4663045051813113e-06 +geopotential_height_at_surface | Min:-2.9894643783569336e+01 Max:+5.3870561523437500e+03 RMS:+6.4442219321892003e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5312859958249614e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.6371389770507812e+02 RMS:+2.2054840004716052e+01 +skin_temperature_at_surface | Min:+2.1746269226074219e+02 Max:+3.2931939697265625e+02 RMS:+2.8736957533345463e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+5.8667091445155686e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.3549806522511076e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8026573181152344e+01 RMS:+1.9275201636346665e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.2046520996093750e+02 RMS:+2.8806775091395389e+02 +soilMoistureVolumetric | Min:+2.1923717111349106e-02 Max:+1.0000000000000000e+00 RMS:+8.6145441587921456e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.2327473163604736e+00 RMS:+1.5878116415501689e-01 +eastward_wind_at_surface | Min:-1.8027540206909180e+01 Max:+2.1014362335205078e+01 RMS:+5.2149711165295214e+00 +northward_wind_at_surface | Min:-2.0649587631225586e+01 Max:+1.8741132736206055e+01 RMS:+4.8319693225541691e+00 +f10m | Min:+9.3893665075302124e-01 Max:+1.0697331428527832e+00 RMS:+9.9592909655665096e-01 +---------------------------------------------------------------------------------------------------- + + + +Obs bias coefficients: +--------------------------------------------------------------- + constant: Min= -0.8381630182271099, Max= 0.8200770020481515, Norm= 2.2810923110282304 + lapseRate_order_2: Min= -0.2969009876260582, Max= 0.3889850080012890, Norm= 0.7014865852485411 + lapseRate: Min= -0.5954660177230151, Max= 1.6232719421371147, Norm= 2.1316868531033766 + emissivityJacobian: Min= -0.0097089996561411, Max= 8.3582897185072635, Norm= 10.2580018725805822 +sensorScanAngle_order_4: Min= -3.4036920070662386, Max= 0.8113600015621431, Norm= 4.8886281019448230 +sensorScanAngle_order_3: Min= -0.7697319984441072, Max= 0.3303030133246302, Norm= 0.9762309707883602 +sensorScanAngle_order_2: Min= -0.5401099920282910, Max= 2.2389800548543497, Norm= 2.4920946301939995 + sensorScanAngle: Min= -0.1069049984217406, Max= 0.4472059905526843, Norm= 0.8480380113023683 +--------------------------------------------------------------- + + + + + + +CostJb : Nonlinear Jb = 0.0000000000001371 +CostJo : Nonlinear Jo(Aircraft) = 605868.5754523422801867, nobs = 504553, Jo/n = 1.2008026420462117, err = 2.2437136734248115 +CostJo : Nonlinear Jo(ascatw_ascat_metop-b) = 15969.4178389218141092, nobs = 26328, Jo/n = 0.6065564356928674, err = 1.8362571773983374 +CostJo : Nonlinear Jo(ATMS N20) = 48397.8952120999601902, nobs = 156648, Jo/n = 0.3089595475977986, err = 5.2724142689429563 +CostJo : Nonlinear Jo(surface_ps) = 26309.8398438642980182, nobs = 107320, Jo/n = 0.2451531852764098, err = 593.0644435685410372 +CostJo : Nonlinear Jo(gnssrobndnbam) = 615434.2065248880535364, nobs = 473850, Jo/n = 1.2987954131579362, err = 0.0003289640309066 +CostJo : Nonlinear Jo(ompsnp_npp) = 1931.2294941937966541, nobs = 3087, Jo/n = 0.6256007431790724, err = 2.4001367423170068 +CostJo : Nonlinear Jo(ompstc_npp) = 1175.5454767024434659, nobs = 3696, Jo/n = 0.3180588410991460, err = 6.0000000000000000 +CostJo : Nonlinear Jo(satwind_goes-16) = 6938.2686619732694453, nobs = 193152, Jo/n = 0.0359212882184666, err = 11.8925397520063765 +CostFunction: Nonlinear J = 1322024.9785049860365689 +DRPCGMinimizer: reduction in residual norm = 0.8446464058086658 +CostFunction::addIncrement: Analysis: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 22 | cube sphere face size: C96 +eastward_wind | Min:-8.7592636108272671e+01 Max:+1.1416704559221755e+02 RMS:+1.7446457173973780e+01 +northward_wind | Min:-9.0989822387615689e+01 Max:+8.9292556762976545e+01 RMS:+9.8047448525325454e+00 +air_temperature | Min:+1.7290489196777892e+02 Max:+3.1016726684615486e+02 RMS:+2.5022379933354054e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7837973632812500e+03 RMS:+9.5699713772439975e+02 +air_pressure_at_surface | Min:+5.1309156249998850e+04 Max:+1.0433031249999082e+05 RMS:+9.8914639246894265e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+9.9999986150945930e-10 Max:+2.1401712670932254e-02 RMS:+5.0230810220750072e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+5.6316837435437916e-04 RMS:+9.4319632690136399e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.6321672592995262e-03 RMS:+3.7885306687535055e-05 +ozone_mass_mixing_ratio | Min:+0.0000000000000000e+00 Max:+1.7394005756664486e-05 RMS:+4.4687792881256477e-06 +geopotential_height_at_surface | Min:-2.9894643783569336e+01 Max:+5.3870561523437500e+03 RMS:+6.4442219321892003e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5312859958249614e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.6371389770507812e+02 RMS:+2.2054840004716052e+01 +skin_temperature_at_surface | Min:+2.1746269226074219e+02 Max:+3.2931939697265625e+02 RMS:+2.8736957533345463e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+5.8667091445155686e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.3549806522511076e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8026573181152344e+01 RMS:+1.9275201636346665e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.2046520996093750e+02 RMS:+2.8806775091395389e+02 +soilMoistureVolumetric | Min:+2.1923717111349106e-02 Max:+1.0000000000000000e+00 RMS:+8.6145441587921456e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.2327473163604736e+00 RMS:+1.5878116415501689e-01 +eastward_wind_at_surface | Min:-1.8027540206909180e+01 Max:+2.1014362335205078e+01 RMS:+5.2149711165295214e+00 +northward_wind_at_surface | Min:-2.0649587631225586e+01 Max:+1.8741132736206055e+01 RMS:+4.8319693225541691e+00 +f10m | Min:+9.3893665075302124e-01 Max:+1.0697331428527832e+00 RMS:+9.9592909655665096e-01 +---------------------------------------------------------------------------------------------------- + + + +Obs bias coefficients: +--------------------------------------------------------------- + constant: Min= -0.8381630182312133, Max= 0.8200770020452758, Norm= 2.2810923110345596 + lapseRate_order_2: Min= -0.2969009876339544, Max= 0.3889850080009647, Norm= 0.7014865852475514 + lapseRate: Min= -0.5954660177224381, Max= 1.6232719421239783, Norm= 2.1316868530895849 + emissivityJacobian: Min= -0.0097089996561437, Max= 8.3582897174893915, Norm= 10.2580018711058969 +sensorScanAngle_order_4: Min= -3.4036920070782095, Max= 0.8113600015462609, Norm= 4.8886281019599895 +sensorScanAngle_order_3: Min= -0.7697319984483566, Max= 0.3303030133237251, Norm= 0.9762309707918347 +sensorScanAngle_order_2: Min= -0.5401099920367962, Max= 2.2389800548459413, Norm= 2.4920946301900422 + sensorScanAngle: Min= -0.1069049984223444, Max= 0.4472059905508466, Norm= 0.8480380112989835 +--------------------------------------------------------------- + + + + + + +CostJb : Nonlinear Jb = 0.0000000000008861 +CostJo : Nonlinear Jo(Aircraft) = 605868.5724426389206201, nobs = 504553, Jo/n = 1.2008026360811230, err = 2.2437136734248115 +CostJo : Nonlinear Jo(ascatw_ascat_metop-b) = 15969.4178366216237919, nobs = 26328, Jo/n = 0.6065564356055008, err = 1.8362571773983374 +CostJo : Nonlinear Jo(ATMS N20) = 48397.8951984271625406, nobs = 156648, Jo/n = 0.3089595475105151, err = 5.2724142689429563 +CostJo : Nonlinear Jo(surface_ps) = 26309.8398381981351122, nobs = 107320, Jo/n = 0.2451531852236129, err = 593.0644435685410372 +CostJo : Nonlinear Jo(gnssrobndnbam) = 615434.2062702839029953, nobs = 473850, Jo/n = 1.2987954126206265, err = 0.0003289640309066 +CostJo : Nonlinear Jo(ompsnp_npp) = 1105.2563637508856118, nobs = 3087, Jo/n = 0.3580357511340737, err = 2.4001367423170068 +CostJo : Nonlinear Jo(ompstc_npp) = 842.7302103307468997, nobs = 3696, Jo/n = 0.2280114205440333, err = 6.0000000000000000 +CostJo : Nonlinear Jo(satwind_goes-16) = 6938.2686610208002094, nobs = 193152, Jo/n = 0.0359212882135355, err = 11.8925397520063765 +CostFunction: Nonlinear J = 1320866.1868212721310556 diff --git a/test/testreference/C96C48_ufs_hybatmDA_lgetkf-fv3inc.ref b/test/testreference/C96C48_ufs_hybatmDA_lgetkf-fv3inc.ref new file mode 100644 index 000000000..9e3d92b61 --- /dev/null +++ b/test/testreference/C96C48_ufs_hybatmDA_lgetkf-fv3inc.ref @@ -0,0 +1,82 @@ +Background State for member 0: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-8.4381935119628906e+01 Max:+1.1147341156005859e+02 RMS:+1.7423562537923519e+01 +northward_wind | Min:-8.6138259887695312e+01 Max:+8.9330894470214844e+01 RMS:+1.0017174203028123e+01 +air_temperature | Min:+1.7350219726562500e+02 Max:+3.0963690185546875e+02 RMS:+2.5015657367644263e+02 +air_pressure_at_surface | Min:+5.2319625000000000e+04 Max:+1.0452528906250000e+05 RMS:+9.8915012275401939e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.6836553484722572e-08 Max:+2.2505994886159897e-02 RMS:+5.0110427820345893e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2010331526398659e-04 RMS:+1.0363528039971751e-05 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.3888616813346744e-03 RMS:+3.5573039146049825e-05 +ozone_mass_mixing_ratio | Min:+1.1367524699323894e-09 Max:+1.7277665392612107e-05 RMS:+4.4686688193802981e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment for member 0: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-2.6755148704831090e+01 Max:+2.7445134265820300e+01 RMS:+7.6898038333711749e-01 +northward_wind | Min:-2.2178789491077385e+01 Max:+2.4185475371090597e+01 RMS:+7.7710948888854692e-01 +air_temperature | Min:-1.0784516433515279e+01 Max:+1.0549022663102676e+01 RMS:+3.2384375878820826e-01 +air_pressure_at_surface | Min:-1.6484601914328323e-03 Max:+1.3856849856779263e-03 RMS:+8.3530946702052195e-05 +water_vapor_mixing_ratio_wrt_moist_air | Min:-1.0021503370922452e-02 Max:+1.3243901954678224e-02 RMS:+1.3115100578902817e-04 +cloud_liquid_ice | Min:-3.2925003109779221e-04 Max:+3.0772213252633877e-04 RMS:+3.4572125152726005e-06 +cloud_liquid_water | Min:-1.3730991635473452e-03 Max:+1.0331594047075395e-03 RMS:+1.3213296694607966e-05 +ozone_mass_mixing_ratio | Min:-1.7236144371589322e-06 Max:+2.2084475912612794e-06 RMS:+3.4502781461392678e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment for member 0: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-2.6755148704831090e+01 Max:+2.7445134265820300e+01 RMS:+7.6898038333711749e-01 +northward_wind | Min:-2.2178789491077385e+01 Max:+2.4185475371090597e+01 RMS:+7.7710948888854692e-01 +air_temperature | Min:-1.0784516433515279e+01 Max:+1.0549022663102676e+01 RMS:+3.2384375878820826e-01 +water_vapor_mixing_ratio_wrt_moist_air | Min:-1.0021503370922452e-02 Max:+1.3243901954678224e-02 RMS:+1.3115100578902817e-04 +cloud_liquid_ice | Min:-3.2925003109779221e-04 Max:+3.0772213252633877e-04 RMS:+3.4572125152726005e-06 +cloud_liquid_water | Min:-1.3730991635473452e-03 Max:+1.0331594047075395e-03 RMS:+1.3213296694607966e-05 +ozone_mass_mixing_ratio | Min:-1.7236144371589322e-06 Max:+2.2084475912612794e-06 RMS:+3.4502781461392678e-08 +air_pressure_thickness | Min:-3.6899298720527440e-05 Max:+3.1017312721814960e-05 RMS:+9.4266922617364414e-07 +layer_thickness | Min:-5.0014265823861933e+01 Max:+3.0898151477016654e+01 RMS:+6.5848460245493412e-01 +---------------------------------------------------------------------------------------------------- +Background State for member 1: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-8.5966087341308594e+01 Max:+1.1214591979980469e+02 RMS:+1.7425599693772437e+01 +northward_wind | Min:-8.5568969726562500e+01 Max:+8.9453910827636719e+01 RMS:+1.0012870700458961e+01 +air_temperature | Min:+1.7322422790527344e+02 Max:+3.1173190307617188e+02 RMS:+2.5015468888662974e+02 +air_pressure_at_surface | Min:+5.2301363281250000e+04 Max:+1.0443097656250000e+05 RMS:+9.8912628070817751e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.7570943811051620e-08 Max:+2.1611798554658890e-02 RMS:+4.9962964224344337e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2922049760818481e-04 RMS:+9.7733563609262597e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.4694335404783487e-03 RMS:+3.5085536774868749e-05 +ozone_mass_mixing_ratio | Min:+2.9826621728012981e-10 Max:+1.7195881810039282e-05 RMS:+4.4692050652263310e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment for member 1: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-2.6410153938847341e+01 Max:+2.5235761322385869e+01 RMS:+7.8807971535887589e-01 +northward_wind | Min:-1.9157350680375867e+01 Max:+1.8014563258468129e+01 RMS:+8.1243167055864374e-01 +air_temperature | Min:-1.0920589024778607e+01 Max:+9.9577809464591880e+00 RMS:+3.3031798515011768e-01 +air_pressure_at_surface | Min:-1.6866912601756212e-03 Max:+1.4343651471904195e-03 RMS:+8.3571864435256723e-05 +water_vapor_mixing_ratio_wrt_moist_air | Min:-1.0886759940962830e-02 Max:+1.4203573478151255e-02 RMS:+1.3382079171167500e-04 +cloud_liquid_ice | Min:-4.8110709002814226e-04 Max:+4.7713624443900487e-04 RMS:+3.6873612628849232e-06 +cloud_liquid_water | Min:-1.4786335187316954e-03 Max:+1.0680992980876744e-03 RMS:+1.3548790780449636e-05 +ozone_mass_mixing_ratio | Min:-1.7924423988974384e-06 Max:+2.4353626139035565e-06 RMS:+3.6860276654647647e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment for member 1: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-2.6410153938847341e+01 Max:+2.5235761322385869e+01 RMS:+7.8807971535887589e-01 +northward_wind | Min:-1.9157350680375867e+01 Max:+1.8014563258468129e+01 RMS:+8.1243167055864374e-01 +air_temperature | Min:-1.0920589024778607e+01 Max:+9.9577809464591880e+00 RMS:+3.3031798515011768e-01 +water_vapor_mixing_ratio_wrt_moist_air | Min:-1.0886759940962830e-02 Max:+1.4203573478151255e-02 RMS:+1.3382079171167500e-04 +cloud_liquid_ice | Min:-4.8110709002814226e-04 Max:+4.7713624443900487e-04 RMS:+3.6873612628849232e-06 +cloud_liquid_water | Min:-1.4786335187316954e-03 Max:+1.0680992980876744e-03 RMS:+1.3548790780449636e-05 +ozone_mass_mixing_ratio | Min:-1.7924423988974384e-06 Max:+2.4353626139035565e-06 RMS:+3.6860276654647647e-08 +air_pressure_thickness | Min:-3.7755067751277238e-05 Max:+3.2106974686030298e-05 RMS:+9.4313099320621716e-07 +layer_thickness | Min:-4.7211113345212652e+01 Max:+3.1397032813900296e+01 RMS:+6.5379246729521723e-01 +---------------------------------------------------------------------------------------------------- diff --git a/test/testreference/C96C48_ufs_hybatmDA_lgetkf_observer.ref b/test/testreference/C96C48_ufs_hybatmDA_lgetkf_observer.ref new file mode 100644 index 000000000..db8872787 --- /dev/null +++ b/test/testreference/C96C48_ufs_hybatmDA_lgetkf_observer.ref @@ -0,0 +1,126 @@ +Initial state for member 1: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.4381935119628906e+01 Max:+1.1147341156005859e+02 RMS:+1.7423562537923519e+01 +northward_wind | Min:-8.6138259887695312e+01 Max:+8.9330894470214844e+01 RMS:+1.0017174203028123e+01 +air_temperature | Min:+1.7350219726562500e+02 Max:+3.0963690185546875e+02 RMS:+2.5015657367644260e+02 +layer_thickness | Min:-3.0061401367187500e+03 Max:-1.6210416793823242e+01 RMS:+9.8503668496048681e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7881135253906250e+03 RMS:+9.5698938964370029e+02 +air_pressure_at_surface | Min:+5.2319625000000000e+04 Max:+1.0452528906250000e+05 RMS:+9.8915012275401925e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.6836553484722572e-08 Max:+2.2505994886159897e-02 RMS:+5.0110427820345893e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2010331526398659e-04 RMS:+1.0363528039971752e-05 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.3888616813346744e-03 RMS:+3.5573039146049825e-05 +ozone_mass_mixing_ratio | Min:+1.1367524699323894e-09 Max:+1.7277665392612107e-05 RMS:+4.4686688193802981e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.5217852783203125e+02 RMS:+2.2019763739169889e+01 +skin_temperature_at_surface | Min:+2.1751763916015625e+02 Max:+3.2452719116210938e+02 RMS:+2.8741264670170318e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1583361816406250e+02 RMS:+2.8817190409943424e+02 +soilMoistureVolumetric | Min:+2.1991550922393799e-02 Max:+1.0000000000000000e+00 RMS:+8.4975027049775798e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0927191972732544e+00 RMS:+1.5092093358969108e-01 +eastward_wind_at_surface | Min:-1.8170446395874023e+01 Max:+2.1278623580932617e+01 RMS:+5.1168825419389767e+00 +northward_wind_at_surface | Min:-2.3760042190551758e+01 Max:+2.0148191452026367e+01 RMS:+4.8082957202774042e+00 +f10m | Min:+9.4115543365478516e-01 Max:+1.0684278011322021e+00 RMS:+9.9573250553770820e-01 +---------------------------------------------------------------------------------------------------- +Initial state for member 2: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.5966087341308594e+01 Max:+1.1214591979980469e+02 RMS:+1.7425599693772437e+01 +northward_wind | Min:-8.5568969726562500e+01 Max:+8.9453910827636719e+01 RMS:+1.0012870700458963e+01 +air_temperature | Min:+1.7322422790527344e+02 Max:+3.1173190307617188e+02 RMS:+2.5015468888662974e+02 +layer_thickness | Min:-3.0080390625000000e+03 Max:-1.6221441268920898e+01 RMS:+9.8509308795874222e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7860113525390625e+03 RMS:+9.5696357050818563e+02 +air_pressure_at_surface | Min:+5.2301363281250000e+04 Max:+1.0443097656250000e+05 RMS:+9.8912628070817751e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.7570943811051620e-08 Max:+2.1611798554658890e-02 RMS:+4.9962964224344337e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2922049760818481e-04 RMS:+9.7733563609262597e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.4694335404783487e-03 RMS:+3.5085536774868749e-05 +ozone_mass_mixing_ratio | Min:+2.9826621728012981e-10 Max:+1.7195881810039282e-05 RMS:+4.4692050652263310e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.4906773376464844e+02 RMS:+2.2005017974954740e+01 +skin_temperature_at_surface | Min:+2.1651719665527344e+02 Max:+3.2563174438476562e+02 RMS:+2.8745862236152567e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1595724487304688e+02 RMS:+2.8817510472919753e+02 +soilMoistureVolumetric | Min:+2.1997323259711266e-02 Max:+1.0000000000000000e+00 RMS:+8.4973291977355625e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0929540395736694e+00 RMS:+1.5094981321317086e-01 +eastward_wind_at_surface | Min:-1.9720079421997070e+01 Max:+2.2345537185668945e+01 RMS:+5.1457488184664619e+00 +northward_wind_at_surface | Min:-2.2769409179687500e+01 Max:+1.9396966934204102e+01 RMS:+4.7505626186338947e+00 +f10m | Min:+9.4070750474929810e-01 Max:+1.0689853429794312e+00 RMS:+9.9570180429785693e-01 +---------------------------------------------------------------------------------------------------- +H(x) for member 1: +Aircraft nobs= 502774 Min=-80.52688703818197, Max=305.4756140974109, RMS=146.5850912266714 + +ascatw_ascat_metop-b nobs= 24972 Min=-14.97150731725557, Max=18.59222631582299, RMS=5.627165086146203 + +ATMS N20 nobs= 17107090 Min=129.7979125777318, Max=294.748015146428, RMS=237.7681141030064 + +surface_ps nobs= 199096 Min=482.3530572788997, Max=106952.1841934663, RMS=94358.02893089037 + +gnssrobndnbam nobs= 792396 Min=3.546380623890607e-06, Max=0.05865236134606326, RMS=0.007295936681788925 + +ompsnp_npp nobs= 3652 Min=0.02233895704097705, Max=544.9716801848433, RMS=74.39669222502185 + +ompstc_npp nobs= 29925 Min=232.1671140621541, Max=578.8735949356186, RMS=330.1688990810148 + +satwind_goes-16 nobs= 192150 Min=-46.73388629014798, Max=73.49052471774161, RMS=13.49994079700484 + + +H(x) for member 2: +Aircraft nobs= 502774 Min=-83.50977510158438, Max=303.9081583779893, RMS=146.5836743742879 + +ascatw_ascat_metop-b nobs= 24972 Min=-15.9452064995462, Max=19.35646326739365, RMS=5.594172065839683 + +ATMS N20 nobs= 17107090 Min=129.597927951064, Max=294.7543239503619, RMS=237.7537725332559 + +surface_ps nobs= 199096 Min=475.4346559768398, Max=106815.2908050268, RMS=94338.51759672751 + +gnssrobndnbam nobs= 792396 Min=3.53531944084558e-06, Max=0.05504232119228934, RMS=0.007290074348817288 + +ompsnp_npp nobs= 3652 Min=0.02236952634391419, Max=551.3696272280527, RMS=74.49290431963087 + +ompstc_npp nobs= 29925 Min=232.2637157554366, Max=581.8883577567274, RMS=330.2398451750421 + +satwind_goes-16 nobs= 192150 Min=-45.04345261420303, Max=72.45073293453751, RMS=13.31522549257862 + + +H(x) ensemble background mean: +Aircraft nobs= 670256 Min=-82.01833106988317, Max=304.2594069546965, RMS=127.3607013100371 + +ascatw_ascat_metop-b nobs= 241220 Min=-15.68963235075079, Max=19.92991820776015, RMS=5.523964770711358 + +ATMS N20 nobs= 17107090 Min=129.6979202643979, Max=294.751169548395, RMS=237.7606829611712 + +surface_ps nobs= 199096 Min=487.1040468122645, Max=106883.7374992466, RMS=94348.2660116278 + +gnssrobndnbam nobs= 792396 Min=3.540850032368094e-06, Max=0.04986936990829795, RMS=0.007288979271240134 + +ompsnp_npp nobs= 3652 Min=0.02235732977445982, Max=548.170653706448, RMS=74.44414609956667 + +ompstc_npp nobs= 29925 Min=232.3594872699685, Max=580.3703615029328, RMS=330.2027869841414 + +satwind_goes-16 nobs= 1605788 Min=-48.18851124449841, Max=74.78861376491878, RMS=10.02029611812022 + + +background y - H(x): +Aircraft nobs= 514449 Min=-244.1467098114697, Max=114.0025485386182, RMS=3.825349314118969 + +ascatw_ascat_metop-b nobs= 241220 Min=-15.49332374410524, Max=19.42541728513033, RMS=2.328319413300086 + +ATMS N20 nobs= 17107090 Min=-139.4179788348109, Max=99999997810.81099, RMS=5096987910.765762 + +surface_ps nobs= 116459 Min=-101683.6161325038, Max=75904.41475640623, RMS=2988.090342492511 + +gnssrobndnbam nobs= 791233 Min=-0.02976546260592265, Max=0.01655246978054331, RMS=0.0008698553061021088 + +ompsnp_npp nobs= 3652 Min=-30.64859598170479, Max=60.86158014936484, RMS=3.944311336450149 + +ompstc_npp nobs= 28934 Min=-98.77302432677061, Max=716.7980683684957, RMS=17.05901286939617 + +satwind_goes-16 nobs= 1605788 Min=-51.49710944510686, Max=38.22800775116848, RMS=3.10195876364875 + + diff --git a/test/testreference/C96C48_ufs_hybatmDA_lgetkf_solver.ref b/test/testreference/C96C48_ufs_hybatmDA_lgetkf_solver.ref new file mode 100644 index 000000000..1f8ac9fd5 --- /dev/null +++ b/test/testreference/C96C48_ufs_hybatmDA_lgetkf_solver.ref @@ -0,0 +1,180 @@ +Initial state for member 1: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.4381935119628906e+01 Max:+1.1147341156005859e+02 RMS:+1.7423562537923519e+01 +northward_wind | Min:-8.6138259887695312e+01 Max:+8.9330894470214844e+01 RMS:+1.0017174203028123e+01 +air_temperature | Min:+1.7350219726562500e+02 Max:+3.0963690185546875e+02 RMS:+2.5015657367644260e+02 +layer_thickness | Min:-3.0061401367187500e+03 Max:-1.6210416793823242e+01 RMS:+9.8503668496048681e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7881135253906250e+03 RMS:+9.5698938964370029e+02 +air_pressure_at_surface | Min:+5.2319625000000000e+04 Max:+1.0452528906250000e+05 RMS:+9.8915012275401925e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.6836553484722572e-08 Max:+2.2505994886159897e-02 RMS:+5.0110427820345893e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2010331526398659e-04 RMS:+1.0363528039971752e-05 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.3888616813346744e-03 RMS:+3.5573039146049825e-05 +ozone_mass_mixing_ratio | Min:+1.1367524699323894e-09 Max:+1.7277665392612107e-05 RMS:+4.4686688193802981e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.5217852783203125e+02 RMS:+2.2019763739169889e+01 +skin_temperature_at_surface | Min:+2.1751763916015625e+02 Max:+3.2452719116210938e+02 RMS:+2.8741264670170318e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1583361816406250e+02 RMS:+2.8817190409943424e+02 +soilMoistureVolumetric | Min:+2.1991550922393799e-02 Max:+1.0000000000000000e+00 RMS:+8.4975027049775798e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0927191972732544e+00 RMS:+1.5092093358969108e-01 +eastward_wind_at_surface | Min:-1.8170446395874023e+01 Max:+2.1278623580932617e+01 RMS:+5.1168825419389767e+00 +northward_wind_at_surface | Min:-2.3760042190551758e+01 Max:+2.0148191452026367e+01 RMS:+4.8082957202774042e+00 +f10m | Min:+9.4115543365478516e-01 Max:+1.0684278011322021e+00 RMS:+9.9573250553770820e-01 +---------------------------------------------------------------------------------------------------- +Initial state for member 2: +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.5966087341308594e+01 Max:+1.1214591979980469e+02 RMS:+1.7425599693772437e+01 +northward_wind | Min:-8.5568969726562500e+01 Max:+8.9453910827636719e+01 RMS:+1.0012870700458963e+01 +air_temperature | Min:+1.7322422790527344e+02 Max:+3.1173190307617188e+02 RMS:+2.5015468888662974e+02 +layer_thickness | Min:-3.0080390625000000e+03 Max:-1.6221441268920898e+01 RMS:+9.8509308795874222e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7860113525390625e+03 RMS:+9.5696357050818563e+02 +air_pressure_at_surface | Min:+5.2301363281250000e+04 Max:+1.0443097656250000e+05 RMS:+9.8912628070817751e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+1.7570943811051620e-08 Max:+2.1611798554658890e-02 RMS:+4.9962964224344337e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.2922049760818481e-04 RMS:+9.7733563609262597e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.4694335404783487e-03 RMS:+3.5085536774868749e-05 +ozone_mass_mixing_ratio | Min:+2.9826621728012981e-10 Max:+1.7195881810039282e-05 RMS:+4.4692050652263310e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.4906773376464844e+02 RMS:+2.2005017974954740e+01 +skin_temperature_at_surface | Min:+2.1651719665527344e+02 Max:+3.2563174438476562e+02 RMS:+2.8745862236152567e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1595724487304688e+02 RMS:+2.8817510472919753e+02 +soilMoistureVolumetric | Min:+2.1997323259711266e-02 Max:+1.0000000000000000e+00 RMS:+8.4973291977355625e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0929540395736694e+00 RMS:+1.5094981321317086e-01 +eastward_wind_at_surface | Min:-1.9720079421997070e+01 Max:+2.2345537185668945e+01 RMS:+5.1457488184664619e+00 +northward_wind_at_surface | Min:-2.2769409179687500e+01 Max:+1.9396966934204102e+01 RMS:+4.7505626186338947e+00 +f10m | Min:+9.4070750474929810e-01 Max:+1.0689853429794312e+00 RMS:+9.9570180429785693e-01 +---------------------------------------------------------------------------------------------------- +H(x) for member 1: +Aircraft nobs= 502774 Min=-80.52688598632812, Max=305.4756164550781, RMS=146.5850912394751 + +ascatw_ascat_metop-b nobs= 24972 Min=-14.97150707244873, Max=18.59222602844238, RMS=5.62716508579711 + +ATMS N20 nobs= 17107090 Min=129.7979125976562, Max=294.7480163574219, RMS=237.7681141040336 + +surface_ps nobs= 199096 Min=482.3530578613281, Max=106952.1875, RMS=94358.02892149292 + +gnssrobndnbam nobs= 792396 Min=3.546380639818381e-06, Max=0.0586523599922657, RMS=0.0072959366825055 + +ompsnp_npp nobs= 3652 Min=0.02233895659446716, Max=544.9716796875, RMS=74.39669225492921 + +ompstc_npp nobs= 29925 Min=232.1671142578125, Max=578.8735961914062, RMS=330.1688989797257 + +satwind_goes-16 nobs= 192150 Min=-46.73388671875, Max=73.49052429199219, RMS=13.49994079676702 + + +H(x) for member 2: +Aircraft nobs= 502774 Min=-83.50977325439453, Max=303.9081726074219, RMS=146.5836743666871 + +ascatw_ascat_metop-b nobs= 24972 Min=-15.94520664215088, Max=19.3564624786377, RMS=5.594172063865287 + +ATMS N20 nobs= 17107090 Min=129.5979309082031, Max=294.7543334960938, RMS=237.7537725343049 + +surface_ps nobs= 199096 Min=475.4346618652344, Max=106815.2890625, RMS=94338.51762073471 + +gnssrobndnbam nobs= 792396 Min=3.535319365255418e-06, Max=0.0550423227250576, RMS=0.007290074349441779 + +ompsnp_npp nobs= 3652 Min=0.02236952632665634, Max=551.36962890625, RMS=74.49290437483097 + +ompstc_npp nobs= 29925 Min=232.2637176513672, Max=581.8883666992188, RMS=330.2398452061242 + +satwind_goes-16 nobs= 192150 Min=-45.04345321655273, Max=72.45072937011719, RMS=13.31522549128388 + + +H(x) ensemble background mean: +Aircraft nobs= 502774 Min=-82.01832962036133, Max=304.2594146728516, RMS=146.5826289292741 + +ascatw_ascat_metop-b nobs= 24972 Min=-15.30188179016113, Max=18.95062828063965, RMS=5.592606120496843 + +ATMS N20 nobs= 17107090 Min=129.6979217529297, Max=294.7511749267578, RMS=237.7606829622101 + +surface_ps nobs= 199096 Min=487.1040496826172, Max=106883.73828125, RMS=94348.26601893629 + +gnssrobndnbam nobs= 792396 Min=3.540850002536899e-06, Max=0.04986936971545219, RMS=0.007288979271877694 + +ompsnp_npp nobs= 3652 Min=0.02235732972621918, Max=548.170654296875, RMS=74.44414614227075 + +ompstc_npp nobs= 29925 Min=232.359489440918, Max=580.370361328125, RMS=330.2027869490538 + +satwind_goes-16 nobs= 192150 Min=-45.88866996765137, Max=72.75020217895508, RMS=13.36273267218127 + + +background y - H(x): +Aircraft nobs= 502774 Min=-18.89226531982422, Max=18.92750930786133, RMS=3.217484448211873 + +ascatw_ascat_metop-b nobs= 24972 Min=-4.998656421899796, Max=4.998543858528137, RMS=1.781285394555728 + +ATMS N20 nobs= 17107090 Min=-139.4179840087891, Max=99999997810.81099, RMS=5096987910.765761 + +surface_ps nobs= 116459 Min=-101683.6171875, Max=75904.4150390625, RMS=2988.090322213662 + +gnssrobndnbam nobs= 791233 Min=-0.02976546250283718, Max=0.01655246969312429, RMS=0.0008698553066247312 + +ompsnp_npp nobs= 3652 Min=-30.64859771728516, Max=60.86158752441406, RMS=3.944311410242143 + +ompstc_npp nobs= 28934 Min=-98.77304077148438, Max=716.7980804443359, RMS=17.05901287422818 + +satwind_goes-16 nobs= 192150 Min=-17.57823753356934, Max=18.68558120727539, RMS=3.266693383014099 + + +Background mean : +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.5174011230468750e+01 Max:+1.1180966567993164e+02 RMS:+1.7400608166952363e+01 +northward_wind | Min:-8.5721366882324219e+01 Max:+8.9159130096435547e+01 RMS:+9.9701196901312930e+00 +air_temperature | Min:+1.7338367462158203e+02 Max:+3.1068440246582031e+02 RMS:+2.5015535491643763e+02 +layer_thickness | Min:-3.0056031494140625e+03 Max:-1.6219569206237793e+01 RMS:+9.8506299054041222e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7870624389648438e+03 RMS:+9.5697638726610160e+02 +air_pressure_at_surface | Min:+5.2310494140625000e+04 Max:+1.0447813281250000e+05 RMS:+9.8913813202294172e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+2.9699791959103550e-08 Max:+2.1151660010218620e-02 RMS:+4.9997254551270454e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+3.7693076592404395e-04 RMS:+9.3960454614081343e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.2183884391561151e-03 RMS:+3.1354590436484046e-05 +ozone_mass_mixing_ratio | Min:+7.5146595890362988e-10 Max:+1.7234122424270026e-05 RMS:+4.4688540296858567e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.4910404968261719e+02 RMS:+2.2007648256514138e+01 +skin_temperature_at_surface | Min:+2.1701741790771484e+02 Max:+3.2172630310058594e+02 RMS:+2.8743523169966045e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1589543151855469e+02 RMS:+2.8817345707140311e+02 +soilMoistureVolumetric | Min:+2.1994437091052532e-02 Max:+1.0000000000000000e+00 RMS:+8.4973686886486732e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0928366184234619e+00 RMS:+1.5091517893438086e-01 +eastward_wind_at_surface | Min:-1.8945262908935547e+01 Max:+2.1812080383300781e+01 RMS:+5.1084993343462717e+00 +northward_wind_at_surface | Min:-2.3117747306823730e+01 Max:+1.9191046714782715e+01 RMS:+4.7533437996987020e+00 +f10m | Min:+9.4175148010253906e-01 Max:+1.0687065720558167e+00 RMS:+9.9571676746347482e-01 +---------------------------------------------------------------------------------------------------- +Analysis mean : +---------------------------------------------------------------------------------------------------- +State print | number of fields = 23 | cube sphere face size: C48 +eastward_wind | Min:-8.4779904407685251e+01 Max:+1.1172180353384172e+02 RMS:+1.7399733262265904e+01 +northward_wind | Min:-8.7156319044549164e+01 Max:+8.9235399901256216e+01 RMS:+9.9932912802591378e+00 +air_temperature | Min:+1.7338367451587715e+02 Max:+3.1032383629093437e+02 RMS:+2.5015203636307027e+02 +layer_thickness | Min:-3.0056031368184022e+03 Max:-1.6220854925143144e+01 RMS:+9.8506512850054082e+02 +air_pressure_thickness | Min:+6.0599988698959351e-01 Max:+1.7869442799477661e+03 RMS:+9.5697446604705669e+02 +air_pressure_at_surface | Min:+5.2310494129060797e+04 Max:+1.0447813272925235e+05 RMS:+9.8913813198384218e+04 +water_vapor_mixing_ratio_wrt_moist_air | Min:+0.0000000000000000e+00 Max:+2.1151662580462943e-02 RMS:+4.9987623813820079e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+4.1463521041293643e-04 RMS:+9.6091775193581227e-06 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.3255527472700904e-03 RMS:+3.3246424078544267e-05 +ozone_mass_mixing_ratio | Min:+1.0289921087641953e-09 Max:+1.7333251806676826e-05 RMS:+4.4689522890690314e-06 +geopotential_height_at_surface | Min:-2.7018375396728516e+01 Max:+5.2697558593750000e+03 RMS:+6.3772571434211386e+02 +slmsk | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+00 RMS:+6.5462209907135938e-01 +sheleg | Min:+0.0000000000000000e+00 Max:+2.4910404968261719e+02 RMS:+2.2007648256514138e+01 +skin_temperature_at_surface | Min:+2.1701741790771484e+02 Max:+3.2172630310058594e+02 RMS:+2.8743523169966045e+02 +vtype | Min:+0.0000000000000000e+00 Max:+2.0000000000000000e+01 RMS:+6.1246929250310931e+00 +stype | Min:+0.0000000000000000e+00 Max:+1.6000000000000000e+01 RMS:+4.5755536879077185e+00 +vfrac | Min:+0.0000000000000000e+00 Max:+9.8551864624023438e+01 RMS:+2.0170282476619530e+01 +stc | Min:+2.0000000000000000e+02 Max:+3.1589543151855469e+02 RMS:+2.8817345707140311e+02 +soilMoistureVolumetric | Min:+2.1994437091052532e-02 Max:+1.0000000000000000e+00 RMS:+8.4973686886486732e-01 +totalSnowDepthMeters | Min:+0.0000000000000000e+00 Max:+1.0928366184234619e+00 RMS:+1.5091517893438086e-01 +eastward_wind_at_surface | Min:-1.8945262908935547e+01 Max:+2.1812080383300781e+01 RMS:+5.1084993343462717e+00 +northward_wind_at_surface | Min:-2.3117747306823730e+01 Max:+1.9191046714782715e+01 RMS:+4.7533437996987020e+00 +f10m | Min:+9.4175148010253906e-01 Max:+1.0687065720558167e+00 RMS:+9.9571676746347482e-01 +---------------------------------------------------------------------------------------------------- diff --git a/test/testreference/atm_jjob_3dvar-fv3inc.ref b/test/testreference/atm_jjob_3dvar-fv3inc.ref new file mode 100644 index 000000000..98a94646b --- /dev/null +++ b/test/testreference/atm_jjob_3dvar-fv3inc.ref @@ -0,0 +1,41 @@ +Background State: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-5.5495644220059390e+01 Max:+8.4934651204487366e+01 RMS:+1.6388250288532191e+01 +northward_wind | Min:-7.3712421229093422e+01 Max:+7.6984825502186652e+01 RMS:+8.1424144891567511e+00 +air_temperature | Min:+1.7482158077318496e+02 Max:+3.1467235233685437e+02 RMS:+2.4978424883064508e+02 +surface_pressure | Min:+5.3298485514404747e+04 Max:+1.0398027192902798e+05 RMS:+9.8897229693652524e+04 +specific_humidity | Min:+1.2691624667179020e-08 Max:+2.0041369334954085e-02 RMS:+4.7792638023125686e-03 +cloud_liquid_ice | Min:+0.0000000000000000e+00 Max:+1.2024392024662985e-03 RMS:+1.4396968866569995e-05 +cloud_liquid_water | Min:+0.0000000000000000e+00 Max:+1.5935686618789048e-03 RMS:+4.1931345590543333e-05 +ozone_mass_mixing_ratio | Min:+1.1998327271379204e-08 Max:+1.7808431790670831e-05 RMS:+4.4947917149861064e-06 +surface_geopotential_height | Min:-2.7018394470214844e+01 Max:+5.2697460937500000e+03 RMS:+6.3032575784066080e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-4.9503077015344843e-07 Max:+7.0838511279092131e-07 RMS:+2.4490899978286723e-09 +northward_wind | Min:-7.2703516684757830e-07 Max:+2.8853321110133834e-07 RMS:+2.1376104971902294e-09 +air_temperature | Min:-2.1723477061641461e-07 Max:+6.5020122974601691e-07 RMS:+1.0998492962503341e-08 +surface_pressure | Min:-7.8580342233181000e-10 Max:+3.2014213502407074e-10 RMS:+1.5159255545534699e-11 +specific_humidity | Min:-6.7425976452941262e-04 Max:+7.2974731745455677e-04 RMS:+2.1043490698817701e-06 +cloud_liquid_ice | Min:-2.7736911125384438e-06 Max:+5.0834107240617123e-07 RMS:+4.7607939912271645e-08 +cloud_liquid_water | Min:-3.7332445167104997e-04 Max:+3.4355489504058373e-04 RMS:+3.0033170533500212e-06 +ozone_mass_mixing_ratio | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 +---------------------------------------------------------------------------------------------------- +FV3 Increment: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-4.9503077015344843e-07 Max:+7.0838511279092131e-07 RMS:+2.4490899978286723e-09 +northward_wind | Min:-7.2703516684757830e-07 Max:+2.8853321110133834e-07 RMS:+2.1376104971902294e-09 +air_temperature | Min:-2.1723477061641461e-07 Max:+6.5020122974601691e-07 RMS:+1.0998492962503341e-08 +specific_humidity | Min:-6.7425976452941262e-04 Max:+7.2974731745455677e-04 RMS:+2.1043490698817701e-06 +cloud_liquid_ice | Min:-2.7736911125384438e-06 Max:+5.0834107240617123e-07 RMS:+4.7607939912271645e-08 +cloud_liquid_water | Min:-3.7332445167104997e-04 Max:+3.4355489504058373e-04 RMS:+3.0033170533500212e-06 +ozone_mass_mixing_ratio | Min:+0.0000000000000000e+00 Max:+0.0000000000000000e+00 RMS:+0.0000000000000000e+00 +air_pressure_thickness | Min:-2.9103830456733704e-11 Max:+2.9103830456733704e-11 RMS:+3.3056019160193798e-13 +layer_thickness | Min:-1.0638235174337751e-01 Max:+1.0329449278924585e-01 RMS:+2.8485086711777381e-04 +---------------------------------------------------------------------------------------------------- diff --git a/test/atm/global-workflow/3dvar.ref b/test/testreference/atm_jjob_3dvar.ref similarity index 100% rename from test/atm/global-workflow/3dvar.ref rename to test/testreference/atm_jjob_3dvar.ref diff --git a/test/testreference/atm_jjob_lgetkf-fv3inc.ref b/test/testreference/atm_jjob_lgetkf-fv3inc.ref new file mode 100644 index 000000000..2c8fed453 --- /dev/null +++ b/test/testreference/atm_jjob_lgetkf-fv3inc.ref @@ -0,0 +1,123 @@ +Background State for member 0: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-5.1619864857418477e+01 Max:+8.6812084442971653e+01 RMS:+1.5983411875766325e+01 +northward_wind | Min:-7.3094846805319690e+01 Max:+7.0353817207582651e+01 RMS:+7.7265473774262041e+00 +air_temperature | Min:+1.7646396818493386e+02 Max:+3.1441817730817547e+02 RMS:+2.4989439192167012e+02 +surface_pressure | Min:+5.3259705655314101e+04 Max:+1.0392378167916714e+05 RMS:+9.8893465602866549e+04 +specific_humidity | Min:+9.5164908108891825e-09 Max:+2.0222136340880194e-02 RMS:+4.8552459174929334e-03 +cloud_liquid_ice | Min:-1.3545705512023003e-20 Max:+6.7304686933261399e-04 RMS:+1.0726563909939355e-05 +cloud_liquid_water | Min:-5.4244251425755909e-20 Max:+1.2879383569881558e-03 RMS:+3.8382491358281577e-05 +ozone_mass_mixing_ratio | Min:+2.9375003505643131e-08 Max:+1.8014885502109894e-05 RMS:+4.4946424525503736e-06 +surface_geopotential_height | Min:-2.7018394470214844e+01 Max:+5.2697460937500000e+03 RMS:+6.3032575784066080e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment for member 0: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-1.7416909136434541e+01 Max:+1.8325867271120192e+01 RMS:+7.2689113073983769e-01 +northward_wind | Min:-1.5335235321425948e+01 Max:+2.1574447615122054e+01 RMS:+7.1328003377466020e-01 +air_temperature | Min:-8.6048230478038406e+00 Max:+8.1497937417599609e+00 RMS:+3.1081395800884187e-01 +surface_pressure | Min:-4.9202937637815580e-04 Max:+8.7924188102306289e-04 RMS:+5.8051418356002832e-05 +specific_humidity | Min:-6.6741214369962698e-03 Max:+9.0731153226882751e-03 RMS:+1.4380776566867527e-04 +cloud_liquid_ice | Min:-4.9931336523754066e-04 Max:+2.6181751401796260e-04 RMS:+3.2747284981508197e-06 +cloud_liquid_water | Min:-1.0141458910771410e-03 Max:+1.1396207487973308e-03 RMS:+1.0447469223790289e-05 +ozone_mass_mixing_ratio | Min:-2.9909193396824413e-06 Max:+3.4967162777667096e-06 RMS:+5.0924831319987802e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment for member 0: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-1.7416909136434541e+01 Max:+1.8325867271120192e+01 RMS:+7.2689113073983769e-01 +northward_wind | Min:-1.5335235321425948e+01 Max:+2.1574447615122054e+01 RMS:+7.1328003377466020e-01 +air_temperature | Min:-8.6048230478038406e+00 Max:+8.1497937417599609e+00 RMS:+3.1081395800884187e-01 +specific_humidity | Min:-6.6741214369962698e-03 Max:+9.0731153226882751e-03 RMS:+1.4380776566867527e-04 +cloud_liquid_ice | Min:-4.9931336523754066e-04 Max:+2.6181751401796260e-04 RMS:+3.2747284981508197e-06 +cloud_liquid_water | Min:-1.0141458910771410e-03 Max:+1.1396207487973308e-03 RMS:+1.0447469223790289e-05 +ozone_mass_mixing_ratio | Min:-2.9909193396824413e-06 Max:+3.4967162777667096e-06 RMS:+5.0924831319987802e-08 +air_pressure_thickness | Min:-1.1013638868462294e-05 Max:+1.9681036064866930e-05 RMS:+6.5512588707706875e-07 +layer_thickness | Min:-2.8045559103640699e+01 Max:+2.1697786412500136e+01 RMS:+6.5544095172004369e-01 +---------------------------------------------------------------------------------------------------- +Background State for member 1: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-5.2853490758012072e+01 Max:+8.7248708527964936e+01 RMS:+1.5955809745480765e+01 +northward_wind | Min:-7.2178651628585953e+01 Max:+7.2568167230757609e+01 RMS:+7.7335061167195889e+00 +air_temperature | Min:+1.7660670217895057e+02 Max:+3.1526174222386965e+02 RMS:+2.4989392943476341e+02 +surface_pressure | Min:+5.3317702550070273e+04 Max:+1.0394629485957995e+05 RMS:+9.8892949759388735e+04 +specific_humidity | Min:+2.1514597275760548e-08 Max:+1.9663168048133908e-02 RMS:+4.8569105861498299e-03 +cloud_liquid_ice | Min:-1.3544569699620215e-20 Max:+7.9557019872326799e-04 RMS:+1.0816147029169270e-05 +cloud_liquid_water | Min:-5.4200711162051571e-20 Max:+1.2298889446687945e-03 RMS:+3.8689917911663205e-05 +ozone_mass_mixing_ratio | Min:+1.6238717942558199e-08 Max:+1.8031521448783218e-05 RMS:+4.4947640660308833e-06 +surface_geopotential_height | Min:-2.7018394470214844e+01 Max:+5.2697460937500000e+03 RMS:+6.3032575784066080e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment for member 1: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-1.7542991285853031e+01 Max:+2.0968845531775742e+01 RMS:+7.2825863145362402e-01 +northward_wind | Min:-1.5283258164430123e+01 Max:+2.0478626874987171e+01 RMS:+7.1562489129210427e-01 +air_temperature | Min:-1.0374519800275246e+01 Max:+9.3297652767893524e+00 RMS:+3.1237829519350230e-01 +surface_pressure | Min:-4.8986046327570421e-04 Max:+9.0817638056250871e-04 RMS:+5.9230402548777353e-05 +specific_humidity | Min:-6.9184909302780918e-03 Max:+8.2127508558306646e-03 RMS:+1.4099077159566875e-04 +cloud_liquid_ice | Min:-5.2537411650465499e-04 Max:+3.1949478810012653e-04 RMS:+3.2097080991341253e-06 +cloud_liquid_water | Min:-1.0684141562485590e-03 Max:+1.1931964279486475e-03 RMS:+1.0416514064617798e-05 +ozone_mass_mixing_ratio | Min:-3.1852115564505394e-06 Max:+3.2851197161513411e-06 RMS:+5.1928484225101225e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment for member 1: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-1.7542991285853031e+01 Max:+2.0968845531775742e+01 RMS:+7.2825863145362402e-01 +northward_wind | Min:-1.5283258164430123e+01 Max:+2.0478626874987171e+01 RMS:+7.1562489129210427e-01 +air_temperature | Min:-1.0374519800275246e+01 Max:+9.3297652767893524e+00 RMS:+3.1237829519350230e-01 +specific_humidity | Min:-6.9184909302780918e-03 Max:+8.2127508558306646e-03 RMS:+1.4099077159566875e-04 +cloud_liquid_ice | Min:-5.2537411650465499e-04 Max:+3.1949478810012653e-04 RMS:+3.2097080991341253e-06 +cloud_liquid_water | Min:-1.0684141562485590e-03 Max:+1.1931964279486475e-03 RMS:+1.0416514064617798e-05 +ozone_mass_mixing_ratio | Min:-3.1852115564505394e-06 Max:+3.2851197161513411e-06 RMS:+5.1928484225101225e-08 +air_pressure_thickness | Min:-1.0965086403302848e-05 Max:+2.0328705431893468e-05 RMS:+6.6843104175422882e-07 +layer_thickness | Min:-3.2106148452359776e+01 Max:+2.5923789087046316e+01 RMS:+6.6540710201306896e-01 +---------------------------------------------------------------------------------------------------- +Background State for member 2: + +---------------------------------------------------------------------------------------------------- +State print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-5.3776366655868109e+01 Max:+8.6331467223030344e+01 RMS:+1.5960680883840784e+01 +northward_wind | Min:-7.0176400159320124e+01 Max:+6.9531049915936578e+01 RMS:+7.7410680097841684e+00 +air_temperature | Min:+1.7648447482434227e+02 Max:+3.1491330999751426e+02 RMS:+2.4989313307279673e+02 +surface_pressure | Min:+5.3350124363319999e+04 Max:+1.0389818047809265e+05 RMS:+9.8892179510558097e+04 +specific_humidity | Min:+2.1846447498856659e-08 Max:+2.0007929878326374e-02 RMS:+4.8392192734415156e-03 +cloud_liquid_ice | Min:-6.7740196346531239e-21 Max:+6.2473018245821010e-04 RMS:+1.0889666282638220e-05 +cloud_liquid_water | Min:-5.4107584399974539e-20 Max:+1.2132298501853738e-03 RMS:+3.8405804865664137e-05 +ozone_mass_mixing_ratio | Min:+1.2289325508931378e-08 Max:+1.8036413152177077e-05 RMS:+4.4950884931704925e-06 +surface_geopotential_height | Min:-2.7018394470214844e+01 Max:+5.2697460937500000e+03 RMS:+6.3032575784066080e+02 +---------------------------------------------------------------------------------------------------- +JEDI Increment for member 2: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 8 | cube sphere face size: C48 +eastward_wind | Min:-1.8014062913663103e+01 Max:+1.8516732485049666e+01 RMS:+7.3383694849572323e-01 +northward_wind | Min:-1.5579280119728031e+01 Max:+2.2762102719398591e+01 RMS:+7.2377717441299694e-01 +air_temperature | Min:-1.0570848751737598e+01 Max:+8.3564092475959129e+00 RMS:+3.1645038788954982e-01 +surface_pressure | Min:-4.7656900311210393e-04 Max:+9.1220166839889316e-04 RMS:+5.8396146445486219e-05 +specific_humidity | Min:-5.2439197475218757e-03 Max:+8.2607880293262357e-03 RMS:+1.4211303446855155e-04 +cloud_liquid_ice | Min:-5.2671607196952148e-04 Max:+2.7498589550193714e-04 RMS:+3.2193226262458792e-06 +cloud_liquid_water | Min:-1.0851123947058787e-03 Max:+1.2045791096627974e-03 RMS:+1.0548571598067807e-05 +ozone_mass_mixing_ratio | Min:-3.2510682480215228e-06 Max:+3.3849184382668304e-06 RMS:+5.2379967545874409e-08 +---------------------------------------------------------------------------------------------------- +FV3 Increment for member 2: + +---------------------------------------------------------------------------------------------------- +Increment print | number of fields = 9 | cube sphere face size: C48 +eastward_wind | Min:-1.8014062913663103e+01 Max:+1.8516732485049666e+01 RMS:+7.3383694849572323e-01 +northward_wind | Min:-1.5579280119728031e+01 Max:+2.2762102719398591e+01 RMS:+7.2377717441299694e-01 +air_temperature | Min:-1.0570848751737598e+01 Max:+8.3564092475959129e+00 RMS:+3.1645038788954982e-01 +specific_humidity | Min:-5.2439197475218757e-03 Max:+8.2607880293262357e-03 RMS:+1.4211303446855155e-04 +cloud_liquid_ice | Min:-5.2671607196952148e-04 Max:+2.7498589550193714e-04 RMS:+3.2193226262458792e-06 +cloud_liquid_water | Min:-1.0851123947058787e-03 Max:+1.2045791096627974e-03 RMS:+1.0548571598067807e-05 +ozone_mass_mixing_ratio | Min:-3.2510682480215228e-06 Max:+3.3849184382668304e-06 RMS:+5.2379967545874409e-08 +air_pressure_thickness | Min:-1.0667572496458888e-05 Max:+2.0418810890987515e-05 RMS:+6.5901623607235396e-07 +layer_thickness | Min:-2.8377559817174188e+01 Max:+2.5490176089209854e+01 RMS:+6.7263739596740091e-01 +---------------------------------------------------------------------------------------------------- diff --git a/test/atm/global-workflow/lgetkf.ref b/test/testreference/atm_jjob_lgetkf.ref similarity index 100% rename from test/atm/global-workflow/lgetkf.ref rename to test/testreference/atm_jjob_lgetkf.ref diff --git a/test/atm/global-workflow/lgetkf_observer.ref b/test/testreference/atm_jjob_lgetkf_observer.ref similarity index 100% rename from test/atm/global-workflow/lgetkf_observer.ref rename to test/testreference/atm_jjob_lgetkf_observer.ref diff --git a/test/atm/global-workflow/lgetkf_solver.ref b/test/testreference/atm_jjob_lgetkf_solver.ref similarity index 100% rename from test/atm/global-workflow/lgetkf_solver.ref rename to test/testreference/atm_jjob_lgetkf_solver.ref diff --git a/ush/CMakeLists.txt b/ush/CMakeLists.txt index 2bf242db4..65f8bbfe8 100644 --- a/ush/CMakeLists.txt +++ b/ush/CMakeLists.txt @@ -1,6 +1,5 @@ list(APPEND ush_files check_yaml_keys.py - jediinc2fv3.py genYAML ) diff --git a/ush/jediinc2fv3.py b/ush/jediinc2fv3.py deleted file mode 100755 index 3bee852df..000000000 --- a/ush/jediinc2fv3.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/env python3 -# translate FV3-JEDI increment to FV3 readable format with delp and hydrostatic delz calculation -import argparse -import netCDF4 as nc -import numpy as np -import logging -import os - -vardict = { - 'ua': 'u_inc', - 'va': 'v_inc', - 't': 'T_inc', - 'T': 'T_inc', - 'sphum': 'sphum_inc', - 'liq_wat': 'liq_wat_inc', - 'o3mr': 'o3mr_inc', - 'ice_wat': 'icmr_inc', - 'lat': 'lat', - 'lon': 'lon', -} - - -def jedi_inc_to_fv3(FV3ges, FV3JEDIinc, FV3inc): - logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S') - # Check if required input netcdf files exist. If not present, exit with error message. - try: - with nc.Dataset(FV3ges, 'r'), nc.Dataset(FV3JEDIinc, 'r'): - ncges = nc.Dataset(FV3ges, 'r') - ncin = nc.Dataset(FV3JEDIinc, 'r') - ncout = nc.Dataset(FV3inc, 'w', format='NETCDF4') - create_fv3inc(ncges, ncin, ncout) - - except FileNotFoundError as e: - logging.error(f"Error occurred with message {e}") - raise - - -def create_fv3inc(ncges, ncin, ncout): - - # Copy over dimensions - for name, dimension in ncin.dimensions.items(): - if name == 'time': - continue - elif name == 'edge': - nameout = 'ilev' - else: - nameout = name - ncout.createDimension(nameout, - (len(dimension) if not dimension.isunlimited() else None)) - # Some global attributes - ncout.source = 'jediinc2fv3.py' - ncout.comment = 'Increment produced by FV3-JEDI and modified for use by FV3 read' - - # Create all the dummy vertical coordinate variables - nlevs = len(ncin.dimensions['lev']) - nlats = len(ncin.dimensions['lat']) - nlons = len(ncin.dimensions['lon']) - pfull = range(1, nlevs+1) - phalf = range(1, nlevs+2) - levvar = ncout.createVariable('lev', 'f4', ('lev')) - levvar[:] = pfull - pfullvar = ncout.createVariable('pfull', 'f4', ('lev')) - pfullvar[:] = pfull - ilevvar = ncout.createVariable('ilev', 'f4', ('ilev')) - ilevvar[:] = phalf - hyaivar = ncout.createVariable('hyai', 'f4', ('ilev')) - hyaivar[:] = phalf - hybivar = ncout.createVariable('hybi', 'f4', ('ilev')) - hybivar[:] = phalf - - # Rename and change dimensionality of fields - for name, variable in ncin.variables.items(): - if len(variable.dimensions) in [4]: - dimsout = variable.dimensions[1:] - dimsout_inc = dimsout - else: - dimsout = variable.dimensions - - if name in vardict: - # The temperature increment is needed to compute the delz - # increment. Either T or t may be used in jedi increment - # files. Set tinc to the appropriate case. - if name in ['T', 't']: - tinc = name - - x = ncout.createVariable(vardict[name], 'f4', dimsout) - if len(variable.dimensions) in [4]: - ncout[vardict[name]][:] = ncin[name][0, ...] - else: - ncout[vardict[name]][:] = ncin[name][:] - - # Populate increment and guess fields - # Note: increment and guess fields have same shape - # ps_inc is (time, lat, lon), ps_ges is {time, grid_yt, grid_xt) - # t_inc is (time, lev, lat, lon), t_ges is (time, pfull, grid_yt, grid_xt) - - ps_ges = ncges.variables['pressfc'][:] - t_ges = ncges.variables['tmp'][:] - q_ges = ncges.variables['spfh'][:] - - ps_inc = ncin.variables['ps'][:] - t_inc = ncin.variables[tinc][:] - q_inc = ncin.variables['sphum'][:] - - # Compute analysis ps - ps_anl = np.zeros((nlats, nlons), float) - ps_anl = ps_ges + ps_inc - - # Set constants and compute derived constants - grav = 9.80665 - airmw = 28.965 - h2omw = 18.015 - runiv = 8314.47 - rdry = runiv/airmw - rvap = runiv/h2omw - cpdry = 3.5*rdry - fv = (rvap/rdry)-1 - rdog = rdry/grav - kappa = rdry/cpdry - kap1 = kappa+1.0 - kapr = 1.0/kappa - - # Get ak,bk from guess file - nc_attrs = ncges.ncattrs() - ak = ncges.getncattr('ak') - bk = ncges.getncattr('bk') - - # Compute guess and analysis interface pressures - prsi_ges = np.zeros((nlevs+1, nlats, nlons), float) - prsi_anl = np.zeros((nlevs+1, nlats, nlons), float) - for k in range(0, nlevs+1): - prsi_ges[k, :, :] = ak[k]+bk[k]*ps_ges[:, :] - prsi_anl[k, :, :] = ak[k]+bk[k]*ps_anl[:, :] - - # Compute pressure increment (delp_inc). Compute - # guess and analysis layer pressures using Philips method - delp_inc = np.zeros((nlevs, nlats, nlons), float) - prsl_ges = np.zeros((nlevs, nlats, nlons), float) - prsl_anl = np.zeros((nlevs, nlats, nlons), float) - for k in range(0, nlevs): - dbk = bk[k+1] - bk[k] - delp_inc[k, :, :] = ps_inc[:, :] * dbk - prsl_ges[k, :, :] = ((prsi_ges[k+1, :, :]**kap1 - prsi_ges[k, :, :]**kap1) / (kap1*(prsi_ges[k+1, :, :] - prsi_ges[k, :, :])))**kapr - prsl_anl[k, :, :] = ((prsi_anl[k+1, :, :]**kap1 - prsi_anl[k, :, :]**kap1) / (kap1*(prsi_anl[k+1, :, :] - prsi_anl[k, :, :])))**kapr - - # Write delp increment to output file - x = ncout.createVariable('delp_inc', 'f4', dimsout_inc) - ncout['delp_inc'][:] = delp_inc[:] - - # Compute analysis temperature andl specific humidity - t_anl = np.zeros((nlevs, nlats, nlons), float) - q_anl = np.zeros((nlevs, nlats, nlons), float) - t_anl = t_ges + t_inc - q_anl = q_ges + q_inc - - # Compute guess and analysis virtual temperature - tv_ges = np.zeros((nlevs, nlats, nlons), float) - tv_anl = np.zeros((nlevs, nlats, nlons), float) - tv_ges = t_ges * (1.0 + fv*q_ges) - tv_anl = t_anl * (1.0 + fv*q_anl) - - # Compute guess and analysis delz and delz increment - delz_ges = np.zeros((nlevs, nlats, nlons), float) - delz_anl = np.zeros((nlevs, nlats, nlons), float) - delz_inc = np.zeros((nlevs, nlats, nlons), float) - for k in range(0, nlevs): - if k == 0: - delz_ges[k, :, :] = rdog * tv_ges[:, k, :, :] * np.log(prsl_ges[k, :, :]/prsi_ges[k+1, :, :]) - delz_anl[k, :, :] = rdog * tv_anl[:, k, :, :] * np.log(prsl_anl[k, :, :]/prsi_anl[k+1, :, :]) - else: - delz_ges[k, :, :] = rdog * tv_ges[:, k, :, :] * np.log(prsi_ges[k, :, :]/prsi_ges[k+1, :, :]) - delz_anl[k, :, :] = rdog * tv_anl[:, k, :, :] * np.log(prsi_anl[k, :, :]/prsi_anl[k+1, :, :]) - - delz_inc[k, :, :] = delz_anl[k, :, :] - delz_ges[k, :, :] - - # Write delz increment to output file - x = ncout.createVariable('delz_inc', 'f4', dimsout_inc) - ncout['delz_inc'][:] = delz_inc[:] - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument('FV3background', type=str, help='Input FV3 background file') - parser.add_argument('FV3JEDIincrement', type=str, help='Input FV3-JEDI LatLon Increment File') - parser.add_argument('FV3increment', type=str, help='Output FV3 Increment File') - args = parser.parse_args() - jedi_inc_to_fv3(args.FV3background, args.FV3JEDIincrement, args.FV3increment) diff --git a/ush/soca/marine_recenter.py b/ush/soca/marine_recenter.py index a3814db85..4c4a0c285 100644 --- a/ush/soca/marine_recenter.py +++ b/ush/soca/marine_recenter.py @@ -8,6 +8,7 @@ from typing import Dict import ufsda from ufsda.stage import soca_fix +import pygfs.utils.marine_da_utils as mdau from wxflow import (AttrDict, chdir, Executable, @@ -15,10 +16,8 @@ logit, parse_j2yaml, Task, - Template, - TemplateConstants, - WorkflowException, - YAMLFile) + add_to_datetime, to_timedelta, + WorkflowException) logger = getLogger(__name__.split('.')[-1]) @@ -59,32 +58,40 @@ def __init__(self, config: Dict) -> None: half_assim_freq = timedelta(hours=int(config['assim_freq'])/2) window_begin = cdate - half_assim_freq + window_end = cdate + half_assim_freq window_begin_iso = window_begin.strftime('%Y-%m-%dT%H:%M:%SZ') window_middle_iso = cdate.strftime('%Y-%m-%dT%H:%M:%SZ') - - self.recen_config = AttrDict( - {'window_begin': f"{window_begin.strftime('%Y-%m-%dT%H:%M:%SZ')}", - 'ATM_WINDOW_BEGIN': window_begin_iso, - 'ATM_WINDOW_MIDDLE': window_middle_iso, - 'DATA': DATA, - 'dump': self.task_config.RUN, - 'stage_dir': DATA, - '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.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') + + _window_begin = add_to_datetime(self.task_config.current_cycle, -to_timedelta(f"{self.task_config.assim_freq}H") / 2) + _window_end = add_to_datetime(self.task_config.current_cycle, to_timedelta(f"{self.task_config.assim_freq}H") / 2) + + local_dict = AttrDict({'window_begin': f"{window_begin.strftime('%Y-%m-%dT%H:%M:%SZ')}", + 'PARMsoca': os.path.join(self.task_config.PARMgfs, 'gdas', 'soca'), + 'MARINE_WINDOW_BEGIN': _window_begin, + 'MARINE_WINDOW_BEGIN_ISO': _window_begin.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'MARINE_WINDOW_END': _window_end, + 'MARINE_WINDOW_END_ISO': _window_end.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'MARINE_WINDOW_LENGTH': f"PT{self.task_config['assim_freq']}H", + 'MARINE_WINDOW_MIDDLE': self.task_config.current_cycle, + 'MARINE_WINDOW_MIDDLE_ISO': self.task_config.current_cycle.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'DATA': DATA, + 'dump': self.task_config.RUN, + 'stage_dir': DATA, + 'soca_input_fix_dir': self.task_config.SOCA_INPUT_FIX_DIR, + 'NMEM_ENS': self.task_config.NMEM_ENS, + 'MARINE_WINDOW_LENGTH': f"PT{config['assim_freq']}H", + 'recen_yaml_template': os.path.join(berror_yaml_dir, 'soca_ensrecenter.yaml'), + 'recen_yaml_file': os.path.join(DATA, 'soca_ensrecenter.yaml'), + 'gridgen_yaml': os.path.join(gdas_home, 'parm', 'soca', 'gridgen', 'gridgen.yaml'), + 'BKG_LIST': 'bkg_list.yaml', + 'window_begin': window_begin, + 'bkg_dir': os.path.join(DATA, 'bkg'), + 'INPUT': os.path.join(DATA, 'INPUT'), + 'ens_dir': os.path.join(DATA, 'ens')}) + + # Extend task_config with local_dict + self.task_config.update(local_dict) @logit(logger) def initialize(self): @@ -101,33 +108,28 @@ def initialize(self): RUN = self.task_config.RUN gcyc = self.task_config.gcyc - ufsda.stage.soca_fix(self.recen_config) + # stage fix files + logger.info(f"Staging SOCA fix files from {self.task_config.SOCA_INPUT_FIX_DIR}") + soca_fix_list = parse_j2yaml(self.task_config.SOCA_FIX_YAML_TMPL, self.task_config) + FileHandler(soca_fix_list).sync() - ################################################################################ - # prepare input.nml - 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.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.task_config.mom_input_nml) - nml.write(self.task_config.mom_input_nml) - - 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) + # prepare the MOM6 input.nml + mdau.prep_input_nml(self.task_config) - ################################################################################ - # Copy initial condition + # stage the soca utility yamls (gridgen, fields and ufo mapping yamls) + logger.info(f"Staging SOCA utility yaml files from {self.task_config.PARMsoca}") + soca_utility_list = parse_j2yaml(self.task_config.MARINE_UTILITY_YAML_TMPL, self.task_config) + FileHandler(soca_utility_list).sync() - bkg_utils.stage_ic(self.task_config.bkg_dir, self.task_config.DATA, gcyc) + # stage backgrounds + bkg_list = parse_j2yaml(self.task_config.MARINE_DET_STAGE_BKG_YAML_TMPL, self.task_config) + FileHandler(bkg_list).sync() +# ################################################################################ +# # Copy initial condition +# +# bkg_utils.stage_ic(self.task_config.bkg_dir, self.task_config.DATA, gcyc) +# ################################################################################ # stage ensemble members logger.info("---------------- Stage ensemble members") @@ -145,9 +147,9 @@ def initialize(self): domain, 'history') mem_dir_real = os.path.realpath(mem_dir) - f009 = f'enkf{RUN}.{domain}.t{gcyc}z.inst.f009.nc' + f00 = f"enkf{RUN}.{domain}.t{gcyc}z.inst.f009.nc" - fname_in = os.path.abspath(os.path.join(mem_dir_real, f009)) + fname_in = os.path.abspath(os.path.join(mem_dir_real, f00)) 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]) @@ -159,7 +161,7 @@ def initialize(self): logger.info(f"---------------- generate soca_ensrecenter.yaml") - recen_yaml = parse_j2yaml(self.task_config.recen_yaml_template, self.recen_config) + recen_yaml = parse_j2yaml(self.task_config.recen_yaml_template, self.task_config) recen_yaml.save(self.task_config.recen_yaml_file) @logit(logger) @@ -178,7 +180,7 @@ def run(self): chdir(self.task_config.DATA) 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_name_gridgen = os.path.join(self.task_config.EXECgfs, 'gdas_soca_gridgen.x') exec_cmd_gridgen.add_default_arg(exec_name_gridgen) exec_cmd_gridgen.add_default_arg(self.task_config.gridgen_yaml) @@ -192,7 +194,7 @@ def run(self): pass 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_name_recen = os.path.join(self.task_config.EXECgfs, 'gdas_ens_handler.x') exec_cmd_recen.add_default_arg(exec_name_recen) exec_cmd_recen.add_default_arg(os.path.basename(self.task_config.recen_yaml_file)) @@ -219,13 +221,18 @@ def finalize(self): logger.info("finalize") RUN = self.task_config.RUN - cyc = self.task_config.cyc + cyc = str(self.task_config.cyc).zfill(2) incr_file = f'enkf{RUN}.t{cyc}z.ocninc.nc' nmem_ens = self.task_config.NMEM_ENS PDYstr = self.task_config.PDY.strftime("%Y%m%d") mem_dir_list = [] copy_list = [] + # Skip the analysis insertion into the CICE restart for now + # TODO (G): Add this back in when we have hardened the soca to cice + # change of variable + + # Copy the recentering increment files to the member COMROOT directories for mem in range(1, nmem_ens+1): mem_dir = os.path.join(self.task_config.ROTDIR, f'enkf{RUN}.{PDYstr}', diff --git a/utils/fv3jedi/fv3jedi_fv3inc.h b/utils/fv3jedi/fv3jedi_fv3inc.h index 8044692a0..183e426aa 100644 --- a/utils/fv3jedi/fv3jedi_fv3inc.h +++ b/utils/fv3jedi/fv3jedi_fv3inc.h @@ -110,12 +110,21 @@ namespace gdasapp { // Read background state fv3jedi::State xxBkg(stateGeom, stateInputConfig); - oops::Log::test() << "Background State: " << std::endl << xxBkg << std::endl; // Read JEDI increment fv3jedi::Increment dxJEDI(jediIncrGeom, jediIncrVars, xxBkg.validTime()); dxJEDI.read(jediIncrInputConfig); - oops::Log::test() << "JEDI Increment: " << std::endl << dxJEDI << std::endl; + + // Testing output for inputs + if ( nmem == 1 ) { + oops::Log::test() << "Background State:" << std::endl << xxBkg << std::endl; + oops::Log::test() << "JEDI Increment:" << std::endl << dxJEDI << std::endl; + } else { + oops::Log::test() << "Background State for member " << imem << ":" << std::endl \ + << xxBkg << std::endl; + oops::Log::test() << "JEDI Increment for member " << imem << ":" << std::endl \ + << dxJEDI << std::endl; + } // Increment conversion // --------------------------------------------------------------------------------- @@ -156,7 +165,14 @@ namespace gdasapp { } } dxFV3.fromFieldSet(dxFsFV3); - oops::Log::test() << "FV3 Increment: " << std::endl << dxFV3 << std::endl; + + // Test output for outputs + if ( nmem == 1 ) { + oops::Log::test() << "FV3 Increment:" << std::endl << dxFV3 << std::endl; + } else { + oops::Log::test() << "FV3 Increment for member " << imem << ":" << std::endl \ + << dxFV3 << std::endl; + } // Write FV3 increment dxFV3.write(fv3IncrOuputConfig); diff --git a/utils/soca/gdas_ens_handler.h b/utils/soca/gdas_ens_handler.h index 019076fcb..4aa1f51f6 100644 --- a/utils/soca/gdas_ens_handler.h +++ b/utils/soca/gdas_ens_handler.h @@ -118,13 +118,9 @@ namespace gdasapp { for (size_t i = 0; i < postProcIncr.ensSize_; ++i) { oops::Log::info() << " demean member " << i << std::endl; ensMembers[i] -= ensMean; + oops::Log::info() << "incr " << i << ":" << ensMembers[i] << std::endl; } - // Get the steric variable change configuration - eckit::LocalConfiguration stericVarChangeConfig; - fullConfig.get("steric height", stericVarChangeConfig); - oops::Log::info() << "steric config 0000: " << stericVarChangeConfig << std::endl; - // Initialize the trajectories used in the linear variable changes const eckit::LocalConfiguration trajConfig(fullConfig, "trajectory"); soca::State determTraj(geom, trajConfig); // deterministic trajectory @@ -136,19 +132,55 @@ namespace gdasapp { // the ensemble mean and the deterministic soca::Increment recenteringIncr(geom, postProcIncr.socaIncrVar_, postProcIncr.dt_); recenteringIncr.diff(determTraj, ensMeanTraj); - eckit::LocalConfiguration sshRecErrOutputConfig(fullConfig, "ssh output.recentering error"); - recenteringIncr = postProcIncr.setToZero(recenteringIncr); + postProcIncr.setToZero(recenteringIncr); + + // Check if we're only re-centering the ensemble fcst around the det. + bool recenterOnly = fullConfig.getBool("recentering around deterministic", false); + + // Save increments and exit if all we're doing is re-centering + // the ensemble fcst around the det. + if (recenterOnly) { + oops::Log::info() << "Only recentering " << std::endl; + int result = 0; + for (size_t i = 0; i < postProcIncr.ensSize_; ++i) { + // make a copy of the ens. member + soca::Increment incr(ensMembers[i]); + + // Add the recentering increment + incr += recenteringIncr; + oops::Log::info() << "recentered incr " << i << ":" << incr << std::endl; + + // Append the vertical geometry (for MOM6 IAU) + postProcIncr.appendLayer(incr); + oops::Log::info() << "incr " << i << ":" << incr << std::endl; + + // Set variables to zero if specified in the configuration + postProcIncr.setToZero(incr); + + // Save the increments used to initialize the ensemble forecast + result = postProcIncr.save(incr, i+1); + } + return result; + } + + // Get the steric variable change configuration + eckit::LocalConfiguration stericVarChangeConfig; + fullConfig.get("steric height", stericVarChangeConfig); + oops::Log::info() << "steric config 0000: " << stericVarChangeConfig << std::endl; + + // Re-balance the perturbations around the deterministic oops::Log::info() << "steric config : " << stericVarChangeConfig << std::endl; postProcIncr.applyLinVarChange(recenteringIncr, stericVarChangeConfig, determTraj); oops::Log::info() << "ensemble mean: " << ensMeanTraj << std::endl; oops::Log::info() << "deterministic: " << determTraj << std::endl; oops::Log::info() << "error: " << recenteringIncr << std::endl; + eckit::LocalConfiguration sshRecErrOutputConfig(fullConfig, "ssh output.recentering error"); recenteringIncr.write(sshRecErrOutputConfig); // Re-process the ensemble of perturbations int result = 0; oops::Variables socaSshVar; - socaSshVar.push_back("ssh"); + socaSshVar.push_back("sea_surface_height_above_geoid"); std::vector sshTotal; std::vector sshSteric; std::vector sshNonSteric; @@ -167,7 +199,7 @@ namespace gdasapp { // Zero out ssh and other specified fields // TODO(G): - assert that at least ssh is in the list // - assert that Temperature is NOT in the list - incr = postProcIncr.setToZero(incr); + postProcIncr.setToZero(incr); // Compute the original steric height perturbation from T and S eckit::LocalConfiguration stericConfig(fullConfig, "steric height"); @@ -186,7 +218,7 @@ namespace gdasapp { oops::Log::info() << "--- ssh non-steric --- " << i << sshNonSteric[i] << std::endl; // Zero out specified fields (again, steric heigh is now in ssh from the previous step) - incr = postProcIncr.setToZero(incr); + postProcIncr.setToZero(incr); // Filter ensemble member and recompute steric ssh, recentering around // the deterministic trajectory @@ -264,7 +296,7 @@ namespace gdasapp { oops::Log::info() << "filtered std: " << ensStd << std::endl; // Prepare D (diag of the static B): replace sigma ssh with sigma ssh_u - ensStd = postProcIncr.setToZero(ensStd); // Set ssh (and other specified fields to zero) + postProcIncr.setToZero(ensStd); // Set ssh (and other specified fields to zero) atlas::FieldSet ensStdFs; ensStd.toFieldSet(ensStdFs); atlas::FieldSet sshNonStericStdFs; diff --git a/utils/soca/gdas_incr_handler.h b/utils/soca/gdas_incr_handler.h index 409f8acbe..30d2502fe 100644 --- a/utils/soca/gdas_incr_handler.h +++ b/utils/soca/gdas_incr_handler.h @@ -35,6 +35,10 @@ namespace gdasapp { oops::Log::info() << "geometry: " << std::endl << geomConfig << std::endl; const soca::Geometry geom(geomConfig, this->getComm()); + // Check that we are using at least 2 mpi tasks + if (this->getComm().size() < 2) { + throw eckit::BadValue("This application requires at least 2 MPI tasks", Here()); + } // Initialize the post processing PostProcIncr postProcIncr(fullConfig, geom, this->getComm()); @@ -50,18 +54,20 @@ namespace gdasapp { // Read increment from file soca::Increment incr = postProcIncr.read(i); - // At the very minimum, we run this script to append the layers state, so do that! - soca::Increment incrWithLayer = postProcIncr.appendLayer(incr); - oops::Log::debug() << "========= after appending layer:" << std::endl; - oops::Log::debug() << incrWithLayer << std::endl; + // Append variables to the increment + oops::Variables extraVars(postProcIncr.socaZeroIncrVar_); + extraVars += postProcIncr.layerVar_; + soca::Increment incr_mom6 = postProcIncr.appendVar(incr, extraVars); // Zero out specified fields - incrWithLayer = postProcIncr.setToZero(incrWithLayer); + postProcIncr.setToZero(incr_mom6); + oops::Log::debug() << "========= after appending variables:" << std::endl; + oops::Log::debug() << incr_mom6 << std::endl; // Save final increment - result = postProcIncr.save(incrWithLayer, i); + result = postProcIncr.save(incr_mom6, i); oops::Log::debug() << "========= after appending layer and after saving:" << std::endl; - oops::Log::debug() << incrWithLayer << std::endl; + oops::Log::debug() << incr_mom6 << std::endl; } return result; } diff --git a/utils/soca/gdas_postprocincr.h b/utils/soca/gdas_postprocincr.h index 4fe241e27..b8638a7b8 100644 --- a/utils/soca/gdas_postprocincr.h +++ b/utils/soca/gdas_postprocincr.h @@ -92,62 +92,71 @@ class PostProcIncr { } // ----------------------------------------------------------------------------- - // Append layer thicknesses to increment - // TODO(guillaume): There's got to be a better way to append a variable. - - soca::Increment appendLayer(soca::Increment& socaIncr) { + // Append variable to increment + soca::Increment appendVar(const soca::Increment& socaIncr, const oops::Variables varToAppend) { oops::Log::info() << "==========================================" << std::endl; - oops::Log::info() << "====== Append Layers" << std::endl; + oops::Log::info() << "====== Append " << varToAppend << std::endl; + + // make a copy of the input increment + soca::Increment socaIncrOut(socaIncr); // concatenate variables oops::Variables outputIncrVar(socaIncrVar_); - outputIncrVar += layerVar_; + outputIncrVar += varToAppend; oops::Log::debug() << "-------------------- outputIncrVar: " << std::endl; oops::Log::debug() << outputIncrVar << std::endl; - // append layer variable to the soca increment + // append variable to the soca increment atlas::FieldSet socaIncrFs; - socaIncr.toFieldSet(socaIncrFs); - socaIncr.updateFields(outputIncrVar); + socaIncrOut.toFieldSet(socaIncrFs); + socaIncrOut.updateFields(outputIncrVar); // pad layer increment with zeros - soca::Increment layerThick(Layers_); - atlas::FieldSet socaLayerThickFs; - oops::Log::debug() << "-------------------- thickness field: " << std::endl; - oops::Log::debug() << layerThick << std::endl; - layerThick.toFieldSet(socaLayerThickFs); - layerThick.updateFields(outputIncrVar); - - // append layer thinckness to increment - socaIncr += layerThick; + soca::Increment incrToAppend(Layers_); // Assumes that Layers_ contains varToAppend + atlas::FieldSet incrToAppendFs; + oops::Log::debug() << "-------------------- incrToAppend fields: " << std::endl; + oops::Log::debug() << incrToAppend << std::endl; + incrToAppend.toFieldSet(incrToAppendFs); + incrToAppend.updateFields(outputIncrVar); + + // append variables to increment + socaIncrOut += incrToAppend; oops::Log::debug() << "-------------------- output increment: " << std::endl; - oops::Log::debug() << socaIncr << std::endl; + oops::Log::debug() << socaIncrOut << std::endl; - return socaIncr; + return socaIncrOut; + } + + // ----------------------------------------------------------------------------- + // Append layer thicknesses to increment + soca::Increment appendLayer(soca::Increment& socaIncr) { + // Append layer thicknesses to the increment + soca::Increment socaIncrOut = appendVar(socaIncr, layerVar_); + return socaIncrOut; } // ----------------------------------------------------------------------------- // Set specified variables to 0 - soca::Increment setToZero(soca::Increment& socaIncr) { + void setToZero(soca::Increment& socaIncr) { oops::Log::info() << "==========================================" << std::endl; if (!this->setToZero_) { oops::Log::info() << "====== no variables to set to 0.0" << std::endl; - return socaIncr; + return; } oops::Log::info() << "====== Set specified increment variables to 0.0" << std::endl; - std::cout << socaZeroIncrVar_ << std::endl; atlas::FieldSet socaIncrFs; socaIncr.toFieldSet(socaIncrFs); + for (auto & field : socaIncrFs) { // only works if rank is 2 ASSERT(field.rank() == 2); // Set variable to zero if (socaZeroIncrVar_.has(field.name())) { - std::cout << "setting " << field.name() << " to 0" << std::endl; + oops::Log::info() << "setting " << field.name() << " to 0" << std::endl; auto view = atlas::array::make_view(field); view.assign(0.0); } @@ -155,7 +164,6 @@ class PostProcIncr { socaIncr.fromFieldSet(socaIncrFs); oops::Log::debug() << "-------------------- increment with zero'ed out fields: " << std::endl; oops::Log::debug() << socaIncr << std::endl; - return socaIncr; } // ----------------------------------------------------------------------------- @@ -169,7 +177,7 @@ class PostProcIncr { soca::LinearVariableChange lvc(this->geom_, lvcConfig); lvc.changeVarTraj(xTraj, socaIncrVar_); lvc.changeVarTL(socaIncr, socaIncrVar_); - oops::Log::info() << "$%^#& in var change:" << socaIncr << std::endl; + oops::Log::info() << " in var change:" << socaIncr << std::endl; } // ----------------------------------------------------------------------------- @@ -178,6 +186,7 @@ class PostProcIncr { int save(soca::Increment& socaIncr, int ensMem = 1) { oops::Log::info() << "==========================================" << std::endl; oops::Log::info() << "-------------------- save increment: " << std::endl; + oops::Log::info() << socaIncr << std::endl; socaIncr.write(outputIncrConfig_); // wait for everybody to be done diff --git a/utils/soca/gdas_soca_diagb.h b/utils/soca/gdas_soca_diagb.h index 563d303b9..9ca6c8a9b 100644 --- a/utils/soca/gdas_soca_diagb.h +++ b/utils/soca/gdas_soca_diagb.h @@ -343,7 +343,7 @@ namespace gdasapp { stdDevFilt(jnode, level, nbz, configD.depthMin, neighbors, nzMld, viewHocn, bkg, viewBathy, stdDevBkg, true, 6); - } + } // end level } // end 3D case } // end jnode } // end var @@ -412,11 +412,32 @@ namespace gdasapp { tmpArray(jnode, level+1)) / 3.0; } stdDevBkg(jnode, 0) = stdDevBkg(jnode, 1); + } // end jnode + } // end iter (vertical) + } // end vertical smoothing case + } // end var (loop through variables) + } // end simple smoothing + + /// Impose an exponential decay to the background error + // ---------------------------------------------------- + if (fullConfig.has("vertical e-folding scale")) { + double efold = 0.0; + fullConfig.get("vertical e-folding scale", efold); + for (auto & var : configD.socaVars.variables()) { + oops::Log::info() + << "====================== apply exponential decay to the background error. " + << " e-folding scale: " << efold << " m for " << var << std::endl; + auto stdDevBkg = atlas::array::make_view(bkgErrFs[var]); + auto numLevels = xbFs["sea_water_potential_temperature"].shape(0); + for (atlas::idx_t jnode = 0; jnode < numLevels; ++jnode) { + for (atlas::idx_t level = 0; level < xbFs[var].shape(1); ++level) { + if (viewDepth(jnode, level) >= 0.0) { + stdDevBkg(jnode, level) *= std::exp(-viewDepth(jnode, level) / efold); } - } - } - } - } + } // end level + } // end jnode + } // end var (loop through variables) + } // end exponential decay /// Use explicit diffusion to smooth the background error // ------------------------------------------------------ @@ -454,7 +475,7 @@ namespace gdasapp { // Apply the diffusion filtering diffuse.setParameters(scalesFs); diffuse.multiply(bkgErrFs, oops::Diffusion::Mode::HorizontalOnly); - } + } // end explicit diffusion // Rescale util::multiplyFieldSet(bkgErrFs, configD.rescale); diff --git a/utils/test/CMakeLists.txt b/utils/test/CMakeLists.txt index 00adbad26..0f62cd33c 100644 --- a/utils/test/CMakeLists.txt +++ b/utils/test/CMakeLists.txt @@ -15,10 +15,10 @@ list( APPEND utils_test_input ) set( gdas_utils_test_ref + testref/rads2ioda.test testref/ghrsst2ioda.test testref/rtofstmp.test testref/rtofssal.test - testref/rads2ioda.test testref/smap2ioda.test testref/smos2ioda.test testref/icecabi2ioda.test @@ -67,14 +67,16 @@ ecbuild_add_test( TARGET test_gdasapp_util_rads2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_rads2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # Test the GHRSST to IODA converter ecbuild_add_test( TARGET test_gdasapp_util_ghrsst2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_ghrsst2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # copy rtofs binary input files to the testing area # and generate the tests @@ -129,46 +131,53 @@ ecbuild_add_test( TARGET test_gdasapp_util_smap2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_smap2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # Test the SMOS to IODA converter ecbuild_add_test( TARGET test_gdasapp_util_smos2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_smos2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # Test the VIIRS AOD to IODA converter ecbuild_add_test( TARGET test_gdasapp_util_viirsaod2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_viirsaod2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # Test the ABI to IODA converter ecbuild_add_test( TARGET test_gdasapp_util_icecabi2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_icecabi2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # Test the AMSR2 to IODA converter ecbuild_add_test( TARGET test_gdasapp_util_icecamsr2ioda COMMAND ${CMAKE_BINARY_DIR}/bin/gdas_obsprovider2ioda.x ARGS "../testinput/gdas_icecamsr2ioda.yaml" LIBS gdas-utils - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # 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) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata) # 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) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obsproc + TEST_DEPENDS test_gdasapp_util_prepdata)