diff --git a/.editorconfig b/.editorconfig index 5ad9da1a41d..047fcbf85da 100644 --- a/.editorconfig +++ b/.editorconfig @@ -22,7 +22,7 @@ indent_style = tab indent_size = 4 max_line_length = 79 -[jobs/*] +[dev/jobs/*] indent_style = space indent_size = 4 shell_variant = bash diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 19d3ace9b40..69c6f7499cc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -74,7 +74,6 @@ jobs/JGLOBAL_MARINE_* @guillaumevernieres @AndrewEichmann-NOAA jobs/JGLOBAL_OCEANICE_PRODUCTS @JesseMeng-NOAA @ChristopherHill-NOAA jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS @CoryMartin-NOAA jobs/JGLOBAL_PREP_EMISSIONS @bbakernoaa -jobs/JGLOBAL_PREP_OBS_AERO @CoryMartin-NOAA jobs/JGLOBAL_PREP_OCEAN_OBS @guillaumevernieres @AndrewEichmann-NOAA jobs/JGLOBAL_*SNOW* @jiaruidong2017 jobs/JGLOBAL_STAGE_IC @DavidHuber-NOAA @aerorahul @@ -161,6 +160,7 @@ ush/gaussian_sfcanl.sh @BrianCurtis-NOAA ush/getdump.sh @DavidHuber-NOAA @aerorahul ush/getges.sh @DavidHuber-NOAA @aerorahul ush/getgfsnctime @CoryMartin-NOAA +ush/getioda.sh @nicholasesposito @CoryMartin-NOAA @RussTreadon-NOAA ush/getncdimlen @CoryMartin-NOAA ush/gfs_bfr2gpk.sh @BoCui-NOAA ush/gfs_bufr.sh @BoCui-NOAA @@ -209,7 +209,6 @@ ush/python/pygfs/task/__init__.py @aerorahul ush/python/pygfs/task/aero_analysis.py @DavidNew-NOAA @CoryMartin-NOAA ush/python/pygfs/task/aero_bmatrix.py @DavidNew-NOAA @CoryMartin-NOAA ush/python/pygfs/task/aero_emissions.py @bbakernoaa -ush/python/pygfs/task/aero_prepobs.py @CoryMartin-NOAA ush/python/pygfs/task/analysis.py @DavidNew-NOAA @RussTreadon-NOAA ush/python/pygfs/task/analysis_stats.py @CoryMartin-NOAA @DavidNew-NOAA ush/python/pygfs/task/archive.py @DavidHuber-NOAA diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3e5e84d2d08..308a8585f20 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,5 @@ name: Bug Report description: Report something that is incorrect or broken -labels: ["triage"] type: "bug" projects: ["NOAA-EMC/41"] diff --git a/.github/ISSUE_TEMPLATE/new_feature.yml b/.github/ISSUE_TEMPLATE/new_feature.yml index fee7d641e8f..512c0395ad7 100644 --- a/.github/ISSUE_TEMPLATE/new_feature.yml +++ b/.github/ISSUE_TEMPLATE/new_feature.yml @@ -1,6 +1,5 @@ name: New Feature description: New capability is desired -labels: ["triage"] type: "feature" projects: ["NOAA-EMC/41"] diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9e9c9eccfec..41d02f0af95 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -41,6 +41,11 @@ # Change characteristics +- Is this change expected to change outputs (e.g. value changes to existing outputs, new files stored in COM, files removed from COM, filename changes, additions/subtractions to archives)? YES/NO (If YES, please indicate to which system(s)) + - [ ] GFS + - [ ] GEFS + - [ ] SFS + - [ ] GCAFS - Is this a breaking change (a change in existing functionality)? YES/NO - Does this change require a documentation update? YES/NO - Does this change require an update to any of the following submodules? YES/NO (If YES, please add a link to any PRs that are pending.) diff --git a/.github/workflows/bash_code_analysis.yaml b/.github/workflows/bash_code_analysis.yaml new file mode 100644 index 00000000000..ca6160175a7 --- /dev/null +++ b/.github/workflows/bash_code_analysis.yaml @@ -0,0 +1,105 @@ +name: bash_code_analysis +on: + # push: + # branches: + # - develop + pull_request: + + workflow_dispatch: + +permissions: + contents: read + +jobs: + + shfmt: + runs-on: ubuntu-22.04 + + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # to get PR metadata + security-events: write + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + # Switch to this action once whole repo is shfmt compliant + # - name: shfmt scan + # uses: reviewdog/action-shfmt@v1 + # with: + # filter_mode: nofilter + # level: warning + # reporter: github-pr-review + + - name: Install shfmt + uses: mfinelli/setup-shfmt@v4 + - name: shfmt scan + run: shfmt -d dev/jobs dev/job_cards dev/scripts dev/ush ush + + shellcheck: + runs-on: ubuntu-22.04 + + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # to get PR metadata + security-events: write + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + submodules: false + + - name: Shellcheck Scan + uses: reviewdog/action-shellcheck@v1 + with: + filter_mode: nofilter + level: warning + reporter: github-pr-review + path: | + dev/jobs + dev/job_cards + dev/scripts + dev/ush + ush + pattern: | + config.* + J* + *.env + *.sh + *.bash + + differential_shellcheck: + # Run again on just changes until whole repo is compliant + runs-on: ubuntu-22.04 + + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # to get PR metadata + security-events: write + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + submodules: false + + - name: Shellcheck Scan + uses: reviewdog/action-shellcheck@v1 + with: + filter_mode: added + level: warning + reporter: github-pr-review + check_all_files_with_shebangs: true + pattern: | + config.* + J* + *.env + *.sh + *.bash + + + diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml deleted file mode 100644 index 4987c8caf01..00000000000 --- a/.github/workflows/linters.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# -name: shellnorms -on: - pull_request: - -permissions: - contents: read - -defaults: - run: - shell: bash -o pipefail {0} - -jobs: - lint-shell: - runs-on: ubuntu-22.04 - - permissions: - security-events: write - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - id: ShellCheck - name: Lint shell scripts - uses: redhat-plumbers-in-action/differential-shellcheck@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - if: ${{ always() }} - name: Upload artifact with ShellCheck defects in SARIF format - uses: actions/upload-artifact@v4 - with: - name: Differential ShellCheck SARIF - path: ${{ steps.ShellCheck.outputs.sarif }} - - # lint-python: - # runs-on: ubuntu-latest - - # permissions: - # security-events: write - - # steps: - # - name: Checkout code - # uses: actions/checkout@v3 - - # - id: VCS_Diff_Lint - # name: Lint python scripts - # uses: fedora-copr/vcs-diff-lint-action@v1 - - # - if: ${{ always() }} - # name: Upload artifact with detected defects in SARIF format - # uses: actions/upload-artifact@v3 - # with: - # name: VCS Diff Lint SARIF - # path: ${{ steps.VCS_Diff_Lint.outputs.sarif }} - - # - if: ${{ failure() }} - # name: Upload SARIF to GitHub using github/codeql-action/upload-sarif - # uses: github/codeql-action/upload-sarif@v2 - # with: - # sarif_file: ${{ steps.VCS_Diff_Lint.outputs.sarif }} diff --git a/.github/workflows/pynorms.yaml b/.github/workflows/python_code_analysis.yaml similarity index 81% rename from .github/workflows/pynorms.yaml rename to .github/workflows/python_code_analysis.yaml index 87915190ef2..bc4b49f4532 100644 --- a/.github/workflows/pynorms.yaml +++ b/.github/workflows/python_code_analysis.yaml @@ -1,5 +1,11 @@ -name: pynorms -on: [push, pull_request] +name: python_code_analysis +on: + push: + branches: + - develop + pull_request: + + workflow_dispatch: jobs: check_norms: diff --git a/.gitignore b/.gitignore index e486214ecce..f83211291ef 100644 --- a/.gitignore +++ b/.gitignore @@ -150,7 +150,7 @@ sorc/ocnicepost.fd #------------------------------ # jobs symlinks # scripts symlinks -scripts/exglobal_prep_ocean_obs.py +dev/scripts/exglobal_prep_ocean_obs.py # ush symlinks ush/bufr2ioda_insitu_profile_argo.py ush/bufr2ioda_insitu_profile_bathy.py @@ -169,11 +169,11 @@ ush/fv3gfs_make_orog.sh ush/global_chgres.sh ush/global_chgres_driver.sh ush/global_cycle_driver.sh +ush/gsi_satbias2ioda_all.sh ush/jediinc2fv3.py ush/imsfv3_scf2ioda.py ush/bufr_snocvr_snomad.py ush/atparse.bash -ush/run_bufr2ioda.py ush/bufr2ioda_insitu* ush/python/gsincdiag_to_ioda ush/python/ufsda @@ -181,6 +181,7 @@ ush/python/pyiodaconv ush/python/soca ush/python/gen_bufr2ioda_json.py ush/python/gen_bufr2ioda_yaml.py +ush/python/run_bufr2ioda.py ush/spoc # ush log file ush/fetch-fix-data.log diff --git a/dev/ci/cases/pr/C48_S2SW.yaml b/dev/ci/cases/pr/C48_S2SW.yaml index 59148444792..cd7e5875903 100644 --- a/dev/ci/cases/pr/C48_S2SW.yaml +++ b/dev/ci/cases/pr/C48_S2SW.yaml @@ -11,6 +11,9 @@ experiment: edate: 2021032312 yaml: {{ HOMEgfs }}/dev/ci/cases/yamls/gfs_defaults_ci.yaml +skip_ci_on_hosts: + - wcoss2 + workflow: engine: rocoto rocoto: diff --git a/dev/ci/cases/pr/C48_S2SWA_gefs_RT.yaml b/dev/ci/cases/pr/C48_S2SWA_gefs_RT.yaml index 4bd99d07b00..ba6749b1e03 100644 --- a/dev/ci/cases/pr/C48_S2SWA_gefs_RT.yaml +++ b/dev/ci/cases/pr/C48_S2SWA_gefs_RT.yaml @@ -9,12 +9,13 @@ experiment: nens: 30 interval: 24 start: cold - gefstype: near-real-time + gefstype: gefs-real-time comroot: {{ 'RUNTESTS' | getenv }}/COMROOT expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR idate: 2024112500 edate: 2024112500 yaml: {{ HOMEgfs }}/dev/ci/cases/yamls/gefs_defaults_ci.yaml + icsdir: /lfs/h2/emc/ens/noscrub/eric.sinsky/RETRO_ICS # TODO run on supported platforms once the gefs forecast and subsequent tasks can succeed with RETRO ICs # Add this to run the stage ic job 'icsdir: /lfs/h2/emc/ens/noscrub/eric.sinsky/RETRO_ICS' diff --git a/dev/ci/cases/pr/C96C48_ufsgsi_hybatmDA.yaml b/dev/ci/cases/pr/C96C48_ufsgsi_hybatmDA.yaml new file mode 100644 index 00000000000..14cc30db214 --- /dev/null +++ b/dev/ci/cases/pr/C96C48_ufsgsi_hybatmDA.yaml @@ -0,0 +1,31 @@ +experiment: + net: gfs + mode: cycled + pslot: {{ 'pslot' | getenv }} + app: ATM + resdetatmos: 96 + resensatmos: 48 + comroot: {{ 'RUNTESTS' | getenv }}/COMROOT + expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR + icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96C48/20250808 + idate: 2024022318 + edate: 2024022406 + nens: 2 + interval: 24 + start: warm + yaml: {{ HOMEgfs }}/dev/ci/cases/yamls/ufsgsi_hybatmDA_defaults.ci.yaml + +skip_ci_on_hosts: + - gaeac5 + - gaeac6 + - orion + - hercules + - awsepicglobalworkflow + +workflow: + engine: rocoto + rocoto: + maxtries: 2 + cyclethrottle: 3 + taskthrottle: 25 + verbosity: 2 diff --git a/dev/ci/cases/pr/C96_gcafs_cycled.yaml b/dev/ci/cases/pr/C96_gcafs_cycled.yaml index 58d9c8ab5f3..a51d4277648 100644 --- a/dev/ci/cases/pr/C96_gcafs_cycled.yaml +++ b/dev/ci/cases/pr/C96_gcafs_cycled.yaml @@ -15,9 +15,7 @@ experiment: yaml: {{ HOMEgfs }}/dev/ci/cases/yamls/gcafs_cycled_defaults_ci.yaml skip_ci_on_hosts: - - orion - gaeac5 - - hercules - awsepicglobalworkflow - ursa diff --git a/dev/ci/cases/yamls/gcafs_cycled_defaults_ci.yaml b/dev/ci/cases/yamls/gcafs_cycled_defaults_ci.yaml index a344a12d16d..8b6fa75db3a 100644 --- a/dev/ci/cases/yamls/gcafs_cycled_defaults_ci.yaml +++ b/dev/ci/cases/yamls/gcafs_cycled_defaults_ci.yaml @@ -3,3 +3,4 @@ defaults: base: DO_TEST_MODE: "NO" AERO_ANL_RUNS: "gcdas" + USE_IODADIR: "YES" diff --git a/dev/ci/cases/yamls/gfs_extended_ci.yaml b/dev/ci/cases/yamls/gfs_extended_ci.yaml index bbf8155ac3f..b45ac7d935a 100644 --- a/dev/ci/cases/yamls/gfs_extended_ci.yaml +++ b/dev/ci/cases/yamls/gfs_extended_ci.yaml @@ -13,3 +13,4 @@ base: FHMAX_GFS: 384 FHMAX_HF_GFS: 120 DO_TEST_MODE: "NO" + DO_ARCHCOM: "YES" diff --git a/dev/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml b/dev/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml index 045a1bc8a4a..bdcc3d90bec 100644 --- a/dev/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml +++ b/dev/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml @@ -5,6 +5,8 @@ base: DO_JEDIATMVAR: "YES" DO_JEDIATMENS: "YES" DO_TEST_MODE: "NO" + CASE_ANL: "C48" + USE_IODADIR: "YES" atmanl: LAYOUT_X_ATMANL: 4 LAYOUT_Y_ATMANL: 4 @@ -23,5 +25,7 @@ esfc: DONST: "NO" nsst: NST_MODEL: "1" +prepatmiodaobs: + DO_CONVERT_IODA: "YES" sfcanl: DONST: "NO" diff --git a/dev/ci/cases/yamls/ufsgsi_hybatmDA_defaults.ci.yaml b/dev/ci/cases/yamls/ufsgsi_hybatmDA_defaults.ci.yaml new file mode 100644 index 00000000000..ab813714613 --- /dev/null +++ b/dev/ci/cases/yamls/ufsgsi_hybatmDA_defaults.ci.yaml @@ -0,0 +1,32 @@ +defaults: + !INC {{ HOMEgfs }}/dev/parm/config/gfs/yaml/defaults.yaml +base: + DOIAU: "NO" + DO_JEDIATMVAR: "YES" + DO_JEDIATMENS: "NO" + DO_TEST_MODE: "NO" + CASE_ANL: "C48" + CASE_HIST: "C96" + DONST: "NO" + USE_IODADIR: "YES" +atmanl: + LAYOUT_X_ATMANL: 4 + LAYOUT_Y_ATMANL: 4 + OBS_LIST_YAML: "${HOMEgfs}/sorc/gdas.cd/test/gw-ci/atm/atm_obs_list_ufs_hybatmDA.yaml.j2" + VAR_JEDI_TEST_YAML: "${HOMEgfs}/sorc/gdas.cd/test/gw-ci/atm/jedi-test_3dvar_ufs_hybatmDA.yaml.j2" + FV3INC_JEDI_TEST_YAML: "${HOMEgfs}/sorc/gdas.cd/test/gw-ci/atm/jedi-test_3dvar-fv3inc_ufs_hybatmDA.yaml.j2" + NUMBER_OUTER_LOOPS: 2 + NINNER_LOOP1: 2 + NINNER_LOOP2: 4 +esfc: + DONST: "NO" +nsst: + NST_MODEL: "1" +prep: + COPY_BIASCOR_SOURCE: "NO" + COPY_BIASCOR_STATIC: "YES" + CONVERT_BIASCOR: "YES" +prepatmiodaobs: + DO_CONVERT_IODA: "YES" +sfcanl: + DONST: "NO" diff --git a/dev/ci/gitlab-ci-hosts.yml b/dev/ci/gitlab-ci-hosts.yml index 6542fd72e09..875cd7c2a32 100644 --- a/dev/ci/gitlab-ci-hosts.yml +++ b/dev/ci/gitlab-ci-hosts.yml @@ -22,19 +22,19 @@ # Template matrices for case lists .hera_cases_matrix: &hera_cases - - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48_hybatmsnowDA", "C96C48_hybatmsoilDA", "C96C48_ufs_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96_gcafs_cycled", "C96_gcafs_cycled_noDA", "C96mx100_S2S"] + - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48_hybatmsnowDA", "C96C48_hybatmsoilDA", "C96C48_ufsgsi_hybatmDA", "C96C48_ufs_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96_gcafs_cycled", "C96_gcafs_cycled_noDA", "C96mx100_S2S"] .gaeac6_cases_matrix: &gaeac6_cases - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48_hybatmsnowDA", "C96C48_hybatmsoilDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96_gcafs_cycled", "C96_gcafs_cycled_noDA", "C96mx100_S2S"] .orion_cases_matrix: &orion_cases - - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C96C48_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S"] + - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C96C48_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S", "C96_gcafs_cycled"] .hercules_cases_matrix: &hercules_cases - - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S"] + - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S", "C96_gcafs_cycled"] .ursa_cases_matrix: &ursa_cases - - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48_hybatmsnowDA", "C96C48_hybatmsoilDA", "C96C48_ufs_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S"] + - caseName: ["C48_ATM", "C48_S2SW", "C48_S2SWA_gefs", "C48mx500_3DVarAOWCDA", "C48mx500_hybAOWCDA", "C96C48_hybatmDA", "C96C48_hybatmsnowDA", "C96C48_hybatmsoilDA", "C96C48_ufsgsi_hybatmDA", "C96C48_ufs_hybatmDA", "C96C48mx500_S2SW_cyc_gfs", "C96_atm3DVar", "C96mx100_S2S"] # Host: Hera - Standard Cases setup_experiments-hera: diff --git a/dev/ctests/README.md b/dev/ctests/README.md index 95e8ae13872..f25ad3a1d1a 100644 --- a/dev/ctests/README.md +++ b/dev/ctests/README.md @@ -251,7 +251,7 @@ source $HOMEgfs/dev/ci/platforms/config.$MACHINE_ID - **Complete Documentation**: `docs/source/testing.rst` - **Test Case Examples**: `cases/*.yaml` - **CI/CD Pipeline**: `../ci/gitlab-ci-hosts.yml` -- **Job Scripts**: `../../jobs/JGLOBAL_*` +- **Job Scripts**: `../jobs/JGLOBAL_*` - **Platform Configuration**: `../ci/platforms/config.*` --- diff --git a/dev/jobs/aeroanlfinal.sh b/dev/job_cards/rocoto/aeroanlfinal.sh similarity index 88% rename from dev/jobs/aeroanlfinal.sh rename to dev/job_cards/rocoto/aeroanlfinal.sh index e5e0c3736eb..a002c5c1940 100755 --- a/dev/jobs/aeroanlfinal.sh +++ b/dev/job_cards/rocoto/aeroanlfinal.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE" status=$? exit "${status}" diff --git a/dev/jobs/aeroanlgenb.sh b/dev/job_cards/rocoto/aeroanlgenb.sh similarity index 87% rename from dev/jobs/aeroanlgenb.sh rename to dev/job_cards/rocoto/aeroanlgenb.sh index be57aae5857..af72ffe6b8b 100755 --- a/dev/jobs/aeroanlgenb.sh +++ b/dev/job_cards/rocoto/aeroanlgenb.sh @@ -16,6 +16,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX" +"${HOMEgfs}/dev/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX" status=$? exit "${status}" diff --git a/dev/jobs/aeroanlinit.sh b/dev/job_cards/rocoto/aeroanlinit.sh similarity index 87% rename from dev/jobs/aeroanlinit.sh rename to dev/job_cards/rocoto/aeroanlinit.sh index eb540376c70..e1df69aabdf 100755 --- a/dev/jobs/aeroanlinit.sh +++ b/dev/job_cards/rocoto/aeroanlinit.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE" status=$? exit "${status}" diff --git a/dev/jobs/aeroanlvar.sh b/dev/job_cards/rocoto/aeroanlvar.sh similarity index 87% rename from dev/jobs/aeroanlvar.sh rename to dev/job_cards/rocoto/aeroanlvar.sh index 8e17bf41f8e..681d30c9428 100755 --- a/dev/jobs/aeroanlvar.sh +++ b/dev/job_cards/rocoto/aeroanlvar.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL" +"${HOMEgfs}/dev/jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL" status=$? exit "${status}" diff --git a/dev/jobs/aerosol_init.sh b/dev/job_cards/rocoto/aerosol_init.sh similarity index 100% rename from dev/jobs/aerosol_init.sh rename to dev/job_cards/rocoto/aerosol_init.sh diff --git a/dev/jobs/anal.sh b/dev/job_cards/rocoto/anal.sh similarity index 89% rename from dev/jobs/anal.sh rename to dev/job_cards/rocoto/anal.sh index d854d86fe31..a2178f92334 100755 --- a/dev/jobs/anal.sh +++ b/dev/job_cards/rocoto/anal.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_ANALYSIS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_ANALYSIS" status=$? exit "${status}" diff --git a/dev/jobs/analcalc.sh b/dev/job_cards/rocoto/analcalc.sh similarity index 88% rename from dev/jobs/analcalc.sh rename to dev/job_cards/rocoto/analcalc.sh index 7e5549b8395..77e5f5d27a5 100755 --- a/dev/jobs/analcalc.sh +++ b/dev/job_cards/rocoto/analcalc.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC" status=$? exit "${status}" diff --git a/dev/jobs/analcalc_fv3jedi.sh b/dev/job_cards/rocoto/analcalc_fv3jedi.sh similarity index 87% rename from dev/jobs/analcalc_fv3jedi.sh rename to dev/job_cards/rocoto/analcalc_fv3jedi.sh index 52bbdf42804..4984ab0eab7 100755 --- a/dev/jobs/analcalc_fv3jedi.sh +++ b/dev/job_cards/rocoto/analcalc_fv3jedi.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI +"${HOMEgfs}"/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI status=$? exit "${status}" diff --git a/dev/jobs/analdiag.sh b/dev/job_cards/rocoto/analdiag.sh similarity index 88% rename from dev/jobs/analdiag.sh rename to dev/job_cards/rocoto/analdiag.sh index 2849a41d7e6..005e49471a8 100755 --- a/dev/jobs/analdiag.sh +++ b/dev/job_cards/rocoto/analdiag.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ATMOS_ANALYSIS_DIAG" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_DIAG" status=$? exit "${status}" diff --git a/dev/jobs/anlstat.sh b/dev/job_cards/rocoto/anlstat.sh similarity index 90% rename from dev/jobs/anlstat.sh rename to dev/job_cards/rocoto/anlstat.sh index 8b73be1026b..55a4c00a293 100755 --- a/dev/jobs/anlstat.sh +++ b/dev/job_cards/rocoto/anlstat.sh @@ -16,5 +16,5 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ANALYSIS_STATS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ANALYSIS_STATS" exit $? diff --git a/dev/jobs/arch_tars.sh b/dev/job_cards/rocoto/arch_tars.sh similarity index 90% rename from dev/jobs/arch_tars.sh rename to dev/job_cards/rocoto/arch_tars.sh index fb8dbdc170a..24f0ab9c688 100755 --- a/dev/jobs/arch_tars.sh +++ b/dev/job_cards/rocoto/arch_tars.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ARCHIVE_TARS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ARCHIVE_TARS" status=$? exit "${status}" diff --git a/dev/jobs/arch_vrfy.sh b/dev/job_cards/rocoto/arch_vrfy.sh similarity index 90% rename from dev/jobs/arch_vrfy.sh rename to dev/job_cards/rocoto/arch_vrfy.sh index 50cb330281b..f289ea5ecf4 100755 --- a/dev/jobs/arch_vrfy.sh +++ b/dev/job_cards/rocoto/arch_vrfy.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ARCHIVE_VRFY" +"${HOMEgfs}/dev/jobs/JGLOBAL_ARCHIVE_VRFY" status=$? exit "${status}" diff --git a/dev/jobs/atmanlfinal.sh b/dev/job_cards/rocoto/atmanlfinal.sh similarity index 88% rename from dev/jobs/atmanlfinal.sh rename to dev/job_cards/rocoto/atmanlfinal.sh index 05202ea5ccf..2dc364af25e 100755 --- a/dev/jobs/atmanlfinal.sh +++ b/dev/job_cards/rocoto/atmanlfinal.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE" status=$? exit "${status}" diff --git a/dev/jobs/atmanlfv3inc.sh b/dev/job_cards/rocoto/atmanlfv3inc.sh similarity index 87% rename from dev/jobs/atmanlfv3inc.sh rename to dev/job_cards/rocoto/atmanlfv3inc.sh index 9d9fac34c55..5e6c9d4cbbb 100755 --- a/dev/jobs/atmanlfv3inc.sh +++ b/dev/job_cards/rocoto/atmanlfv3inc.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT" status=$? exit "${status}" diff --git a/dev/jobs/atmanlinit.sh b/dev/job_cards/rocoto/atmanlinit.sh similarity index 88% rename from dev/jobs/atmanlinit.sh rename to dev/job_cards/rocoto/atmanlinit.sh index 1fe059958e0..8ec82291a7f 100755 --- a/dev/jobs/atmanlinit.sh +++ b/dev/job_cards/rocoto/atmanlinit.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE" status=$? exit "${status}" diff --git a/dev/jobs/atmanlvar.sh b/dev/job_cards/rocoto/atmanlvar.sh similarity index 87% rename from dev/jobs/atmanlvar.sh rename to dev/job_cards/rocoto/atmanlvar.sh index 4e6156af443..98b1063c985 100755 --- a/dev/jobs/atmanlvar.sh +++ b/dev/job_cards/rocoto/atmanlvar.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlfinal.sh b/dev/job_cards/rocoto/atmensanlfinal.sh similarity index 88% rename from dev/jobs/atmensanlfinal.sh rename to dev/job_cards/rocoto/atmensanlfinal.sh index a127724b24a..42b51412ced 100755 --- a/dev/jobs/atmensanlfinal.sh +++ b/dev/job_cards/rocoto/atmensanlfinal.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlfv3inc.sh b/dev/job_cards/rocoto/atmensanlfv3inc.sh similarity index 87% rename from dev/jobs/atmensanlfv3inc.sh rename to dev/job_cards/rocoto/atmensanlfv3inc.sh index 9e2cbc7a82e..43cb11cc7a5 100755 --- a/dev/jobs/atmensanlfv3inc.sh +++ b/dev/job_cards/rocoto/atmensanlfv3inc.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlinit.sh b/dev/job_cards/rocoto/atmensanlinit.sh similarity index 87% rename from dev/jobs/atmensanlinit.sh rename to dev/job_cards/rocoto/atmensanlinit.sh index e30e96fce31..08786874a4a 100755 --- a/dev/jobs/atmensanlinit.sh +++ b/dev/job_cards/rocoto/atmensanlinit.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlletkf.sh b/dev/job_cards/rocoto/atmensanlletkf.sh similarity index 88% rename from dev/jobs/atmensanlletkf.sh rename to dev/job_cards/rocoto/atmensanlletkf.sh index 53b296235f3..e33f2d03206 100755 --- a/dev/jobs/atmensanlletkf.sh +++ b/dev/job_cards/rocoto/atmensanlletkf.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlobs.sh b/dev/job_cards/rocoto/atmensanlobs.sh similarity index 88% rename from dev/jobs/atmensanlobs.sh rename to dev/job_cards/rocoto/atmensanlobs.sh index fa47622c6db..fbf45a07b3d 100755 --- a/dev/jobs/atmensanlobs.sh +++ b/dev/job_cards/rocoto/atmensanlobs.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_OBS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_OBS" status=$? exit "${status}" diff --git a/dev/jobs/atmensanlsol.sh b/dev/job_cards/rocoto/atmensanlsol.sh similarity index 88% rename from dev/jobs/atmensanlsol.sh rename to dev/job_cards/rocoto/atmensanlsol.sh index 0318e2ccdc4..81bf908c068 100755 --- a/dev/jobs/atmensanlsol.sh +++ b/dev/job_cards/rocoto/atmensanlsol.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMENS_ANALYSIS_SOL" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_SOL" status=$? exit "${status}" diff --git a/dev/jobs/atmos_ensstat.sh b/dev/job_cards/rocoto/atmos_ensstat.sh similarity index 94% rename from dev/jobs/atmos_ensstat.sh rename to dev/job_cards/rocoto/atmos_ensstat.sh index 47c355ba497..ed64b5f79c3 100755 --- a/dev/jobs/atmos_ensstat.sh +++ b/dev/job_cards/rocoto/atmos_ensstat.sh @@ -24,7 +24,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do ############################################################### # Execute the JJOB ############################################################### - "${HOMEgfs}/jobs/JGLOBAL_ATMOS_ENSSTAT" + "${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_ENSSTAT" status=$? [[ ${status} -ne 0 ]] && exit "${status}" done diff --git a/dev/jobs/atmos_products.sh b/dev/job_cards/rocoto/atmos_products.sh similarity index 94% rename from dev/jobs/atmos_products.sh rename to dev/job_cards/rocoto/atmos_products.sh index 145f4c7dead..ab2952c5977 100755 --- a/dev/jobs/atmos_products.sh +++ b/dev/job_cards/rocoto/atmos_products.sh @@ -24,7 +24,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do ############################################################### # Execute the JJOB ############################################################### - "${HOMEgfs}/jobs/JGLOBAL_ATMOS_PRODUCTS" + "${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_PRODUCTS" status=$? [[ ${status} -ne 0 ]] && exit "${status}" done diff --git a/dev/jobs/awips.sh b/dev/job_cards/rocoto/awips.sh similarity index 92% rename from dev/jobs/awips.sh rename to dev/job_cards/rocoto/awips.sh index 9f9aca44589..158407387ed 100755 --- a/dev/jobs/awips.sh +++ b/dev/job_cards/rocoto/awips.sh @@ -19,7 +19,7 @@ for fhr in "${fhr_list[@]}"; do ############################################################### # Execute the JJOB # TODO ############################################################### - # "${HOMEgfs}/jobs/J${RUN^^}_ATMOS_AWIPS" + # "${HOMEgfs}/dev/jobs/J${RUN^^}_ATMOS_AWIPS" err=$? if [[ ${err} -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/awips_20km_1p0deg.sh b/dev/job_cards/rocoto/awips_20km_1p0deg.sh similarity index 91% rename from dev/jobs/awips_20km_1p0deg.sh rename to dev/job_cards/rocoto/awips_20km_1p0deg.sh index c8010b3eb9f..233e2f02b01 100755 --- a/dev/jobs/awips_20km_1p0deg.sh +++ b/dev/job_cards/rocoto/awips_20km_1p0deg.sh @@ -38,14 +38,14 @@ for fhr3 in ${fhrlst}; do if ((fhr % 3 == 0)); then export fcsthr="${fhr3}" export DATA="${DATAROOT}/${jobid}.${fcsthr}" - "${HOMEgfs}/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG" + "${HOMEgfs}/dev/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG" fi # Process every 6 hrs from hour 90 up to hour 240 elif [[ ${fhr} -ge 90 ]] && [[ ${fhr} -le 240 ]]; then if ((fhr % 6 == 0)); then export fcsthr="${fhr3}" export DATA="${DATAROOT}/${jobid}.${fcsthr}" - "${HOMEgfs}/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG" + "${HOMEgfs}/dev/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG" fi fi done diff --git a/dev/jobs/cleanup.sh b/dev/job_cards/rocoto/cleanup.sh similarity index 91% rename from dev/jobs/cleanup.sh rename to dev/job_cards/rocoto/cleanup.sh index 0cb259555f6..7af2d3eb942 100755 --- a/dev/jobs/cleanup.sh +++ b/dev/job_cards/rocoto/cleanup.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_CLEANUP" +"${HOMEgfs}/dev/jobs/JGLOBAL_CLEANUP" status=$? exit "${status}" diff --git a/dev/jobs/earc_tars.sh b/dev/job_cards/rocoto/earc_tars.sh similarity index 89% rename from dev/jobs/earc_tars.sh rename to dev/job_cards/rocoto/earc_tars.sh index 16508f162dc..e0cecadf1c5 100755 --- a/dev/jobs/earc_tars.sh +++ b/dev/job_cards/rocoto/earc_tars.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ENS_ARCHIVE_TARS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_ARCHIVE_TARS" status=$? exit "${status}" diff --git a/dev/jobs/earc_vrfy.sh b/dev/job_cards/rocoto/earc_vrfy.sh similarity index 89% rename from dev/jobs/earc_vrfy.sh rename to dev/job_cards/rocoto/earc_vrfy.sh index 1f6b437046c..25e0d31ad41 100755 --- a/dev/jobs/earc_vrfy.sh +++ b/dev/job_cards/rocoto/earc_vrfy.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ENS_ARCHIVE_VRFY" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_ARCHIVE_VRFY" status=$? exit "${status}" diff --git a/dev/jobs/ecen.sh b/dev/job_cards/rocoto/ecen.sh similarity index 94% rename from dev/jobs/ecen.sh rename to dev/job_cards/rocoto/ecen.sh index b202fdd291e..7e267ca0ed2 100755 --- a/dev/jobs/ecen.sh +++ b/dev/job_cards/rocoto/ecen.sh @@ -22,7 +22,7 @@ for fhr in ${fhrlst}; do export job=ecen export jobid="${job}.$$" - "${HOMEgfs}/jobs/JGDAS_ENKF_ECEN" + "${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_ECEN" status=$? if [[ ${status} -ne 0 ]]; then exit "${status}" diff --git a/dev/jobs/ecen_fv3jedi.sh b/dev/job_cards/rocoto/ecen_fv3jedi.sh similarity index 89% rename from dev/jobs/ecen_fv3jedi.sh rename to dev/job_cards/rocoto/ecen_fv3jedi.sh index 0d3f13c6c57..9e84069279c 100755 --- a/dev/jobs/ecen_fv3jedi.sh +++ b/dev/job_cards/rocoto/ecen_fv3jedi.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGDAS_ENKF_ECEN_FV3JEDI +"${HOMEgfs}"/dev/jobs/JGLOBAL_ENKF_ECEN_FV3JEDI status=$? exit "${status}" diff --git a/dev/jobs/echgres.sh b/dev/job_cards/rocoto/echgres.sh similarity index 89% rename from dev/jobs/echgres.sh rename to dev/job_cards/rocoto/echgres.sh index f8532306da7..0b14cf7f311 100755 --- a/dev/jobs/echgres.sh +++ b/dev/job_cards/rocoto/echgres.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ATMOS_CHGRES_FORENKF" +"${HOMEgfs}/dev/jobs/JGDAS_ATMOS_CHGRES_FORENKF" status=$? exit "${status}" diff --git a/dev/jobs/ediag.sh b/dev/job_cards/rocoto/ediag.sh similarity index 90% rename from dev/jobs/ediag.sh rename to dev/job_cards/rocoto/ediag.sh index df628a147c6..c0710d0acdb 100755 --- a/dev/jobs/ediag.sh +++ b/dev/job_cards/rocoto/ediag.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ENKF_DIAG" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_DIAG" status=$? exit "${status}" diff --git a/dev/jobs/eobs.sh b/dev/job_cards/rocoto/eobs.sh similarity index 89% rename from dev/jobs/eobs.sh rename to dev/job_cards/rocoto/eobs.sh index 5821bf0f186..517a6a64402 100755 --- a/dev/jobs/eobs.sh +++ b/dev/job_cards/rocoto/eobs.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ENKF_SELECT_OBS" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_SELECT_OBS" status=$? exit "${status}" diff --git a/dev/jobs/epos.sh b/dev/job_cards/rocoto/epos.sh similarity index 94% rename from dev/jobs/epos.sh rename to dev/job_cards/rocoto/epos.sh index c8a37b858fb..6e2dfa0b6ef 100755 --- a/dev/jobs/epos.sh +++ b/dev/job_cards/rocoto/epos.sh @@ -23,7 +23,7 @@ for fhr in ${fhrlst}; do export FHMIN_EPOS=${fhr} export FHMAX_EPOS=${fhr} export FHOUT_EPOS=${fhr} - "${HOMEgfs}/jobs/JGDAS_ENKF_POST" + "${HOMEgfs}/dev/jobs/JGDAS_ENKF_POST" status=$? if [[ ${status} -ne 0 ]]; then exit "${status}" diff --git a/dev/jobs/esfc.sh b/dev/job_cards/rocoto/esfc.sh similarity index 90% rename from dev/jobs/esfc.sh rename to dev/job_cards/rocoto/esfc.sh index 756134fb153..b052431d296 100755 --- a/dev/jobs/esfc.sh +++ b/dev/job_cards/rocoto/esfc.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ENKF_SFC" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_SFC" status=$? exit "${status}" diff --git a/dev/jobs/esnowanl.sh b/dev/job_cards/rocoto/esnowanl.sh similarity index 89% rename from dev/jobs/esnowanl.sh rename to dev/job_cards/rocoto/esnowanl.sh index 7ee1d0f6079..d1112b26c7e 100755 --- a/dev/jobs/esnowanl.sh +++ b/dev/job_cards/rocoto/esnowanl.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_SNOWENS_ANALYSIS" +"${HOMEgfs}/dev/jobs/JGLOBAL_SNOWENS_ANALYSIS" status=$? exit "${status}" diff --git a/dev/jobs/eupd.sh b/dev/job_cards/rocoto/eupd.sh similarity index 90% rename from dev/jobs/eupd.sh rename to dev/job_cards/rocoto/eupd.sh index a9a992dd529..58bc59c1c28 100755 --- a/dev/jobs/eupd.sh +++ b/dev/job_cards/rocoto/eupd.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ENKF_UPDATE" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENKF_UPDATE" status=$? exit "${status}" diff --git a/dev/jobs/extractvars.sh b/dev/job_cards/rocoto/extractvars.sh similarity index 93% rename from dev/jobs/extractvars.sh rename to dev/job_cards/rocoto/extractvars.sh index da9194dc152..125ff8394f5 100755 --- a/dev/jobs/extractvars.sh +++ b/dev/job_cards/rocoto/extractvars.sh @@ -18,7 +18,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN EXTRACTVARS ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_EXTRACTVARS" +"${HOMEgfs}/dev/jobs/JGLOBAL_EXTRACTVARS" status=$? if [[ "${status}" -ne 0 ]]; then exit "${status}" diff --git a/dev/jobs/fbwind.sh b/dev/job_cards/rocoto/fbwind.sh similarity index 87% rename from dev/jobs/fbwind.sh rename to dev/job_cards/rocoto/fbwind.sh index 2c298b74f51..e2a253cb0ee 100755 --- a/dev/jobs/fbwind.sh +++ b/dev/job_cards/rocoto/fbwind.sh @@ -11,7 +11,7 @@ export job="fbwind" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_FBWIND" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_FBWIND" status=$? exit "${status}" diff --git a/dev/jobs/fcst.sh b/dev/job_cards/rocoto/fcst.sh similarity index 93% rename from dev/jobs/fcst.sh rename to dev/job_cards/rocoto/fcst.sh index 11de0bd6b68..57cd65bd798 100755 --- a/dev/jobs/fcst.sh +++ b/dev/job_cards/rocoto/fcst.sh @@ -20,7 +20,7 @@ export job="fcst" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_FORECAST" +"${HOMEgfs}/dev/jobs/JGLOBAL_FORECAST" status=$? exit "${status}" diff --git a/dev/jobs/fetch.sh b/dev/job_cards/rocoto/fetch.sh similarity index 88% rename from dev/jobs/fetch.sh rename to dev/job_cards/rocoto/fetch.sh index 55a87a01c0d..4c55258de75 100755 --- a/dev/jobs/fetch.sh +++ b/dev/job_cards/rocoto/fetch.sh @@ -13,7 +13,7 @@ export job="fetch" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_FETCH" +"${HOMEgfs}/dev/jobs/JGLOBAL_FETCH" status=$? exit "${status}" diff --git a/dev/jobs/fit2obs.sh b/dev/job_cards/rocoto/fit2obs.sh similarity index 93% rename from dev/jobs/fit2obs.sh rename to dev/job_cards/rocoto/fit2obs.sh index f4471a73069..77fd9731fce 100755 --- a/dev/jobs/fit2obs.sh +++ b/dev/job_cards/rocoto/fit2obs.sh @@ -18,7 +18,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN FIT2OBS ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_FIT2OBS" +"${HOMEgfs}/dev/jobs/JGDAS_FIT2OBS" status=$? if [[ ${status} -ne 0 ]]; then exit "${status}" diff --git a/dev/jobs/gempak.sh b/dev/job_cards/rocoto/gempak.sh similarity index 92% rename from dev/jobs/gempak.sh rename to dev/job_cards/rocoto/gempak.sh index e58b76ba030..c20b3a121f7 100755 --- a/dev/jobs/gempak.sh +++ b/dev/job_cards/rocoto/gempak.sh @@ -17,7 +17,7 @@ for fhr in "${fhr_list[@]}"; do ############################################################### # Execute the JJOB ############################################################### - "${HOMEgfs}/jobs/J${RUN^^}_ATMOS_GEMPAK" + "${HOMEgfs}/dev/jobs/J${RUN^^}_ATMOS_GEMPAK" err=$? [[ ${err} -ne 0 ]] && exit "${err}" done diff --git a/dev/jobs/gempakgrb2spec.sh b/dev/job_cards/rocoto/gempakgrb2spec.sh similarity index 82% rename from dev/jobs/gempakgrb2spec.sh rename to dev/job_cards/rocoto/gempakgrb2spec.sh index 6fad75c1d72..e0594ec8bde 100755 --- a/dev/jobs/gempakgrb2spec.sh +++ b/dev/job_cards/rocoto/gempakgrb2spec.sh @@ -9,7 +9,7 @@ export job="gempakpgrb2spec" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC" status=$? exit "${status}" diff --git a/dev/jobs/gempakmeta.sh b/dev/job_cards/rocoto/gempakmeta.sh similarity index 86% rename from dev/jobs/gempakmeta.sh rename to dev/job_cards/rocoto/gempakmeta.sh index 0619ea02228..d980d9e8bdd 100755 --- a/dev/jobs/gempakmeta.sh +++ b/dev/job_cards/rocoto/gempakmeta.sh @@ -11,7 +11,7 @@ export job="gempakmeta" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_GEMPAK_META" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_GEMPAK_META" status=$? exit "${status}" diff --git a/dev/jobs/gempakmetancdc.sh b/dev/job_cards/rocoto/gempakmetancdc.sh similarity index 85% rename from dev/jobs/gempakmetancdc.sh rename to dev/job_cards/rocoto/gempakmetancdc.sh index 7d447bce25d..423e48e7c24 100755 --- a/dev/jobs/gempakmetancdc.sh +++ b/dev/job_cards/rocoto/gempakmetancdc.sh @@ -11,7 +11,7 @@ export job="gempakmetancdc" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGDAS_ATMOS_GEMPAK_META_NCDC" +"${HOMEgfs}/dev/jobs/JGDAS_ATMOS_GEMPAK_META_NCDC" status=$? exit "${status}" diff --git a/dev/jobs/gempakncdcupapgif.sh b/dev/job_cards/rocoto/gempakncdcupapgif.sh similarity index 85% rename from dev/jobs/gempakncdcupapgif.sh rename to dev/job_cards/rocoto/gempakncdcupapgif.sh index 7f3988ca0bc..8e95860300a 100755 --- a/dev/jobs/gempakncdcupapgif.sh +++ b/dev/job_cards/rocoto/gempakncdcupapgif.sh @@ -11,7 +11,7 @@ export job="gempakncdcupapgif" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF" status=$? exit "${status}" diff --git a/dev/jobs/gen_control_ic.sh b/dev/job_cards/rocoto/gen_control_ic.sh similarity index 84% rename from dev/jobs/gen_control_ic.sh rename to dev/job_cards/rocoto/gen_control_ic.sh index 0d4bddbc600..cfe6299501e 100755 --- a/dev/jobs/gen_control_ic.sh +++ b/dev/job_cards/rocoto/gen_control_ic.sh @@ -10,7 +10,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL" status=$? exit "${status}" diff --git a/dev/jobs/genesis.sh b/dev/job_cards/rocoto/genesis.sh similarity index 88% rename from dev/jobs/genesis.sh rename to dev/job_cards/rocoto/genesis.sh index 0e954ffd897..0f3102faa1c 100755 --- a/dev/jobs/genesis.sh +++ b/dev/job_cards/rocoto/genesis.sh @@ -14,7 +14,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_CYCLONE_GENESIS" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_CYCLONE_GENESIS" status=$? exit "${status}" diff --git a/dev/jobs/genesis_fsu.sh b/dev/job_cards/rocoto/genesis_fsu.sh similarity index 89% rename from dev/jobs/genesis_fsu.sh rename to dev/job_cards/rocoto/genesis_fsu.sh index b39eff9d88b..0290ef1659b 100755 --- a/dev/jobs/genesis_fsu.sh +++ b/dev/job_cards/rocoto/genesis_fsu.sh @@ -14,7 +14,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_FSU_GENESIS" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_FSU_GENESIS" status=$? exit "${status}" diff --git a/dev/jobs/globus_arch.sh b/dev/job_cards/rocoto/globus_arch.sh similarity index 90% rename from dev/jobs/globus_arch.sh rename to dev/job_cards/rocoto/globus_arch.sh index 9bd32136e45..2d33c047678 100755 --- a/dev/jobs/globus_arch.sh +++ b/dev/job_cards/rocoto/globus_arch.sh @@ -13,7 +13,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_GLOBUS_ARCH" +"${HOMEgfs}/dev/jobs/JGLOBAL_GLOBUS_ARCH" status=$? exit "${status}" diff --git a/dev/jobs/globus_earc.sh b/dev/job_cards/rocoto/globus_earc.sh similarity index 89% rename from dev/jobs/globus_earc.sh rename to dev/job_cards/rocoto/globus_earc.sh index 0bb421b41f7..61f7d5f6f49 100755 --- a/dev/jobs/globus_earc.sh +++ b/dev/job_cards/rocoto/globus_earc.sh @@ -13,7 +13,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ENS_GLOBUS_ARCH" +"${HOMEgfs}/dev/jobs/JGLOBAL_ENS_GLOBUS_ARCH" status=$? exit "${status}" diff --git a/dev/jobs/marineanlchkpt.sh b/dev/job_cards/rocoto/marineanlchkpt.sh similarity index 87% rename from dev/jobs/marineanlchkpt.sh rename to dev/job_cards/rocoto/marineanlchkpt.sh index 3c1de075cae..7734d330de4 100755 --- a/dev/jobs/marineanlchkpt.sh +++ b/dev/job_cards/rocoto/marineanlchkpt.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT status=$? exit "${status}" diff --git a/dev/jobs/marineanlecen.sh b/dev/job_cards/rocoto/marineanlecen.sh similarity index 92% rename from dev/jobs/marineanlecen.sh rename to dev/job_cards/rocoto/marineanlecen.sh index 9d1678c9122..8c1f633b97a 100755 --- a/dev/jobs/marineanlecen.sh +++ b/dev/job_cards/rocoto/marineanlecen.sh @@ -20,6 +20,6 @@ export PYTHONPATH ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_ANALYSIS_ECEN +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_ANALYSIS_ECEN status=$? exit "${status}" diff --git a/dev/jobs/marineanlfinal.sh b/dev/job_cards/rocoto/marineanlfinal.sh similarity index 88% rename from dev/jobs/marineanlfinal.sh rename to dev/job_cards/rocoto/marineanlfinal.sh index 127f74693fd..991cd7cda49 100755 --- a/dev/jobs/marineanlfinal.sh +++ b/dev/job_cards/rocoto/marineanlfinal.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE status=$? exit "${status}" diff --git a/dev/jobs/marineanlinit.sh b/dev/job_cards/rocoto/marineanlinit.sh similarity index 88% rename from dev/jobs/marineanlinit.sh rename to dev/job_cards/rocoto/marineanlinit.sh index 4a5e75db985..5357a8f24c3 100755 --- a/dev/jobs/marineanlinit.sh +++ b/dev/job_cards/rocoto/marineanlinit.sh @@ -16,6 +16,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE status=$? exit "${status}" diff --git a/dev/jobs/marineanlletkf.sh b/dev/job_cards/rocoto/marineanlletkf.sh similarity index 88% rename from dev/jobs/marineanlletkf.sh rename to dev/job_cards/rocoto/marineanlletkf.sh index 51a342d58f0..70add214186 100755 --- a/dev/jobs/marineanlletkf.sh +++ b/dev/job_cards/rocoto/marineanlletkf.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_MARINE_ANALYSIS_LETKF" +"${HOMEgfs}/dev/jobs/JGLOBAL_MARINE_ANALYSIS_LETKF" status=$? exit "${status}" diff --git a/dev/jobs/marineanlvar.sh b/dev/job_cards/rocoto/marineanlvar.sh similarity index 87% rename from dev/jobs/marineanlvar.sh rename to dev/job_cards/rocoto/marineanlvar.sh index ac8d06a4a0c..facad6c38ad 100755 --- a/dev/jobs/marineanlvar.sh +++ b/dev/job_cards/rocoto/marineanlvar.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL" +"${HOMEgfs}/dev/jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL" status=$? exit "${status}" diff --git a/dev/jobs/marinebmat.sh b/dev/job_cards/rocoto/marinebmat.sh similarity index 90% rename from dev/jobs/marinebmat.sh rename to dev/job_cards/rocoto/marinebmat.sh index 94d3dd3e9f2..d2b898ce4ad 100755 --- a/dev/jobs/marinebmat.sh +++ b/dev/job_cards/rocoto/marinebmat.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_BMAT +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_BMAT status=$? exit "${status}" diff --git a/dev/jobs/marinebmatinit.sh b/dev/job_cards/rocoto/marinebmatinit.sh similarity index 88% rename from dev/jobs/marinebmatinit.sh rename to dev/job_cards/rocoto/marinebmatinit.sh index 4cbaff95a8d..db9685d6c04 100755 --- a/dev/jobs/marinebmatinit.sh +++ b/dev/job_cards/rocoto/marinebmatinit.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_MARINE_BMAT_INITIALIZE +"${HOMEgfs}"/dev/jobs/JGLOBAL_MARINE_BMAT_INITIALIZE status=$? exit "${status}" diff --git a/dev/jobs/metp.sh b/dev/job_cards/rocoto/metp.sh similarity index 85% rename from dev/jobs/metp.sh rename to dev/job_cards/rocoto/metp.sh index d31310ef20c..38fd4272d45 100755 --- a/dev/jobs/metp.sh +++ b/dev/job_cards/rocoto/metp.sh @@ -10,6 +10,6 @@ if ((status != 0)); then exit "${status}"; fi export job="metp${METPCASE}" export jobid="${job}.$$" -"${HOMEgfs}/jobs/JGFS_ATMOS_VERIFICATION" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_VERIFICATION" exit $? diff --git a/dev/jobs/npoess.sh b/dev/job_cards/rocoto/npoess.sh similarity index 85% rename from dev/jobs/npoess.sh rename to dev/job_cards/rocoto/npoess.sh index e992dc73a7b..7c5d59b8abb 100755 --- a/dev/jobs/npoess.sh +++ b/dev/job_cards/rocoto/npoess.sh @@ -11,7 +11,7 @@ export job="npoess_pgrb2_0p5deg" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS" status=$? exit "${status}" diff --git a/dev/jobs/oceanice_products.sh b/dev/job_cards/rocoto/oceanice_products.sh similarity index 94% rename from dev/jobs/oceanice_products.sh rename to dev/job_cards/rocoto/oceanice_products.sh index a23c70f5113..b8564ec4f4c 100755 --- a/dev/jobs/oceanice_products.sh +++ b/dev/job_cards/rocoto/oceanice_products.sh @@ -24,7 +24,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do ############################################################### # Execute the JJOB ############################################################### - "${HOMEgfs}/jobs/JGLOBAL_OCEANICE_PRODUCTS" + "${HOMEgfs}/dev/jobs/JGLOBAL_OCEANICE_PRODUCTS" status=$? [[ ${status} -ne 0 ]] && exit "${status}" done diff --git a/dev/jobs/offlineanl.sh b/dev/job_cards/rocoto/offlineanl.sh similarity index 88% rename from dev/jobs/offlineanl.sh rename to dev/job_cards/rocoto/offlineanl.sh index 26f5576c58d..74a8da33182 100755 --- a/dev/jobs/offlineanl.sh +++ b/dev/job_cards/rocoto/offlineanl.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS" +"${HOMEgfs}/dev/jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS" status=$? exit "${status}" diff --git a/dev/jobs/postsnd.sh b/dev/job_cards/rocoto/postsnd.sh similarity index 87% rename from dev/jobs/postsnd.sh rename to dev/job_cards/rocoto/postsnd.sh index a7da693a5a7..f8d5e15e65a 100755 --- a/dev/jobs/postsnd.sh +++ b/dev/job_cards/rocoto/postsnd.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ################################################################ # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_POSTSND" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_POSTSND" err=$? exit "${err}" diff --git a/dev/jobs/prep.sh b/dev/job_cards/rocoto/prep.sh similarity index 69% rename from dev/jobs/prep.sh rename to dev/job_cards/rocoto/prep.sh index 4ab3c6795ee..59df45e563e 100755 --- a/dev/jobs/prep.sh +++ b/dev/job_cards/rocoto/prep.sh @@ -32,15 +32,32 @@ RUN=${RUN_local} YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_OBS:COM_OBS_TMPL \ COMOUT_OBS:COM_OBS_TMPL \ COMINobsproc:COM_OBSPROC_TMPL \ - COMIN_TCVITAL:COM_TCVITAL_TMPL + COMINobsforge:COM_OBSFORGE_TMPL \ + COMIN_TCVITAL:COM_TCVITAL_TMPL \ + COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ COMOUT_OBS_PREV:COM_OBS_TMPL \ - COMINobsproc_PREV:COM_OBSPROC_TMPL + COMINobsproc_PREV:COM_OBSPROC_TMPL \ + COMOUT_ATMOS_ANALYSIS_PREV:COM_ATMOS_ANALYSIS_TMPL mkdir -p "${COMOUT_OBS}" ############################################################### +# Copy IODA files to ROTDIR +if [[ ${USE_IODADIR:-"NO"} == "YES" ]]; then + "${HOMEgfs}/ush/getioda.sh" "${PDY}" "${cyc}" "${RUN_local}" "${COMINobsforge}" "${COMOUT_OBS}" + status=$? + if [[ ${status} -ne 0 ]]; then + exit "${status}" + fi +fi + +if [[ "${RUN_local}" == "gcdas" ]]; then + echo "GCDAS only needs IODA files; exiting prep.sh" + exit 0 +fi + # Copy dump files to ROTDIR "${HOMEgfs}/ush/getdump.sh" "${PDY}" "${cyc}" "${RUN_local}" "${COMINobsproc}" "${COMOUT_OBS}" status=$? @@ -85,7 +102,7 @@ if [[ ${PROCESS_TROPCY} == "YES" ]]; then rm -f "${COMOUT_OBS}/${RUN_local}.t${cyc}z.syndata.tcvitals.tm00" - "${HOMEgfs}/jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC" + "${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC" status=$? if [[ ${status} -ne 0 ]]; then exit "${status}" @@ -95,6 +112,26 @@ else cpfs "${COMINobsproc}/${RUN_local}.t${cyc}z.syndata.tcvitals.tm00" "${COMOUT_OBS}/" fi +############################################################### +# If requested, copy bias correction files from source or stait to analysis directories +# TODO: remove this when JEDI ATM can cycle bias correction coefficents +if [[ ${RUN} == "gdas" && ${COPY_BIASCOR_SOURCE:-"NO"} == "YES" ]]; then + for file in abias abias_pc abias_air; do + if [[ -s "${SOURCE_BIASCOR}/${file}.${GDUMP}.${gPDY}${gcyc}" ]]; then + cpreq "${SOURCE_BIASCOR}/${file}.${GDUMP}.${gPDY}${gcyc}" "${COMOUT_ATMOS_ANALYSIS_PREV}/${GDUMP}.t${gcyc}z.${file}" + cpreq "${SOURCE_BIASCOR}/${file}.${GDUMP}.${gPDY}${gcyc}" "${COMOUT_ATMOS_ANALYSIS_PREV}/${GDUMP}.t${gcyc}z.${file}.txt" + fi + done +fi +if [[ ${RUN} == "gdas" && ${COPY_BIASCOR_STATIC:-"NO"} == "YES" ]]; then + for file in abias abias_pc abias_air; do + if [[ -s "${COMOUT_ATMOS_ANALYSIS_PREV}/${GDUMP}.t${gcyc}z.${file}.txt" ]]; then + mkdir -p "${COMOUT_ATMOS_ANALYSIS}" + cpreq "${COMOUT_ATMOS_ANALYSIS_PREV}/${GDUMP}.t${gcyc}z.${file}.txt" "${COMOUT_ATMOS_ANALYSIS}/${GDUMP}.t${cyc}z.${file}.txt" + fi + done +fi + ############################################################### # Generate prepbufr files from dumps and prior gdas guess rm -f "${COMOUT_OBS}/${OPREFIX}prepbufr" @@ -160,6 +197,23 @@ if [[ ${err} -ne 0 ]]; then err_exit "Failed to obtain/create ${files}, ABORT!" fi +################################################################################ +# If requested, create radiance bias correction files for JEDI +if [[ ${RUN} == "gdas" && ${CONVERT_BIASCOR:-"NO"} == "YES" ]]; then + cd "${DATAROOT}" || true + "${HOMEgfs}/ush/gsi_satbias2ioda_all.sh" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "gsi_satbias2ioda failed, ABORT!" + fi + + # Remove temporary working directory + cd "${DATAROOT}" || true + if [[ "${KEEPDATA}" == "NO" ]]; then + rm -rf "${DATA}" + fi +fi + ################################################################################ # Exit out cleanly diff --git a/dev/jobs/prep_emissions.sh b/dev/job_cards/rocoto/prep_emissions.sh similarity index 89% rename from dev/jobs/prep_emissions.sh rename to dev/job_cards/rocoto/prep_emissions.sh index 11bd0799307..c764660bb74 100755 --- a/dev/jobs/prep_emissions.sh +++ b/dev/job_cards/rocoto/prep_emissions.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_PREP_EMISSIONS" +"${HOMEgfs}/dev/jobs/JGLOBAL_PREP_EMISSIONS" status=$? exit "${status}" diff --git a/dev/jobs/prep_sfc.sh b/dev/job_cards/rocoto/prep_sfc.sh similarity index 89% rename from dev/jobs/prep_sfc.sh rename to dev/job_cards/rocoto/prep_sfc.sh index 4d4164ca7ad..fd524f04fc5 100755 --- a/dev/jobs/prep_sfc.sh +++ b/dev/job_cards/rocoto/prep_sfc.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_PREP_SFC" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_PREP_SFC" status=$? exit "${status}" diff --git a/dev/jobs/prepoceanobs.sh b/dev/job_cards/rocoto/prepoceanobs.sh similarity index 90% rename from dev/jobs/prepoceanobs.sh rename to dev/job_cards/rocoto/prepoceanobs.sh index 38f71e3ee39..ee68a3464c6 100755 --- a/dev/jobs/prepoceanobs.sh +++ b/dev/job_cards/rocoto/prepoceanobs.sh @@ -15,6 +15,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}"/jobs/JGLOBAL_PREP_OCEAN_OBS +"${HOMEgfs}"/dev/jobs/JGLOBAL_PREP_OCEAN_OBS status=$? exit "${status}" diff --git a/dev/jobs/sfcanl.sh b/dev/job_cards/rocoto/sfcanl.sh similarity index 90% rename from dev/jobs/sfcanl.sh rename to dev/job_cards/rocoto/sfcanl.sh index 0d029f943d2..d6738fe3a11 100755 --- a/dev/jobs/sfcanl.sh +++ b/dev/job_cards/rocoto/sfcanl.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_SFCANL" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_SFCANL" status=$? exit "${status}" diff --git a/dev/jobs/snowanl.sh b/dev/job_cards/rocoto/snowanl.sh similarity index 89% rename from dev/jobs/snowanl.sh rename to dev/job_cards/rocoto/snowanl.sh index 84b401f7750..eb4c7a92f98 100755 --- a/dev/jobs/snowanl.sh +++ b/dev/job_cards/rocoto/snowanl.sh @@ -13,6 +13,6 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_SNOW_ANALYSIS" +"${HOMEgfs}/dev/jobs/JGLOBAL_SNOW_ANALYSIS" status=$? exit "${status}" diff --git a/dev/jobs/stage_ic.sh b/dev/job_cards/rocoto/stage_ic.sh similarity index 87% rename from dev/jobs/stage_ic.sh rename to dev/job_cards/rocoto/stage_ic.sh index e104d785f9c..cb5c215f438 100755 --- a/dev/jobs/stage_ic.sh +++ b/dev/job_cards/rocoto/stage_ic.sh @@ -13,7 +13,7 @@ export job="stage_ic" export jobid="${job}.$$" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_STAGE_IC" +"${HOMEgfs}/dev/jobs/JGLOBAL_STAGE_IC" status=$? exit "${status}" diff --git a/dev/jobs/tracker.sh b/dev/job_cards/rocoto/tracker.sh similarity index 88% rename from dev/jobs/tracker.sh rename to dev/job_cards/rocoto/tracker.sh index 6062e6086dd..c13de1848fe 100755 --- a/dev/jobs/tracker.sh +++ b/dev/job_cards/rocoto/tracker.sh @@ -14,7 +14,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGFS_ATMOS_CYCLONE_TRACKER" +"${HOMEgfs}/dev/jobs/JGFS_ATMOS_CYCLONE_TRACKER" status=$? exit "${status}" diff --git a/dev/jobs/upp.sh b/dev/job_cards/rocoto/upp.sh similarity index 93% rename from dev/jobs/upp.sh rename to dev/job_cards/rocoto/upp.sh index 7dbce24453f..ca6dd65a23c 100755 --- a/dev/jobs/upp.sh +++ b/dev/job_cards/rocoto/upp.sh @@ -17,7 +17,7 @@ source "${HOMEgfs}/ush/detect_machine.sh" source "${HOMEgfs}/dev/ush/load_modules.sh" upp status=$? if [[ ${status} -ne 0 ]]; then - exit "${status}"; + exit "${status}" fi export job="upp" @@ -28,6 +28,6 @@ export FORECAST_HOUR=$((10#${FHR3})) ############################################################### # Execute the JJOB ############################################################### -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_UPP" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_UPP" exit $? diff --git a/dev/jobs/verfozn.sh b/dev/job_cards/rocoto/verfozn.sh similarity index 91% rename from dev/jobs/verfozn.sh rename to dev/job_cards/rocoto/verfozn.sh index 4ae7c594fc2..018be19a002 100755 --- a/dev/jobs/verfozn.sh +++ b/dev/job_cards/rocoto/verfozn.sh @@ -18,7 +18,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN OZMON DATA EXTRACTION ===============" -"${HOMEgfs}/jobs/JGDAS_ATMOS_VERFOZN" +"${HOMEgfs}/dev/jobs/JGDAS_ATMOS_VERFOZN" status=$? exit "${status}" diff --git a/dev/jobs/verfrad.sh b/dev/job_cards/rocoto/verfrad.sh similarity index 91% rename from dev/jobs/verfrad.sh rename to dev/job_cards/rocoto/verfrad.sh index 815983deb80..6e8b13049f0 100755 --- a/dev/jobs/verfrad.sh +++ b/dev/job_cards/rocoto/verfrad.sh @@ -18,7 +18,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN RADMON DATA EXTRACTION ===============" -"${HOMEgfs}/jobs/JGDAS_ATMOS_VERFRAD" +"${HOMEgfs}/dev/jobs/JGDAS_ATMOS_VERFRAD" status=$? exit "${status}" diff --git a/dev/jobs/vminmon.sh b/dev/job_cards/rocoto/vminmon.sh similarity index 91% rename from dev/jobs/vminmon.sh rename to dev/job_cards/rocoto/vminmon.sh index 20c4d5dad6b..b05c2963859 100755 --- a/dev/jobs/vminmon.sh +++ b/dev/job_cards/rocoto/vminmon.sh @@ -18,7 +18,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN MINMON ===============" -"${HOMEgfs}/jobs/JGLOBAL_ATMOS_VMINMON" +"${HOMEgfs}/dev/jobs/JGLOBAL_ATMOS_VMINMON" status=$? exit "${status}" diff --git a/dev/jobs/wave_stat.sh b/dev/job_cards/rocoto/wave_stat.sh similarity index 94% rename from dev/jobs/wave_stat.sh rename to dev/job_cards/rocoto/wave_stat.sh index abe1ef0a04c..a2b8260d5f5 100755 --- a/dev/jobs/wave_stat.sh +++ b/dev/job_cards/rocoto/wave_stat.sh @@ -22,7 +22,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do FHR3=$(printf '%03d' "${FORECAST_HOUR}") jobid="${job}_f${FHR3}.$$" # Execute the JJOB - "${HOMEgfs}/jobs/JGEFS_WAVE_STAT" + "${HOMEgfs}/dev/jobs/JGEFS_WAVE_STAT" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/wave_stat_pnt.sh b/dev/job_cards/rocoto/wave_stat_pnt.sh similarity index 91% rename from dev/jobs/wave_stat_pnt.sh rename to dev/job_cards/rocoto/wave_stat_pnt.sh index beabf3cd573..71c3fbab146 100755 --- a/dev/jobs/wave_stat_pnt.sh +++ b/dev/job_cards/rocoto/wave_stat_pnt.sh @@ -14,7 +14,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN WAVESTAT PNT ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGEFS_WAVE_STAT_PNT" +"${HOMEgfs}/dev/jobs/JGEFS_WAVE_STAT_PNT" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/waveawipsbulls.sh b/dev/job_cards/rocoto/waveawipsbulls.sh similarity index 89% rename from dev/jobs/waveawipsbulls.sh rename to dev/job_cards/rocoto/waveawipsbulls.sh index fb28736b965..68304158c0c 100755 --- a/dev/jobs/waveawipsbulls.sh +++ b/dev/job_cards/rocoto/waveawipsbulls.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_PRDGEN_BULLS" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_PRDGEN_BULLS" status=$? exit "${status}" diff --git a/dev/jobs/waveawipsgridded.sh b/dev/job_cards/rocoto/waveawipsgridded.sh similarity index 89% rename from dev/jobs/waveawipsgridded.sh rename to dev/job_cards/rocoto/waveawipsgridded.sh index 9fbfd40a7f4..100bf545d31 100755 --- a/dev/jobs/waveawipsgridded.sh +++ b/dev/job_cards/rocoto/waveawipsgridded.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED" status=$? exit "${status}" diff --git a/dev/jobs/wavegempak.sh b/dev/job_cards/rocoto/wavegempak.sh similarity index 93% rename from dev/jobs/wavegempak.sh rename to dev/job_cards/rocoto/wavegempak.sh index e9dc4bf7bcd..60a66e749eb 100755 --- a/dev/jobs/wavegempak.sh +++ b/dev/job_cards/rocoto/wavegempak.sh @@ -21,7 +21,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do fhr3=$(printf '%03d' "${FORECAST_HOUR}") jobid="${job}_f${fhr3}.$$" # Execute the JJOB - "${HOMEgfs}/jobs/JGLOBAL_WAVE_GEMPAK" + "${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_GEMPAK" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/waveinit.sh b/dev/job_cards/rocoto/waveinit.sh similarity index 91% rename from dev/jobs/waveinit.sh rename to dev/job_cards/rocoto/waveinit.sh index c04a50298ec..4770c56356a 100755 --- a/dev/jobs/waveinit.sh +++ b/dev/job_cards/rocoto/waveinit.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_INIT" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_INIT" status=$? exit "${status}" diff --git a/dev/jobs/wavepostbndpnt.sh b/dev/job_cards/rocoto/wavepostbndpnt.sh similarity index 92% rename from dev/jobs/wavepostbndpnt.sh rename to dev/job_cards/rocoto/wavepostbndpnt.sh index cc30ce0f268..8bd2969a178 100755 --- a/dev/jobs/wavepostbndpnt.sh +++ b/dev/job_cards/rocoto/wavepostbndpnt.sh @@ -19,7 +19,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN WAVE_POST_BNDPNT ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_POST_BNDPNT" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_POST_BNDPNT" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/wavepostbndpntbll.sh b/dev/job_cards/rocoto/wavepostbndpntbll.sh similarity index 92% rename from dev/jobs/wavepostbndpntbll.sh rename to dev/job_cards/rocoto/wavepostbndpntbll.sh index ec9d66c993e..91e34d691b3 100755 --- a/dev/jobs/wavepostbndpntbll.sh +++ b/dev/job_cards/rocoto/wavepostbndpntbll.sh @@ -19,7 +19,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN WAVE_POST_BNDPNT ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_POST_BNDPNTBLL" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_POST_BNDPNTBLL" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/wavepostpnt.sh b/dev/job_cards/rocoto/wavepostpnt.sh similarity index 93% rename from dev/jobs/wavepostpnt.sh rename to dev/job_cards/rocoto/wavepostpnt.sh index 612b39ef959..ad18783810d 100755 --- a/dev/jobs/wavepostpnt.sh +++ b/dev/job_cards/rocoto/wavepostpnt.sh @@ -17,7 +17,7 @@ export jobid="${job}.$$" echo echo "=============== START TO RUN WAVE_POST_PNT ===============" # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_POST_PNT" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_POST_PNT" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/wavepostsbs.sh b/dev/job_cards/rocoto/wavepostsbs.sh similarity index 93% rename from dev/jobs/wavepostsbs.sh rename to dev/job_cards/rocoto/wavepostsbs.sh index 678f201b26d..4acfe335914 100755 --- a/dev/jobs/wavepostsbs.sh +++ b/dev/job_cards/rocoto/wavepostsbs.sh @@ -22,7 +22,7 @@ for FORECAST_HOUR in "${fhr_list[@]}"; do fhr3=$(printf '%03d' "${FORECAST_HOUR}") jobid="${job}_f${fhr3}.$$" # Execute the JJOB - "${HOMEgfs}/jobs/JGLOBAL_WAVE_POST_SBS" + "${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_POST_SBS" err=$? if [[ "${err}" -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/waveprep.sh b/dev/job_cards/rocoto/waveprep.sh similarity index 92% rename from dev/jobs/waveprep.sh rename to dev/job_cards/rocoto/waveprep.sh index ac2bbbc022a..d24086f93a4 100755 --- a/dev/jobs/waveprep.sh +++ b/dev/job_cards/rocoto/waveprep.sh @@ -15,7 +15,7 @@ export jobid="${job}.$$" ############################################################### # Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_WAVE_PREP" +"${HOMEgfs}/dev/jobs/JGLOBAL_WAVE_PREP" status=$? if [[ ${status} -ne 0 ]]; then exit "${status}" diff --git a/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX b/dev/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX similarity index 99% rename from jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX rename to dev/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX index 2824af6cdd6..11e35d01590 100755 --- a/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX +++ b/dev/jobs/JGDAS_AERO_ANALYSIS_GENERATE_BMATRIX @@ -16,7 +16,6 @@ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx COMIN_OBS:COM_OBS_TMPL \ COMIN_ATMOS_RESTART:COM_ATMOS_RESTART_TMPL \ COMOUT_CONF:COM_CONF_TMPL - mkdir -p "${COMOUT_CHEM_BMAT}" mkdir -p "${COMOUT_CONF}" diff --git a/jobs/JGDAS_ATMOS_CHGRES_FORENKF b/dev/jobs/JGDAS_ATMOS_CHGRES_FORENKF similarity index 100% rename from jobs/JGDAS_ATMOS_CHGRES_FORENKF rename to dev/jobs/JGDAS_ATMOS_CHGRES_FORENKF diff --git a/jobs/JGDAS_ATMOS_GEMPAK b/dev/jobs/JGDAS_ATMOS_GEMPAK similarity index 100% rename from jobs/JGDAS_ATMOS_GEMPAK rename to dev/jobs/JGDAS_ATMOS_GEMPAK diff --git a/jobs/JGDAS_ATMOS_GEMPAK_META_NCDC b/dev/jobs/JGDAS_ATMOS_GEMPAK_META_NCDC similarity index 100% rename from jobs/JGDAS_ATMOS_GEMPAK_META_NCDC rename to dev/jobs/JGDAS_ATMOS_GEMPAK_META_NCDC diff --git a/jobs/JGDAS_ATMOS_VERFOZN b/dev/jobs/JGDAS_ATMOS_VERFOZN similarity index 100% rename from jobs/JGDAS_ATMOS_VERFOZN rename to dev/jobs/JGDAS_ATMOS_VERFOZN diff --git a/jobs/JGDAS_ATMOS_VERFRAD b/dev/jobs/JGDAS_ATMOS_VERFRAD similarity index 100% rename from jobs/JGDAS_ATMOS_VERFRAD rename to dev/jobs/JGDAS_ATMOS_VERFRAD diff --git a/jobs/JGDAS_ENKF_POST b/dev/jobs/JGDAS_ENKF_POST similarity index 100% rename from jobs/JGDAS_ENKF_POST rename to dev/jobs/JGDAS_ENKF_POST diff --git a/jobs/JGDAS_FIT2OBS b/dev/jobs/JGDAS_FIT2OBS similarity index 100% rename from jobs/JGDAS_FIT2OBS rename to dev/jobs/JGDAS_FIT2OBS diff --git a/jobs/JGEFS_WAVE_STAT b/dev/jobs/JGEFS_WAVE_STAT similarity index 100% rename from jobs/JGEFS_WAVE_STAT rename to dev/jobs/JGEFS_WAVE_STAT diff --git a/jobs/JGEFS_WAVE_STAT_PNT b/dev/jobs/JGEFS_WAVE_STAT_PNT similarity index 100% rename from jobs/JGEFS_WAVE_STAT_PNT rename to dev/jobs/JGEFS_WAVE_STAT_PNT diff --git a/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG b/dev/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG similarity index 100% rename from jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG rename to dev/jobs/JGFS_ATMOS_AWIPS_20KM_1P0DEG diff --git a/jobs/JGFS_ATMOS_CYCLONE_GENESIS b/dev/jobs/JGFS_ATMOS_CYCLONE_GENESIS similarity index 100% rename from jobs/JGFS_ATMOS_CYCLONE_GENESIS rename to dev/jobs/JGFS_ATMOS_CYCLONE_GENESIS diff --git a/jobs/JGFS_ATMOS_CYCLONE_TRACKER b/dev/jobs/JGFS_ATMOS_CYCLONE_TRACKER similarity index 100% rename from jobs/JGFS_ATMOS_CYCLONE_TRACKER rename to dev/jobs/JGFS_ATMOS_CYCLONE_TRACKER diff --git a/jobs/JGFS_ATMOS_FBWIND b/dev/jobs/JGFS_ATMOS_FBWIND similarity index 100% rename from jobs/JGFS_ATMOS_FBWIND rename to dev/jobs/JGFS_ATMOS_FBWIND diff --git a/jobs/JGFS_ATMOS_FSU_GENESIS b/dev/jobs/JGFS_ATMOS_FSU_GENESIS similarity index 100% rename from jobs/JGFS_ATMOS_FSU_GENESIS rename to dev/jobs/JGFS_ATMOS_FSU_GENESIS diff --git a/jobs/JGFS_ATMOS_GEMPAK b/dev/jobs/JGFS_ATMOS_GEMPAK similarity index 100% rename from jobs/JGFS_ATMOS_GEMPAK rename to dev/jobs/JGFS_ATMOS_GEMPAK diff --git a/jobs/JGFS_ATMOS_GEMPAK_META b/dev/jobs/JGFS_ATMOS_GEMPAK_META similarity index 100% rename from jobs/JGFS_ATMOS_GEMPAK_META rename to dev/jobs/JGFS_ATMOS_GEMPAK_META diff --git a/jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF b/dev/jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF similarity index 100% rename from jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF rename to dev/jobs/JGFS_ATMOS_GEMPAK_NCDC_UPAPGIF diff --git a/jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC b/dev/jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC similarity index 100% rename from jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC rename to dev/jobs/JGFS_ATMOS_GEMPAK_PGRB2_SPEC diff --git a/jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS b/dev/jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS similarity index 100% rename from jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS rename to dev/jobs/JGFS_ATMOS_PGRB2_SPEC_NPOESS diff --git a/jobs/JGFS_ATMOS_POSTSND b/dev/jobs/JGFS_ATMOS_POSTSND similarity index 97% rename from jobs/JGFS_ATMOS_POSTSND rename to dev/jobs/JGFS_ATMOS_POSTSND index d2d7491f9fb..10f6248081e 100755 --- a/jobs/JGFS_ATMOS_POSTSND +++ b/dev/jobs/JGFS_ATMOS_POSTSND @@ -12,6 +12,7 @@ source "${HOMEgfs}/ush/jjob_header.sh" -e "postsnd" -c "base postsnd" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL \ + COMIN_ATMOS_BUFR:COM_ATMOS_BUFR_TMPL \ COMOUT_ATMOS_BUFR:COM_ATMOS_BUFR_TMPL \ COMOUT_ATMOS_WMO:COM_ATMOS_WMO_TMPL \ COMOUT_ATMOS_GEMPAK:COM_ATMOS_GEMPAK_TMPL diff --git a/jobs/JGFS_ATMOS_VERIFICATION b/dev/jobs/JGFS_ATMOS_VERIFICATION similarity index 100% rename from jobs/JGFS_ATMOS_VERIFICATION rename to dev/jobs/JGFS_ATMOS_VERIFICATION diff --git a/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE b/dev/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE similarity index 100% rename from jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE rename to dev/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE diff --git a/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE b/dev/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE similarity index 100% rename from jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE rename to dev/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE diff --git a/jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL b/dev/jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL similarity index 100% rename from jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL rename to dev/jobs/JGLOBAL_AERO_ANALYSIS_VARIATIONAL diff --git a/jobs/JGLOBAL_ANALYSIS_STATS b/dev/jobs/JGLOBAL_ANALYSIS_STATS similarity index 100% rename from jobs/JGLOBAL_ANALYSIS_STATS rename to dev/jobs/JGLOBAL_ANALYSIS_STATS diff --git a/jobs/JGLOBAL_ARCHIVE_TARS b/dev/jobs/JGLOBAL_ARCHIVE_TARS similarity index 97% rename from jobs/JGLOBAL_ARCHIVE_TARS rename to dev/jobs/JGLOBAL_ARCHIVE_TARS index f3b95db93cc..67b45b993ab 100755 --- a/jobs/JGLOBAL_ARCHIVE_TARS +++ b/dev/jobs/JGLOBAL_ARCHIVE_TARS @@ -11,6 +11,7 @@ fi ############################################## YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ + COMIN_ATMOS_ANLMON:COM_ATMOS_ANLMON_TMPL \ COMIN_ATMOS_BUFR:COM_ATMOS_BUFR_TMPL \ COMIN_ATMOS_GEMPAK:COM_ATMOS_GEMPAK_TMPL \ COMIN_ATMOS_GENESIS:COM_ATMOS_GENESIS_TMPL \ @@ -31,6 +32,7 @@ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ICE_INPUT:COM_ICE_INPUT_TMPL \ COMIN_ICE_RESTART:COM_ICE_RESTART_TMPL \ COMIN_ICE_GRIB:COM_ICE_GRIB_TMPL \ + COMIN_ICE_NETCDF:COM_ICE_NETCDF_TMPL \ COMIN_OBS:COM_OBS_TMPL \ COMIN_TOP:COM_TOP_TMPL \ COMIN_OCEAN_HISTORY:COM_OCEAN_HISTORY_TMPL \ diff --git a/jobs/JGLOBAL_ARCHIVE_VRFY b/dev/jobs/JGLOBAL_ARCHIVE_VRFY similarity index 88% rename from jobs/JGLOBAL_ARCHIVE_VRFY rename to dev/jobs/JGLOBAL_ARCHIVE_VRFY index e5965c22706..2e6e9a42d37 100755 --- a/jobs/JGLOBAL_ARCHIVE_VRFY +++ b/dev/jobs/JGLOBAL_ARCHIVE_VRFY @@ -20,6 +20,12 @@ for grid in "0p25" "0p50" "1p00"; do "COMIN_ATMOS_GRIB_${grid}:COM_ATMOS_GRIB_GRID_TMPL" done +# GEFS-specific: Ensemble statistics path +if [[ "${RUN}" == "gefs" ]]; then + MEMDIR="ensstat" YMD=${PDY} HH=${cyc} GRID="1p00" declare_from_tmpl -rx \ + COMIN_ATMOS_ENSSTAT_1p00:COM_ATMOS_GRIB_GRID_TMPL +fi + ############################################################### # Run archive script ############################################################### diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FINALIZE diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_FV3_INCREMENT diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_INITIALIZE diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_LETKF diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_OBS b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_OBS similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_OBS rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_OBS diff --git a/jobs/JGLOBAL_ATMENS_ANALYSIS_SOL b/dev/jobs/JGLOBAL_ATMENS_ANALYSIS_SOL similarity index 100% rename from jobs/JGLOBAL_ATMENS_ANALYSIS_SOL rename to dev/jobs/JGLOBAL_ATMENS_ANALYSIS_SOL diff --git a/jobs/JGLOBAL_ATMOS_ANALYSIS b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS similarity index 100% rename from jobs/JGLOBAL_ATMOS_ANALYSIS rename to dev/jobs/JGLOBAL_ATMOS_ANALYSIS diff --git a/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC similarity index 97% rename from jobs/JGLOBAL_ATMOS_ANALYSIS_CALC rename to dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC index cf59158117a..bfb5c74a3ad 100755 --- a/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC +++ b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC @@ -28,6 +28,7 @@ RUN=${rCDUMP} YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ + COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ COMIN_ATMOS_RESTART:COM_ATMOS_RESTART_TMPL RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ diff --git a/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI similarity index 96% rename from jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI rename to dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI index e14bf395744..e343fd235ca 100755 --- a/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI +++ b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC_FV3JEDI @@ -26,9 +26,9 @@ YMD=${PDY} HH=${cyc} RUN=${RUN} declare_from_tmpl -rx \ YMD=${PDY} HH=${cyc} RUN=${RUN} declare_from_tmpl -rx \ COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ - COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL + COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ - COMOUT_CONF:COM_CONF_TMPL + COMOUT_CONF:COM_CONF_TMPL mkdir -m 775 -p "${COMOUT_CONF}" diff --git a/jobs/JGDAS_ATMOS_ANALYSIS_DIAG b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_DIAG similarity index 70% rename from jobs/JGDAS_ATMOS_ANALYSIS_DIAG rename to dev/jobs/JGLOBAL_ATMOS_ANALYSIS_DIAG index ad83614bff8..553a58e1160 100755 --- a/jobs/JGDAS_ATMOS_ANALYSIS_DIAG +++ b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_DIAG @@ -1,27 +1,28 @@ #! /usr/bin/env bash -source "${HOMEgfs}/ush/jjob_header.sh" -e "anal" -c "base anal analdiag" +source "${HOMEgfs}/ush/jjob_header.sh" -e "analdiag" -c "base anal analdiag" ############################################## # Set variables used in the script ############################################## -export DO_CALC_ANALYSIS=${DO_CALC_ANALYSIS:-"YES"} +#export DO_CALC_ANALYSIS=${DO_CALC_ANALYSIS:-"YES"} ############################################## # Begin JOB SPECIFIC work ############################################## # shellcheck disable=SC2153 -GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") -export gPDY=${GDATE:0:8} -export gcyc=${GDATE:8:2} -export GDUMP="gdas" -export GDUMP_ENS="enkf${GDUMP}" +#GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") +#export gPDY=${GDATE:0:8} +#export gcyc=${GDATE:8:2} +#export GDUMP="gdas" +#export GDUMP_ENS="enkf${GDUMP}" -export OPREFIX="${RUN/enkf/}.t${cyc}z." -export GPREFIX="${GDUMP}.t${gcyc}z." -export APREFIX="${RUN}.t${cyc}z." +#export OPREFIX="${RUN/enkf/}.t${cyc}z." +#export GPREFIX="${GDUMP}.t${gcyc}z." +#export APREFIX="${RUN}.t${cyc}z." YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ + COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL mkdir -m 775 -p "${COMOUT_ATMOS_ANALYSIS}" diff --git a/jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL b/dev/jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL similarity index 100% rename from jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL rename to dev/jobs/JGLOBAL_ATMOS_CHGRES_GEN_CONTROL diff --git a/jobs/JGLOBAL_ATMOS_ENSSTAT b/dev/jobs/JGLOBAL_ATMOS_ENSSTAT similarity index 100% rename from jobs/JGLOBAL_ATMOS_ENSSTAT rename to dev/jobs/JGLOBAL_ATMOS_ENSSTAT diff --git a/jobs/JGLOBAL_ATMOS_POST_MANAGER b/dev/jobs/JGLOBAL_ATMOS_POST_MANAGER similarity index 100% rename from jobs/JGLOBAL_ATMOS_POST_MANAGER rename to dev/jobs/JGLOBAL_ATMOS_POST_MANAGER diff --git a/jobs/JGLOBAL_ATMOS_PREP_SFC b/dev/jobs/JGLOBAL_ATMOS_PREP_SFC similarity index 100% rename from jobs/JGLOBAL_ATMOS_PREP_SFC rename to dev/jobs/JGLOBAL_ATMOS_PREP_SFC diff --git a/jobs/JGLOBAL_ATMOS_PRODUCTS b/dev/jobs/JGLOBAL_ATMOS_PRODUCTS similarity index 100% rename from jobs/JGLOBAL_ATMOS_PRODUCTS rename to dev/jobs/JGLOBAL_ATMOS_PRODUCTS diff --git a/jobs/JGLOBAL_ATMOS_SFCANL b/dev/jobs/JGLOBAL_ATMOS_SFCANL similarity index 98% rename from jobs/JGLOBAL_ATMOS_SFCANL rename to dev/jobs/JGLOBAL_ATMOS_SFCANL index 41fdeec5969..59f542b729d 100755 --- a/jobs/JGLOBAL_ATMOS_SFCANL +++ b/dev/jobs/JGLOBAL_ATMOS_SFCANL @@ -33,7 +33,7 @@ RUN="enkfgdas" MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ mkdir -p "${COMOUT_ATMOS_RESTART}" # Use CFP to stage and save files in parallel - export USE_CFP=YES +export USE_CFP=YES ############################################################### # Run relevant script diff --git a/jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC b/dev/jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC similarity index 100% rename from jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC rename to dev/jobs/JGLOBAL_ATMOS_TROPCY_QC_RELOC diff --git a/jobs/JGLOBAL_ATMOS_UPP b/dev/jobs/JGLOBAL_ATMOS_UPP similarity index 100% rename from jobs/JGLOBAL_ATMOS_UPP rename to dev/jobs/JGLOBAL_ATMOS_UPP diff --git a/jobs/JGLOBAL_ATMOS_VMINMON b/dev/jobs/JGLOBAL_ATMOS_VMINMON similarity index 100% rename from jobs/JGLOBAL_ATMOS_VMINMON rename to dev/jobs/JGLOBAL_ATMOS_VMINMON diff --git a/jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE b/dev/jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE similarity index 100% rename from jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE rename to dev/jobs/JGLOBAL_ATM_ANALYSIS_FINALIZE diff --git a/jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT b/dev/jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT similarity index 100% rename from jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT rename to dev/jobs/JGLOBAL_ATM_ANALYSIS_FV3_INCREMENT diff --git a/jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE b/dev/jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE similarity index 100% rename from jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE rename to dev/jobs/JGLOBAL_ATM_ANALYSIS_INITIALIZE diff --git a/jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL b/dev/jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL similarity index 100% rename from jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL rename to dev/jobs/JGLOBAL_ATM_ANALYSIS_VARIATIONAL diff --git a/jobs/JGLOBAL_CLEANUP b/dev/jobs/JGLOBAL_CLEANUP similarity index 100% rename from jobs/JGLOBAL_CLEANUP rename to dev/jobs/JGLOBAL_CLEANUP diff --git a/jobs/JGLOBAL_ENS_ARCHIVE_TARS b/dev/jobs/JGLOBAL_ENKF_ARCHIVE_TARS similarity index 97% rename from jobs/JGLOBAL_ENS_ARCHIVE_TARS rename to dev/jobs/JGLOBAL_ENKF_ARCHIVE_TARS index 093877876d4..2e22ada681b 100755 --- a/jobs/JGLOBAL_ENS_ARCHIVE_TARS +++ b/dev/jobs/JGLOBAL_ENKF_ARCHIVE_TARS @@ -25,7 +25,7 @@ mkdir -p "${COMIN_CONF}" # Calls an external bash command; do not fail on unassigned/error set +eu export -n SHELLOPTS -"${SCRgfs}/exgdas_enkf_earc_tars.py" +"${SCRgfs}/exglobal_enkf_earc_tars.py" export err=$? set +x if [[ ${err} -ne 0 ]]; then diff --git a/jobs/JGLOBAL_ENS_ARCHIVE_VRFY b/dev/jobs/JGLOBAL_ENKF_ARCHIVE_VRFY similarity index 97% rename from jobs/JGLOBAL_ENS_ARCHIVE_VRFY rename to dev/jobs/JGLOBAL_ENKF_ARCHIVE_VRFY index 832ff9a0277..77c3d1973fc 100755 --- a/jobs/JGLOBAL_ENS_ARCHIVE_VRFY +++ b/dev/jobs/JGLOBAL_ENKF_ARCHIVE_VRFY @@ -14,7 +14,7 @@ MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ # Run archive script ############################################################### -"${SCRgfs}/exgdas_enkf_earc_vrfy.py" +"${SCRgfs}/exglobal_enkf_earc_vrfy.py" err=$? if [[ ${err} -ne 0 ]]; then exit "${err}" diff --git a/dev/jobs/JGLOBAL_ENKF_DIAG b/dev/jobs/JGLOBAL_ENKF_DIAG new file mode 100755 index 00000000000..fa494dfb847 --- /dev/null +++ b/dev/jobs/JGLOBAL_ENKF_DIAG @@ -0,0 +1,112 @@ +#! /usr/bin/env bash + +source "${HOMEgfs}/ush/jjob_header.sh" -e "ediag" -c "base anal eobs analdiag ediag" + +############################################## +# Set variables used in the script +############################################## + +############################################## +# Begin JOB SPECIFIC work +############################################## +# shellcheck disable=SC2153 +#GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") +#export gPDY=${GDATE:0:8} +#export gcyc=${GDATE:8:2} +#export GDUMP="gdas" +#export GDUMP_ENS="enkf${GDUMP}" + +export CASE=${CASE_ENS} + +#export OPREFIX="${RUN/enkf/}.t${cyc}z." +export APREFIX="${RUN}.t${cyc}z." +#export GPREFIX="${GDUMP_ENS}.t${gcyc}z." +#GPREFIX_DET="${GDUMP}.t${gcyc}z." + +#RUN=${RUN/enkf/} YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ +# COMIN_OBS:COM_OBS_TMPL +MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ + COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ + COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL + +#RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ +# COMIN_OBS_PREV:COM_OBS_TMPL \ +# COMIN_ATMOS_ANALYSIS_DET_PREV:COM_ATMOS_ANALYSIS_TMPL + +#MEMDIR="ensstat" RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ +# COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL + +#export ATMGES_ENSMEAN="${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}ensmean.atm.f006.nc" +#if [[ ! -f "${ATMGES_ENSMEAN}" ]]; then +# export err=1 +# err_exit "FILE MISSING: ATMGES_ENSMEAN == ${ATMGES_ENSMEAN}" +#fi + +# Link observational data +#export PREPQC="${COMIN_OBS}/${OPREFIX}prepbufr" +#if [[ ! -f ${PREPQC} ]]; then +# echo "WARNING: Global PREPBUFR FILE ${PREPQC} MISSING" +#fi +#export TCVITL="${COMIN_OBS}/${OPREFIX}syndata.tcvitals.tm00" +#if [[ ${DONST} == "YES" ]]; then +# export NSSTBF="${COMIN_OBS}/${OPREFIX}nsstbufr" +#fi +#export PREPQCPF="${COMIN_OBS}/${OPREFIX}prepbufr.acft_profiles" + +# Guess Bias correction coefficients related to control +#export GBIAS=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias.txt +#export GBIASPC=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias_pc.txt +#export GBIASAIR=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias_air.txt +#export GRADSTAT=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}radstat.tar + +# Bias correction coefficients related to ensemble mean +#export ABIAS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias.txt" +#export ABIASPC="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_pc.txt" +#export ABIASAIR="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_air.txt" +#export ABIASe="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_int.txt" + +# Diagnostics related to ensemble mean +export CNVSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat_ensmean.tar" +export OZNSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat_ensmean.tar" +export RADSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat_ensmean.tar" + +# Select observations based on ensemble mean +#export RUN_SELECT="YES" +#export USE_SELECT="NO" +#export SELECT_OBS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput.ensmean" + +export DIAG_SUFFIX="_ensmean" +export DIAG_COMPRESS="NO" + +# GSI namelist options specific to eobs +#export SETUP_INVOBS="passive_bc=.false.,${SETUP_INVOBS}" + +############################################################### +# Run relevant script + +${ANALDIAGSH:-${SCRgfs}/exglobal_diag.sh} && true +export err=$? +if [[ ${err} -ne 0 ]]; then + err_exit +fi + +############################################## +# End JOB SPECIFIC work +############################################## + +############################################## +# Final processing +############################################## +if [[ -e "${pgmout}" ]]; then + cat "${pgmout}" +fi + +########################################## +# Remove the Temporary working directory +########################################## +cd "${DATAROOT}" || true +if [[ "${KEEPDATA}" == "NO" ]]; then + rm -rf "${DATA}" +fi + +exit 0 diff --git a/jobs/JGDAS_ENKF_ECEN b/dev/jobs/JGLOBAL_ENKF_ECEN similarity index 96% rename from jobs/JGDAS_ENKF_ECEN rename to dev/jobs/JGLOBAL_ENKF_ECEN index e3024ceb43b..0d8a67fc324 100755 --- a/jobs/JGDAS_ENKF_ECEN +++ b/dev/jobs/JGLOBAL_ENKF_ECEN @@ -36,7 +36,7 @@ MEMDIR="ensstat" RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ ############################################################### # Run relevant script -${ENKFRECENSH:-${SCRgfs}/exgdas_enkf_ecen.sh} && true +${ENKFRECENSH:-${SCRgfs}/exglobal_enkf_ecen.sh} && true export err=$? if [[ ${err} -ne 0 ]]; then err_exit diff --git a/jobs/JGDAS_ENKF_ECEN_FV3JEDI b/dev/jobs/JGLOBAL_ENKF_ECEN_FV3JEDI similarity index 96% rename from jobs/JGDAS_ENKF_ECEN_FV3JEDI rename to dev/jobs/JGLOBAL_ENKF_ECEN_FV3JEDI index 3d2ff374a4f..12fe96146db 100755 --- a/jobs/JGDAS_ENKF_ECEN_FV3JEDI +++ b/dev/jobs/JGLOBAL_ENKF_ECEN_FV3JEDI @@ -36,7 +36,7 @@ mkdir -m 755 -p "${COMOUT_CONF}" # Run relevant script ############################################## -EXSCRIPT=${GDASATMRUNPY:-${SCRgfs}/exgdas_enkf_ecen_fv3jedi.py} +EXSCRIPT=${GDASATMRUNPY:-${SCRgfs}/exglobal_enkf_ecen_fv3jedi.py} ${EXSCRIPT} && true export err=$? if [[ ${err} -ne 0 ]]; then diff --git a/jobs/JGDAS_ENKF_SELECT_OBS b/dev/jobs/JGLOBAL_ENKF_SELECT_OBS similarity index 92% rename from jobs/JGDAS_ENKF_SELECT_OBS rename to dev/jobs/JGLOBAL_ENKF_SELECT_OBS index 3417f6f6e77..f038f524b5f 100755 --- a/jobs/JGDAS_ENKF_SELECT_OBS +++ b/dev/jobs/JGLOBAL_ENKF_SELECT_OBS @@ -84,15 +84,15 @@ export ABIASAIR="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_air.txt" export ABIASe="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_int.txt" # Diagnostics related to ensemble mean -export GSISTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}gsistat.ensmean.txt" -export CNVSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat.ensmean.tar" -export OZNSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat.ensmean.tar" -export RADSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat.ensmean.tar" +export GSISTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}gsistat_ensmean.txt" +export CNVSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat_ensmean.tar" +export OZNSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat_ensmean.tar" +export RADSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat_ensmean.tar" # Select observations based on ensemble mean export RUN_SELECT="YES" export USE_SELECT="NO" -export SELECT_OBS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput.ensmean" +export SELECT_OBS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput_ensmean.tar" export DIAG_SUFFIX="_ensmean" @@ -109,7 +109,7 @@ done ############################################################### # Run relevant script -${INVOBSSH:-${SCRgfs}/exgdas_enkf_select_obs.sh} && true +${INVOBSSH:-${SCRgfs}/exglobal_enkf_select_obs.sh} && true export err=$? if [[ ${err} -ne 0 ]]; then err_exit diff --git a/jobs/JGDAS_ENKF_SFC b/dev/jobs/JGLOBAL_ENKF_SFC similarity index 96% rename from jobs/JGDAS_ENKF_SFC rename to dev/jobs/JGLOBAL_ENKF_SFC index ee2bb8112a9..0e33d9e4dac 100755 --- a/jobs/JGDAS_ENKF_SFC +++ b/dev/jobs/JGLOBAL_ENKF_SFC @@ -37,12 +37,12 @@ RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ COMIN_ATMOS_ANALYSIS_DET_PREV:COM_ATMOS_ANALYSIS_TMPL # Use CFP to stage and save files in parallel - export USE_CFP=YES +export USE_CFP=YES ############################################################### # Run relevant script -${ENKFRESFCSH:-${SCRgfs}/exgdas_enkf_sfc.sh} && true +${ENKFRESFCSH:-${SCRgfs}/exglobal_enkf_sfc.sh} && true export err=$? if [[ ${err} -ne 0 ]]; then err_exit diff --git a/jobs/JGDAS_ENKF_UPDATE b/dev/jobs/JGLOBAL_ENKF_UPDATE similarity index 72% rename from jobs/JGDAS_ENKF_UPDATE rename to dev/jobs/JGLOBAL_ENKF_UPDATE index 96d5dff079a..47d2fb0640b 100755 --- a/jobs/JGDAS_ENKF_UPDATE +++ b/dev/jobs/JGLOBAL_ENKF_UPDATE @@ -9,15 +9,12 @@ source "${HOMEgfs}/ush/jjob_header.sh" -e "eupd" -c "base anal eupd" ############################################## # Begin JOB SPECIFIC work ############################################## -# shellcheck disable=SC2153 -GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") -export gPDY=${GDATE:0:8} -export gcyc=${GDATE:8:2} -export GDUMP="gdas" -export GDUMP_ENS="enkf${GDUMP}" +# shellcheck disable=SC2155 +export GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") +export GDUMP="enkfgdas" # EnKF ensemble always uses RUN=enkfgdas for prior members export APREFIX="${RUN}.t${cyc}z." -export GPREFIX="${GDUMP_ENS}.t${gcyc}z." +export GPREFIX="${GDUMP}.t${GDATE:8:2}z." MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_ANALYSIS_STAT:COM_ATMOS_ANALYSIS_TMPL @@ -25,13 +22,13 @@ MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMOUT_ATMOS_ANALYSIS_STAT:COM_ATMOS_ANALYSIS_TMPL -MEMDIR="ensstat" RUN="enkfgdas" YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ +MEMDIR="ensstat" RUN="enkfgdas" YMD=${GDATE:0:8} HH=${GDATE:8:2} declare_from_tmpl -rx \ COMIN_ATMOS_HISTORY_STAT_PREV:COM_ATMOS_HISTORY_TMPL ############################################################### # Run relevant script -${ENKFUPDSH:-${SCRgfs}/exgdas_enkf_update.sh} && true +${ENKFUPDSH:-${SCRgfs}/exglobal_enkf_update.sh} && true export err=$? if [[ ${err} -ne 0 ]]; then err_exit @@ -40,8 +37,8 @@ fi ############################################## # Send Alerts ############################################## -if [[ "${SENDDBN}" == "YES" ]] ; then - "${DBNROOT}/bin/dbn_alert" "MODEL" "ENKF1_MSC_enkfstat" "${job}" "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX}enkfstat.txt" +if [[ "${SENDDBN}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" "MODEL" "ENKF1_MSC_enkfstat" "${job}" "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX}enkfstat.txt" fi ############################################## diff --git a/jobs/JGLOBAL_ENS_GLOBUS_ARCH b/dev/jobs/JGLOBAL_ENS_GLOBUS_ARCH similarity index 100% rename from jobs/JGLOBAL_ENS_GLOBUS_ARCH rename to dev/jobs/JGLOBAL_ENS_GLOBUS_ARCH diff --git a/jobs/JGLOBAL_EXTRACTVARS b/dev/jobs/JGLOBAL_EXTRACTVARS similarity index 100% rename from jobs/JGLOBAL_EXTRACTVARS rename to dev/jobs/JGLOBAL_EXTRACTVARS diff --git a/jobs/JGLOBAL_FETCH b/dev/jobs/JGLOBAL_FETCH similarity index 100% rename from jobs/JGLOBAL_FETCH rename to dev/jobs/JGLOBAL_FETCH diff --git a/jobs/JGLOBAL_FORECAST b/dev/jobs/JGLOBAL_FORECAST similarity index 100% rename from jobs/JGLOBAL_FORECAST rename to dev/jobs/JGLOBAL_FORECAST diff --git a/jobs/JGLOBAL_GLOBUS_ARCH b/dev/jobs/JGLOBAL_GLOBUS_ARCH similarity index 100% rename from jobs/JGLOBAL_GLOBUS_ARCH rename to dev/jobs/JGLOBAL_GLOBUS_ARCH diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_CHECKPOINT diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_ECEN b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_ECEN similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_ECEN rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_ECEN diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_FINALIZE diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_INITIALIZE diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_LETKF b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_LETKF similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_LETKF rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_LETKF diff --git a/jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL b/dev/jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL similarity index 100% rename from jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL rename to dev/jobs/JGLOBAL_MARINE_ANALYSIS_VARIATIONAL diff --git a/jobs/JGLOBAL_MARINE_BMAT b/dev/jobs/JGLOBAL_MARINE_BMAT similarity index 100% rename from jobs/JGLOBAL_MARINE_BMAT rename to dev/jobs/JGLOBAL_MARINE_BMAT diff --git a/jobs/JGLOBAL_MARINE_BMAT_INITIALIZE b/dev/jobs/JGLOBAL_MARINE_BMAT_INITIALIZE similarity index 100% rename from jobs/JGLOBAL_MARINE_BMAT_INITIALIZE rename to dev/jobs/JGLOBAL_MARINE_BMAT_INITIALIZE diff --git a/jobs/JGLOBAL_OCEANICE_PRODUCTS b/dev/jobs/JGLOBAL_OCEANICE_PRODUCTS similarity index 100% rename from jobs/JGLOBAL_OCEANICE_PRODUCTS rename to dev/jobs/JGLOBAL_OCEANICE_PRODUCTS diff --git a/jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS b/dev/jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS similarity index 100% rename from jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS rename to dev/jobs/JGLOBAL_OFFLINE_ATMOS_ANALYSIS diff --git a/jobs/JGLOBAL_PREP_EMISSIONS b/dev/jobs/JGLOBAL_PREP_EMISSIONS similarity index 100% rename from jobs/JGLOBAL_PREP_EMISSIONS rename to dev/jobs/JGLOBAL_PREP_EMISSIONS diff --git a/jobs/JGLOBAL_PREP_OCEAN_OBS b/dev/jobs/JGLOBAL_PREP_OCEAN_OBS similarity index 100% rename from jobs/JGLOBAL_PREP_OCEAN_OBS rename to dev/jobs/JGLOBAL_PREP_OCEAN_OBS diff --git a/jobs/JGLOBAL_SNOWENS_ANALYSIS b/dev/jobs/JGLOBAL_SNOWENS_ANALYSIS similarity index 100% rename from jobs/JGLOBAL_SNOWENS_ANALYSIS rename to dev/jobs/JGLOBAL_SNOWENS_ANALYSIS diff --git a/jobs/JGLOBAL_SNOW_ANALYSIS b/dev/jobs/JGLOBAL_SNOW_ANALYSIS similarity index 100% rename from jobs/JGLOBAL_SNOW_ANALYSIS rename to dev/jobs/JGLOBAL_SNOW_ANALYSIS diff --git a/jobs/JGLOBAL_STAGE_IC b/dev/jobs/JGLOBAL_STAGE_IC similarity index 100% rename from jobs/JGLOBAL_STAGE_IC rename to dev/jobs/JGLOBAL_STAGE_IC diff --git a/jobs/JGLOBAL_WAVE_GEMPAK b/dev/jobs/JGLOBAL_WAVE_GEMPAK similarity index 100% rename from jobs/JGLOBAL_WAVE_GEMPAK rename to dev/jobs/JGLOBAL_WAVE_GEMPAK diff --git a/jobs/JGLOBAL_WAVE_INIT b/dev/jobs/JGLOBAL_WAVE_INIT similarity index 100% rename from jobs/JGLOBAL_WAVE_INIT rename to dev/jobs/JGLOBAL_WAVE_INIT diff --git a/jobs/JGLOBAL_WAVE_POST_BNDPNT b/dev/jobs/JGLOBAL_WAVE_POST_BNDPNT similarity index 100% rename from jobs/JGLOBAL_WAVE_POST_BNDPNT rename to dev/jobs/JGLOBAL_WAVE_POST_BNDPNT diff --git a/jobs/JGLOBAL_WAVE_POST_BNDPNTBLL b/dev/jobs/JGLOBAL_WAVE_POST_BNDPNTBLL similarity index 100% rename from jobs/JGLOBAL_WAVE_POST_BNDPNTBLL rename to dev/jobs/JGLOBAL_WAVE_POST_BNDPNTBLL diff --git a/jobs/JGLOBAL_WAVE_POST_PNT b/dev/jobs/JGLOBAL_WAVE_POST_PNT similarity index 100% rename from jobs/JGLOBAL_WAVE_POST_PNT rename to dev/jobs/JGLOBAL_WAVE_POST_PNT diff --git a/jobs/JGLOBAL_WAVE_POST_SBS b/dev/jobs/JGLOBAL_WAVE_POST_SBS similarity index 100% rename from jobs/JGLOBAL_WAVE_POST_SBS rename to dev/jobs/JGLOBAL_WAVE_POST_SBS diff --git a/jobs/JGLOBAL_WAVE_PRDGEN_BULLS b/dev/jobs/JGLOBAL_WAVE_PRDGEN_BULLS similarity index 100% rename from jobs/JGLOBAL_WAVE_PRDGEN_BULLS rename to dev/jobs/JGLOBAL_WAVE_PRDGEN_BULLS diff --git a/jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED b/dev/jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED similarity index 100% rename from jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED rename to dev/jobs/JGLOBAL_WAVE_PRDGEN_GRIDDED diff --git a/jobs/JGLOBAL_WAVE_PREP b/dev/jobs/JGLOBAL_WAVE_PREP similarity index 100% rename from jobs/JGLOBAL_WAVE_PREP rename to dev/jobs/JGLOBAL_WAVE_PREP diff --git a/dev/jobs/prepatmiodaobs.sh b/dev/jobs/prepatmiodaobs.sh deleted file mode 100755 index 4633c81b060..00000000000 --- a/dev/jobs/prepatmiodaobs.sh +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/env bash - -############################################################### -# Source UFSDA workflow modules -source "${HOMEgfs}/dev/ush/load_modules.sh" ufsda -status=$? -if [[ ${status} -ne 0 ]]; then - exit "${status}" -fi - -export job="prepatmobs" -export jobid="${job}.$$" - -############################################################### -# Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_ATM_PREP_IODA_OBS" -status=$? -exit "${status}" diff --git a/dev/jobs/prepobsaero.sh b/dev/jobs/prepobsaero.sh deleted file mode 100755 index 1996172958f..00000000000 --- a/dev/jobs/prepobsaero.sh +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env bash - -set -x - -############################################################### -# Source UFSDA workflow modules -source "${HOMEgfs}/dev/ush/load_modules.sh" ufsda -status=$? -if [[ ${status} -ne 0 ]]; then - exit "${status}" -fi - -export job="prepobsaero" -export jobid="${job}.$$" - -############################################################### -# Execute the JJOB -"${HOMEgfs}/jobs/JGLOBAL_PREP_OBS_AERO" -status=$? -exit "${status}" diff --git a/dev/parm/config/gcafs/config.base.j2 b/dev/parm/config/gcafs/config.base.j2 index 503a9e03bd6..c091f269c62 100644 --- a/dev/parm/config/gcafs/config.base.j2 +++ b/dev/parm/config/gcafs/config.base.j2 @@ -51,6 +51,8 @@ export PACKAGEROOT="{{ PACKAGEROOT }}" # TODO: set via prod_envir in Ops export COMROOT="{{ COMROOT }}" # TODO: set via prod_envir in Ops export COMINsyn="{{ COMINsyn }}" export DMPDIR="{{ DMPDIR }}" +export IODADIR="{{ IODADIR }}" +export USE_IODADIR="{{ USE_IODADIR }}" # Gempak from external models # Default locations are to dummy locations for testing @@ -146,8 +148,6 @@ source "${EXPDIR}/config.com" export LOGSCRIPT=${LOGSCRIPT:-""} #export LOGSCRIPT=${LOGSCRIPT:-"startmsg"} -export REDOUT="1>" -export REDERR="2>" export SENDECF=${SENDECF:-"NO"} export SENDSDM=${SENDSDM:-"NO"} diff --git a/dev/parm/config/gcafs/config.fetch b/dev/parm/config/gcafs/config.fetch index 7cce1d1be27..bcd65154126 100644 --- a/dev/parm/config/gcafs/config.fetch +++ b/dev/parm/config/gcafs/config.fetch @@ -17,7 +17,12 @@ if [[ "${PDY}${cyc}" -gt "${SDATE}" ]]; then gdas_version="prod" fi export gdas_version - export FETCH_YAML_TMPL_LIST="${PARMgfs}/fetch/${NET}_${APP}_gdas-anl.yaml.j2,${PARMgfs}/fetch/${NET}_${APP}_gdas-dtfanl.yaml.j2" + if [[ "${machine}" == "ORION" || "${machine}" == "HERCULES" ]]; then + FETCH_YAML_TMPL_LIST="${PARMgfs}/fetch/${NET}_${APP}_gdas-anl_msu.yaml.j2,${PARMgfs}/fetch/${NET}_${APP}_gdas-dtfanl_msu.yaml.j2" + else + FETCH_YAML_TMPL_LIST="${PARMgfs}/fetch/${NET}_${APP}_gdas-anl.yaml.j2,${PARMgfs}/fetch/${NET}_${APP}_gdas-dtfanl.yaml.j2" + fi + export FETCH_YAML_TMPL_LIST else # fetch based on first cycle # Determine start type diff --git a/dev/parm/config/gcafs/config.prep.j2 b/dev/parm/config/gcafs/config.prep.j2 new file mode 120000 index 00000000000..c06426da0f3 --- /dev/null +++ b/dev/parm/config/gcafs/config.prep.j2 @@ -0,0 +1 @@ +../gfs/config.prep.j2 \ No newline at end of file diff --git a/dev/parm/config/gcafs/config.prepatmiodaobs b/dev/parm/config/gcafs/config.prepatmiodaobs deleted file mode 120000 index 4a93cd3b05d..00000000000 --- a/dev/parm/config/gcafs/config.prepatmiodaobs +++ /dev/null @@ -1 +0,0 @@ -../gfs/config.prepatmiodaobs \ No newline at end of file diff --git a/dev/parm/config/gcafs/config.prepobsaero b/dev/parm/config/gcafs/config.prepobsaero deleted file mode 100644 index f70138991c8..00000000000 --- a/dev/parm/config/gcafs/config.prepobsaero +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -x - -########## config.prepobsaero ########## -# Prepare and thin/superob aerosol observations - -echo "BEGIN: config.prepobsaero" - -# Get task specific resources -source "${EXPDIR}/config.resources" prepobsaero - -export OBSPROCYAML="${PARMgfs}/gdas/aero/obs/lists/gdas_aero_obsproc.yaml.j2" -export OBSPROCEXE="${EXECgfs}/gdas_obsprovider2ioda.x" -export VIIRS_DATA_DIR="/scratch2/NCEPDEV/stmp3/Yaping.Wang/VIIRS/AWS/" -export SENSORS="npp,n20" - - -echo "END: config.prepaeroobs" diff --git a/dev/parm/config/gcafs/config.resources b/dev/parm/config/gcafs/config.resources index 1fee7c60684..5308ac6f8fd 100644 --- a/dev/parm/config/gcafs/config.resources +++ b/dev/parm/config/gcafs/config.resources @@ -12,12 +12,12 @@ if (( $# != 1 )); then echo "Must specify an input task argument to set resource variables!" echo "argument can be any one of the following:" echo "stage_ic aerosol_init fetch" - echo "prep prepatmiodaobs" + echo "prep" echo "atmanlinit atmanlvar atmanlfv3inc atmanlfinal" echo "atmensanlinit atmensanlobs atmensanlsol atmensanlletkf atmensanlfv3inc atmensanlfinal ecen_fv3jedi analcalc_fv3jedi" echo "snowanl esnowanl" echo "prep_emissions" - echo "prepobsaero aeroanlinit aeroanlvar aeroanlfinal aeroanlgenb" + echo "aeroanlinit aeroanlvar aeroanlfinal aeroanlgenb" echo "offlineanl" echo "anal sfcanl analcalc analdiag anlstat fcst echgres" echo "upp atmos_products" @@ -28,7 +28,7 @@ if (( $# != 1 )); then echo "waveinit waveprep wavepostsbs wavepostbndpnt wavepostbndpntbll wavepostpnt" echo "wavegempak waveawipsbulls waveawipsgridded" echo "postsnd awips gempak npoess" - echo "marineanlinit prepoceanobs marinebmat marineanlvar marineanlecen marineanalletkf marineanlchkpt marineanlfinal ocnanalvrfy" + echo "marineanlinit marinebmat marineanlvar marineanlecen marineanalletkf marineanlchkpt marineanlfinal ocnanalvrfy" exit 1 fi @@ -147,13 +147,6 @@ case ${step} in memory="${mem_node_max}" ;; - "prepatmiodaobs") - walltime="00:30:00" - ntasks=1 - threads_per_task=1 - tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - ;; - "aerosol_init") walltime="00:05:00" ntasks=1 @@ -370,14 +363,6 @@ case ${step} in tasks_per_node=$(( max_tasks_per_node / threads_per_task )) ;; - "prepobsaero") - walltime="00:30:00" - ntasks=1 - threads_per_task=1 - tasks_per_node=1 - memory="96GB" - ;; - "aeroanlinit") # below lines are for creating JEDI YAML case "${CASE}" in @@ -534,14 +519,6 @@ case ${step} in memory="24GB" ;; - "prepoceanobs") - walltime="00:10:00" - ntasks=1 - threads_per_task=1 - tasks_per_node=${max_tasks_per_node} - memory="48GB" - ;; - "marinebmat") npes=16 ntasks=16 diff --git a/dev/parm/config/gcafs/yaml/defaults.yaml b/dev/parm/config/gcafs/yaml/defaults.yaml index 62e4c78ac89..38f1de65dcc 100644 --- a/dev/parm/config/gcafs/yaml/defaults.yaml +++ b/dev/parm/config/gcafs/yaml/defaults.yaml @@ -83,13 +83,6 @@ marineanlletkf: SOCA_ANL_GEOM: "${FIXgfs}/gdas/soca/72x35x25/soca" SOCA_OBS_LIST: "${PARMgfs}/gdas/marine/obs/obs_list.yaml.j2" -prepoceanobs: - SOCA_INPUT_FIX_DIR: "${FIXgfs}/gdas/soca/72x35x25/soca" - SOCA_OBS_LIST: "${PARMgfs}/gdas/marine/obs/obs_list.yaml" # TODO: This is also repeated in ocnanal - OBSPREP_YAML: "${PARMgfs}/gdas/marine/obsprep/obsprep_config.yaml" - use_exp_obs: "YES" - dmpdir_exp: "${BASE_DATA}/experimental_obs" - fcst: CHECK_LAND_RESTART_OROG: "YES" diff --git a/dev/parm/config/gefs/config.base.j2 b/dev/parm/config/gefs/config.base.j2 index 4e9cf02f71c..a44ca83d6aa 100644 --- a/dev/parm/config/gefs/config.base.j2 +++ b/dev/parm/config/gefs/config.base.j2 @@ -64,7 +64,7 @@ export DO_AWIPS="{{ DO_AWIPS }}" # AWIPS products # Experiment mode (cycled or forecast-only) export MODE="{{ MODE }}" # cycled/forecast-only export DO_TEST_MODE="{{ DO_TEST_MODE }}" # option to change configuration for automated testing -export GEFSTYPE="{{ GEFSTYPE }}" # near-real-time/gefs-offline +export GEFSTYPE="{{ GEFSTYPE }}" # gefs-real-time/gefs-offline #################################################### # DO NOT ADD MACHINE DEPENDENT STUFF BELOW THIS LINE # IF YOU HAVE TO MAKE MACHINE SPECIFIC CHANGES BELOW @@ -111,8 +111,6 @@ source "${EXPDIR}/config.com" export LOGSCRIPT=${LOGSCRIPT:-""} #export LOGSCRIPT=${LOGSCRIPT:-"startmsg"} -export REDOUT="1>" -export REDERR="2>" export SENDECF=${SENDECF:-"NO"} export SENDSDM=${SENDSDM:-"NO"} diff --git a/dev/parm/config/gefs/config.nsst b/dev/parm/config/gefs/config.nsst.j2 similarity index 96% rename from dev/parm/config/gefs/config.nsst rename to dev/parm/config/gefs/config.nsst.j2 index f9a29d44d3a..04abadc91dc 100644 --- a/dev/parm/config/gefs/config.nsst +++ b/dev/parm/config/gefs/config.nsst.j2 @@ -11,7 +11,7 @@ echo "BEGIN: config.nsst" export NST_MODEL=2 # nstf_name(2) : NST_SPINUP : 0 = OFF, 1 = ON, -export NST_SPINUP=0 +export NST_SPINUP="{{ NST_SPINUP }}" # nstf_name(3) : NST_RESV (Reserved, NSST Analysis) : 0 = OFF, 1 = ON export NST_RESV=0 diff --git a/dev/parm/config/gefs/config.oceanice_products b/dev/parm/config/gefs/config.oceanice_products index 48483613f43..7b30de84bc5 100644 --- a/dev/parm/config/gefs/config.oceanice_products +++ b/dev/parm/config/gefs/config.oceanice_products @@ -7,9 +7,10 @@ echo "BEGIN: config.oceanice_products" # Get task specific resources source "${EXPDIR}/config.resources" oceanice_products +export write_grib2=False +export write_netcdf=False export OCEANICEPRODUCTS_CONFIG="${PARMgfs}/post/oceanice_products_${NET}.yaml" # Maximum number of rocoto tasks per member export MAX_TASKS=25 - echo "END: config.oceanice_products" diff --git a/dev/parm/config/gefs/config.stage_ic.j2 b/dev/parm/config/gefs/config.stage_ic.j2 index 4d6514cf9f4..8693fc170c8 100644 --- a/dev/parm/config/gefs/config.stage_ic.j2 +++ b/dev/parm/config/gefs/config.stage_ic.j2 @@ -11,7 +11,7 @@ export ICSDIR="{{ ICSDIR }}" # User provided ICSDIR; blank if not provided export BASE_IC="{{ BASE_IC }}" # Platform home for staged ICs if [[ ${RUN} == "gefs" ]] ; then - if [[ ${GEFSTYPE} = "near-real-time" ]] ; then + if [[ ${GEFSTYPE} = "gefs-real-time" ]] ; then export STAGE_IC_YAML_TMPL="${PARMgfs}/stage/master_gefs_RT.yaml.j2" elif [[ ${GEFSTYPE} = "gefs-offline" ]] ; then export STAGE_IC_YAML_TMPL="${PARMgfs}/stage/master_gefs.yaml.j2" diff --git a/dev/parm/config/gefs/config.ufs b/dev/parm/config/gefs/config.ufs index 04924ab1283..33c06d70d0a 100644 --- a/dev/parm/config/gefs/config.ufs +++ b/dev/parm/config/gefs/config.ufs @@ -311,7 +311,7 @@ if [[ "${skip_mom6}" == "false" ]]; then TOPOEDITS="ufs.topo_edits_011818.nc" case ${RUN} in gfs|gefs|sfs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) @@ -339,7 +339,7 @@ if [[ "${skip_mom6}" == "false" ]]; then eps_imesh="1.0e-1" case ${RUN} in gfs|gefs|sfs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) @@ -368,7 +368,7 @@ if [[ "${skip_mom6}" == "false" ]]; then eps_imesh="1.0e-1" case ${RUN} in gfs|gefs|sfs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) diff --git a/dev/parm/config/gefs/yaml/defaults.yaml b/dev/parm/config/gefs/yaml/defaults.yaml index e20890d5582..b302a8bf30b 100644 --- a/dev/parm/config/gefs/yaml/defaults.yaml +++ b/dev/parm/config/gefs/yaml/defaults.yaml @@ -29,6 +29,8 @@ fcst: MONO: "non-mono" ocn: MOM6_INTERP_ICS: "NO" +nsst: + NST_SPINUP: 0 # config.aero has just a system-specific path to add. # This is handled by the setup_expt.py, but it has to be told to write to it. aero: {} diff --git a/dev/parm/config/gfs/config.atmanl.j2 b/dev/parm/config/gfs/config.atmanl.j2 index d0e0e8d0f88..29e7279bd63 100644 --- a/dev/parm/config/gfs/config.atmanl.j2 +++ b/dev/parm/config/gfs/config.atmanl.j2 @@ -19,11 +19,14 @@ export BIAS_FILES_YAML="${PARMgfs}/gdas/atm/atm_bias_files.yaml.j2" export LOCALIZATION_TYPE="bump" -if [[ ${DOHYBVAR} = "YES" ]]; then - # shellcheck disable=SC2153 - export CASE_ANL=${CASE_ENS} -else - export CASE_ANL=${CASE} +export CASE_GSIBEC=${CASE_ANL} +if [[ "${DOHYBVAR}" = "YES" && "${ATMINC_GRID}" = "gaussian" ]]; then + export CASE_GSIBEC=${CASE_HIST} + export CASE_HIST=${CASE_ANL} fi +export NUMBER_OUTER_LOOPS="{{ NUMBER_OUTER_LOOPS | default() }}" +export NINNER_LOOP1="{{ NINNER_LOOP1 | default () }}" +export NINNER_LOOP2="{{ NINNER_LOOP2 | default () }}" + echo "END: config.atmanl" diff --git a/dev/parm/config/gfs/config.base.j2 b/dev/parm/config/gfs/config.base.j2 index caeeb9b9a6c..a624674aceb 100644 --- a/dev/parm/config/gfs/config.base.j2 +++ b/dev/parm/config/gfs/config.base.j2 @@ -51,6 +51,8 @@ export PACKAGEROOT="{{ PACKAGEROOT }}" # TODO: set via prod_envir in Ops export COMROOT="{{ COMROOT }}" # TODO: set via prod_envir in Ops export COMINsyn="{{ COMINsyn }}" export DMPDIR="{{ DMPDIR }}" +export IODADIR="{{ IODADIR }}" +export USE_IODADIR="{{ USE_IODADIR }}" # Gempak from external models # Default locations are to dummy locations for testing @@ -142,8 +144,6 @@ source "${EXPDIR}/config.com" export LOGSCRIPT=${LOGSCRIPT:-""} #export LOGSCRIPT=${LOGSCRIPT:-"startmsg"} -export REDOUT="1>" -export REDERR="2>" export SENDECF=${SENDECF:-"NO"} export SENDSDM=${SENDSDM:-"NO"} @@ -205,6 +205,7 @@ export OPS_RES="C768" # Do not change # TODO: Why is this needed and where is it export LEVS=128 export CASE="{{ CASE_CTL }}" export CASE_ENS="{{ CASE_ENS }}" +export CASE_ANL="{{ CASE_ANL | default('${CASE}') }}" export CASE_HIST="{{ CASE_HIST | default('${CASE}') }}" export OCNRES="{{ OCNRES }}" export ICERES="${OCNRES}" @@ -526,4 +527,13 @@ export OFFSET_START_HOUR=0 # Number of regional collectives to create soundings for export NUM_SND_COLLECTIVES=${NUM_SND_COLLECTIVES:-9} +# Set JEDI atmospheric DA increment type +if [[ "${DO_JEDIATMVAR}" == "YES" ]]; then + if [[ "${DO_JEDIATMENS}" == "YES" ]]; then + export ATMINC_GRID="cubed_sphere_grid" + else + export ATMINC_GRID="gaussian" + fi +fi + echo "END: config.base" diff --git a/dev/parm/config/gfs/config.cleanup b/dev/parm/config/gfs/config.cleanup index 543d624caf2..a4af66b493d 100644 --- a/dev/parm/config/gfs/config.cleanup +++ b/dev/parm/config/gfs/config.cleanup @@ -9,22 +9,40 @@ source "${EXPDIR}/config.resources" cleanup export CLEANUP_COM="YES" # NO=retain ROTDIR. YES default in cleanup.sh #--starting and ending hours of previous cycles to be removed from rotating directory -export RMOLDSTD=144 -export RMOLDEND=24 +# RUN-based cleanup variables +# Keep all files newer than SELECTIVE_CLEANUP_MIN hours +# Selectively remove files between SELECTIVE_CLEANUP_MAX and SELECTIVE_CLEANUP_MIN hours old, based on exclude_string +# Remove all GEMPAK files older than GEMPAK_CLEANUP hours if DO_GEMPAK is set to YES and only for RUN==gfs +# Remove **all** files and directories older than max(SELECTIVE_CLEANUP_MAX, GEMPAK_CLEANUP, RTOFS_CLEANUP) -if [[ "${DO_GEMPAK}" == "YES" && "${RUN}" == "gfs" ]]; then - export RMOLDSTD=346 - export RMOLDEND=222 +# RTOFS-specific variables (runs every RUN) +# Remove all RTOFS files older than RTOFS_CLEANUP hours + +export SELECTIVE_CLEANUP_MAX=144 +export SELECTIVE_CLEANUP_MIN=24 +export GEMPAK_CLEANUP=240 +export RTOFS_CLEANUP=24 +if [[ ${SELECTIVE_CLEANUP_MIN} -gt ${SELECTIVE_CLEANUP_MAX} ]]; then + echo "FATAL ERROR: Invalid selective cleanup times: " + echo " SELECTIVE_CLEANUP_MIN=${SELECTIVE_CLEANUP_MIN} > SELECTIVE_CLEANUP_MAX=${SELECTIVE_CLEANUP_MAX}" + exit 1 +fi + +# GEMPAK_CLEANUP must not be less than SELECTIVE_CLEANUP_MIN, which acts as the starting point for cleanup +if [[ "${DO_GEMPAK}" == "YES" && ${GEMPAK_CLEANUP} -lt ${SELECTIVE_CLEANUP_MIN} ]]; then + echo "FATAL ERROR: Invalid GEMPAK cleanup time: " + echo " GEMPAK_CLEANUP=${GEMPAK_CLEANUP} < SELECTIVE_CLEANUP_MIN=${SELECTIVE_CLEANUP_MIN}" + exit 2 fi # Specify the list of files to exclude from the first stage of cleanup # Because arrays cannot be exported, list is a single string of comma- # separated values. This string is split to form an array at runtime. +export selective_exclude_string="" case ${RUN} in - gdas | gfs) exclude_string="*prepbufr*, *cnvstat.tar*, *analysis.atm.a*.nc" ;; - enkf*) exclude_string="*f006.ens*" ;; - *) exclude_string="" ;; + gdas | gfs) selective_exclude_string+="*prepbufr*, *cnvstat.tar*, *analysis.atm.a*.nc" ;; + enkf*) selective_exclude_string+="*f006.ens*" ;; + *) selective_exclude_string="" ;; esac -export exclude_string echo "END: config.cleanup" diff --git a/dev/parm/config/gfs/config.com b/dev/parm/config/gfs/config.com index bba449b0db3..05615f256b5 100644 --- a/dev/parm/config/gfs/config.com +++ b/dev/parm/config/gfs/config.com @@ -37,22 +37,23 @@ echo "BEGIN: config.com" # shellcheck disable=SC2034 if [[ "${RUN_ENVIR:-emc}" == "nco" ]]; then COM_OBSPROC_TMPL=$(compath.py "${envir}/obsproc/${obsproc_ver}")'/${RUN}.${YMD}/${HH}/atmos' + COM_OBSFORGE_TMPL=$(compath.py "${envir}/obsforge/${obsforge_ver}")'/${RUN}.${YMD}/${HH}/' COM_RTOFS_TMPL=$(compath.py "${envir}/rtofs/${rtofs_ver}") COM_TCVITAL_TMPL=$(compath.py "${envir}/gfs/${gfs_ver}")'/${RUN}.${YMD}/${HH}/atmos' else COM_OBSPROC_TMPL='${DMPDIR}/${RUN}${DUMP_SUFFIX}.${YMD}/${HH}/atmos' + COM_OBSFORGE_TMPL='${IODADIR}/${RUN}${DUMP_SUFFIX}.${YMD}/${HH}' COM_RTOFS_TMPL='${DMPDIR}' COM_TCVITAL_TMPL='${DMPDIR}/${RUN}.${YMD}/${HH}/atmos' fi declare -rx COM_OBS_TMPL='${ROTDIR}/${RUN}.${YMD}/${HH}/obs' -declare -rx COM_OBSPROC_TMPL COM_RTOFS_TMPL +declare -rx COM_OBSPROC_TMPL COM_RTOFS_TMPL COM_OBSFORGE_TMPL COM_BASE='${ROTDIR}/${RUN}.${YMD}/${HH}/${MEMDIR}' declare -rx COM_TOP_TMPL='${ROTDIR}/${RUN}.${YMD}/${HH}' declare -rx COM_CONF_TMPL=${COM_BASE}'/conf' -declare -rx COM_OBS_JEDI=${COM_BASE}'/obs_jedi' declare -rx COM_ATMOS_INPUT_TMPL=${COM_BASE}'/model/atmos/input' declare -rx COM_ATMOS_RESTART_TMPL=${COM_BASE}'/model/atmos/restart' diff --git a/dev/parm/config/gfs/config.esfc b/dev/parm/config/gfs/config.esfc index 156649ace36..0c35240dc31 100644 --- a/dev/parm/config/gfs/config.esfc +++ b/dev/parm/config/gfs/config.esfc @@ -21,8 +21,8 @@ if [[ ${DOIAU_ENKF} = "YES" ]]; then export DOSFCANL_ENKF="NO" fi -# Turn off NST in JEDIATMENS -if [[ "${DO_JEDIATMENS}" == "YES" ]]; then +# Turn off NST in JEDIATMENS or JEDIATMVAR +if [[ "${DO_JEDIATMENS}" == "YES" || "${DO_JEDIATMVAR}" == "YES" ]]; then export DONST="NO" fi diff --git a/dev/parm/config/gfs/config.oceanice_products b/dev/parm/config/gfs/config.oceanice_products index 6cce26997ce..7f1d94bf0b9 100644 --- a/dev/parm/config/gfs/config.oceanice_products +++ b/dev/parm/config/gfs/config.oceanice_products @@ -10,6 +10,8 @@ source "${EXPDIR}/config.resources" oceanice_products # Maximum number of rocoto tasks per member export MAX_TASKS=25 +export write_grib2=False +export write_netcdf=False export OCEANICEPRODUCTS_CONFIG="${PARMgfs}/post/oceanice_products_gfs.yaml" # No. of forecast hours to process in a single job diff --git a/dev/parm/config/gfs/config.prep b/dev/parm/config/gfs/config.prep.j2 similarity index 88% rename from dev/parm/config/gfs/config.prep rename to dev/parm/config/gfs/config.prep.j2 index c10e5012e76..a8b8f0c619a 100644 --- a/dev/parm/config/gfs/config.prep +++ b/dev/parm/config/gfs/config.prep.j2 @@ -65,4 +65,11 @@ else export DTYPS_nsst='sfcshp dbuoyb mbuoyb tesac bathy trkob' fi +# Set flags to optionally use external bias correction files +# TODO: remove when JEDI can cycle bias correcdtion files +export SOURCE_BIASCOR="{{ SOURCE_BIASCOR }}" +export COPY_BIASCOR_SOURCE="{{ COPY_BIASCOR_SOURCE }}" +export COPY_BIASCOR_STATIC="{{ COPY_BIASCOR_STATIC }}" +export CONVERT_BIASCOR="{{ CONVERT_BIASCOR }}" + echo "END: config.prep" diff --git a/dev/parm/config/gfs/config.prepatmiodaobs b/dev/parm/config/gfs/config.prepatmiodaobs deleted file mode 100644 index e29cf67b070..00000000000 --- a/dev/parm/config/gfs/config.prepatmiodaobs +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env bash - -########## config.prepatmiodaobs ########## -# Atm Obs Prep specific - -echo "BEGIN: config.prepatmiodaobs" - -# Get task specific resources -. "${EXPDIR}/config.resources" prepatmiodaobs - -echo "END: config.prepatmiodaobs" diff --git a/dev/parm/config/gfs/config.prepobsaero b/dev/parm/config/gfs/config.prepobsaero deleted file mode 100644 index 237238809e3..00000000000 --- a/dev/parm/config/gfs/config.prepobsaero +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -x - -########## config.prepobsaero ########## -# Prepare and thin/superob aerosol observations - -echo "BEGIN: config.prepobsaero" - -# Get task specific resources -source "${EXPDIR}/config.resources" prepobsaero - -export OBSPROCYAML="${PARMgfs}/gdas/aero/obs/lists/gdas_aero_obsproc.yaml.j2" -export OBSPROCEXE="${EXECgfs}/gdas_ioda_obsprovider2ioda.x" -export VIIRS_DATA_DIR="/scratch2/NCEPDEV/stmp3/Yaping.Wang/VIIRS/AWS/" -export SENSORS="npp,n20" - - -echo "END: config.prepaeroobs" diff --git a/dev/parm/config/gfs/config.resources b/dev/parm/config/gfs/config.resources index 2f3829622eb..f2eb37465d0 100644 --- a/dev/parm/config/gfs/config.resources +++ b/dev/parm/config/gfs/config.resources @@ -12,11 +12,11 @@ if (( $# != 1 )); then echo "Must specify an input task argument to set resource variables!" echo "argument can be any one of the following:" echo "stage_ic aerosol_init fetch" - echo "prep prep_sfc prepatmiodaobs" + echo "prep prep_sfc" echo "atmanlinit atmanlvar atmanlfv3inc atmanlfinal" echo "atmensanlinit atmensanlobs atmensanlsol atmensanlletkf atmensanlfv3inc atmensanlfinal ecen_fv3jedi analcalc_fv3jedi" echo "snowanl esnowanl" - echo "prepobsaero aeroanlinit aeroanlvar aeroanlfinal aeroanlgenb" + echo "aeroanlinit aeroanlvar aeroanlfinal aeroanlgenb" echo "anal sfcanl analcalc analdiag anlstat fcst echgres" echo "upp atmos_products" echo "tracker genesis genesis_fsu" @@ -69,8 +69,7 @@ case ${machine} in export PARTITION_BATCH="compute" npe_node_max=48 max_tasks_per_node=48 - # TODO Supply a max mem/node value for AWS - mem_node_max="" + mem_node_max="192GB" ;; "AZUREPW") export PARTITION_BATCH="compute" @@ -116,13 +115,6 @@ case ${step} in memory="${mem_node_max}" ;; - "prepatmiodaobs") - walltime="00:30:00" - ntasks=1 - threads_per_task=1 - tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - ;; - "aerosol_init") walltime="00:05:00" ntasks=1 @@ -340,14 +332,6 @@ case ${step} in tasks_per_node=$(( max_tasks_per_node / threads_per_task )) ;; - "prepobsaero") - walltime="00:30:00" - ntasks=1 - threads_per_task=1 - tasks_per_node=1 - memory="96GB" - ;; - "aeroanlinit") # below lines are for creating JEDI YAML case "${CASE}" in @@ -773,12 +757,19 @@ case ${step} in fi ;; - "analdiag") + "analdiag" | "ediag") walltime="00:15:00" ntasks=96 # Should be at least twice ediag's tasks + memory="48GB" + #if [[ "${step}" == "ediag" ]]; then + # ntasks=48 + #fi threads_per_task=1 + if [[ ${ntasks} -gt ${max_tasks_per_node} ]]; then + ntasks=${max_tasks_per_node} + export is_exclusive=True + fi tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - memory="48GB" ;; "anlstat") @@ -868,7 +859,7 @@ case ${step} in MEDTHREADS=${nthreads_mediator:-1} MEDPETS=${MEDPETS:-${FV3PETS}} (( MEDPETS = FV3PETS )) - (( MEDTHREADS = FV3THREADS )) + (( MEDTHREADS = FV3THREADS )) (( "${MEDPETS}" > 4800 )) && MEDPETS=4800 export MEDPETS MEDTHREADS echo "MEDIATOR using (threads, PETS) = (${MEDTHREADS}, ${MEDPETS})" @@ -994,7 +985,7 @@ case ${step} in ;; "upp") - #ntasks cannot be greater than $CASE_HIST + #ntasks cannot be greater than $CASE_HIST #define resources based on $CASE_HIST for upp case "${CASE_HIST}" in "C48" | "C96") @@ -1270,14 +1261,6 @@ case ${step} in fi ;; - "ediag") - walltime="00:15:00" - ntasks=48 - threads_per_task=1 - tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - memory="30GB" - ;; - "eupd") walltime="00:45:00" case "${CASE}" in @@ -1395,7 +1378,7 @@ case ${step} in elif [[ "${RUN}" = *gfs ]]; then ntasks=28 tasks_per_node=28 - memory="4GB" + memory="6GB" fi ;; diff --git a/dev/parm/config/gfs/config.resources.AWSPW b/dev/parm/config/gfs/config.resources.AWSPW index c76f50bf0ce..45b19dd296f 100644 --- a/dev/parm/config/gfs/config.resources.AWSPW +++ b/dev/parm/config/gfs/config.resources.AWSPW @@ -68,7 +68,7 @@ case ${step} in "esfc") export is_exclusive="True" - export tasks_per_node=40 + export tasks_per_node=${max_tasks_per_node} ;; "upp") diff --git a/dev/parm/config/gfs/config.resources.WCOSS2 b/dev/parm/config/gfs/config.resources.WCOSS2 index 2c7161e8d87..042317ac3bc 100644 --- a/dev/parm/config/gfs/config.resources.WCOSS2 +++ b/dev/parm/config/gfs/config.resources.WCOSS2 @@ -35,7 +35,7 @@ case ${step} in ;; "arch_vrfy" | "arch_tars" | "earc_vrfy" | "earc_tars" | "getic") - declare -x "memory"="10GB" + declare -x "memory"="3GB" ;; "eupd") diff --git a/dev/parm/config/gfs/config.ufs b/dev/parm/config/gfs/config.ufs index 6c883d66bf7..411b0461b46 100644 --- a/dev/parm/config/gfs/config.ufs +++ b/dev/parm/config/gfs/config.ufs @@ -451,7 +451,7 @@ if [[ "${skip_mom6}" == "false" ]]; then TOPOEDITS="ufs.topo_edits_011818.nc" case ${RUN} in gfs|gefs|sfs|gcafs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) @@ -479,7 +479,7 @@ if [[ "${skip_mom6}" == "false" ]]; then eps_imesh="1.0e-1" case ${RUN} in gfs|gefs|sfs|gcafs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) @@ -516,7 +516,7 @@ if [[ "${skip_mom6}" == "false" ]]; then eps_imesh="1.0e-1" case ${RUN} in gfs|gefs|sfs|gcafs) - MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_40L.nc" + MOM6_DIAG_COORD_DEF_Z_FILE="interpolate_zgrid_30L.nc" MOM6_DIAG_MISVAL="-1e34" ;; gdas|enkfgdas|enkfgfs) diff --git a/dev/parm/config/sfs/config.base.j2 b/dev/parm/config/sfs/config.base.j2 index 32a26ab5f8a..860f892ce15 100644 --- a/dev/parm/config/sfs/config.base.j2 +++ b/dev/parm/config/sfs/config.base.j2 @@ -110,8 +110,6 @@ source "${EXPDIR}/config.com" export LOGSCRIPT=${LOGSCRIPT:-""} #export LOGSCRIPT=${LOGSCRIPT:-"startmsg"} -export REDOUT="1>" -export REDERR="2>" export SENDECF=${SENDECF:-"NO"} export SENDSDM=${SENDSDM:-"NO"} @@ -318,23 +316,8 @@ export DO_METP="NO" # Run METPLUS jobs - set METPLUS settings in config. export DO_FIT2OBS="NO" # Run fit to observations package # Archiving options -export HPSSARCH="{{ HPSSARCH }}" # save data to HPSS archive -export LOCALARCH="{{ LOCALARCH }}" # save data to local archive -if [[ ${HPSSARCH} = "YES" ]] && [[ ${LOCALARCH} = "YES" ]]; then - echo "Both HPSS and local archiving selected. Please choose one or the other." - exit 3 -elif [[ ${HPSSARCH} = "YES" ]] || [[ ${LOCALARCH} = "YES" ]]; then - export DO_ARCHCOM="YES" -else - export DO_ARCHCOM="NO" -fi -export ARCH_CYC=00 # Archive data at this cycle for warm start and/or forecast-only capabilities -export ARCH_WARMICFREQ=4 # Archive frequency in days for warm start capability -export ARCH_FCSTICFREQ=1 # Archive frequency in days for gdas and gfs forecast-only capability -export ARCH_EXPDIR='YES' # Archive the EXPDIR configs, XML, and database -export ARCH_EXPDIR_FREQ=0 # How often to archive the EXPDIR in hours or 0 for first and last cycle only -export ARCH_HASHES='YES' # Archive the hashes of the GW and submodules and 'git status' for each; requires ARCH_EXPDIR -export ARCH_DIFFS='NO' # Archive the output of 'git diff' for the GW; requires ARCH_EXPDIR +export DO_ARCHCOM="NO" # Tar and archive the COM directories +export ARCHCOM_TO="{{ ARCHCOM_TO }}" # Valid options are hpss, globus_hpss, and local # Number of regional collectives to create soundings for export NUM_SND_COLLECTIVES=${NUM_SND_COLLECTIVES:-9} diff --git a/dev/parm/config/sfs/config.nsst b/dev/parm/config/sfs/config.nsst deleted file mode 120000 index 3a015c1d65f..00000000000 --- a/dev/parm/config/sfs/config.nsst +++ /dev/null @@ -1 +0,0 @@ -../gefs/config.nsst \ No newline at end of file diff --git a/dev/parm/config/sfs/config.nsst.j2 b/dev/parm/config/sfs/config.nsst.j2 new file mode 100644 index 00000000000..137e785eb65 --- /dev/null +++ b/dev/parm/config/sfs/config.nsst.j2 @@ -0,0 +1,32 @@ +#! /usr/bin/env bash + +########## config.nsst ########## +# NSST specific + +echo "BEGIN: config.nsst" + +# NSST parameters contained within nstf_name + +# nstf_name(1) : NST_MODEL (NSST Model) : 0 = OFF, 1 = ON but uncoupled, 2 = ON and coupled +export NST_MODEL=2 + +# nstf_name(2) : NST_SPINUP : 0 = OFF, 1 = ON, +export NST_SPINUP="{{ NST_SPINUP }}" + +# nstf_name(3) : NST_RESV (Reserved, NSST Analysis) : 0 = OFF, 1 = ON +export NST_RESV=0 + +# nstf_name(4,5) : ZSEA1, ZSEA2 the two depths to apply vertical average (bias correction) +export ZSEA1=0 +export ZSEA2=0 + +export NST_GSI=3 # default 0: No NST info at all; + # 1: Input NST info but not used in GSI; + # 2: Input NST info, used in CRTM simulation, no Tr analysis + # 3: Input NST info, used in both CRTM simulation and Tr analysis +export NSTINFO=0 # number of elements added in obs. data array (default = 0) +if [[ ${NST_GSI} -gt 0 ]]; then + export NSTINFO=4 +fi + +echo "END: config.nsst" diff --git a/dev/parm/config/sfs/yaml/defaults.yaml b/dev/parm/config/sfs/yaml/defaults.yaml index c322c9a0142..305183fdf88 100644 --- a/dev/parm/config/sfs/yaml/defaults.yaml +++ b/dev/parm/config/sfs/yaml/defaults.yaml @@ -29,6 +29,8 @@ fcst: MONO: "mono" ocn: MOM6_INTERP_ICS: "NO" +nsst: + NST_SPINUP: 0 # config.aero has just a system-specific path to add. # This is handled by the setup_expt.py, but it has to be told to write to it. aero: {} diff --git a/scripts/exgdas_aero_analysis_generate_bmatrix.py b/dev/scripts/exgdas_aero_analysis_generate_bmatrix.py similarity index 100% rename from scripts/exgdas_aero_analysis_generate_bmatrix.py rename to dev/scripts/exgdas_aero_analysis_generate_bmatrix.py diff --git a/scripts/exgdas_atmos_chgres_forenkf.sh b/dev/scripts/exgdas_atmos_chgres_forenkf.sh similarity index 51% rename from scripts/exgdas_atmos_chgres_forenkf.sh rename to dev/scripts/exgdas_atmos_chgres_forenkf.sh index 04e720d3e64..f51be67b285 100755 --- a/scripts/exgdas_atmos_chgres_forenkf.sh +++ b/dev/scripts/exgdas_atmos_chgres_forenkf.sh @@ -26,9 +26,10 @@ GDUMP=${GDUMP:-"gdas"} # Derived base variables # shellcheck disable=SC2153 GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") +export GDATE BDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - 3 hours") -bPDY=${BDATE:0:8} -bcyc=${BDATE:8:2} +export bPDY=${BDATE:0:8} +export bcyc=${BDATE:8:2} # Utilities export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} @@ -73,111 +74,80 @@ DOHYBVAR=${DOHYBVAR:-"NO"} lrun_subdirs=${lrun_subdirs:-".true."} USE_CFP=${USE_CFP:-"NO"} CFP_MP=${CFP_MP:-"NO"} -nm="" -if [ $CFP_MP = "YES" ]; then - nm=0 -fi -if [ $DOHYBVAR = "YES" ]; then - l_hyb_ens=.true. - export l4densvar=${l4densvar:-".false."} - export lwrite4danl=${lwrite4danl:-".false."} + +if [[ "${DOHYBVAR}" == "YES" ]]; then + export l_hyb_ens=.true. + export l4densvar=${l4densvar:-".false."} + export lwrite4danl=${lwrite4danl:-".false."} else - echo "DOHYBVAR != YES, this script will exit without regridding deterministic forecast" - exit 0 + echo "DOHYBVAR != YES, this script will exit without regridding deterministic forecast" + exit 0 fi ################################################################################ ################################################################################ # get resolution information -LONB_ENKF=${LONB_ENKF:-$($NCLEN $ATMFCST_ENSRES grid_xt)} # get LONB_ENKF -LATB_ENKF=${LATB_ENKF:-$($NCLEN $ATMFCST_ENSRES grid_yt)} # get LATB_ENFK -LEVS_ENKF=${LEVS_ENKF:-$($NCLEN $ATMFCST_ENSRES pfull)} # get LATB_ENFK +LONB_ENKF=${LONB_ENKF:-$(${NCLEN} "${ATMFCST_ENSRES}" grid_xt)} # get LONB_ENKF +LATB_ENKF=${LATB_ENKF:-$(${NCLEN} "${ATMFCST_ENSRES}" grid_yt)} # get LATB_ENFK +LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} "${ATMFCST_ENSRES}" pfull)} # get LATB_ENFK ############################################################## # If analysis increment is written by GSI, regrid forecasts to increment resolution -if [ $DO_CALC_ANALYSIS == "YES" ]; then - $NLN $ATMF06 fcst.06 - $NLN $ATMF06ENS fcst.ensres.06 - $NLN $ATMFCST_ENSRES atmens_fcst - if [ $DOHYBVAR = "YES" -a $l4densvar = ".true." -a $lwrite4danl = ".true." ]; then - $NLN $ATMF03 fcst.03 - $NLN $ATMF03ENS fcst.ensres.03 - $NLN $ATMF04 fcst.04 - $NLN $ATMF04ENS fcst.ensres.04 - $NLN $ATMF05 fcst.05 - $NLN $ATMF05ENS fcst.ensres.05 - $NLN $ATMF07 fcst.07 - $NLN $ATMF07ENS fcst.ensres.07 - $NLN $ATMF08 fcst.08 - $NLN $ATMF08ENS fcst.ensres.08 - $NLN $ATMF09 fcst.09 - $NLN $ATMF09ENS fcst.ensres.09 - fi - export OMP_NUM_THREADS=$NTHREADS_CHGRES - SIGLEVEL=${SIGLEVEL:-${FIXgfs}/am/global_hyblev.l${LEVS_ENKF}.txt} - - if [[ "${USE_CFP}" == "YES" ]]; then - rm -f "${DATA}/mp_chgres.sh" - fi - - nfhrs=$(echo "${IAUFHRS_ENKF}" | sed 's/,/ /g') - for FHR in $nfhrs; do - echo "Regridding deterministic forecast for forecast hour $FHR" - rm -f chgres_nc_gauss0$FHR.nml -cat > chgres_nc_gauss0$FHR.nml << EOF +if [[ ${DO_CALC_ANALYSIS} == "YES" ]]; then + ${NLN} "${ATMF06}" fcst.06 + ${NLN} "${ATMF06ENS}" fcst.ensres.06 + ${NLN} "${ATMFCST_ENSRES}" atmens_fcst + if [[ "${DOHYBVAR}" == "YES" ]] && [[ "${l4densvar}" == ".true." ]] && [[ "${lwrite4danl}" == ".true." ]]; then + ${NLN} "${ATMF03}" fcst.03 + ${NLN} "${ATMF03ENS}" fcst.ensres.03 + ${NLN} "${ATMF04}" fcst.04 + ${NLN} "${ATMF04ENS}" fcst.ensres.04 + ${NLN} "${ATMF05}" fcst.05 + ${NLN} "${ATMF05ENS}" fcst.ensres.05 + ${NLN} "${ATMF07}" fcst.07 + ${NLN} "${ATMF07ENS}" fcst.ensres.07 + ${NLN} "${ATMF08}" fcst.08 + ${NLN} "${ATMF08ENS}" fcst.ensres.08 + ${NLN} "${ATMF09}" fcst.09 + ${NLN} "${ATMF09ENS}" fcst.ensres.09 + fi + export OMP_NUM_THREADS=${NTHREADS_CHGRES} + SIGLEVEL=${SIGLEVEL:-${FIXgfs}/am/global_hyblev.l${LEVS_ENKF}.txt} + + if [[ "${USE_CFP}" == "YES" ]]; then + rm -f "${DATA}/mp_chgres.sh" + fi + + nfhrs="${IAUFHRS_ENKF//,/ }" + for FHR in ${nfhrs}; do + echo "Regridding deterministic forecast for forecast hour ${FHR}" + rm -f "chgres_nc_gauss0${FHR}.nml" + cat > "chgres_nc_gauss0${FHR}.nml" << EOF &chgres_setup -i_output=$LONB_ENKF -j_output=$LATB_ENKF -input_file="fcst.0$FHR" -output_file="fcst.ensres.0$FHR" -terrain_file="atmens_fcst" -ref_file="atmens_fcst" + i_output=${LONB_ENKF} + j_output=${LATB_ENKF} + input_file="fcst.0${FHR}" + output_file="fcst.ensres.0${FHR}" + terrain_file="atmens_fcst" + ref_file="atmens_fcst" / EOF - if [[ $USE_CFP == "YES" ]]; then - echo "$nm $APRUN_CHGRES $CHGRESNCEXEC chgres_nc_gauss0$FHR.nml" | tee -a $DATA/mp_chgres.sh - if [[ ${CFP_MP:-"NO"} = "YES" ]]; then - nm=$((nm+1)) - fi - else - - export pgm=$CHGRESNCEXEC - . prep_step - - ${APRUN_CHGRES} "${CHGRESNCEXEC}" "chgres_nc_gauss0${FHR}.nml" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit - fi - fi - done - - if [[ ${USE_CFP} == "YES" ]]; then - chmod 755 ${DATA}/mp_chgres.sh - ncmd=$(wc -l < "${DATA}/mp_chgres.sh") - if [[ ${ncmd} -gt 0 ]]; then - ncmd_max=$((ncmd < max_tasks_per_node ? ncmd : max_tasks_per_node)) - APRUNCFP_CHGRES=$(eval echo "${APRUNCFP}") - - export pgm=${CHGRESNCEXEC} - source prep_step - - ${APRUNCFP_CHGRES} "${DATA}/mp_chgres.sh" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit - fi - fi - fi + echo "${APRUN_CHGRES} ${CHGRESNCEXEC} chgres_nc_gauss0${FHR}.nml" | tee -a "${DATA}/mp_chgres.sh" + + done + + # Run with MPMD + "${USHgfs}/run_mpmd.sh" "${DATA}/mp_chgres.sh" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit + fi else - echo "DO_CALC_ANALYSIS != YES, doing nothing" + echo "DO_CALC_ANALYSIS != YES, doing nothing" fi +cd "${pwd}" || exit -################################################################################ -# Postprocessing -cd $pwd - -exit $err +exit "${err}" diff --git a/scripts/exgdas_atmos_gempak_gif_ncdc.sh b/dev/scripts/exgdas_atmos_gempak_gif_ncdc.sh similarity index 86% rename from scripts/exgdas_atmos_gempak_gif_ncdc.sh rename to dev/scripts/exgdas_atmos_gempak_gif_ncdc.sh index 06c6f2ce496..aaa4072cc7f 100755 --- a/scripts/exgdas_atmos_gempak_gif_ncdc.sh +++ b/dev/scripts/exgdas_atmos_gempak_gif_ncdc.sh @@ -18,17 +18,17 @@ if [[ ${MODEL} == GDAS ]]; then export fhr3 for fhr3 in ${fcsthrs}; do gempak_file="${COMIN_ATMOS_GEMPAK_1p00}/${RUN}_1p00_${PDY}${cyc}f${fhr3}" - if ! wait_for_file "${gempak_file}" "${sleep_interval}" "${max_tries}" ; then + if ! wait_for_file "${gempak_file}" "${sleep_interval}" "${max_tries}"; then export err=10 if [[ ${err} -ne 0 ]]; then - err_exit "${gempak_file} not found after ${max_tries} iterations" + err_exit "${gempak_file} not found after ${max_tries} iterations" fi fi if [[ ! -f "${gempak_file}" ]]; then export err=1 if [[ ${err} -ne 0 ]]; then - err_exit "Could not copy ${gempak_file}" + err_exit "Could not copy ${gempak_file}" fi fi @@ -37,7 +37,7 @@ if [[ ${MODEL} == GDAS ]]; then "${HOMEgfs}/gempak/ush/gempak_${RUN}_f${fhr3}_gif.sh" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit + err_exit fi done fi diff --git a/scripts/exgdas_atmos_nawips.sh b/dev/scripts/exgdas_atmos_nawips.sh similarity index 76% rename from scripts/exgdas_atmos_nawips.sh rename to dev/scripts/exgdas_atmos_nawips.sh index 786b1c2b431..7bebb7766df 100755 --- a/scripts/exgdas_atmos_nawips.sh +++ b/dev/scripts/exgdas_atmos_nawips.sh @@ -18,11 +18,11 @@ cd "${DATA_RUN}" || exit 1 source "${USHgfs}/product_functions.sh" for table in g2varswmo2.tbl g2vcrdwmo2.tbl g2varsncep1.tbl g2vcrdncep1.tbl; do - source_table="${HOMEgfs}/gempak/fix/${table}" - if [[ ! -f "${source_table}" ]]; then - err_exit "${table} is missing" - fi - cpreq "${source_table}" "${table}" + source_table="${HOMEgfs}/gempak/fix/${table}" + if [[ ! -f "${source_table}" ]]; then + err_exit "${table} is missing" + fi + cpreq "${source_table}" "${table}" done NAGRIB="${GEMEXE}/nagrib2" @@ -37,15 +37,13 @@ proj= output=T pdsext=no - - GEMGRD="${RUN}_${grid}_${PDY}${cyc}f${fhr3}" source_dirvar="COMOUT_ATMOS_GRIB_${grid}" export GRIBIN="${!source_dirvar}/${RUN}.${cycle}.pres_a.${grid}.f${fhr3}.grib2" GRIBIN_chk="${GRIBIN}.idx" if [[ ! -r "${GRIBIN_chk}" ]]; then - err_exit "GRIB index file ${GRIBIN_chk} not found!" + err_exit "GRIB index file ${GRIBIN_chk} not found!" fi cpreq "${GRIBIN}" "grib${fhr3}" @@ -73,13 +71,13 @@ EOF export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "${NAGRIB} failed to create ${GEMGRD}!" + err_exit "${NAGRIB} failed to create ${GEMGRD}!" fi cpfs "${GEMGRD}" "${destination}/${GEMGRD}" -if [[ "${SENDDBN}" == "YES" ]] ; then - "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" \ - "${destination}/${GEMGRD}" +if [[ "${SENDDBN}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" \ + "${destination}/${GEMGRD}" fi "${GEMEXE}/gpend" diff --git a/dev/scripts/exgdas_atmos_verfozn.sh b/dev/scripts/exgdas_atmos_verfozn.sh new file mode 100755 index 00000000000..e6f3a369da8 --- /dev/null +++ b/dev/scripts/exgdas_atmos_verfozn.sh @@ -0,0 +1,43 @@ +#! /usr/bin/env bash + +################################################################################ +# exgdas_atmos_verfozn.sh +# +# This script runs the data extract/validation portion of the Ozone Monitor +# (OznMon) DA package. +# +################################################################################ +export err=0 + +if [[ -s "${oznstat}" ]]; then + #------------------------------------------------------------------ + # Copy data files file to local data directory. + # Untar oznstat file. + #------------------------------------------------------------------ + + cpreq "${oznstat}" "./oznstat.${PDY}${cyc}" + + tar -xvf "oznstat.${PDY}${cyc}" + rm -f "oznstat.${PDY}${cyc}" + + netcdf=0 + for filenc4 in diag*nc4.gz; do + netcdf=1 + file=$(echo "${filenc4}" | cut -d'.' -f1-2).gz + mv "${filenc4}" "${file}" + done + + export OZNMON_NETCDF=${netcdf} + + "${USHgfs}/ozn_xtrct.sh" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "ozn_xtrct.sh failed!" + fi + +else + # oznstat file not found + export err=1 + err_exit "${oznstat} does not exist!" +fi +exit 0 diff --git a/scripts/exgdas_atmos_verfrad.sh b/dev/scripts/exgdas_atmos_verfrad.sh similarity index 63% rename from scripts/exgdas_atmos_verfrad.sh rename to dev/scripts/exgdas_atmos_verfrad.sh index aece88c12a9..7fe7dbc0934 100755 --- a/scripts/exgdas_atmos_verfrad.sh +++ b/dev/scripts/exgdas_atmos_verfrad.sh @@ -20,9 +20,9 @@ # Do not exit on errors so that restricted data can be protected set +eu -if [[ ! -s ${radstat} || ! -s ${biascr} ]]; then - export err=1 - err_exit "Required data files ${radstat} and/or ${biascr} are missing!!" +if [[ ! -s "${radstat}" || ! -s "${biascr}" ]]; then + export err=1 + err_exit "Required data files ${radstat} and/or ${biascr} are missing!!" fi #------------------------------------------------------------------ @@ -30,7 +30,7 @@ fi # Untar radstat file. #------------------------------------------------------------------ -cpreq "${biascr}" "./biascr.${PDY}${cyc}" +cpreq "${biascr}" "./biascr.${PDY}${cyc}" cpreq "${radstat}" "./radstat.${PDY}${cyc}" tar -xvf "radstat.${PDY}${cyc}" @@ -44,9 +44,10 @@ rm "radstat.${PDY}${cyc}" # new sources to the list before writing back out. #------------------------------------------------------------------ -radstat_satype=$(ls d*ges* | awk -F_ '{ print $2 "_" $3 }') -if [[ "${VERBOSE}" = "YES" ]]; then - echo "${radstat_satype}" +radstat_files=$(find ./ -name 'd*ges*') +radstat_satype=$(awk -F_ '{ print $2 "_" $3 }' <<< "${radstat_files}") +if [[ "${VERBOSE}" == "YES" ]]; then + echo "${radstat_satype}" fi echo satype_file = "${satype_file}" @@ -57,14 +58,15 @@ echo satype_file = "${satype_file}" # the cycle being processed is 00z. #------------------------------------------------------------------ if [[ ${cyc} = "00" ]]; then - use_tankdir=${TANKverf_radM1} + use_tankdir=${TANKverf_radM1} else - use_tankdir=${TANKverf_rad} + use_tankdir=${TANKverf_rad} fi +export use_tankdir echo satype_file = "${satype_file}" -export SATYPE=$(cat "${satype_file}") - +SATYPE=$(cat "${satype_file}") +export SATYPE #------------------------------------------------------------- # Update the SATYPE if any new sat/instrument was @@ -74,19 +76,19 @@ export SATYPE=$(cat "${satype_file}") satype_changes=0 new_satype=${SATYPE} for type in ${radstat_satype}; do - type_count=$(echo "${SATYPE}" | grep "${type}" | wc -l) - - if [[ ${type_count} -eq 0 ]]; then - if [[ "${VERBOSE}" = "YES" ]]; then - echo "Found ${type} in radstat file but not in SATYPE list. Adding it now." - fi - satype_changes=1 - new_satype="${new_satype} ${type}" - fi + type_count=$(grep -c "${type}" <<< "${SATYPE}") + + if [[ ${type_count} -eq 0 ]]; then + if [[ "${VERBOSE}" = "YES" ]]; then + echo "Found ${type} in radstat file but not in SATYPE list. Adding it now." + fi + satype_changes=1 + new_satype="${new_satype} ${type}" + fi done if [[ ${satype_changes} -eq 1 ]]; then - SATYPE=${new_satype} + SATYPE=${new_satype} fi #------------------------------------------------------------------ @@ -96,31 +98,32 @@ netcdf=0 for type in ${SATYPE}; do - if [[ ${netcdf} -eq 0 && -e "diag_${type}_ges.${PDY}${cyc}.nc4.${Z}" ]]; then - netcdf=1 - fi - - if [[ $(find . -maxdepth 1 -type f -name "diag_${type}_ges.${PDY}${cyc}*.${Z}" | wc -l) -gt 0 ]]; then - mv "diag_${type}_ges.${PDY}${cyc}"*".${Z}" "${type}.${Z}" - ${UNCOMPRESS} "./${type}.${Z}" - else - echo "WARNING: diag_${type}_ges.${PDY}${cyc}*.${Z} not available, skipping" - fi - - if [[ ${USE_ANL} -eq 1 ]]; then - file_count=$(find . -maxdepth 1 -type f -name "diag_${type}_anl.${PDY}${cyc}*.${Z}" | wc -l) - if [[ ${file_count} -gt 0 ]]; then - mv "diag_${type}_anl.${PDY}${cyc}"*".${Z}" "${type}_anl.${Z}" - ${UNCOMPRESS} "./${type}_anl.${Z}" - else - echo "WARNING: diag_${type}_anl.${PDY}${cyc}*.${Z} not available, skipping" - fi - fi + if [[ ${netcdf} -eq 0 && -e "diag_${type}_ges.${PDY}${cyc}.nc4.${Z}" ]]; then + netcdf=1 + fi + + # shellcheck disable=SC2312 + if [[ $(find . -maxdepth 1 -type f -name "diag_${type}_ges.${PDY}${cyc}*.${Z}" | wc -l) -gt 0 ]]; then + mv "diag_${type}_ges.${PDY}${cyc}"*".${Z}" "${type}.${Z}" + ${UNCOMPRESS} "./${type}.${Z}" + else + echo "WARNING: diag_${type}_ges.${PDY}${cyc}*.${Z} not available, skipping" + fi + + if [[ ${USE_ANL} -eq 1 ]]; then + # shellcheck disable=SC2312 + file_count=$(find . -maxdepth 1 -type f -name "diag_${type}_anl.${PDY}${cyc}*.${Z}" | wc -l) + if [[ ${file_count} -gt 0 ]]; then + mv "diag_${type}_anl.${PDY}${cyc}"*".${Z}" "${type}_anl.${Z}" + ${UNCOMPRESS} "./${type}_anl.${Z}" + else + echo "WARNING: diag_${type}_anl.${PDY}${cyc}*.${Z} not available, skipping" + fi + fi done export RADMON_NETCDF=${netcdf} - #------------------------------------------------------------------ # Run the child scripts. #------------------------------------------------------------------ @@ -131,7 +134,7 @@ rc_angle=$? # Allow all scripts to run. Call err_exit at the end, after files are restricted. if [[ ${rc_angle} -ne 0 ]]; then - echo "FATAL ERROR: radmon_verf_angle.sh failed!" + echo "FATAL ERROR: radmon_verf_angle.sh failed!" fi "${USHgfs}/radmon_verf_bcoef.sh" && true @@ -139,7 +142,7 @@ rc_bcoef=$? "${USHgfs}/rstprod.sh" if [[ ${rc_bcoef} -ne 0 ]]; then - echo "FATAL ERROR: radmon_verf_bcoef.sh failed!" + echo "FATAL ERROR: radmon_verf_bcoef.sh failed!" fi "${USHgfs}/radmon_verf_bcor.sh" && true @@ -147,7 +150,7 @@ rc_bcor=$? "${USHgfs}/rstprod.sh" if [[ ${rc_bcoef} -ne 0 ]]; then - echo "FATAL ERROR: radmon_verf_bcor.sh failed!" + echo "FATAL ERROR: radmon_verf_bcor.sh failed!" fi "${USHgfs}/radmon_verf_time.sh" && true @@ -155,7 +158,7 @@ rc_time=$? "${USHgfs}/rstprod.sh" if [[ ${rc_bcoef} -ne 0 ]]; then - echo "FATAL ERROR: radmon_verf_time.sh failed!" + echo "FATAL ERROR: radmon_verf_time.sh failed!" fi ##################################################################### @@ -164,7 +167,7 @@ fi export err=$((rc_angle + rc_bcoef + rc_bcor + rc_time)) if [[ ${err} -ne 0 ]]; then - err_exit "One or more radiance monitor subtasks failed!" + err_exit "One or more radiance monitor subtasks failed!" fi exit 0 diff --git a/dev/scripts/exgdas_enkf_post.sh b/dev/scripts/exgdas_enkf_post.sh new file mode 100755 index 00000000000..99b53593cf3 --- /dev/null +++ b/dev/scripts/exgdas_enkf_post.sh @@ -0,0 +1,169 @@ +#! /usr/bin/env bash + +################################################################################ +#### UNIX Script Documentation Block +# . . +# Script name: exgdas_enkf_post.sh +# Script description: Global ensemble forecast post processing +# +# Author: Rahul Mahajan Org: NCEP/EMC Date: 2017-03-02 +# +# Abstract: This script post-processes global ensemble forecast output +# +# $Id$ +# +# Attributes: +# Language: POSIX shell +# +################################################################################ + +# Directories. +pwd=$(pwd) + +APRUN_EPOS=${APRUN_EPOS:-${APRUN:-""}} +NTHREADS_EPOS=${NTHREADS_EPOS:-1} + +# Fix files +LEVS=${LEVS:-64} +HYBENSMOOTH=${HYBENSMOOTH:-${FIXgfs}/gsi/global_hybens_smoothinfo.l${LEVS}.txt} + +# Executables. +GETATMENSMEANEXEC=${GETATMENSMEANEXEC:-${EXECgfs}/getsigensmeanp_smooth.x} +GETSFCENSMEANEXEC=${GETSFCENSMEANEXEC:-${EXECgfs}/getsfcensmeanp.x} + +# Other variables. +PREFIX=${PREFIX:-""} +FHMIN=${FHMIN_EPOS:-3} +FHMAX=${FHMAX_EPOS:-9} +FHOUT=${FHOUT_EPOS:-3} + +if [[ "${RUN}" == "enkfgfs" ]]; then + NMEM_ENS=${NMEM_ENS_GFS:-${NMEM_ENS:-30}} +else + NMEM_ENS=${NMEM_ENS:-80} +fi +SMOOTH_ENKF=${SMOOTH_ENKF:-"NO"} +ENKF_SPREAD=${ENKF_SPREAD:-"NO"} + +################################################################################ +# Preprocessing +ENKF_SUFFIX="s" +if [[ "${SMOOTH_ENKF}" == "NO" ]]; then + ENKF_SUFFIX="" +fi + +################################################################################ +# Copy executables to working directory +cpreq "${GETSFCENSMEANEXEC}" "${DATA}" +cpreq "${GETATMENSMEANEXEC}" "${DATA}" + +export OMP_NUM_THREADS=${NTHREADS_EPOS} + +################################################################################ +# Forecast ensemble member files +for imem in $(seq 1 "${NMEM_ENS}"); do + memchar="mem"$(printf %03i "${imem}") + MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ + COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL + + for fhr in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + fhrchar=$(printf %03i "${fhr}") + ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.f${fhrchar}.nc" "sfcf${fhrchar}_${memchar}" + ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.f${fhrchar}.nc" "atmf${fhrchar}_${memchar}" + done +done + +# Forecast ensemble mean and smoothed files +MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ + COMOUT_ATMOS_HISTORY_STAT:COM_ATMOS_HISTORY_TMPL +if [[ ! -d "${COMOUT_ATMOS_HISTORY_STAT}" ]]; then + mkdir -p "${COMOUT_ATMOS_HISTORY_STAT}" +fi + +for fhr in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + fhrchar=$(printf %03i "${fhr}") + ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.sfc.f${fhrchar}.nc" "sfcf${fhrchar}.ensmean" + ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.atm.f${fhrchar}.nc" "atmf${fhrchar}.ensmean" + if [[ "${SMOOTH_ENKF}" == "YES" ]]; then + for imem in $(seq 1 "${NMEM_ENS}"); do + memchar="mem"$(printf %03i "${imem}") + MEMDIR="${memchar}" YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ + COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL + ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.f${fhrchar}${ENKF_SUFFIX}.nc" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" + done + fi + if [[ "${ENKF_SPREAD}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensspread.atm.f${fhrchar}.nc" "atmf${fhrchar}.ensspread" + fi +done + +################################################################################ +# Generate ensemble mean surface and atmospheric files + +if [[ "${SMOOTH_ENKF}" == "YES" ]]; then + cpreq "${HYBENSMOOTH}" ./hybens_smoothinfo +fi + +for fhr in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + fhrchar=$(printf %03i "${fhr}") + + export pgm=${GETSFCENSMEANEXEC} + source prep_step + + ${APRUN_EPOS} "${DATA}/$(basename "${GETSFCENSMEANEXEC}")" ./ "sfcf${fhrchar}.ensmean" "sfcf${fhrchar}" "${NMEM_ENS}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to calculate ensemble surface mean for forecast hour ${fhr}" + fi + + export pgm=${GETATMENSMEANEXEC} + source prep_step + + if [[ "${ENKF_SPREAD}" == "YES" ]]; then + ${APRUN_EPOS} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" ./ "atmf${fhrchar}.ensmean" "atmf${fhrchar}" "${NMEM_ENS}" "atmf${fhrchar}.ensspread" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to calculate ensemble atmospheric mean and spread for forecast hour ${fhr}" + fi + else + ${APRUN_EPOS} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" ./ "atmf${fhrchar}.ensmean" "atmf${fhrchar}" "${NMEM_ENS}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to calculate ensemble atmospheric mean for forecast hour ${fhr}" + fi + fi +done + +################################################################################ +# If smoothing on but no smoothing output, copy smoothed ensemble atmospheric files +if [[ "${SMOOTH_ENKF}" == "YES" ]]; then + for fhr in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + fhrchar=$(printf "%03i" "${fhr}") + if [[ ! -s "atmf${fhrchar}${ENKF_SUFFIX}_mem001" ]]; then + echo "WARNING! no smoothed ensemble member for fhour = ${fhrchar}" >&2 + for imem in $(seq 1 "${NMEM_ENS}"); do + memchar="mem"$(printf "%03i" "${imem}") + cpreq "atmf${fhrchar}_${memchar}" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" + done + fi + done +fi + +################################################################################ +# Send DBN alerts +if [[ "${SENDDBN}" == "YES" ]]; then + for fhr in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + fhrchar=$(printf "%03i" "${fhr}") + if ((fhr % 3 == 0)); then + if [[ -s "./sfcf${fhrchar}.ensmean" ]]; then + "${DBNROOT}/bin/dbn_alert" "MODEL" "GFS_ENKF" "${job}" "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.sfc.f${fhrchar}.nc" + fi + fi + done +fi + +################################################################################ +# Postprocessing +cd "${pwd}" || exit 1 + +exit "${err}" diff --git a/scripts/exgfs_aero_init_aerosol.py b/dev/scripts/exgfs_aero_init_aerosol.py similarity index 100% rename from scripts/exgfs_aero_init_aerosol.py rename to dev/scripts/exgfs_aero_init_aerosol.py diff --git a/dev/scripts/exgfs_atmos_awips_20km_1p0deg.sh b/dev/scripts/exgfs_atmos_awips_20km_1p0deg.sh new file mode 100755 index 00000000000..267a0623791 --- /dev/null +++ b/dev/scripts/exgfs_atmos_awips_20km_1p0deg.sh @@ -0,0 +1,244 @@ +#! /usr/bin/env bash + +############################################################################## +# UTILITY SCRIPT NAME : exgfs_awips_20km_1p0deg.sh +# DATE WRITTEN : 11/01/2017 +# +# Abstract: This utility script produces the GFS AWIPS 20km and 1.0 deg +# grids GRIB2 +# +# Input: 1 arguments are passed to this script. +# 1st argument - Forecast Hour - format of 3I (3 digits) +# +############################################################################### +# echo "------------------------------------------------" +# echo "JGFS_AWIPS_00/06/12/18 GFS postprocessing" +# echo "------------------------------------------------" +# echo "History: NOV 2017 - First implementation of this new script to " +# echo " process GFS AWIPS 20km and 1.0 deg grids products " +# echo " MAR 2025 - Remove job reference from product name strings " +# echo " " +############################################################################### + +fcsthr="$1" +num=$# + +if [[ ${num} -ne 1 ]]; then + echo "" + echo " FATAL ERROR: Incorrect number of arguments " + echo "" + echo "" + echo "Usage: $0 \${fcsthr} (3 digits) " + echo "" + exit 16 +fi + +cd "${DATA}" || exit 2 + +# "Import" functions used in this script +source "${USHgfs}/product_functions.sh" + +############################################### +# Wait for the availability of the pgrb file +############################################### +sleep_interval=10 +max_tries=180 +idxfile="${COMIN_ATMOS_GRIB_0p25}/${RUN}.${cycle}.pres_b.0p25.f${fcsthr}.grib2.idx" +if ! wait_for_file "${idxfile}" "${sleep_interval}" "${max_tries}"; then + msg="FATAL ERROR: No GFS pgrb2 file after waiting" + err_exit "${msg}" +fi + +######################################## + +echo " ------------------------------------------" +echo " BEGIN MAKING GFS AWIPS PRODUCTS" +echo " ------------------------------------------" + +set +x +echo " " +echo "#######################################" +echo " Process GRIB AWIP GRIB2 PRODUCTS " +echo "#######################################" +echo " " +set_trace + +# Set type of Interpolation for WGRIB2 +export opt1=' -set_grib_type same -new_grid_winds earth ' +export opt1uv=' -set_grib_type same -new_grid_winds grid ' +export opt21=' -new_grid_interpolation bilinear -if ' +export opt22=":(CSNOW|CRAIN|CFRZR|CICEP|ICSEV):" +export opt23=' -new_grid_interpolation neighbor -fi ' +export opt24=' -set_bitmap 1 -set_grib_max_bits 16 -if ' +export opt25=":(APCP|ACPCP|PRATE|CPRAT):" +export opt26=' -set_grib_max_bits 25 -fi -if ' +export opt27=":(APCP|ACPCP|PRATE|CPRAT|DZDT):" +export opt28=' -new_grid_interpolation budget -fi ' + +############################################################### +# Process GFS GRIB AWIP PRODUCTS IN GRIB2 # +############################################################### + +cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.t${cyc}z.pres_a.0p25.f${fcsthr}.grib2" "tmpfile2${fcsthr}" +cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.t${cyc}z.pres_b.0p25.f${fcsthr}.grib2" "tmpfile2b${fcsthr}" +cat "tmpfile2${fcsthr}" "tmpfile2b${fcsthr}" > "tmpfile${fcsthr}" +# shellcheck disable=SC2312 +${WGRIB2} "tmpfile${fcsthr}" | grep -F -f "${PARMgfs}/product/gfs_awips_parmlist_g2" | + ${WGRIB2} -i -grib masterfile "tmpfile${fcsthr}" && true +export err=$? +if [[ ${err} -ne 0 ]]; then + err_exit "masterfile does not exist." +fi + +${WGRIB2} masterfile -match ":PWAT:entire atmosphere" -grib gfs_pwat.grb +# shellcheck disable=SC2312 +${WGRIB2} masterfile | grep -v ":PWAT:entire atmosphere" | ${WGRIB2} -i -grib temp_gfs masterfile +################################################################## +# Process to change PWAT from level 200 to 10 (Entire Atmosphere) +# in production defintion template (PDT) 4.0 +################################################################## +${WGRIB2} gfs_pwat.grb -set_byte 4 23 10 -grib gfs_pwat_levels_10.grb && true +export err=$? +if [[ ${err} -ne 0 ]]; then + err_exit "Failed to redefine PWAT for the entire atmosphere!" +fi + +cat temp_gfs gfs_pwat_levels_10.grb > tmp_masterfile + +for GRID in conus ak prico pac 003; do + case ${GRID} in + conus) + gridconus="lambert:265.0:25.0:25.0 226.541:369:20318.0 12.19:257:20318.0" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} tmp_masterfile ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${gridconus} "awps_file_f${fcsthr}_${GRID}" + ;; + ak) + gridak="nps:210.0:60.0 170.0:277:22500 35.0:225:22500" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} tmp_masterfile ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${gridak} "awps_file_f${fcsthr}_${GRID}" + ;; + prico) + gridprico="latlon 271.75:275:0.25 50.75:205:-0.25" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${gridprico} "awps_file_f${fcsthr}_${GRID}" + ;; + pac) + gridpac="mercator:20.0 110.0:837:20000:270.0 -45.0:725:20000:65.7345" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${gridpac} "awps_file_f${fcsthr}_${GRID}" + ;; + 003) + ###################################################################### + # Process GFS GRIB AWIP 1.0 DEGREE (GRID 003) PRODUCTS IN GRIB2 # + ###################################################################### + grid003="latlon 0:360:1.0 90:181:-1.0" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${grid003} "awps_file_f${fcsthr}_${GRID}" + ;; + *) + export err=2 + err_exit "Unknown output grid ${GRID}" + ;; + esac + trim_rh "awps_file_f${fcsthr}_${GRID}" + scale_dec "awps_file_f${fcsthr}_${GRID}" + ${GRB2INDEX} "awps_file_f${fcsthr}_${GRID}" "awps_file_fi${fcsthr}_${GRID}" + + ########################################################################### + # Checking fields in awps_file_f${fcsthr}_${GRID} file + # before TOCGRIB2 adding WMO headers for AWIPS products. + # + # NOTE: numparm is the total of fields in grib2_awpgfs_20km_conusf000 file + ########################################################################### + numparm=247 + # shellcheck disable=SC2312 + numrec=$(${WGRIB2} "awps_file_f${fcsthr}_${GRID}" | wc -l) + + if [[ ${numrec} -lt ${numparm} ]]; then + export err=1 + msg="awps_file_f${fcsthr}_${GRID} file is missing fields for AWIPS !" + err_exit "${msg}" + fi + + # Processing AWIPS GRIB2 grids with WMO headers + + pgm=tocgrib2 + export pgm + prep_step + startmsg + + if [[ ${GRID} = "003" && $((10#${fcsthr} % 6)) == 0 ]]; then + export FORT11="awps_file_f${fcsthr}_${GRID}" + export FORT31="awps_file_fi${fcsthr}_${GRID}" + export FORT51="grib2.awpgfs${fcsthr}.${GRID}" + + cpreq "${PARMgfs}/wmo/grib2_awpgfs${fcsthr}.${GRID}" "parm_list" + + ${TOCGRIB2} < "parm_list" >> "${pgmout}" 2> errfile && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to generate the awips Grib2 file!" + fi + + ############################## + # Post Files to ${COMOUT_ATMOS_WMO} + ############################## + + cpfs "grib2.awpgfs${fcsthr}.${GRID}" \ + "${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID}" + + ############################## + # Distribute Data + ############################## + + if [[ "${SENDDBN}" == "YES" || "${SENDAWIP}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" NTC_LOW "${NET}" "${job}" \ + "${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID}" + else + echo "File ${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID} not posted to db_net." + fi + elif [[ ${GRID} != "003" ]]; then + export FORT11="awps_file_f${fcsthr}_${GRID}" + export FORT31="awps_file_fi${fcsthr}_${GRID}" + export FORT51="grib2.awpgfs_20km_${GRID}_f${fcsthr}" + + cpreq "${PARMgfs}/wmo/grib2_awpgfs_20km_${GRID}f${fcsthr}" "parm_list" + + ${TOCGRIB2} < "parm_list" >> "${pgmout}" 2> errfile && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to write the AWIPS grib2 file" + fi + + ############################## + # Post Files to ${COMOUT_ATMOS_WMO} + ############################## + + cpfs "grib2.awpgfs_20km_${GRID}_f${fcsthr}" \ + "${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr}" + + ############################## + # Distribute Data + ############################## + + if [[ "${SENDDBN}" == "YES" || "${SENDAWIP}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" NTC_LOW "${NET}" "${job}" \ + "${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr}" + else + echo "File ${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr} not posted to db_net." + fi + fi + echo "Awip Processing ${fcsthr} hour completed normally" + +done + +if [[ -e "${pgmout}" ]]; then + cat "${pgmout}" +fi + +############## END OF SCRIPT ####################### diff --git a/scripts/exgfs_atmos_fbwind.sh b/dev/scripts/exgfs_atmos_fbwind.sh similarity index 65% rename from scripts/exgfs_atmos_fbwind.sh rename to dev/scripts/exgfs_atmos_fbwind.sh index 8f9bbb8094f..2c76bb097c4 100755 --- a/scripts/exgfs_atmos_fbwind.sh +++ b/dev/scripts/exgfs_atmos_fbwind.sh @@ -22,27 +22,27 @@ cd "${DATA}" || exit 2 outfile_name="${COMOUT}/${RUN}.atmos.t${cyc}z.fbwind.pacific.ascii" -set +x -echo " " -echo "#############################################################" -echo " Process Bulletins of forecast winds and temps for Hawaii " -echo " and 15 sites outside of the Hawaiian Islands. " -echo "#############################################################" -echo " " -set_trace +cat << EOF + +############################################################# + Process Bulletins of forecast winds and temps for Hawaii + and 15 sites outside of the Hawaiian Islands. +############################################################# + +EOF export pgm=bulls_fbwndgfs source prep_step for fhr3 in 006 012 024; do - cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.${cycle}.pres_a.0p25.f${fhr3}.grib2" "tmp_pgrb2_0p25${fhr3}" - cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.${cycle}.pres_b.0p25.f${fhr3}.grib2" "tmp_pgrb2b_0p25${fhr3}" - cat "tmp_pgrb2_0p25${fhr3}" "tmp_pgrb2b_0p25${fhr3}" > "tmp0p25filef${fhr3}" - # shellcheck disable=SC2312 - ${WGRIB2} "tmp0p25filef${fhr3}" | grep -F -f "${PARMgfs}/product/gfs_fbwnd_parmlist_g2" | \ - ${WGRIB2} -i -grib "tmpfilef${fhr3}" "tmp0p25filef${fhr3}" - ${CNVGRIB} -g21 "tmpfilef${fhr3}" "gfs.t${cyc}z.grbf${fhr3}_grb1" - ${GRBINDEX} "gfs.t${cyc}z.grbf${fhr3}_grb1" "gfs.t${cyc}z.grbf${fhr3}_grb1.idx" + cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.${cycle}.pres_a.0p25.f${fhr3}.grib2" "tmp_pgrb2_0p25${fhr3}" + cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.${cycle}.pres_b.0p25.f${fhr3}.grib2" "tmp_pgrb2b_0p25${fhr3}" + cat "tmp_pgrb2_0p25${fhr3}" "tmp_pgrb2b_0p25${fhr3}" > "tmp0p25filef${fhr3}" + # shellcheck disable=SC2312 + ${WGRIB2} "tmp0p25filef${fhr3}" | grep -F -f "${PARMgfs}/product/gfs_fbwnd_parmlist_g2" | + ${WGRIB2} -i -grib "tmpfilef${fhr3}" "tmp0p25filef${fhr3}" + ${CNVGRIB} -g21 "tmpfilef${fhr3}" "gfs.t${cyc}z.grbf${fhr3}_grb1" + ${GRBINDEX} "gfs.t${cyc}z.grbf${fhr3}_grb1" "gfs.t${cyc}z.grbf${fhr3}_grb1.idx" done export FORT11="gfs.t${cyc}z.grbf006_grb1" @@ -66,7 +66,7 @@ cpreq "${PARMgfs}/product/fbwnd_pacific.stnlist" fbwnd_pacific.stnlist "${EXECgfs}/fbwndgfs.x" < fbwnd_pacific.stnlist >> "${pgmout}" 2> errfile && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run fbwnd for the Pacific!" + err_exit "Failed to run fbwnd for the Pacific!" fi "${USHgfs}/make_ntc_bull.pl" WMOBH NONE KWNO NONE tran.fbwnd_pacific "${outfile_name}" diff --git a/scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh b/dev/scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh similarity index 90% rename from scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh rename to dev/scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh index dae24b09cbe..0e84508a149 100755 --- a/scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh +++ b/dev/scripts/exgfs_atmos_gempak_gif_ncdc_skew_t.sh @@ -13,8 +13,8 @@ export NTS="${HOMEgfs}/gempak/ush/restore" if [[ "${MODEL}" == GDAS ]] || [[ "${MODEL}" == GFS ]]; then case "${MODEL}" in - GDAS) fcsthrs="0";; - GFS) fcsthrs="0 12 24 36 48";; + GDAS) fcsthrs="0" ;; + GFS) fcsthrs="0 12 24 36 48" ;; *) echo "FATAL ERROR: Unrecognized model type ${MODEL}" exit 5 @@ -26,7 +26,7 @@ if [[ "${MODEL}" == GDAS ]] || [[ "${MODEL}" == GFS ]]; then for fhr in ${fcsthrs}; do fhr3=$(printf %03d "${fhr}") export GRIBFILE=${COMIN_ATMOS_GEMPAK_1p00}/${RUN}_1p00_${PDY}${cyc}f${fhr3} - if ! wait_for_file "${GRIBFILE}" "${sleep_interval}" "${max_tries}" ; then + if ! wait_for_file "${GRIBFILE}" "${sleep_interval}" "${max_tries}"; then echo "FATAL ERROR: ${GRIBFILE} not found after ${max_tries} iterations" exit 10 fi @@ -43,7 +43,7 @@ fi cd "${DATA}" || exit 1 -export RSHPDY="${PDY:4:}${PDY:2:2}" +export RSHPDY="${PDY:4}${PDY:2:2}" cpreq "${HOMEgfs}/gempak/dictionaries/sonde.land.tbl" sonde.land.tbl cpreq "${HOMEgfs}/gempak/dictionaries/metar.tbl" metar.tbl @@ -53,11 +53,11 @@ cpreq "${COMIN_OBS}/${RUN}.${cycle}.adpupa.tm00.bufr_d" fort.40 "${HOMEgfs}/exec/rdbfmsua.x" >> "${pgmout}" 2> errfile export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run rdbfmsua!" + err_exit "Failed to run rdbfmsua!" fi # shellcheck disable=SC2012,SC2155 -export filesize=$( ls -l rdbfmsua.out | awk '{print $5}' ) +export filesize=$(ls -l rdbfmsua.out | awk '{print $5}') ################################################################ # only run script if rdbfmsua.out contained upper air data. @@ -74,9 +74,8 @@ fi ############################################################ -if [[ -e "${pgmout}" ]] ; then - cat "${pgmout}" +if [[ -e "${pgmout}" ]]; then + cat "${pgmout}" fi - exit diff --git a/dev/scripts/exgfs_atmos_gempak_meta.sh b/dev/scripts/exgfs_atmos_gempak_meta.sh new file mode 100755 index 00000000000..130913e918e --- /dev/null +++ b/dev/scripts/exgfs_atmos_gempak_meta.sh @@ -0,0 +1,89 @@ +#! /usr/bin/env bash + +GEMGRD1="${RUN}_1p00_${PDY}${cyc}f" + +export numproc=23 + +# Find the last hour available +for ((fhr = fhend; fhr >= fhbeg; fhr = fhr - fhinc)); do + fhr3=$(printf "%03d" "${fhr}") + if [[ -r "${COMIN_ATMOS_GEMPAK_1p00}/${GEMGRD1}${fhr3}" ]]; then + break + fi +done + +sleep_interval=20 +max_tries=180 +first_time=0 +do_all=0 + +#loop through and process needed forecast hours +while [[ ${fhr} -le ${fhend} ]]; do + # + # First check to see if this is a rerun. If so make all Meta files + if [[ ${fhr} -gt 126 && ${first_time} -eq 0 ]]; then + do_all=1 + fi + first_time=1 + + if [[ ${fhr} -eq 120 ]]; then + fhr=126 + fi + + gempak_file="${COMIN_ATMOS_GEMPAK_1p00}/${GEMGRD1}${fhr3}" + if ! wait_for_file "${gempak_file}" "${sleep_interval}" "${max_tries}"; then + err_exit "FATAL ERROR: gempak grid file ${gempak_file} not available after maximum wait time." + fi + + export fhr + + ######################################################## + # Create a script to be poe'd + # + # Note: The number of scripts to be run MUST match the number + # of total_tasks set in the ecf script, or the job will fail. + # + rm -f poescript + + fhr3=$(printf "%03d" "${fhr}") + + if [[ ${do_all} -eq 1 ]]; then + do_all=0 + # shellcheck disable=SC2312 + awk '{print $1}' "${HOMEgfs}/gempak/fix/gfs_meta" | envsubst > "poescript" + else + # + # Do not try to grep out 12, it will grab the 12 from 126. + # This will work as long as we don't need 12 fhr metafiles + # + if [[ ${fhr} -ne 12 ]]; then + # shellcheck disable=SC2312 + grep "${fhr}" "${HOMEgfs}/gempak/fix/gfs_meta" | awk -F" [0-9]" '{print $1}' | envsubst > "poescript" + fi + fi + + # If this is the final fcst hour, alert the + # file to all centers. + # + if [[ ${fhr} -ge ${fhend} ]]; then + export DBN_ALERT_TYPE=GFS_METAFILE_LAST + fi + + export fend=${fhr} + + cat poescript + + "${HOMEgfs}/ush/run_mpmd.sh" poescript && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to generate one or more gempak meta plots!" + fi + + if [[ ${fhr} -eq 126 ]]; then + fhr=$((fhr + 6)) + else + fhr=$((fhr + fhinc)) + fi +done + +exit diff --git a/scripts/exgfs_atmos_goes_nawips.sh b/dev/scripts/exgfs_atmos_goes_nawips.sh similarity index 55% rename from scripts/exgfs_atmos_goes_nawips.sh rename to dev/scripts/exgfs_atmos_goes_nawips.sh index 083de278498..da085ca4ce1 100755 --- a/scripts/exgfs_atmos_goes_nawips.sh +++ b/dev/scripts/exgfs_atmos_goes_nawips.sh @@ -11,11 +11,11 @@ fhr3=$1 source "${USHgfs}/product_functions.sh" for table in g2varswmo2.tbl g2vcrdwmo2.tbl g2varsncep1.tbl g2vcrdncep1.tbl; do - source_table="${HOMEgfs}/gempak/fix/${table}" - if [[ ! -f "${source_table}" ]]; then - err_exit "FATAL ERROR: ${table} is missing" - fi - cpreq "${source_table}" "${table}" + source_table="${HOMEgfs}/gempak/fix/${table}" + if [[ ! -f "${source_table}" ]]; then + err_exit "FATAL ERROR: ${table} is missing" + fi + cpreq "${source_table}" "${table}" done NAGRIB_TABLE="${HOMEgfs}/gempak/fix/nagrib.tbl" @@ -24,36 +24,34 @@ NAGRIB="${GEMEXE}/nagrib2" # shellcheck disable=SC2312 entry=$(grep "^${RUN2} " "${NAGRIB_TABLE}" | awk 'index($1,"#") != 1 {print $0}') -if [[ "${entry}" != "" ]] ; then - cpyfil=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $2}') - garea=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $3}') - gbtbls=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $4}') - maxgrd=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $5}') - kxky=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $6}') - grdarea=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $7}') - proj=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $8}') - output=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $9}') +if [[ "${entry}" != "" ]]; then + cpyfil=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $2}') + garea=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $3}') + gbtbls=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $4}') + maxgrd=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $5}') + kxky=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $6}') + grdarea=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $7}') + proj=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $8}') + output=$(echo "${entry}" | awk 'BEGIN {FS="|"} {print $9}') else - cpyfil=gds - garea=dset - gbtbls= - maxgrd=4999 - kxky= - grdarea= - proj= - output=T + cpyfil=gds + garea=dset + gbtbls= + maxgrd=4999 + kxky= + grdarea= + proj= + output=T fi pdsext=no - - GEMGRD="${RUN2}_${PDY}${cyc}f${fhr3}" GRIBIN="${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.${GRIB}${fhr3}${EXT}" GRIBIN_chk="${GRIBIN}" if [[ ! -r "${GRIBIN_chk}" ]]; then - export err=7 - err_exit "GRIB index file ${GRIBIN_chk} not found!" + export err=7 + err_exit "GRIB index file ${GRIBIN_chk} not found!" fi cpreq "${GRIBIN}" "grib${fhr3}" @@ -81,13 +79,13 @@ EOF export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run ${NAGRIB}!" + err_exit "Failed to run ${NAGRIB}!" fi cpfs "${GEMGRD}" "${COMOUT_ATMOS_GEMPAK_0p25}/${GEMGRD}" -if [[ ${SENDDBN} == "YES" ]] ; then - "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" \ - "${COMOUT_ATMOS_GEMPAK_0p25}/${GEMGRD}" +if [[ ${SENDDBN} == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" \ + "${COMOUT_ATMOS_GEMPAK_0p25}/${GEMGRD}" fi "${GEMEXE}/gpend" diff --git a/dev/scripts/exgfs_atmos_grib2_special_npoess.sh b/dev/scripts/exgfs_atmos_grib2_special_npoess.sh new file mode 100755 index 00000000000..d1c37c56dd8 --- /dev/null +++ b/dev/scripts/exgfs_atmos_grib2_special_npoess.sh @@ -0,0 +1,199 @@ +#! /usr/bin/env bash + +##################################################################### +# echo "-----------------------------------------------------" +# echo " exglobal_grib2_special_npoess.sh" +# echo " Jan 2008 - Chuang - Produces 1x1 degree special Grib from master." +# echo "-----------------------------------------------------" +##################################################################### + +cd "${DATA}" || exit 2 + +############################################################ +# Define Variables: +# ----------------- +# SHOUR is the starting forecast hour. normally 0 except for restarts. +# FHOUR is the ending forecast hour. +# FHINC is the increment hour for each forecast steps. +# FH is the current forecast hour. +# SLEEP_TIME is the number of seconds to sleep before exiting with error. +# SLEEP_INT is the number of seconds to sleep between restrt file checks. +# restart_file is the name of the file to key off of to kick off pgrb +# generation. +############################################################ + +############################################################ +# NO processing Analysis special Files +############################################################ + +# Set type of Interpolation for WGRIB2 +export opt1=' -set_grib_type same -new_grid_winds earth ' +export opt1uv=' -set_grib_type same -new_grid_winds grid ' +export opt21=' -new_grid_interpolation bilinear -if ' +export opt22=":(CSNOW|CRAIN|CFRZR|CICEP|ICSEV):" +export opt23=' -new_grid_interpolation neighbor -fi ' +export opt24=' -set_bitmap 1 -set_grib_max_bits 16 -if ' +export opt25=":(APCP|ACPCP|PRATE|CPRAT):" +export opt26=' -set_grib_max_bits 25 -fi -if ' +export opt27=":(APCP|ACPCP|PRATE|CPRAT|DZDT):" +export opt28=' -new_grid_interpolation budget -fi ' + +#################################### +# Specify Timeout Behavior of Post +# +# SLEEP_TIME - Amount of time to wait for +# a restart file before exiting +# SLEEP_INT - Amount of time to wait between +# checking for restart files +#################################### +export SLEEP_TIME=${SLEEP_TIME:-900} +export SLEEP_INT=${SLEEP_TIME:-5} + +SLEEP_LOOP_MAX=$((SLEEP_TIME / SLEEP_INT)) + +# TODO: Does this section do anything? I retained if for clarity of +# changes/updates, but it does not appear to do anything. + +#################################### +# Check if this is a restart +#################################### +if [[ -f "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb2" ]]; then + modelrecvy=$(cat < "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb") + recvy_cyc="${modelrecvy:8:2}" + recvy_shour="${modelrecvy:10:13}" + + if [[ ${RERUN} == "NO" ]]; then + NEW_SHOUR=$((recvy_shour + FHINC)) + if ((NEW_SHOUR >= SHOUR)); then + export SHOUR="${NEW_SHOUR}" + fi + if ((recvy_shour >= FHOUR)); then + echo "Forecast Pgrb Generation Already Completed to ${FHOUR}" + else + echo "Starting: PDY=${PDY} cycle=t${recvy_cyc}z SHOUR=${SHOUR}" + fi + fi +fi + +############################################################################## +# Specify Forecast Hour Range F000 - F024 for GFS_NPOESS_PGRB2_0P5DEG +############################################################################## +export SHOUR=0 +export FHOUR=24 +export FHINC=3 +if ((FHOUR > FHMAX_GFS)); then + export FHOUR="${FHMAX_GFS}" +fi + +############################################################ +# Loop Through the Post Forecast Files +############################################################ +for ((fhr = SHOUR; fhr <= FHOUR; fhr = fhr + FHINC)); do + + fhr3=$(printf "%03d" "${fhr}") + + ############################### + # Start Looping for the + # existence of the restart files + ############################### + export pgm="postcheck" + grib_file="${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_b.0p50.f${fhr3}.grib2.idx" + if ! wait_for_file "${grib_file}" "${SLEEP_INT}" "${SLEEP_LOOP_MAX}"; then + export err=9 + err_exit "FATAL ERROR: 0p50 grib file not available after max sleep time" + fi + + ###################################################################### + # Process Global NPOESS 0.50 GFS GRID PRODUCTS IN GRIB2 F000 - F024 # + ###################################################################### + paramlist="${PARMgfs}/product/global_npoess_paramlist_g2" + cpreq "${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_a.0p50.f${fhr3}.grib2" tmpfile2 + cpreq "${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_b.0p50.f${fhr3}.grib2" tmpfile2b + cat tmpfile2 tmpfile2b > tmpfile + # shellcheck disable=SC2312 + ${WGRIB2} tmpfile | grep -F -f "${paramlist}" | ${WGRIB2} -i -grib pgb2file tmpfile && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "FATAL ERROR: Failed to write pgb2file from the specified parm file \"${paramlist}\"!" + fi + + cpfs pgb2file "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.pgrb2f${fhr3}.npoess" + + if [[ "${SENDDBN}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL GFS_PGBNPOESS "${job}" \ + "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.pgrb2f${fhr3}.npoess" + else + echo "File ${RUN}.${cycle}.pgrb2f${fhr3}.npoess not posted to db_net." + fi + echo "${PDY}${cyc}${fhr3}" > "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.halfdeg.npoess" + rm -f tmpfile pgb2file + +done + +################################################################ +# Specify Forecast Hour Range F000 - F180 for GOESSIMPGRB files +################################################################ +export SHOUR=${FHMIN_GFS} +export FHOUR=${FHMAX_GOES} +export FHINC=${FHOUT_GOES} + +################################# +# Process GFS PGRB2_SPECIAL_POST +################################# + +for ((fhr = SHOUR; fhr <= FHOUR; fhr = fhr + FHINC)); do + + fhr3=$(printf "%03d" "${fhr}") + + ############################### + # Start Looping for the + # existence of the restart files + ############################### + export pgm="postcheck" + # grib_file="${COMIN_ATMOS_MASTER}/${RUN}.t${cyc}z.goesmasterf${fhr3}.grb2" + grib_file="${COMIN_ATMOS_MASTER}/${RUN}.t${cyc}z.master-goes.f${fhr3}.grib2" + if ! wait_for_file "${grib_file}" "${SLEEP_INT}" "${SLEEP_LOOP_MAX}"; then + export err=9 + err_exit "FATAL ERROR: GOES master grib file ${grib_file} not available after max sleep time" + fi + ############################### + # Put restart files into /nwges + # for backup to start Model Fcst + ############################### + cpreq "${grib_file}" masterfile + export grid0p25="latlon 0:1440:0.25 90:721:-0.25" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${grid0p25} pgb2file + + export gridconus="lambert:253.0:50.0:50.0 214.5:349:32463.0 1.0:277:32463.0" + # shellcheck disable=SC2086,SC2248 + ${WGRIB2} masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ + ${opt27} ${opt28} -new_grid ${gridconus} pgb2file2 + + ${WGRIB2} pgb2file -s > pgb2ifile + + cpfs pgb2file "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr3}" + cpfs pgb2ifile "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr3}.idx" + cpfs pgb2file2 "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2f${fhr3}.grd221" + + if [[ ${SENDDBN} == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMPGB2_0P25 "${job}" \ + "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr}" + "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMPGB2_0P25_WIDX "${job}" \ + "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr}.idx" + "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMGRD221_PGB2 "${job}" \ + "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2f${fhr}.grd221" + fi + + echo "${PDY}${cyc}${fhr}" > "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb" + rm -f pgb2file2 pgb2ifile + + if [[ ${SENDECF} == "YES" ]]; then + # TODO Does this even do anything? + export fhour=$((fhr % 6)) + fi + +done + +################## END OF SCRIPT ####################### diff --git a/scripts/exgfs_atmos_nawips.sh b/dev/scripts/exgfs_atmos_nawips.sh similarity index 70% rename from scripts/exgfs_atmos_nawips.sh rename to dev/scripts/exgfs_atmos_nawips.sh index f3d288bdd09..66cbfa2d8d0 100755 --- a/scripts/exgfs_atmos_nawips.sh +++ b/dev/scripts/exgfs_atmos_nawips.sh @@ -37,16 +37,15 @@ pdsext=no sleep_interval=10 max_tries=360 - mkdir -p "lock.${fhr3}" cd "lock.${fhr3}" || exit 1 for table in g2varswmo2.tbl g2vcrdwmo2.tbl g2varsncep1.tbl g2vcrdncep1.tbl; do - source_table="${HOMEgfs}/gempak/fix/${table}" - if [[ ! -f "${source_table}" ]]; then - err_exit "FATAL ERROR: ${table} is missing" - fi - cpreq "${source_table}" "${table}" + source_table="${HOMEgfs}/gempak/fix/${table}" + if [[ ! -f "${source_table}" ]]; then + err_exit "FATAL ERROR: ${table} is missing" + fi + cpreq "${source_table}" "${table}" done GEMGRD="${RUN}_${grid}_${PDY}${cyc}f${fhr3}" @@ -64,9 +63,9 @@ export opt27=":(APCP|ACPCP|PRATE|CPRAT|DZDT):" export opt28=' -new_grid_interpolation budget -fi ' case ${grid} in - # TODO: Why aren't we interpolating from the 0p25 grids for 35-km and 40-km? - '0p50' | '0p25') grid_in=${grid};; - *) grid_in="1p00";; + # TODO: Why aren't we interpolating from the 0p25 grids for 35-km and 40-km? + '0p50' | '0p25') grid_in=${grid} ;; + *) grid_in="1p00" ;; esac source_var="COMIN_ATMOS_GRIB_${grid_in}" @@ -74,23 +73,23 @@ export GRIBIN="${!source_var}/${RUN}.${cycle}.pres_a.${grid_in}.f${fhr3}.grib2" GRIBIN_chk="${!source_var}/${RUN}.${cycle}.pres_a.${grid_in}.f${fhr3}.grib2.idx" if ! wait_for_file "${GRIBIN_chk}" "${sleep_interval}" "${max_tries}"; then - export err=7 - err_exit "After 1 hour of waiting for ${GRIBIN_chk} file at F${fhr3} to end." + export err=7 + err_exit "After 1 hour of waiting for ${GRIBIN_chk} file at F${fhr3} to end." fi case "${grid}" in - 35km_pac) grid_spec='latlon 130.0:416:0.312 75.125:186:-0.312';; - 35km_atl) grid_spec='latlon 230.0:480:0.312 75.125:242:-0.312';; - 40km) grid_spec='lambert:265.0:25.0:25.0 226.541:185:40635.0 12.19:129:40635.0';; - *) grid_spec='';; + 35km_pac) grid_spec='latlon 130.0:416:0.312 75.125:186:-0.312' ;; + 35km_atl) grid_spec='latlon 230.0:480:0.312 75.125:242:-0.312' ;; + 40km) grid_spec='lambert:265.0:25.0:25.0 226.541:185:40635.0 12.19:129:40635.0' ;; + *) grid_spec='' ;; esac if [[ "${grid_spec}" != "" ]]; then - # shellcheck disable=SC2086,SC2248 - "${WGRIB2}" "${GRIBIN}" ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} ${opt27} ${opt28} -new_grid ${grid_spec} "grib${fhr3}" - trim_rh "grib${fhr3}" + # shellcheck disable=SC2086,SC2248 + "${WGRIB2}" "${GRIBIN}" ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} ${opt27} ${opt28} -new_grid ${grid_spec} "grib${fhr3}" + trim_rh "grib${fhr3}" else - cpreq "${GRIBIN}" "grib${fhr3}" + cpreq "${GRIBIN}" "grib${fhr3}" fi export pgm="nagrib2 F${fhr3}" @@ -116,20 +115,20 @@ EOF export err=$? if [[ ${err} -ne 0 ]]; then - err_exit + err_exit fi "${GEMEXE}/gpend" export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "${GEMEXE}/gpend failed!" + err_exit "${GEMEXE}/gpend failed!" fi cpfs "${GEMGRD}" "${destination}/${GEMGRD}" -if [[ ${SENDDBN} == "YES" ]] ; then +if [[ ${SENDDBN} == "YES" ]]; then "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" \ - "${destination}/${GEMGRD}" + "${destination}/${GEMGRD}" fi cd "${DATA_RUN}" || exit 1 diff --git a/scripts/exgfs_atmos_postsnd.sh b/dev/scripts/exgfs_atmos_postsnd.sh similarity index 68% rename from scripts/exgfs_atmos_postsnd.sh rename to dev/scripts/exgfs_atmos_postsnd.sh index a366b1fad50..725acf5548b 100755 --- a/scripts/exgfs_atmos_postsnd.sh +++ b/dev/scripts/exgfs_atmos_postsnd.sh @@ -23,7 +23,7 @@ # it requires 7 nodes & allocate 21 processes per node(num_ppn=21) ################################################################ -runscript=${USHgfs}/gfs_bufr.sh +runscript="${USHgfs}/gfs_bufr.sh" cd "${DATA}" || exit 2 @@ -53,13 +53,13 @@ declare -x LEVS hour_list=() # Generate hours from 0 to NEND1 with interval NINT1 -for (( hour=0; hour<=NEND1 && hour<=ENDHOUR; hour+=NINT1 )); do - hour_list+=("$(printf "%03d" "$hour")") +for ((hour = 0; hour <= NEND1 && hour <= ENDHOUR; hour += NINT1)); do + hour_list+=("$(printf "%03d" "${hour}")") done # Generate hours from NEND1 + NINT3 to ENDHOUR with interval NINT3 -for (( hour=NEND1+NINT3; hour<=ENDHOUR; hour+=NINT3 )); do - hour_list+=("$(printf "%03d" "$hour")") +for ((hour = NEND1 + NINT3; hour <= ENDHOUR; hour += NINT3)); do + hour_list+=("$(printf "%03d" "${hour}")") done # Print the hour list @@ -69,55 +69,55 @@ echo "Hour List:" "${hour_list[@]}" export ntasks="${#hour_list[@]}" # Print the total number of hours -echo "Total number of hours: $ntasks" +echo "Total number of hours: ${ntasks}" # allocate 21 processes per node # don't allocate more processes, or it might have memory issue #export tasks_per_node=21 #export APRUN="mpiexec -np ${ntasks} -ppn ${tasks_per_node} --cpu-bind core cfp " -rm -f ${DATA}/poescript_bufr +rm -f "${DATA}/poescript_bufr" for fhr in "${hour_list[@]}"; do - if [ ! -s "${DATA}/${fhr}" ]; then mkdir -p ${DATA}/${fhr}; fi - export FINT=${NINT1} - ## 1-hourly output before $NEND1, 3-hourly output after - if [[ $((10#${fhr})) -gt $((10#${NEND1})) ]]; then - export FINT=${NINT3} - fi - if [[ $((10#${fhr})) -eq 0 ]]; then - export F00FLAG="YES" - else - export F00FLAG="NO" - fi - - # Convert fhr to integer - fhr_int=$((10#$fhr)) - - # Get previous hour - if (( fhr_int == STARTHOUR )); then - fhr_p=${fhr_int} - else - fhr_p=$(( fhr_int - FINT )) - fi - - # Format fhr_p with leading zeros - fhr_p="$(printf "%03d" "$fhr_p")" - - filename="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.logf${fhr}.${logfm}" - if [[ -z ${filename} ]]; then - err_exit "File ${filename} not found." - else - echo "${runscript} ${fhr} ${fhr_p} ${FINT} ${F00FLAG} ${DATA}/${fhr}" >> "${DATA}/poescript_bufr" - fi + if [[ ! -s "${DATA}/${fhr}" ]]; then mkdir -p "${DATA}/${fhr}"; fi + export FINT=${NINT1} + ## 1-hourly output before $NEND1, 3-hourly output after + if [[ $((10#${fhr})) -gt $((10#${NEND1})) ]]; then + export FINT=${NINT3} + fi + if [[ $((10#${fhr})) -eq 0 ]]; then + export F00FLAG="YES" + else + export F00FLAG="NO" + fi + + # Convert fhr to integer + fhr_int=$((10#${fhr})) + + # Get previous hour + if ((fhr_int == STARTHOUR)); then + fhr_p=${fhr_int} + else + fhr_p=$((fhr_int - FINT)) + fi + + # Format fhr_p with leading zeros + fhr_p="$(printf "%03d" "${fhr_p}")" + + filename="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.logf${fhr}.${logfm}" + if [[ -z ${filename} ]]; then + err_exit "FATAL ERROR: File ${filename} not found." + else + echo "${runscript} ${fhr} ${fhr_p} ${FINT} ${F00FLAG} ${DATA}/${fhr}" >> "${DATA}/poescript_bufr" + fi done # Run with MPMD "${USHgfs}/run_mpmd.sh" "${DATA}/poescript_bufr" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "One or more BUFR MPMD tasks failed!" + err_exit "One or more BUFR MPMD tasks failed!" fi cd "${DATA}" || exit 2 @@ -135,32 +135,35 @@ done # start to generate bufr products at fhr=${ENDHOUR} export MAKEBUFR=YES -export fhr="$(printf "%03d" "$ENDHOUR")" +fhr="$(printf "%03d" "${ENDHOUR}")" +export fhr export FINT=${NINT1} ## 1-hourly output before $NEND1, 3-hourly output after if [[ $((10#${fhr})) -gt $((10#${NEND1})) ]]; then - export FINT=${NINT3} + export FINT=${NINT3} fi if [[ $((10#${fhr})) -eq 0 ]]; then - export F00FLAG="YES" + export F00FLAG="YES" else - export F00FLAG="NO" + export F00FLAG="NO" fi ${runscript} "${fhr}" "${fhr_p}" "${FINT}" "${F00FLAG}" "${DATA}" -############################################################## -# Tar and gzip the individual bufr files and send them to /com -############################################################## -cd "${COMOUT_ATMOS_BUFR}" || exit 2 -tar -cf - . | /usr/bin/gzip > "${RUN}.${cycle}.bufrsnd.tar.gz" -cd "${DATA}" || exit 2 +############################################ +# Tar and gzip the bufr files created so far +############################################ +find "${COMIN_ATMOS_BUFR}" -maxdepth 1 -type f -name "bufr.*" -printf '%f\n' > "${DATA}/all_bufr_files.txt" + +tar -czf "${RUN}.${cycle}.soundings.tar.gz" -C "${COMIN_ATMOS_BUFR}" -T "${DATA}/all_bufr_files.txt" + +cpfs "${RUN}.${cycle}.soundings.tar.gz" "${COMOUT_ATMOS_BUFR}/" ######################################## # Send the single tar file to OSO ######################################## if [[ "${SENDDBN}" == "YES" ]]; then "${DBNROOT}/bin/dbn_alert" MODEL GFS_BUFRSND_TAR "${job}" \ - "${COMOUT_ATMOS_BUFR}/${RUN}.${cycle}.bufrsnd.tar.gz" + "${COMOUT_ATMOS_BUFR}/${RUN}.${cycle}.soundings.tar.gz" fi ######################################## @@ -168,7 +171,7 @@ fi # data and add appropriate WMO Headers ######################################## rm -rf poe_col -for (( m = 1; m <= NUM_SND_COLLECTIVES; m++ )); do +for ((m = 1; m <= NUM_SND_COLLECTIVES; m++)); do echo "${USHgfs}/gfs_sndp.sh ${m} " >> poe_col done @@ -188,8 +191,7 @@ ${APRUN_POSTSNDCFP} cmdfile # GEMPAK surface and sounding data files ######################################## if [[ "${DO_GEMPAK:-"NO"}" == "YES" ]]; then - sh "${USHgfs}/gfs_bfr2gpk.sh" + sh "${USHgfs}/gfs_bfr2gpk.sh" fi - ############## END OF SCRIPT ####################### diff --git a/dev/scripts/exgfs_pmgr.sh b/dev/scripts/exgfs_pmgr.sh new file mode 100755 index 00000000000..101c5bb4649 --- /dev/null +++ b/dev/scripts/exgfs_pmgr.sh @@ -0,0 +1,48 @@ +#! /usr/bin/env bash + +# +# Script name: exgfs_pmgr.sh.sms +# +# This script monitors the progress of the gfs_fcst job +# + +hour=0 +TEND=384 + +if [[ -e posthours ]]; then + rm -f posthours +fi + +declare -a posthours +while [[ "${hour}" -le "${TEND}" ]]; do + posthours+=("${hour}") + if [[ ${hour} -lt 240 ]]; then + if [[ ${hour} -lt 120 ]]; then + hour=$((hour + 1)) + else + hour=$((hour + 3)) + fi + else + hour=$((hour + 12)) + fi +done + +# +# Wait for all fcst hours to finish +# +sleep_interval=10 +max_tries=1000 +for fhr in "${posthours[@]}"; do + fhr3=$(sprintf "%03d" "${fhr}") + log_file="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.logf${fhr3}.txt" + if ! wait_for_file "${log_file}" "${sleep_interval}" "${max_tries}"; then + msg="FATAL ERROR: After 2 hours of waiting for GFS FCST hour ${fhr3}." + err_exit "${msg}" + fi + if [[ ${fhr} -eq 0 ]]; then + ecflow_client --event release_postanl + fi + ecflow_client --event "release_post${fhr3}" +done + +exit diff --git a/dev/scripts/exgfs_prdgen_manager.sh b/dev/scripts/exgfs_prdgen_manager.sh new file mode 100755 index 00000000000..7e4496cc1e8 --- /dev/null +++ b/dev/scripts/exgfs_prdgen_manager.sh @@ -0,0 +1,45 @@ +#! /usr/bin/env bash + +# +# Script name: exgfs_pmgr.sh.sms +# +# This script monitors the progress of the gfs_fcst job +# + +hour=0 +TEND=384 + +if [[ -e pgrb2_hours ]]; then + rm -f pgrb2_hours +fi + +declare -a pgrb2_hours +while [[ "${hour}" -le "${TEND}" ]]; do + pgrb2_hours+=("${hour}") + if [[ ${hour} -lt 240 ]]; then + if [[ ${hour} -lt 120 ]]; then + hour=$((hour + 1)) + else + hour=$((hour + 3)) + fi + else + hour=$((hour + 12)) + fi +done + +# +# Wait for all fcst hours to finish +# +sleep_interval=10 +max_tries=1000 +for fhr in "${pgrb2_hours[@]}"; do + fhr3=$(sprintf "%03d" "${fhr}") + master_file="${COMIN_ATMOS_MASTER}/gfs.${cycle}.master.grb2f${fhr3}" + if ! wait_for_file "${master_file}" "${sleep_interval}" "${max_tries}"; then + export err=1 + err_exit "After 2 hours of waiting for GFS POST hour ${fhr3}." + fi + ecflow_client --event "release_pgrb2_${fhr3}" +done + +exit diff --git a/scripts/exgfs_wave_init.sh b/dev/scripts/exgfs_wave_init.sh similarity index 51% rename from scripts/exgfs_wave_init.sh rename to dev/scripts/exgfs_wave_init.sh index 74e328bcccb..19f3bc6992f 100755 --- a/scripts/exgfs_wave_init.sh +++ b/dev/scripts/exgfs_wave_init.sh @@ -28,59 +28,58 @@ EOF # 1.a Model definition files - # Eliminate duplicate grids # Use an associative array, since they don't allow duplicate keys declare -A grdALL for grd in ${WAVECUR_FID} ${WAVEICE_FID} ${WAVEWND_FID} ${waveuoutpGRD} ${waveGRD} ${wavepostGRD} ${waveinterpGRD}; do - # For ease of access, make the value the same as the key - grdALL["${grd}"]="${grd}" + # For ease of access, make the value the same as the key + grdALL["${grd}"]="${grd}" done for grdID in "${grdALL[@]}"; do - echo "INFO: Setting up to generate mod_def file for ${grdID}" - if [[ -f "${FIXgfs}/wave/ww3_grid.inp.${grdID}" ]]; then - cpreq "${FIXgfs}/wave/ww3_grid.inp.${grdID}" "ww3_grid.inp.${grdID}" - echo "INFO: ww3_grid.inp.${grdID} copied (${FIXgfs}/wave/ww3_grid.inp.${grdID})." - else - export err=2 - err_exit "No inp file for model definition file for grid ${grdID}" - fi + echo "INFO: Setting up to generate mod_def file for ${grdID}" + if [[ -f "${FIXgfs}/wave/ww3_grid.inp.${grdID}" ]]; then + cpreq "${FIXgfs}/wave/ww3_grid.inp.${grdID}" "ww3_grid.inp.${grdID}" + echo "INFO: ww3_grid.inp.${grdID} copied (${FIXgfs}/wave/ww3_grid.inp.${grdID})." + else + export err=2 + err_exit "No inp file for model definition file for grid ${grdID}" + fi - if [[ -f "${FIXgfs}/wave/${grdID}.msh" ]]; then - cpreq "${FIXgfs}/wave/${grdID}.msh" "${grdID}.msh" - fi - #TODO: how do we say "it's unstructured, and therefore need to have error check here" + if [[ -f "${FIXgfs}/wave/${grdID}.msh" ]]; then + cpreq "${FIXgfs}/wave/${grdID}.msh" "${grdID}.msh" + fi + #TODO: how do we say "it's unstructured, and therefore need to have error check here" - echo "${USHgfs}/wave_grid_moddef.sh ${grdID}" >> mpmd_script + echo "${USHgfs}/wave_grid_moddef.sh ${grdID}" >> mpmd_script done # 1.a.1 Execute MPMD or process serially "${USHgfs}/run_mpmd.sh" "${DATA}/mpmd_script" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "run_mpmd.sh failed!" + err_exit "run_mpmd.sh failed!" fi # 1.a.3 File check for grdID in "${grdALL[@]}"; do - if [[ -f "${COMOUT_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" ]]; then - echo "INFO: mod_def.${grdID} succesfully created/copied" - else - export err=3 - err_exit "No model definition file for grid ${grdID}" - fi + if [[ -f "${COMOUT_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" ]]; then + echo "INFO: mod_def.${grdID} succesfully created/copied" + else + export err=3 + err_exit "No model definition file for grid ${grdID}" + fi done # Copy to other members if needed if [[ "${NET}" == "gefs" && ${NMEM_ENS} -gt 0 ]]; then - for mem in $(seq -f "%03g" 1 "${NMEM_ENS}"); do - MEMDIR="mem${mem}" YMD="${PDY}" HH="${cyc}" declare_from_tmpl COMOUT_WAVE_PREP_MEM:COM_WAVE_PREP_TMPL - mkdir -p "${COMOUT_WAVE_PREP_MEM}" - for grdID in "${grdALL[@]}"; do - cpfs "${COMOUT_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" "${COMOUT_WAVE_PREP_MEM}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" + for mem in $(seq -f "%03g" 1 "${NMEM_ENS}"); do + MEMDIR="mem${mem}" YMD="${PDY}" HH="${cyc}" declare_from_tmpl COMOUT_WAVE_PREP_MEM:COM_WAVE_PREP_TMPL + mkdir -p "${COMOUT_WAVE_PREP_MEM}" + for grdID in "${grdALL[@]}"; do + cpfs "${COMOUT_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" "${COMOUT_WAVE_PREP_MEM}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" + done done - done fi # End of MWW3 init config script ------------------------------------------- # diff --git a/dev/scripts/exgfs_wave_nawips.sh b/dev/scripts/exgfs_wave_nawips.sh new file mode 100755 index 00000000000..5400a29962d --- /dev/null +++ b/dev/scripts/exgfs_wave_nawips.sh @@ -0,0 +1,132 @@ +#! /usr/bin/env bash + +################################################################### +# echo "----------------------------------------------------" +# echo "exnawips - convert NCEP GRIB files into GEMPAK Grids" +# echo "----------------------------------------------------" +# echo "History: Mar 2000 - First implementation of this new script." +# echo "Sept 2011 - First implementation of this new script" +# echo " March 2020- Modified for GEFSv12.0" +# March-2020 Roberto.Padilla@noaa.gov +##################################################################### + +source "${USHgfs}/wave_domain_grid.sh" +source "${USHgfs}/atparse.bash" + +NAGRIB="nagrib2" +fhr3=$(printf "%03d" "${FORECAST_HOUR}") + +cpreq "${HOMEgfs}/gempak/fix/g2varswmo2.tbl" "${DATA}/" + +grids=${GEMPAK_GRIDS:-${waveinterpGRD:-'aoc_9km gnh_10m gsh_15m'}} + +# Create a template for the GEMPAK control file +rm -f "${DATA}/gempak.parm.tmpl" +cat << EOF > "${DATA}/gempak.parm.tmpl" +GBFILE = @[GBFILE] +INDXFL = +GDOUTF = @[GEMGRD] +PROJ = +GRDAREA = +KXKY = +MAXGRD = 4999 +CPYFIL = gds +GAREA = dset +OUTPUT = T +GBTBLS = g2varswmo2.tbl +G2TBLS = +GBDIAG = +PDSEXT = no +l +r +EOF + +# Loop over the grids +for grid in ${grids}; do + case ${grid} in + aoc_9km) + grdIDout='gfswavearc' + ;; + at_10m) + grdIDout='gfswaveat10m' + ;; + ep_10m) + grdIDout='gfswaveep10m' + ;; + wc_10m) + grdIDout='gfswavewc10m' + ;; + glo_30m) + grdIDout='gfswavegl30m' + ;; + gnh_10m) + grdIDout='gfswavenh' + ;; + gsh_15m) + grdIDout='gfswavesh' + ;; + glo_200) + grdIDout='gfswaves200k' + ;; + *) + echo "FATAL ERROR: Unspecified grid '${grid}'" + exit 9 + ;; + esac + process_grdID "${grid}" + + com_varname="COMIN_WAVE_GRID_${GRDREGION}_${GRDRES}" + com_dir=${!com_varname} + GRIBIN="${RUN}.${cycle}.${GRDREGION}.${GRDRES}.f${fhr3}.grib2" + cpreq "${com_dir}/${GRIBIN}" "./${GRIBIN}" + + nagrib_file="${GRIBIN}" + if [[ "${GRDREGION}.${GRDRES}" = "global.0p25" ]]; then + nagrib_file="${RUN}.${cycle}.global.${gridIDout}.${fhr3}.grib2" + ${WGRIB2} -lola 0:720:0.5 -90:361:0.5 "${nagrib_file}" grib "${GRIBIN}" + export err=$? + if [[ ${err} -ne 0 ]]; then + export pgm="${WGRIB2}" + err_exit "wgrib2 failed to interpolate" + fi + fi + + GEMGRD="${grdIDout}_${PDY}${cyc}f${fhr3}" + GBFILE="grib_${grid}" + + cpreq "${nagrib_file}" "${GBFILE}" + + rm -f "gempak.parm.${grid}" + atparse < "${DATA}/gempak.parm.tmpl" >> "${DATA}/gempak.parm.${grid}" + cat "${DATA}/gempak.parm.${grid}" + + startmsg + export pgm="${NAGRIB}" + ${pgm} < "${DATA}/gempak.parm.${grid}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "${pgm} failed during the generation of ${GEMGRD}" + fi + ##################################################### + # GEMPAK DOES NOT ALWAYS HAVE A NON ZERO RETURN CODE + # WHEN IT CAN NOT PRODUCE THE DESIRED GRID. CHECK + # FOR THIS CASE HERE. + ##################################################### + if [[ -f "${GEMGRD}" ]]; then + ls -l "${GEMGRD}" + else + export err=1 + export pgm="GEMPAK CHECK FILE" + err_exit "Gempak failed to generate the desired grid ${GEMGRD}" + fi + + if [[ "${NAGRIB}" == "nagrib2" ]]; then gpend; fi + + # Copy output to COMOUT + cpfs "${GEMGRD}" "${COMOUT_WAVE_GEMPAK}/${GEMGRD}" + + if [[ "${SENDDBN}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" "${COMOUT_WAVE_GEMPAK}/${GEMGRD}" + fi + +done diff --git a/scripts/exgfs_wave_post_gridded_sbs.sh b/dev/scripts/exgfs_wave_post_gridded_sbs.sh similarity index 56% rename from scripts/exgfs_wave_post_gridded_sbs.sh rename to dev/scripts/exgfs_wave_post_gridded_sbs.sh index 6d17b35521b..0d12e48075c 100755 --- a/scripts/exgfs_wave_post_gridded_sbs.sh +++ b/dev/scripts/exgfs_wave_post_gridded_sbs.sh @@ -37,12 +37,12 @@ cat << EOF INFO: Post-process grids: ${wavepostGRD} EOF -fhr3=$(printf %03i ${FORECAST_HOUR}) +fhr3=$(printf %03i "${FORECAST_HOUR}") valid_time=$(date -u -d "${PDY} ${cyc} + ${FORECAST_HOUR} hours" "+%Y%m%d%H") # Copy model definition files for grdID in ${waveGRD} ${wavepostGRD} ${waveinterpGRD}; do - cpreq "${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" "mod_def.${grdID}" + cpreq "${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" "mod_def.${grdID}" done # Copy model forecast data to DATA @@ -50,12 +50,12 @@ cpreq "${COMIN_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.f${fhr3}.bin" "./out_grd # Check for input templates for grib2 products (copying will be done in the grib2 script) if [[ "${DOGRB_WAV}" == "YES" ]]; then - for grbGRD in ${waveinterpGRD} ${wavepostGRD}; do - if [[ ! -f "${PARMgfs}/wave/ww3_grib2.${grbGRD}.inp.tmpl" ]]; then - export err=1 - err_exit "No template for grib generation" - fi - done + for grbGRD in ${waveinterpGRD} ${wavepostGRD}; do + if [[ ! -f "${PARMgfs}/wave/ww3_grib2.${grbGRD}.inp.tmpl" ]]; then + export err=1 + err_exit "No template for grib generation" + fi + done fi # Data summary @@ -68,53 +68,53 @@ cat << EOF EOF if [[ "${DOGRB_WAV}" == "NO" ]]; then - export err=1 - err_exit "DOGRB_WAV = NO; No grib2 products will be created, ABORT!" + export err=1 + err_exit "DOGRB_WAV = NO; No grib2 products will be created, ABORT!" fi # 2.a Command file set-up rm -f cmdfile.* cmdfile -count=0 # Counter for command files +count=0 # Counter for command files # Products on the interpolation grid "waveinterpGRD" if [[ "${DOGRI_WAV}" == "YES" ]]; then - dt_int=3600. - n_int=9999 - ymdh_int=$(date -u -d "${valid_time:0:8} ${valid_time:8:2} - ${WAVHINDH} hours" "+%Y%m%d%H") - for grdID in ${waveinterpGRD}; do - count=$(( count+1 )) - echo "#!/bin/bash" > "cmdfile.${count}" - echo "${USHgfs}/wave_grid_interp_sbs.sh ${grdID} ${ymdh_int} ${dt_int} ${n_int} > ${DATA}/grid_interp_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" - echo "cat ${DATA}/grid_interp_${grdID}.out" >> "cmdfile.${count}" - if [[ "${DOGRB_WAV}" == "YES" ]]; then - process_grdID "${grdID}" - echo "${USHgfs}/wave_grib2_sbs.sh ${grdID} ${GRIDNR} ${MODNR} ${valid_time} ${FORECAST_HOUR} ${GRDREGION} ${GRDRES} '${OUTPARS_WAV}' > ${DATA}/grib2_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" - echo "cat ${DATA}/grib2_${grdID}.out" >> "${DATA}/cmdfile.${count}" - fi - chmod 755 "cmdfile.${count}" - echo "${DATA}/cmdfile.${count}" >> "${DATA}/cmdfile" - done + dt_int=3600. + n_int=9999 + ymdh_int=$(date -u -d "${valid_time:0:8} ${valid_time:8:2} - ${WAVHINDH} hours" "+%Y%m%d%H") + for grdID in ${waveinterpGRD}; do + count=$((count + 1)) + echo "#!/bin/bash" > "cmdfile.${count}" + echo "${USHgfs}/wave_grid_interp_sbs.sh ${grdID} ${ymdh_int} ${dt_int} ${n_int} > ${DATA}/grid_interp_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" + echo "cat ${DATA}/grid_interp_${grdID}.out" >> "cmdfile.${count}" + if [[ "${DOGRB_WAV}" == "YES" ]]; then + process_grdID "${grdID}" + echo "${USHgfs}/wave_grib2_sbs.sh ${grdID} ${GRIDNR} ${MODNR} ${valid_time} ${FORECAST_HOUR} ${GRDREGION} ${GRDRES} '${OUTPARS_WAV}' > ${DATA}/grib2_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" + echo "cat ${DATA}/grib2_${grdID}.out" >> "${DATA}/cmdfile.${count}" + fi + chmod 755 "cmdfile.${count}" + echo "${DATA}/cmdfile.${count}" >> "${DATA}/cmdfile" + done fi # Products on the post-processing grid "wavepostGRD" if [[ "${DOGRB_WAV}" == "YES" ]]; then - for grdID in ${wavepostGRD}; do # First concatenate grib files for sbs grids - count=$(( count+1 )) - process_grdID "${grdID}" - echo "#!/bin/bash" > "cmdfile.${count}" - echo "${USHgfs}/wave_grib2_sbs.sh ${grdID} ${GRIDNR} ${MODNR} ${valid_time} ${FORECAST_HOUR} ${GRDREGION} ${GRDRES} '${OUTPARS_WAV}' > grib2_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" - echo "cat ${DATA}/grib2_${grdID}.out" >> "${DATA}/cmdfile.${count}" - chmod 755 "cmdfile.${count}" - echo "${DATA}/cmdfile.${count}" >> "${DATA}/cmdfile" - done + for grdID in ${wavepostGRD}; do # First concatenate grib files for sbs grids + count=$((count + 1)) + process_grdID "${grdID}" + echo "#!/bin/bash" > "cmdfile.${count}" + echo "${USHgfs}/wave_grib2_sbs.sh ${grdID} ${GRIDNR} ${MODNR} ${valid_time} ${FORECAST_HOUR} ${GRDREGION} ${GRDRES} '${OUTPARS_WAV}' > grib2_${grdID}.out 2>&1" >> "${DATA}/cmdfile.${count}" + echo "cat ${DATA}/grib2_${grdID}.out" >> "${DATA}/cmdfile.${count}" + chmod 755 "cmdfile.${count}" + echo "${DATA}/cmdfile.${count}" >> "${DATA}/cmdfile" + done fi # Ensure there are enough processors for MPMD else use serial if [[ ${ntasks} -lt ${count} ]]; then - if [[ "${USE_CFP:-}" == "YES" ]]; then - echo "WARNING: Not enough processors for MPMD, '${ntasks} < ${count}', running in serial mode" - export USE_CFP="NO" - fi + if [[ "${USE_CFP:-}" == "YES" ]]; then + echo "WARNING: Not enough processors for MPMD, '${ntasks} < ${count}', running in serial mode" + export USE_CFP="NO" + fi fi # Execute command file @@ -122,7 +122,7 @@ echo "INFO: Running MPMD job with ${count} commands" "${USHgfs}/run_mpmd.sh" "${DATA}/cmdfile" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "run_mpmd.sh failed!" + err_exit "run_mpmd.sh failed!" fi # Check if grib2 file created @@ -131,8 +131,8 @@ com_varname="COMOUT_WAVE_GRID_${GRDREGION}_${GRDRES}" com_dir=${!com_varname} gribchk="${RUN}.t${cyc}z.${GRDREGION}.${GRDRES}.f${fhr3}.grib2" if [[ ! -s "${com_dir}/${gribchk}" ]]; then - export err=2 - err_exit "'${gribchk}' not generated in this job" + export err=2 + err_exit "'${gribchk}' not generated in this job" fi exit 0 diff --git a/dev/scripts/exgfs_wave_post_pnt.sh b/dev/scripts/exgfs_wave_post_pnt.sh new file mode 100755 index 00000000000..6525a18339c --- /dev/null +++ b/dev/scripts/exgfs_wave_post_pnt.sh @@ -0,0 +1,304 @@ +#! /usr/bin/env bash + +################################################################################ +# +# UNIX Script Documentation Block +# Script name: exgfs_wave_post_pnt.sh +# Script description: Creates point output products from NetCDF WW3 point data +# +# Abstract: This script is the point postprocessor for the wave component in GFS. +# It executes several scripts forpreparing and creating output data +# as follows: +# +# wave_tar.sh : tars the spectral and bulletin multiple files +# +# COM inputs: +# - ${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin +# - ${COMIN_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${FH3}.nc +# +# $Id$ +# +# Attributes: +# Language: Bourne-again (Bash) Shell +# +############################################################################### +# +# --------------------------------------------------------------------------- # +# 0. Preparations + +# 0.a Basic modes of operation + +export WAV_MOD_TAG="${RUN}.t${cyc}z" + +# Script will run only if pre-defined NTASKS +# The actual work is distributed over these tasks. +if [[ -z "${NTASKS}" ]]; then + export err=1 + err_exit "Requires NTASKS to be set" +fi + +# 0.c Defining model grids + +waveuoutpGRD=${waveuoutpGRD:?buoyNotSet} + +# 0.c.1 Define a temporary directory for storing ascii point output files +# and flush it + +export STA_DIR="${DATA}/station_ascii_files" +rm -rf "${STA_DIR}" +mkdir -p "${STA_DIR}" +mkdir -p "${STA_DIR}/spec" +mkdir -p "${STA_DIR}/bull" +mkdir -p "${STA_DIR}/cbull" + +printf "\n Grid information :\n ------------------\n Output points : %s\n" "${waveuoutpGRD}" + +# --------------------------------------------------------------------------- # +# 1. Get files that are used by most child scripts + +printf "\nPreparing input files :\n-------------------------\n" + +# 1.a Model definition files and output files (set up using poe) + +# Copy model definition files +iloop=0 +for grdID in ${waveuoutpGRD}; do + if [[ -f "${COMIN_WAVE_PREP}/${WAV_MOD_TAG}.mod_def.${grdID}.bin" ]]; then + echo " Mod def file for ${grdID} found in ${COMIN_WAVE_PREP}. copying ...." + cpreq -f "${COMIN_WAVE_PREP}/${WAV_MOD_TAG}.mod_def.${grdID}.bin" "mod_def.${grdID}" + iloop=$((iloop + 1)) + fi +done + +for grdID in ${waveuoutpGRD}; do + if [[ -f "mod_def.${grdID}" ]]; then + echo "File mod_def.${grdID} found. Syncing to all nodes ..." + else + export err=2 + err_exit "NO MOD_DEF FILE mod_def.${grdID}" + fi +done + +# 1.b Output locations file + +rm -f buoy.loc +if [[ -f "${PARMgfs}/wave/wave_${NET}.buoys" ]]; then + cpreq -f "${PARMgfs}/wave/wave_${NET}.buoys" buoy.loc.temp + if [[ "${DOBNDPNT_WAV}" == "YES" ]]; then + #only do boundary points + # shellcheck disable=SC2312 + sed -n '/^\$.*/!p' buoy.loc.temp | grep IBP > buoy.loc || { + echo "WARNING: No boundary points found in buoy file ${PARMgfs}/wave/wave_${NET}.buoys" + echo " Ending job without doing anything." + exit 0 + } + else + #exclude boundary points + # shellcheck disable=SC2312 + sed -n '/^\$.*/!p' buoy.loc.temp | grep -v IBP > buoy.loc + fi +fi + +if [[ -s buoy.loc ]]; then + echo " buoy.loc and buoy.ibp copied and processed (${PARMgfs}/wave/wave_${NET}.buoys)." +else + export err=3 + err_exit 'NO BUOY LOCATION FILE' +fi + +# 1.c Input template files + +if [[ -f "${PARMgfs}/wave/ww3_outp_spec.inp.tmpl" ]]; then + cpreq -f "${PARMgfs}/wave/ww3_outp_spec.inp.tmpl" ww3_outp_spec.inp.tmpl +fi + +if [[ -f ww3_outp_spec.inp.tmpl ]]; then + echo " ww3_outp_spec.inp.tmpl copied. Syncing to all grids ..." +else + export err=3 + err_exit "NO TEMPLATE FOR SPEC INPUT FILE" +fi + +if [[ -f "${PARMgfs}/wave/ww3_outp_bull.inp.tmpl" ]]; then + cpreq "${PARMgfs}/wave/ww3_outp_bull.inp.tmpl" ww3_outp_bull.inp.tmpl +fi + +if [[ -f ww3_outp_bull.inp.tmpl ]]; then + echo " ww3_outp_bull.inp.tmpl copied. Syncing to all nodes ..." +else + export err=4 + err_exit "NO TEMPLATE FOR BULLETIN INPUT FILE" +fi + +# 1.d Linking the output files + +# Loop through forecast hours to link output file +fhr=${FHMIN_WAV} +while [[ ${fhr} -le ${FHMAX_WAV_PNT} ]]; do + ymdhms=$(date --utc +%Y%m%d.%H0000 -d "${PDY} ${cyc} + ${fhr} hours") + FH3=$(printf %03i "${fhr}") + pfile="${COMIN_WAVE_HISTORY}/${WAV_MOD_TAG}.points.f${FH3}.nc" + if [[ -f "${pfile}" ]]; then + ${NLN} "${pfile}" "./${ymdhms}.out_pnt.ww3.nc" + else + export err=7 + err_exit "NO RAW POINT OUTPUT FILE ${ymdhms}.out_pnt.ww3.nc" + fi + + FHINCP=$((DTPNT_WAV / 3600)) + fhr=$((fhr + FHINCP)) # no gridded output, loop with out_pnt stride +done + +# 1.e Getting buoy information for points + +ymdh=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${WAVHINDH} hours") +tstart="${ymdh:0:8} ${ymdh:8:2}0000" +truntime="${PDY} ${cyc}0000" +N=$(((FHMAX_WAV_PNT - FHMIN_WAV) * 3600 / DTPNT_WAV + 1)) + +if [[ "${DOSPC_WAV}" == "YES" || "${DOBLL_WAV}" == "YES" ]]; then + sed -e "s/TIME/${tstart}/g" \ + -e "s/DT/${DTPNT_WAV}/g" \ + -e "s/999/${N}/g" \ + -e "s/PREFIX/${RUN}/g" \ + -e "s/^.*POINT.*/\$ &/g" \ + -e "s/ITYPE/0/g" \ + -e "s/FORMAT/F/g" \ + ww3_outp_spec.inp.tmpl > ww3_outp.inp +fi + +rm -f buoy_tmp.loc buoy_log.ww3 ww3_oup.inp +${NLN} "./mod_def.${waveuoutpGRD}" ./mod_def.ww3 + +export pgm="${NET,,}_ww3_outp.x" +source prep_step + +"${EXECgfs}/${pgm}" > buoy_lst.loc 2>&1 +export err=$? +if [[ ${err} -ne 0 && ! -f buoy_log.ww3 ]]; then + cat buoy_tmp.loc || true + export err=5 + err_exit "${WAV_MOD_TAG} post ${date} ${cycle} : buoy log file failed to be created." +fi + +# Create new buoy_log.ww3 +# shellcheck disable=SC2312 +awk '{print $3}' buoy.loc | sed 's/'\''//g' > ibp_tags +grep -F -f ibp_tags buoy_log.ww3 > buoy_log.tmp +rm -f buoy_log.dat +mv buoy_log.tmp buoy_log.dat + +Nb=$(wc -l < buoy_log.dat) + +if [[ -s buoy_log.dat ]]; then + echo 'Buoy log file created. Syncing to all nodes ...' +else + export err=6 + err_exit "NO BUOY LOG FILE CREATED" +fi + +# 1.f Data summary + +# shellcheck disable=SC2312 +cat << EOF + +Input files read and processed at : $(date) + +Data summary : +--------------------------------------------- + Sufficient data for spectral files : ${DOSPC_WAV} (${Nb} points) + Sufficient data for bulletins : ${DOBLL_WAV} (${Nb} points) + Boundary points : ${DOBNDPNT_WAV} + +EOF + +# --------------------------------------------------------------------------- # +# 2. Make files for processing boundary points +# +# 2.a Creating ww3_outp.inp for each job and execute ww3_outp + +echo ' Making command file for wave post points ' + +# shellcheck disable=SC2312 +grep -F -f ibp_tags buoy_log.dat | awk '{ print $2 }' > buoys +# shellcheck disable=SC2312 +grep -F -f buoys buoy_log.ww3 | awk '{ print $1 }' > points +# shellcheck disable=SC2312 +points=$(awk '{print $0 "\\n"}' points | tr -d '\n') +rm -f buoys + +# Generate the ww3_outp.inp file from the template +if [[ "${DOSPC_WAV}" == "YES" ]]; then + sed -e "s/TIME/${tstart}/g" \ + -e "s/DT/${DTPNT_WAV}/g" \ + -e "s/999/${N}/g" \ + -e "s/PREFIX/${RUN}/g" \ + -e "s|POINT|${points}|g" \ + -e "s/ITYPE/1/g" \ + -e "s/FORMAT/F/g" \ + ww3_outp_spec.inp.tmpl > ww3_outp.inp + + export pgm="${NET,,}_ww3_outp.x" + "${EXECgfs}/${pgm}" +fi + +if [[ "${DOBLL_WAV}" == "YES" ]]; then + sed -e "s/TIME/${tstart}/g" \ + -e "s/DT/${DTPNT_WAV}/g" \ + -e "s/999/${N}/g" \ + -e "s/PREFIX/${RUN}/g" \ + -e "s|POINT|${points}|g" \ + -e "s/REFT/${truntime}/g" \ + ww3_outp_bull.inp.tmpl > ww3_outp.inp + export pgm="${NET,,}_ww3_outp.x" + "${EXECgfs}/${pgm}" +fi + +# --------------------------------------------------------------------------- # +# 3. Compress point output data into tar files + +# 3.a Set up cmdfile + +rm -f cmdtarfile +touch cmdtarfile +chmod 744 cmdtarfile + +printf "\n Making command file for taring all point output files." + +# 3.b Execute the taring + +if [[ "${DOBNDPNT_WAV}" == "YES" ]]; then + if [[ "${DOSPC_WAV}" == "YES" ]]; then + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibp ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibp_tar.out" >> cmdtarfile + fi + if [[ "${DOBLL_WAV}" == "YES" ]]; then + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibpbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibpbull_tar.out" >> cmdtarfile + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibpcbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibpcbull_tar.out" >> cmdtarfile + fi +else + if [[ "${DOSPC_WAV}" == "YES" ]]; then + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} spec ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_spec_tar.out" >> cmdtarfile + fi + if [[ "${DOBLL_WAV}" == "YES" ]]; then + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} bull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_bull_tar.out" >> cmdtarfile + echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} cbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_cbull_tar.out" >> cmdtarfile + fi +fi + +# Ensure there are enough processors for MPMD else use serial +ncmds=$(wc -l < cmdtarfile) +if [[ ${NTASKS} -lt ${ncmds} ]]; then + if [[ "${USE_CFP:-}" == "YES" ]]; then + echo "WARNING: Not enough processors for MPMD, '${NTASKS} < ${ncmd}', running in serial mode" + export USE_CFP="NO" + fi +fi + +"${USHgfs}/run_mpmd.sh" "${DATA}/cmdtarfile" && true +export err=$? +if [[ ${err} -ne 0 ]]; then + export pgm="run_mpmd.sh" + err_exit "run_mpmd failed while tarring point outputs." +fi + +# End of WW3 point postprocessor script ---------------------------------------- # diff --git a/scripts/exgfs_wave_prdgen_bulls.sh b/dev/scripts/exgfs_wave_prdgen_bulls.sh similarity index 50% rename from scripts/exgfs_wave_prdgen_bulls.sh rename to dev/scripts/exgfs_wave_prdgen_bulls.sh index afe487fc4e0..e1f89b217da 100755 --- a/scripts/exgfs_wave_prdgen_bulls.sh +++ b/dev/scripts/exgfs_wave_prdgen_bulls.sh @@ -22,125 +22,117 @@ # 0.a Basic modes of operation # PATH for working and home directories - export envir=${envir:-ops} - export cyc=${cyc:-00} - export cycle=${cycle:-t${cyc}z} - export pgmout=OUTPUT.$$ - export pgm="wave prdgen" +export envir=${envir:-ops} +export cyc=${cyc:-00} +export cycle=${cycle:-t${cyc}z} +export pgmout=OUTPUT.$$ +export pgm="wave prdgen" # 0.b Date and time stuff - export date=${PDY} - export YMDH=${PDY}${cyc} - cat << EOF - - ************************************** - *** MWW3 BULLETINS PRODUCTS SCRIPT *** - ************************************** - ${date} ${cycle} - - Starting at : $(date) - - -EOF +export date=${PDY} +export YMDH=${PDY}${cyc} # 1. Get necessary files - echo " Copying bulletins from ${COMIN_WAVE_STATION}" +echo " Copying bulletins from ${COMIN_WAVE_STATION}" # 1.a Link the input file and untar it - BullIn="${COMIN_WAVE_STATION}/${RUN}.${cycle}.cbull.tar" - if [[ -f "${BullIn}" ]]; then - cpreq "${BullIn}" "cbull.tar" - else - export err=1 - err_exit "${RUN} wave prdgen ${date} ${cycle} : bulletin tar file missing." - fi - - echo " Untarring bulletins ..." - tar -xf cbull.tar - OK=$? - - if [[ ${OK} -eq 0 ]]; then - echo " Unpacking successfull ..." - rm -f cbull.tar - else - export err=2 - err_exit "ERROR IN BULLETIN TAR FILE" - fi +BullIn="${COMIN_WAVE_STATION}/${RUN}.${cycle}.cbull.tar" +if [[ -f "${BullIn}" ]]; then + cpreq "${BullIn}" "cbull.tar" +else + export err=1 + err_exit "${RUN} wave prdgen ${date} ${cycle} : bulletin tar file missing." +fi + +echo " Untarring bulletins ..." +tar -xf cbull.tar +OK=$? + +if [[ ${OK} -eq 0 ]]; then + echo " Unpacking successfull ..." + rm -f cbull.tar +else + export err=2 + err_exit "ERROR IN BULLETIN TAR FILE" +fi # 1.b Output locations from bulletin files - Nb=$(ls -1 *.cbull | wc -l) - echo ' ' - echo " Number of bulletin files : ${Nb}" - echo ' --------------------------' - echo ' ' +# shellcheck disable=SC2312 +Nb=$(find . -type f -name "*.cbull" -printf '.' | wc -c) +echo ' ' +echo " Number of bulletin files : ${Nb}" +echo ' --------------------------' +echo ' ' # 1.c Get the datat cards - if [ -f "${PARMgfs}/wave/bull_awips_gfswave.${waveGRD}" ]; then - cpreq "${PARMgfs}/wave/bull_awips_gfswave.${waveGRD}" "awipsbull.data" - else - export err=3 - err_exit "Bulletin header data file missing." - fi +if [[ -f "${PARMgfs}/wave/bull_awips_gfswave.${waveGRD}" ]]; then + cpreq "${PARMgfs}/wave/bull_awips_gfswave.${waveGRD}" "awipsbull.data" +else + export err=3 + err_exit "Bulletin header data file missing." +fi # 2. AWIPS bulletins for output points - printf "\nAWIPS bulletins ...\n------------------\n Sourcing data file with header info ..." +printf "\nAWIPS bulletins ...\n------------------\n Sourcing data file with header info ..." # 2.b Set up environment variables - source awipsbull.data +source awipsbull.data # 2.c Generate list of bulletins to process - echo ' Generating buoy list ...' - bulls=$(sed -e 's/export b//g' -e 's/=/ /' awipsbull.data | grep -v "#" |awk '{print $1}') +echo ' Generating buoy list ...' +# shellcheck disable=SC2312 +bulls=$(sed -e 's/export b//g' -e 's/=/ /' awipsbull.data | grep -v "#" | awk '{print $1}') # 2.d Looping over buoys running formbul - echo ' Looping over buoys ... \n' - - for bull in ${bulls}; do - fname="${RUN}.${bull}.cbull" - oname="awipsbull.${bull}.${cycle}.${RUN}.wave" - headr=$(grep "b${bull}=" awipsbull.data | sed 's/=/ /g' | awk '{ print $3}') - echo "Processing ${bull} (${headr} ${oname}) ..." - - if [[ -z "${headr}" ]] || [[ ! -s "${fname}" ]]; then - export err=4 - err_exit "MISSING BULLETIN INFO" - fi +echo ' Looping over buoys ...' +echo + +for bull in ${bulls}; do + fname="${RUN}.${bull}.cbull" + oname="awipsbull.${bull}.${cycle}.${RUN}.wave" + # shellcheck disable=SC2312 + headr=$(grep "b${bull}=" awipsbull.data | sed 's/=/ /g' | awk '{ print $3}') + echo "Processing ${bull} (${headr} ${oname}) ..." + + if [[ -z "${headr}" ]] || [[ ! -s "${fname}" ]]; then + export err=4 + err_exit "MISSING BULLETIN INFO" + fi - formbul.pl -d "${headr}" -f "${fname}" -j "${job}" -m "${RUN}.wave" \ - -p "${COMOUT_WAVE_WMO}" -s "NO" -o "${oname}" > formbul.out 2>&1 - OK=$? + formbul.pl -d "${headr}" -f "${fname}" -j "${job}" -m "${RUN}.wave" \ + -p "${COMOUT_WAVE_WMO}" -s "NO" -o "${oname}" > formbul.out 2>&1 + OK=$? - if [[ ${OK} -ne 0 || ! -f "${oname}" ]]; then - cat formbul.out - export err=5 - export pgm="formbul" - err_exit "error in formbul.pl failed for bulletin ${bull}" - fi + if [[ ${OK} -ne 0 || ! -f "${oname}" ]]; then + cat formbul.out + export err=5 + export pgm="formbul" + err_exit "error in formbul.pl failed for bulletin ${bull}" + fi - cat "${oname}" >> "awipsbull.${cycle}.${RUN}.wave" + cat "${oname}" >> "awipsbull.${cycle}.${RUN}.wave" - done +done # 3. Send output files to the proper destination cpfs "awipsbull.${cycle}.${RUN}.wave" "${COMOUT_WAVE_WMO}/awipsbull.${cycle}.${RUN}.wave" if [[ "${SENDDBN_NTC}" == YES ]]; then make_ntc_bull.pl "WMOBH" "NONE" "KWBC" "NONE" "${DATA}/awipsbull.${cycle}.${RUN}.wave" \ - "${COMOUT_WAVE_WMO}/awipsbull.${cycle}.${RUN}.wave" + "${COMOUT_WAVE_WMO}/awipsbull.${cycle}.${RUN}.wave" else if [[ "${envir}" == "para" || "${envir}" == "test" || "${envir}" == "dev" ]]; then echo "Making NTC bulletin for parallel environment, but do not alert." SENDDBN=NO make_ntc_bull.pl "WMOBH" "NONE" "KWBC" "NONE" \ - "${DATA}/awipsbull.${cycle}.${RUN}.wave" \ - "${COMOUT_WAVE_WMO}/awipsbull.${cycle}.${RUN}.wave" + "${DATA}/awipsbull.${cycle}.${RUN}.wave" \ + "${COMOUT_WAVE_WMO}/awipsbull.${cycle}.${RUN}.wave" fi fi # --------------------------------------------------------------------------- # # 4. Clean up - rm -f "${RUN}".*.cbull awipsbull.data +rm -f "${RUN}".*.cbull awipsbull.data # --------------------------------------------------------------------------- # # 5. Ending output - # End of MWW3 product generation script -------------------------------------- # diff --git a/dev/scripts/exgfs_wave_prdgen_gridded.sh b/dev/scripts/exgfs_wave_prdgen_gridded.sh new file mode 100755 index 00000000000..07ee67f5d49 --- /dev/null +++ b/dev/scripts/exgfs_wave_prdgen_gridded.sh @@ -0,0 +1,194 @@ +#! /usr/bin/env bash + +############################################################################### +# # +# This script is the product generator ("graphics job") for the # +# GFSv16-wave output for gridded wave fields # +# # +# COM inputs: # +# - ${COMIN_WAVE_GRID}/${RUN}.${cycle}.${grdOut}.f${fhr}.grib2 # +# # +# COM outputs: # +# - ${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut} # +# # +# Origination : 05/02/2007 # +# Last update : 10/08/2020 # +# # +# Oct, 2020 Roberto.Padilla@noaa.gov, Henrique.HAlves@noaa.gov # +# - Merging wave scripts to GFSv16 global workflow # +# # +############################################################################### +# --------------------------------------------------------------------------- # +# 0. Preparations + +source "${USHgfs}/wave_domain_grid.sh" + +# 0.a Basic modes of operation + +fstart=${fstart:-0} +FHMAX_WAV=${FHMAX_WAV_WMO:-180} #180 Total of hours to process +FHMAX_HF_WAV=${FHMAX_HF_WAV_WMO:-72} #from 00 to 72 inc=3 +FHOUT_WAV=${FHOUT_WAV_WMO:-6} #from 72 to 180 inc=6 +FHOUT_HF_WAV=${FHOUT_HF_WAV_WMO:-3} + +echo "Starting MWW3 GRIDDED PRODUCTS SCRIPT" +# Output grids +grids=${GEMPAK_GRIDS:-'aoc_9km at_10m ep_10m wc_10m glo_30m'} +# 0.b Date and time stuff +cat << EOF + + **************************** + *** MWW3 PRODUCTS SCRIPT *** + **************************** + ${PDY} ${cycle} + + AWIPS grib fields + Wave Grids : ${grids} +EOF + +# --------------------------------------------------------------------------- # +# 1. Get necessary files +printf "\nPreparing input files\n-----------------------" + +#======================================================================= + +ASWELL=(SWELL1 SWELL2) # Indices of HS from partitions +ASWPER=(SWPER1 SWPER2) # Indices of PERIODS from partitions +ASWDIR=(SWDIR1 SWDIR2) # Indices of DIRECTIONS from partitions +# (should be same as ASWELL) +#declare -a arrpar=(WIND UGRD VGRD HTSGW PERPW DIRPW WVHGT WVPER WVDIR WDIR ${ASWELL[@]} ${ASWDIR[@]} ${ASWPER[@]}) +declare -a arrpar=(WIND WDIR UGRD VGRD HTSGW PERPW DIRPW WVHGT "${ASWELL[@]}" WVPER "${ASWPER[@]}" WVDIR "${ASWDIR[@]}") +nparam=$(echo "${arrpar[@]}" | wc -w) + +# 1.a Grib file (AWIPS and FAX charts) +# Get input grid + +sleep_interval=5 +max_tries=1000 + +fhcnt="${fstart}" +while [[ "${fhcnt}" -le "${FHMAX_WAV}" ]]; do + fhr=$(printf "%03d" "${fhcnt}") + for grdOut in ${grids}; do + process_grdID "${grdOut}" + + com_varname="COMIN_WAVE_GRID_${GRDREGION}_${GRDRES}" + com_dir=${!com_varname} + + GRIBIN="${com_dir}/${RUN}.${cycle}.${GRDREGION}.${GRDRES}.f${fhr}.grib2" + GRIBIN_chk="${GRIBIN}.idx" + if ! wait_for_file "${GRIBIN_chk}" "${sleep_interval}" "${max_tries}"; then + export err=1 + err_exit "${GRIBIN_chk} not found after waiting $((sleep_interval * (max_tries - 1))) secs" + fi + GRIBOUT="${RUN}.${cycle}.${grdID}.f${fhr}.clipped.grib2" + + iparam=1 + while [[ ${iparam} -le ${nparam} ]]; do + nip=${arrpar[${iparam} - 1]} + prepar=${nip::-1} # Part prefix (assumes 1 digit index) + paridx="${nip:0-1}" + npart=0 + case ${prepar} in + SWELL) npart=1 ;; + SWDIR) npart=1 ;; + SWPER) npart=1 ;; + *) npart=0 ;; + esac + echo "${nip} ${prepar} ${paridx} ${npart}" + rm -f temp.grib2 + if [[ ${npart} -eq 0 ]]; then + #shellcheck disable=SC2312 + ${WGRIB2} "${GRIBIN}" -s | grep ":${nip}" | "${WGRIB2}" -i "${GRIBIN}" -grib temp.grib2 > wgrib.out 2>&1 + #shellcheck disable=SC2312 + ${WGRIB2} temp.grib2 -append -grib "${GRIBOUT}" + else + #shellcheck disable=SC2312 + ${WGRIB2} "${GRIBIN}" -s | grep ":${prepar}" | grep "${paridx} in sequence" | + ${WGRIB2} -i "${GRIBIN}" -grib temp.grib2 > wgrib.out 2>&1 + ${WGRIB2} temp.grib2 -append -grib "${GRIBOUT}" + fi + iparam=$((iparam + 1)) + done #end wave param loop + #====================================================================== + GRIBIN="${RUN}.${cycle}.${grdID}.f${fhr}.clipped.grib2" + + ${NLN} "${GRIBIN}" "gribfile.${grdID}.f${fhr}" + + # 1.d Input template files + parmfile="${PARMgfs}/wave/grib2_${RUN}wave.${grdOut}.f${fhr}" + if [[ -f "${parmfile}" ]]; then + ${NLN} "${parmfile}" "awipsgrb.${grdID}.f${fhr}" + else + export err=3 + err_exit "NO template grib2_${RUN}wave.${grdID}.f${fhr}" + fi + + # 2. AWIPS product generation + # 2.a AWIPS GRIB file with headers + echo ' ' + echo 'AWIPS headers to GRIB file ...' + echo '------------------------------' + + # 2.a.1 Set up for tocgrib2 + echo " Do set up for tocgrib2." + # 2.a.2 Make GRIB index + echo " Make GRIB index for tocgrib2." + export pgm="${GRB2INDEX}" + ${GRB2INDEX} "gribfile.${grdID}.f${fhr}" "gribindex.${grdID}.f${fhr}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "ERROR IN grb2index MWW3 for grid ${grdID}" + fi + + # 2.a.3 Run AWIPS GRIB packing program tocgrib2 + + echo " Run tocgrib2" + export pgm="${TOCGRIB2}" + export pgmout=tocgrib2.out + source prep_step + + AWIPSGRB="awipsgrib" + export FORT11="gribfile.${grdID}.f${fhr}" + export FORT31="gribindex.${grdID}.f${fhr}" + export FORT51="${AWIPSGRB}.${grdID}.f${fhr}" + + ${TOCGRIB2} < "awipsgrb.${grdID}.f${fhr}" > "${pgmout}" 2>&1 + export err=$? + if [[ ${err} -ne 0 ]]; then + cat "${pgmout}" + err_exit "ERROR IN tocgrib2" + else + echo '*** tocgrib2 ran succesfully *** ' + fi + + # 2.a.7 Get the AWIPS grib bulletin out ... + echo " Get awips GRIB bulletins out ..." + echo " Saving ${AWIPSGRB}.${grdOut}.f${fhr} as grib2.${cycle}.awipsww3_${grdID}.f${fhr}" + echo " in ${COMOUT_WAVE_WMO}" + cpfs "${AWIPSGRB}.${grdID}.f${fhr}" "${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut}" + + if [[ "${SENDDBN}" == "YES" ]]; then + echo " Sending ${AWIPSGRB}.${grdID}.f${fhr} to DBRUN." + "${DBNROOT}/bin/dbn_alert" GRIB_LOW "${RUN}" "${job}" "${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut}" + fi + rm -f "${AWIPSGRB}.${grdID}.f${fhr}" "${pgmout}" + done # For grids + + if [[ ${fhcnt} -ge ${FHMAX_HF_WAV} ]]; then + inc="${FHOUT_WAV}" + else + inc="${FHOUT_HF_WAV}" + fi + ((fhcnt = fhcnt + inc)) +done #For fcst time + +# --------------------------------------------------------------------------- # +# 5. Clean up + +rm -f gribfile gribindex.* awipsgrb.* awipsbull.data + +# --------------------------------------------------------------------------- # +# 6. Ending output + +# End of GFSWAVE product generation script -------------------------------------- # diff --git a/dev/scripts/exgfs_wave_prep.sh b/dev/scripts/exgfs_wave_prep.sh new file mode 100755 index 00000000000..bb139147b35 --- /dev/null +++ b/dev/scripts/exgfs_wave_prep.sh @@ -0,0 +1,356 @@ +#! /usr/bin/env bash + +################################################################################ +# +# UNIX Script Documentation Block +# Script name: exwave_prep.sh +# Script description: Creates output products from binary WW3 data +# +# Abstract: This is the preprocessor for the wave component in GFS. +# It executes several scripts for preparing and creating input data +# as follows: +# # +# wave_prnc_ice.sh : preprocess ice fields. # +# wave_prnc_cur.sh : preprocess current fields. # +# # +# COM inputs: # +# - ${COMIN_WAVE_PREP}/${RUN}.wave.mod_def.${grdID} # +# - ${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f#HHH_prog.nc # +# # +# COM outputs: # +# - ${COMOUT_WAVE_PREP}/${RUN}.wave.${WAVECUR_FID}.${cycle}.cur # +# # +# Update record : # +# # +# - Origination: 01-Mar-2007 # +# # +# WAV_MOD_ID and WAV_MOD_TAG replace modID. WAV_MOD_TAG # +# is used for ensemble-specific I/O. For deterministic # +# WAV_MOD_ID=WAV_MOD_TAG # +# # +############################################################################### +# --------------------------------------------------------------------------- # +# 0. Preparations + +# 0.a Basic modes of operation + +# Set wave model ID tag to include member number +# if ensemble; waveMEMB var empty in deterministic +export WAV_MOD_TAG="${RUN}wave${waveMEMB}" + +mkdir outtmp + +# 0.b Date and time stuff + +# Beginning time for outpupt may differ from SDATE if DOIAU=YES +# Roll back ${IAU_FHROT} hours of DOIAU=YES +IAU_FHROT=3 +if [[ "${DOIAU}" == "YES" ]]; then + WAVHINDH=$((WAVHINDH + IAU_FHROT)) +fi +# Set time stamps for model start and output +# For special case when IAU is on but this is an initial half cycle +if [[ ${IAU_OFFSET} -eq 0 ]]; then + # shellcheck disable=SC2153 + ymdh_beg="${PDY}${cyc}" +else + ymdh_beg=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${WAVHINDH} hours") +fi +ymdh_end=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${FHMAX_WAV} hours") +time_beg=$(date --utc -d "${ymdh_beg:0:8} ${ymdh_beg:8:2}" +"%Y%m%d %H0000") +time_end=$(date --utc -d "${ymdh_end:0:8} ${ymdh_end:8:2}" +"%Y%m%d %H0000") +export ymdh_beg_out="${PDY}${cyc}" +export time_beg_out="${PDY} ${cyc}0000" + +# Restart file times (already has IAU_FHROT in WAVHINDH) +RSTOFFSET=$((WAVHCYC - WAVHINDH)) +# Update restart time is added offset relative to model start +RSTOFFSET=$((RSTOFFSET + RSTIOFF_WAV)) +ymdh_rst_ini=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${RSTOFFSET} hours") +RST2OFFSET=$((DT_2_RST_WAV / 3600)) +# DT2 relative to first-first-cycle restart file +ymdh_rst2_ini=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${RST2OFFSET} hours") +# First restart file for cycling +time_rst_ini="${ymdh_rst_ini:0:8} ${ymdh_rst_ini:8:2}0000" +# shellcheck disable=SC2153 +if [[ ${DT_1_RST_WAV} -eq 1 ]]; then + time_rst1_end=${time_rst_ini} +else + RST1OFFSET=$((DT_1_RST_WAV / 3600)) + ymdh_rst1_end=$(date --utc +%Y%m%d%H -d "${ymdh_rst_ini} + ${RST1OFFSET} hours") + time_rst1_end="${ymdh_rst1_end:0:8} ${ymdh_rst1_end:8:2}0000" +fi +export time_rst1_end +# Second restart file for checkpointing +if [[ "${RSTTYPE_WAV}" == "T" ]]; then + time_rst2_ini="${ymdh_rst2_ini:0:8} ${ymdh_rst2_ini:8:2}0000" + time_rst2_end=${time_end} + # Condition for gdas run or any other run when checkpoint stamp is > ymdh_end + if [[ ${ymdh_rst2_ini} -ge ${ymdh_end} ]]; then + ymdh_rst2_ini=$(date --utc +%Y%m%d%H -d "${ymdh_end} + 3 hours") + time_rst2_ini="${ymdh_rst2_ini:0:8} ${ymdh_rst2_ini:8:2}0000" + time_rst2_end=${time_rst2_ini} + fi +else + time_rst2_ini="$" + time_rst2_end= + DT_2_RST_WAV= +fi +export time_rst2_end +cat << EOF + +Times in wave model format : +---------------------------- + date / cycle : ${PDY} ${cycle} + starting time : ${time_beg} + ending time : ${time_end} + +EOF + +# Script will run only if pre-defined NTASKS +# The actual work is distributed over these tasks. +if [[ -z ${NTASKS} ]]; then + export err=1 + err_exit "Requires NTASKS to be set" +fi + +# --------------------------------------------------------------------------- # +# 1. Get files that are used by most child scripts + +printf "Preparing input files :\n-----------------------\n" + +# 1.a Model definition files + +rm -f cmdfile +touch cmdfile + +grdINP='' +if [[ "${WW3ATMINP}" == 'YES' ]]; then + grdINP="${grdINP} ${WAVEWND_FID}" +fi +if [[ "${WW3ICEINP}" == 'YES' ]]; then + grdINP="${grdINP} ${WAVEICE_FID}" +fi +if [[ "${WW3CURINP}" == 'YES' ]]; then + grdINP="${grdINP} ${WAVECUR_FID}" +fi + +for grdID in ${grdINP} ${waveGRD}; do + cpreq "${COMIN_WAVE_PREP}/${RUN}.wave.mod_def.${grdID}" "mod_def.${grdID}" +done + +# 1.b Netcdf Preprocessor template files +declare -a itype +if [[ "${WW3ATMINP}" == 'YES' ]]; then + itype+=(wind) +fi +if [[ "${WW3ICEINP}" == 'YES' ]]; then + itype+=("ice") +fi +if [[ "${WW3CURINP}" == 'YES' ]]; then + itype+=("cur") +fi + +for type in "${itype[@]}"; do + case ${type} in + wind) + grdID=${WAVEWND_FID} + ;; + ice) + grdID=${WAVEICE_FID} + ;; + cur) + grdID=${WAVECUR_FID} + ;; + *) + export err=3 + err_exit 'Input type not yet implemented' + ;; + esac + cpreq "${PARMgfs}/wave/ww3_prnc.${type}.${grdID}.inp.tmpl" ./ +done + +# --------------------------------------------------------------------------- # +# ICEC processing + +if [[ "${WW3ICEINP}" == 'YES' ]]; then + + # --------------------------------------------------------------------------- # + # 2. Ice pre - processing + + # 2.a Check if ice input is perturbed (number of inputs equal to number of wave + # ensemble members + if [[ "${RUNMEM}" == "-1" || "${WW3ICEIENS}" == "T" || "${waveMEMB}" == "00" ]]; then + + "${USHgfs}/wave_prnc_ice.sh" > wave_prnc_ice.out && true + ERR=$? + + if [[ -d ice || ${ERR} -ne 0 ]]; then + sed "s/^/wave_prnc_ice.out : /g" wave_prnc_ice.out + echo ' ' + if [[ ${ERR} -ne 0 ]]; then + export err=${ERR} + else + export err=5 + fi + err_exit "ice field not generated" + else + mv -f wave_prnc_ice.out "${DATA}/outtmp" + printf "\n Ice field unpacking successful.\n" + fi + + else + echo ' ' + echo "WARNING: Ice input is not perturbed, single ice file generated, skipping ${WAV_MOD_TAG}" + echo ' ' + fi +else + echo ' ' + echo "WARNING: No input ice file generated, this run did not request pre-processed ice data" + echo ' ' +fi + +# --------------------------------------------------------------------------- # +# WIND processing +if [[ "${WW3ATMINP}" == 'YES' ]]; then + + export err=6 + err_exit "Not set-up to preprocess wind" +fi + +#------------------------------------------------------------------- +# 3. Process current fields + +if [[ "${WW3CURINP}" == 'YES' ]]; then + + # Get into single file + if [[ "${RUNMEM}" == "-1" || "${WW3CURIENS}" == "T" || "${waveMEMB}" == "00" ]]; then + + printf "\n Concatenate binary current fields ...\n" + + # Prepare files for cfp process + rm -f cmdfile + touch cmdfile + chmod 744 cmdfile + + BDATE=$(date --utc +%Y%m%d%H -d "${RPDY}00 - 24 hours") + bPDY=${BDATE:0:8} + + ymdh_rtofs=${RPDY}00 # RTOFS runs once daily use ${PDY}00 + if [[ ${ymdh_beg} -lt ${ymdh_rtofs} ]]; then + #If the start time is before the first hour of RTOFS, use the previous cycle + export RPDY=${bPDY} + fi + #Set the first time for RTOFS files to be the beginning time of simulation + ymdh_rtofs=${ymdh_beg} + + if [[ "${FHMAX_WAV_CUR}" -le 72 ]]; then + rtofsfile1="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f024_prog.nc" + rtofsfile2="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f048_prog.nc" + rtofsfile3="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f072_prog.nc" + if [[ ! -f ${rtofsfile1} ]] || [[ ! -f ${rtofsfile2} ]] || [[ ! -f ${rtofsfile3} ]]; then + #Needed current files are not available, so use RTOFS from previous day + export RPDY=${bPDY} + fi + else + rtofsfile1="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f096_prog.nc" + rtofsfile2="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f120_prog.nc" + rtofsfile3="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f144_prog.nc" + rtofsfile4="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f168_prog.nc" + rtofsfile5="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f192_prog.nc" + if [[ ! -f ${rtofsfile1} ]] || [[ ! -f ${rtofsfile2} ]] || [[ ! -f ${rtofsfile3} ]] || + [[ ! -f ${rtofsfile4} ]] || [[ ! -f ${rtofsfile5} ]]; then + #Needed current files are not available, so use RTOFS from previous day + export RPDY=${bPDY} + fi + fi + + ymdh_end_rtofs=$(date --utc +%Y%m%d%H -d "${RPDY}00 + ${FHMAX_WAV_CUR} hours") + if [[ ${ymdh_end} -lt ${ymdh_end_rtofs} ]]; then + ymdh_end_rtofs=${ymdh_end} + fi + + DATE_DT=${WAV_CUR_HF_DT} + FLGHF='T' + FLGFIRST='T' + fext='f' + + while [[ ${ymdh_rtofs} -le ${ymdh_end_rtofs} ]]; do + # Timing has to be made relative to the single 00z RTOFS cycle for RTOFS PDY (RPDY) + # Start at first fhr for + fhr_rtofs=$(${NHOUR} "${ymdh_rtofs}" "${RPDY}00") + fh3_rtofs=$(printf "%03d" "${fhr_rtofs#0}") + + curfile1h="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_${fext}${fh3_rtofs}_prog.nc" + curfile3h="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_${fext}${fh3_rtofs}_prog.nc" + + if [[ -s ${curfile1h} && "${FLGHF}" == "T" ]]; then + curfile="${curfile1h}" + elif [[ -s ${curfile3h} ]]; then + curfile="${curfile3h}" + FLGHF='F' + else + echo ' ' + if [[ "${FLGHF}" == "T" ]]; then + curfile="${curfile1h}" + else + curfile="${curfile3h}" + fi + export err=11 + err_exit "NO CURRENT FILE (RTOFS): ${curfile}" + fi + + echo "${USHgfs}/wave_prnc_cur.sh ${ymdh_rtofs} ${curfile} ${fhr_rtofs} ${FLGFIRST} > cur_${ymdh_rtofs}.out 2>&1" >> cmdfile + + if [[ "${FLGFIRST}" == "T" ]]; then + FLGFIRST='F' + fi + + if [[ ${fhr_rtofs} -ge ${WAV_CUR_HF_FH} ]]; then + DATE_DT=${WAV_CUR_DT} + fi + ymdh_rtofs=$(date --utc +%Y%m%d%H -d "${ymdh_rtofs} + ${DATE_DT} hours") + done + + "${USHgfs}/run_mpmd.sh" "${DATA}/cmdfile" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + export pgm="run_mpmd.sh" + echo "run_mpmd failed while generating currents." + # TODO: Should this raise a fatal error whether or not rtofs files are found? + fi + + files=$(find ./ -name "rtofs.*") + + if [[ -z "${files}" ]]; then + export err=11 + err_exit "NO ${WAVECUR_FID}.* FILES FOUND" + fi + + rm -f "cur.${WAVECUR_FID}" + + for file in ${files}; do + echo "${file}" + cat "${file}" >> "cur.${WAVECUR_FID}" + done + + cpfs "cur.${WAVECUR_FID}" "${COMOUT_WAVE_PREP}/${RUN}.wave.${WAVECUR_FID}.${cycle}.cur" + + else + echo + echo " Current input is not perturbed, single cur file generated, skipping ${WAV_MOD_TAG}" + echo + fi + +else + + echo + echo ' Current inputs not generated, this run did not request pre-processed currents ' + echo + +fi + +# --------------------------------------------------------------------------- # +# 4. Ending output + +# End of MWW3 preprocessor script ------------------------------------------- # diff --git a/scripts/exglobal_aero_analysis_finalize.py b/dev/scripts/exglobal_aero_analysis_finalize.py similarity index 100% rename from scripts/exglobal_aero_analysis_finalize.py rename to dev/scripts/exglobal_aero_analysis_finalize.py diff --git a/scripts/exglobal_aero_analysis_initialize.py b/dev/scripts/exglobal_aero_analysis_initialize.py similarity index 100% rename from scripts/exglobal_aero_analysis_initialize.py rename to dev/scripts/exglobal_aero_analysis_initialize.py diff --git a/scripts/exglobal_aero_analysis_variational.py b/dev/scripts/exglobal_aero_analysis_variational.py similarity index 100% rename from scripts/exglobal_aero_analysis_variational.py rename to dev/scripts/exglobal_aero_analysis_variational.py diff --git a/scripts/exglobal_analysis_stats.py b/dev/scripts/exglobal_analysis_stats.py similarity index 100% rename from scripts/exglobal_analysis_stats.py rename to dev/scripts/exglobal_analysis_stats.py diff --git a/scripts/exglobal_archive_tars.py b/dev/scripts/exglobal_archive_tars.py similarity index 99% rename from scripts/exglobal_archive_tars.py rename to dev/scripts/exglobal_archive_tars.py index ece0e4e325a..e05433c14ac 100755 --- a/scripts/exglobal_archive_tars.py +++ b/dev/scripts/exglobal_archive_tars.py @@ -41,7 +41,7 @@ def main(): 'IAUFHRS', 'DO_FIT2OBS', 'NET', 'FHOUT_HF_GFS', 'FHMAX_HF_GFS', 'OFFSET_START_HOUR', 'ARCH_EXPDIR', 'EXPDIR', 'ARCH_EXPDIR_FREQ', 'ARCH_HASHES', 'ARCH_DIFFS', 'SDATE', 'EDATE', 'HOMEgfs', 'DO_GEMPAK', 'DATASETS_YAML', - 'WAVE_OUT_GRIDS', 'DO_GSISOILDA', 'DO_LAND_IAU', 'TARBALL_TYPE'] + 'WAVE_OUT_GRIDS', 'DO_GSISOILDA', 'DO_LAND_IAU', 'TARBALL_TYPE', 'ATMINC_GRID'] archive_dict = AttrDict() for key in keys: diff --git a/dev/scripts/exglobal_archive_vrfy.py b/dev/scripts/exglobal_archive_vrfy.py new file mode 100755 index 00000000000..634c1c1db34 --- /dev/null +++ b/dev/scripts/exglobal_archive_vrfy.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +import os + +from pygfs.task.archive import Archive +from pygfs.utils.archive_vars import ArchiveVrfyVars +from wxflow import AttrDict, Logger, cast_strdict_as_dtypedict, logit, chdir + +# initialize root logger +logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) + + +@logit(logger) +def main(): + + config = cast_strdict_as_dtypedict(os.environ) + + # Instantiate the Archive task object + archive = Archive(config) + + # Collect all archive variables in complete arch_dict for YAML templates + # Use static utility methods from ArchiveVrfyVars + arch_dict = ArchiveVrfyVars.get_all_yaml_vars(archive.task_config) + + # Pass arch_dict to configure_vrfy which will render the Jinja2 YAML + arcdir_set = archive.configure_vrfy(arch_dict) + + with chdir(config.ROTDIR): + + # Populate the product archive (ARCDIR) + archive.execute_store_products(arcdir_set) + + # Clean up any temporary files + archive.clean() + + +if __name__ == '__main__': + main() diff --git a/scripts/exglobal_atm_analysis_finalize.py b/dev/scripts/exglobal_atm_analysis_finalize.py similarity index 100% rename from scripts/exglobal_atm_analysis_finalize.py rename to dev/scripts/exglobal_atm_analysis_finalize.py diff --git a/scripts/exglobal_atm_analysis_fv3_increment.py b/dev/scripts/exglobal_atm_analysis_fv3_increment.py similarity index 100% rename from scripts/exglobal_atm_analysis_fv3_increment.py rename to dev/scripts/exglobal_atm_analysis_fv3_increment.py diff --git a/scripts/exglobal_atm_analysis_initialize.py b/dev/scripts/exglobal_atm_analysis_initialize.py similarity index 100% rename from scripts/exglobal_atm_analysis_initialize.py rename to dev/scripts/exglobal_atm_analysis_initialize.py diff --git a/scripts/exglobal_atm_analysis_variational.py b/dev/scripts/exglobal_atm_analysis_variational.py similarity index 100% rename from scripts/exglobal_atm_analysis_variational.py rename to dev/scripts/exglobal_atm_analysis_variational.py diff --git a/scripts/exglobal_atmens_analysis_finalize.py b/dev/scripts/exglobal_atmens_analysis_finalize.py similarity index 100% rename from scripts/exglobal_atmens_analysis_finalize.py rename to dev/scripts/exglobal_atmens_analysis_finalize.py diff --git a/scripts/exglobal_atmens_analysis_fv3_increment.py b/dev/scripts/exglobal_atmens_analysis_fv3_increment.py similarity index 100% rename from scripts/exglobal_atmens_analysis_fv3_increment.py rename to dev/scripts/exglobal_atmens_analysis_fv3_increment.py diff --git a/scripts/exglobal_atmens_analysis_initialize.py b/dev/scripts/exglobal_atmens_analysis_initialize.py similarity index 100% rename from scripts/exglobal_atmens_analysis_initialize.py rename to dev/scripts/exglobal_atmens_analysis_initialize.py diff --git a/scripts/exglobal_atmens_analysis_letkf.py b/dev/scripts/exglobal_atmens_analysis_letkf.py similarity index 100% rename from scripts/exglobal_atmens_analysis_letkf.py rename to dev/scripts/exglobal_atmens_analysis_letkf.py diff --git a/scripts/exglobal_atmens_analysis_obs.py b/dev/scripts/exglobal_atmens_analysis_obs.py similarity index 100% rename from scripts/exglobal_atmens_analysis_obs.py rename to dev/scripts/exglobal_atmens_analysis_obs.py diff --git a/scripts/exglobal_atmens_analysis_sol.py b/dev/scripts/exglobal_atmens_analysis_sol.py similarity index 100% rename from scripts/exglobal_atmens_analysis_sol.py rename to dev/scripts/exglobal_atmens_analysis_sol.py diff --git a/scripts/exglobal_atmos_analysis.sh b/dev/scripts/exglobal_atmos_analysis.sh similarity index 53% rename from scripts/exglobal_atmos_analysis.sh rename to dev/scripts/exglobal_atmos_analysis.sh index a8b800a1ac5..a53153d97e8 100755 --- a/scripts/exglobal_atmos_analysis.sh +++ b/dev/scripts/exglobal_atmos_analysis.sh @@ -20,7 +20,8 @@ # Set environment. # Directories. -pwd=$(pwd) +# shellcheck disable=SC2153 +cd "${DATA}" || exit 1 # Base variables rCDUMP=${rCDUMP:-"gdas"} @@ -29,16 +30,16 @@ GDUMP=${GDUMP:-"gdas"} # Derived base variables # shellcheck disable=SC2153 GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") +export GDATE BDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - 3 hours") -bPDY=${BDATE:0:8} -bcyc=${BDATE:8:2} +export bPDY=${BDATE:0:8} +export bcyc=${BDATE:8:2} # Utilities export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} export NCLEN=${NCLEN:-${USHgfs}/getncdimlen} COMPRESS=${COMPRESS:-gzip} UNCOMPRESS=${UNCOMPRESS:-gunzip} -APRUNCFP=${APRUNCFP:-""} APRUN_GSI=${APRUN_GSI:-${APRUN:-""}} NTHREADS_GSI=${NTHREADS_GSI:-${NTHREADS:-1}} @@ -56,8 +57,6 @@ IASI_CADS=${IASI_CADS:-".false."} CRIS_CADS=${CRIS_CADS:-".false."} # Diagnostic files options -netcdf_diag=${netcdf_diag:-".true."} -binary_diag=${binary_diag:-".false."} lobsdiag_forenkf=${lobsdiag_forenkf:-".false."} # IAU @@ -185,11 +184,7 @@ ABIAS=${ABIAS:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias.txt} ABIASPC=${ABIASPC:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_pc.txt} ABIASAIR=${ABIASAIR:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_air.txt} ABIASe=${ABIASe:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_int.txt} -RADSTAT=${RADSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat.tar} GSISTAT=${GSISTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}gsistat.txt} -PCPSTAT=${PCPSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}pcpstat} -CNVSTAT=${CNVSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat.tar} -OZNSTAT=${OZNSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat.tar} # Increment files ATMINC=${ATMINC:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i006.nc} @@ -198,21 +193,8 @@ ATMINC=${ATMINC:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i006.nc} RUN_SELECT=${RUN_SELECT:-"NO"} USE_SELECT=${USE_SELECT:-"NO"} USE_RADSTAT=${USE_RADSTAT:-"YES"} -SELECT_OBS=${SELECT_OBS:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput} +SELECT_OBS=${SELECT_OBS:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput.tar} GENDIAG=${GENDIAG:-"YES"} -DIAG_SUFFIX=${DIAG_SUFFIX:-""} -if [[ ${netcdf_diag} == ".true." ]] ; then - DIAG_SUFFIX="${DIAG_SUFFIX}.nc4" -fi -DIAG_COMPRESS=${DIAG_COMPRESS:-"YES"} -DIAG_TARBALL=${DIAG_TARBALL:-"YES"} -USE_CFP=${USE_CFP:-"NO"} -CFP_MP=${CFP_MP:-"NO"} -nm="" -if [[ ${CFP_MP} == "YES" ]]; then - nm=0 -fi -DIAG_DIR=${DIAG_DIR:-${COMOUT_ATMOS_ANALYSIS}/gsidiags} # Set script / GSI control parameters DOHYBVAR=${DOHYBVAR:-"NO"} @@ -234,67 +216,68 @@ export INCREMENTS_TO_ZERO=${INCREMENTS_TO_ZERO:-"'NONE'"} USE_CORRELATED_OBERRS=${USE_CORRELATED_OBERRS:-"YES"} # Get header information from Guess files -LONB=${LONB:-$(${NCLEN} ${ATMGES} grid_xt)} # get LONB -LATB=${LATB:-$(${NCLEN} ${ATMGES} grid_yt)} # get LATB -LEVS=${LEVS:-$(${NCLEN} ${ATMGES} pfull)} # get LEVS -JCAP=${JCAP:--9999} # there is no jcap in these files -if [[ ${JCAP} -eq -9999 && ${LATB} -ne -9999 ]]; then - JCAP=$((LATB-2)) +LONB=${LONB:-$(${NCLEN} "${ATMGES}" grid_xt)} # get LONB +LATB=${LATB:-$(${NCLEN} "${ATMGES}" grid_yt)} # get LATB +LEVS=${LEVS:-$(${NCLEN} "${ATMGES}" pfull)} # get LEVS +JCAP=${JCAP:--9999} # there is no jcap in these files +if [[ "${JCAP}" -eq -9999 && "${LATB}" -ne -9999 ]]; then + JCAP=$((LATB - 2)) fi -if [[ ${LONB} -eq -9999 || ${LATB} -eq -9999 || ${LEVS} -eq -9999 || ${JCAP} -eq -9999 ]]; then - exit 9 +if [[ "${LONB}" -eq -9999 || "${LATB}" -eq -9999 || "${LEVS}" -eq -9999 || "${JCAP}" -eq -9999 ]]; then + exit 9 fi # Get header information from Ensemble Guess files -if [[ ${DOHYBVAR} == "YES" ]]; then - SFCGES_ENSMEAN=${SFCGES_ENSMEAN:-${COMIN_ATMOS_HISTORY_ENS_PREV}/${GPREFIX_ENS}ensmean.sfc.f006.nc} - export ATMGES_ENSMEAN=${ATMGES_ENSMEAN:-${COMIN_ATMOS_HISTORY_ENS_PREV}/${GPREFIX_ENS}ensmean.atm.f006.nc} - LONB_ENKF=${LONB_ENKF:-$(${NCLEN} ${ATMGES_ENSMEAN} grid_xt)} # get LONB_ENKF - LATB_ENKF=${LATB_ENKF:-$(${NCLEN} ${ATMGES_ENSMEAN} grid_yt)} # get LATB_ENFK - LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} ${ATMGES_ENSMEAN} pfull)} # get LATB_ENFK - JCAP_ENKF=${JCAP_ENKF:--9999} # again, no jcap in the netcdf files - NLON_ENKF=${NLON_ENKF:-${LONB_ENKF}} - NLAT_ENKF=${NLAT_ENKF:-$((${LATB_ENKF}+2))} - if [[ ${JCAP_ENKF} -eq -9999 && ${LATB_ENKF} -ne -9999 ]]; then - JCAP_ENKF=$((LATB_ENKF-2)) - fi - if [[ ${LONB_ENKF} -eq -9999 || ${LATB_ENKF} -eq -9999 || ${LEVS_ENKF} -eq -9999 || ${JCAP_ENKF} -eq -9999 ]]; then - exit 9 - fi +if [[ "${DOHYBVAR}" == "YES" ]]; then + SFCGES_ENSMEAN=${SFCGES_ENSMEAN:-${COMIN_ATMOS_HISTORY_ENS_PREV}/${GPREFIX_ENS}ensmean.sfc.f006.nc} + export ATMGES_ENSMEAN=${ATMGES_ENSMEAN:-${COMIN_ATMOS_HISTORY_ENS_PREV}/${GPREFIX_ENS}ensmean.atm.f006.nc} + LONB_ENKF=${LONB_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" grid_xt)} # get LONB_ENKF + LATB_ENKF=${LATB_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" grid_yt)} # get LATB_ENFK + LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" pfull)} # get LATB_ENFK + JCAP_ENKF=${JCAP_ENKF:--9999} # again, no jcap in the netcdf files + NLON_ENKF=${NLON_ENKF:-${LONB_ENKF}} + NLAT_ENKF=${NLAT_ENKF:-$((LATB_ENKF + 2))} + if [[ "${JCAP_ENKF}" -eq -9999 && "${LATB_ENKF}" -ne -9999 ]]; then + JCAP_ENKF=$((LATB_ENKF - 2)) + fi + if [[ "${LONB_ENKF}" -eq -9999 || "${LATB_ENKF}" -eq -9999 || "${LEVS_ENKF}" -eq -9999 || "${JCAP_ENKF}" -eq -9999 ]]; then + exit 9 + fi else - LONB_ENKF=0 # just for if statement later + LONB_ENKF=0 # just for if statement later fi # Get dimension information based on CASE res=${CASE_HIST:1} -JCAP_CASE=$((res*2-2)) -LATB_CASE=$((res*2)) -LONB_CASE=$((res*4)) +JCAP_CASE=$((res * 2 - 2)) +LATB_CASE=$((res * 2)) +LONB_CASE=$((res * 4)) +export JCAP_CASE LATB_CASE LONB_CASE # Set analysis resolution information -if [[ ${DOHYBVAR} == "YES" ]]; then - JCAP_A=${JCAP_A:-${JCAP_ENKF:-${JCAP}}} - LONA=${LONA:-${LONB_ENKF:-${LONB}}} - LATA=${LATA:-${LATB_ENKF:-${LATB}}} +if [[ "${DOHYBVAR}" == "YES" ]]; then + JCAP_A=${JCAP_A:-${JCAP_ENKF:-${JCAP}}} + LONA=${LONA:-${LONB_ENKF:-${LONB}}} + LATA=${LATA:-${LATB_ENKF:-${LATB}}} else - JCAP_A=${JCAP_A:-${JCAP}} - LONA=${LONA:-${LONB}} - LATA=${LATA:-${LATB}} + JCAP_A=${JCAP_A:-${JCAP}} + LONA=${LONA:-${LONB}} + LATA=${LATA:-${LATB}} fi NLON_A=${NLON_A:-${LONA}} -NLAT_A=${NLAT_A:-$((${LATA}+2))} +NLAT_A=${NLAT_A:-$((LATA + 2))} -DELTIM=${DELTIM:-$((3600/(${JCAP_A}/20)))} +DELTIM=${DELTIM:-$((3600 / (JCAP_A / 20)))} # determine if writing or calculating increment -if [[ ${DO_CALC_INCREMENT} == "YES" ]]; then - write_fv3_increment=".false." +if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + write_fv3_increment=".false." else - write_fv3_increment=".true." - WRITE_INCR_ZERO="incvars_to_zero= ${INCREMENTS_TO_ZERO}," - WRITE_ZERO_STRAT="incvars_zero_strat= ${INCVARS_ZERO_STRAT}," - WRITE_STRAT_EFOLD="incvars_efold= ${INCVARS_EFOLD}," + write_fv3_increment=".true." + WRITE_INCR_ZERO="incvars_to_zero= ${INCREMENTS_TO_ZERO}," + WRITE_ZERO_STRAT="incvars_zero_strat= ${INCVARS_ZERO_STRAT}," + WRITE_STRAT_EFOLD="incvars_efold= ${INCVARS_EFOLD}," fi # GSI Fix files @@ -334,206 +317,210 @@ RAPIDREFRESH_CLDSURF=${RAPIDREFRESH_CLDSURF:-""} CHEM=${CHEM:-""} NST=${NST:-""} -#uGSI Namelist parameters -lrun_subdirs=${lrun_subdirs:-".true."} -if [[ ${DOHYBVAR} == "YES" ]]; then - l_hyb_ens=.true. - export l4densvar=${l4densvar:-".false."} - export lwrite4danl=${lwrite4danl:-".false."} +# GSI Namelist parameters +if [[ "${DOHYBVAR}" == "YES" ]]; then + l_hyb_ens=.true. + export l4densvar=${l4densvar:-".false."} + export lwrite4danl=${lwrite4danl:-".false."} else - l_hyb_ens=.false. - export l4densvar=.false. - export lwrite4danl=.false. + l_hyb_ens=.false. + export l4densvar=.false. + export lwrite4danl=.false. fi # Set 4D-EnVar specific variables -if [[ ${DOHYBVAR} == "YES" && ${l4densvar} == ".true." && ${lwrite4danl} == ".true." ]]; then - ATMA03=${ATMA03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a003.nc} - ATMI03=${ATMI03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i003.nc} - ATMA04=${ATMA04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a004.nc} - ATMI04=${ATMI04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i004.nc} - ATMA05=${ATMA05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a005.nc} - ATMI05=${ATMI05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i005.nc} - ATMA07=${ATMA07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a007.nc} - ATMI07=${ATMI07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i007.nc} - ATMA08=${ATMA08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a008.nc} - ATMI08=${ATMI08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i008.nc} - ATMA09=${ATMA09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a009.nc} - ATMI09=${ATMI09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i009.nc} +if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then + ATMA03=${ATMA03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a003.nc} + ATMI03=${ATMI03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i003.nc} + ATMA04=${ATMA04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a004.nc} + ATMI04=${ATMI04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i004.nc} + ATMA05=${ATMA05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a005.nc} + ATMI05=${ATMI05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i005.nc} + ATMA07=${ATMA07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a007.nc} + ATMI07=${ATMI07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i007.nc} + ATMA08=${ATMA08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a008.nc} + ATMI08=${ATMI08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i008.nc} + ATMA09=${ATMA09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a009.nc} + ATMI09=${ATMI09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i009.nc} fi ############################################################## # Fixed files -${NLN} ${BERROR} berror_stats -${NLN} ${SATANGL} satbias_angle -if [[ ${SATINFO} == "generate" ]]; then - ${USHgfs}/create_gsi_info.sh sat "${PDY}${cyc}" "${DATA}" +${NLN} "${BERROR}" berror_stats +${NLN} "${SATANGL}" satbias_angle +if [[ "${SATINFO}" == "generate" ]]; then + # shellcheck disable=SC2153 + "${USHgfs}/create_gsi_info.sh" sat "${PDY}${cyc}" "${DATA}" else - ${NLN} ${SATINFO} satinfo + ${NLN} "${SATINFO}" satinfo fi -${NLN} ${RADCLOUDINFO} cloudy_radiance_info.txt -${NLN} ${ATMSFILTER} atms_beamwidth.txt -${NLN} ${ANAVINFO} anavinfo -if [[ ${CONVINFO} == "generate" ]]; then - ${USHgfs}/create_gsi_info.sh conv "${PDY}${cyc}" "${DATA}" "${USE_2M_OBS}" +${NLN} "${RADCLOUDINFO}" cloudy_radiance_info.txt +${NLN} "${ATMSFILTER}" atms_beamwidth.txt +${NLN} "${ANAVINFO}" anavinfo +if [[ "${CONVINFO}" == "generate" ]]; then + "${USHgfs}/create_gsi_info.sh" conv "${PDY}${cyc}" "${DATA}" "${USE_2M_OBS}" else - ${NLN} "${CONVINFO}" convinfo + ${NLN} "${CONVINFO}" convinfo fi -${NLN} "${vqcdat}" vqctp001.dat -${NLN} "${INSITUINFO}" insituinfo -if [[ ${OZINFO} == "generate" ]]; then - ${USHgfs}/create_gsi_info.sh oz "${PDY}${cyc}" "${DATA}" +${NLN} "${vqcdat}" vqctp001.dat +${NLN} "${INSITUINFO}" insituinfo +if [[ "${OZINFO}" == "generate" ]]; then + "${USHgfs}/create_gsi_info.sh" oz "${PDY}${cyc}" "${DATA}" else - ${NLN} "${OZINFO}" ozinfo + ${NLN} "${OZINFO}" ozinfo fi -${NLN} "${PCPINFO}" pcpinfo -${NLN} "${AEROINFO}" aeroinfo -${NLN} "${SCANINFO}" scaninfo -${NLN} "${HYBENSINFO}" hybens_info -${NLN} "${OBERROR}" errtable -${NLN} "${BLACKLST}" blacklist +${NLN} "${PCPINFO}" pcpinfo +${NLN} "${AEROINFO}" aeroinfo +${NLN} "${SCANINFO}" scaninfo +${NLN} "${HYBENSINFO}" hybens_info +${NLN} "${OBERROR}" errtable +${NLN} "${BLACKLST}" blacklist -${NLN} "${FIXgfs}/gsi/AIRS_CLDDET.NL" AIRS_CLDDET.NL -${NLN} "${FIXgfs}/gsi/CRIS_CLDDET.NL" CRIS_CLDDET.NL -${NLN} "${FIXgfs}/gsi/IASI_CLDDET.NL" IASI_CLDDET.NL +${NLN} "${FIXgfs}/gsi/AIRS_CLDDET.NL" AIRS_CLDDET.NL +${NLN} "${FIXgfs}/gsi/CRIS_CLDDET.NL" CRIS_CLDDET.NL +${NLN} "${FIXgfs}/gsi/IASI_CLDDET.NL" IASI_CLDDET.NL #If using correlated error, link to the covariance files -if [[ ${USE_CORRELATED_OBERRS} == "YES" ]]; then - if grep -q "Rcov" ${ANAVINFO} ; then - # shellcheck disable=SC2312 - mapfile -t covfile_array < <(find "${FIXgfs}/gsi/" -name "Rcov*") - if (( ${#covfile_array[@]} > 0 )); then - for covfile in "${covfile_array[@]}"; do - covfile_base=$(basename "${covfile}") - ${NLN} "${covfile}" "${DATA}/${covfile_base}" - done - echo "using correlated obs error" - else - echo "FATAL ERROR: Satellite error covariance files (Rcov) are missing." - echo "Check for the required Rcov files in " ${ANAVINFO} - exit 1 - fi - else - echo "FATAL ERROR: Satellite error covariance info missing in " ${ANAVINFO} - exit 1 - fi - -# Correlated error utlizes mkl lapack. Found it necesary to fix the -# number of mkl threads to ensure reproducible results independent -# of the job configuration. - export MKL_NUM_THREADS=1 +if [[ "${USE_CORRELATED_OBERRS}" == "YES" ]]; then + if grep -q "Rcov" "${ANAVINFO}"; then + # shellcheck disable=SC2312 + mapfile -t covfile_array < <(find "${FIXgfs}/gsi/" -name "Rcov*") + if ((${#covfile_array[@]} > 0)); then + for covfile in "${covfile_array[@]}"; do + covfile_base=$(basename "${covfile}") + # shellcheck disable=SC2153 + ${NLN} "${covfile}" "${DATA}/${covfile_base}" + done + echo "using correlated obs error" + else + export err=1 + err_exit "FATAL ERROR: Satellite error covariance files (Rcov) are missing. Check for the required Rcov files in ${ANAVINFO}" + fi + else + export err=1 + err_exit "FATAL ERROR: Satellite error covariance info missing in ${ANAVINFO}" + fi + + # Correlated error utlizes mkl lapack. Found it necesary to fix the + # number of mkl threads to ensure reproducible results independent + # of the job configuration. + export MKL_NUM_THREADS=1 else - echo "not using correlated obs error" + echo "not using correlated obs error" fi ############################################################## # CRTM Spectral and Transmittance coefficients mkdir -p crtm_coeffs +# shellcheck disable=SC2312 for file in $(awk '{if($1!~"!"){print $1}}' satinfo | sort | uniq); do - instr=$(echo ${file} | cut -c1-4) - if [[ ${instr} == "hirs" ]]; then - ${NLN} "${HIRS_FIX}/${file}.SpcCoeff.bin" "./crtm_coeffs/${file}.SpcCoeff.bin" - else - ${NLN} "${CRTM_FIX}/${file}.SpcCoeff.bin" "./crtm_coeffs/${file}.SpcCoeff.bin" - fi - ${NLN} "${CRTM_FIX}/${file}.TauCoeff.bin" "./crtm_coeffs/${file}.TauCoeff.bin" + if [[ ${file:0:4} == "hirs" ]]; then + ${NLN} "${HIRS_FIX}/${file}.SpcCoeff.bin" "./crtm_coeffs/${file}.SpcCoeff.bin" + else + ${NLN} "${CRTM_FIX}/${file}.SpcCoeff.bin" "./crtm_coeffs/${file}.SpcCoeff.bin" + fi + ${NLN} "${CRTM_FIX}/${file}.TauCoeff.bin" "./crtm_coeffs/${file}.TauCoeff.bin" done ${NLN} "${CRTM_FIX}/amsua_metop-a_v2.SpcCoeff.bin" "./crtm_coeffs/amsua_metop-a_v2.SpcCoeff.bin" -${NLN} "${CRTM_FIX}/Nalli.IRwater.EmisCoeff.bin" "./crtm_coeffs/Nalli.IRwater.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.IRice.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRice.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.IRland.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRland.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.IRsnow.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRsnow.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.VISice.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISice.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.VISland.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISland.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/NPOESS.VISsnow.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISsnow.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/Nalli.IRwater.EmisCoeff.bin" "./crtm_coeffs/Nalli.IRwater.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.IRice.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRice.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.IRland.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRland.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.IRsnow.EmisCoeff.bin" "./crtm_coeffs/NPOESS.IRsnow.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.VISice.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISice.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.VISland.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISland.EmisCoeff.bin" +${NLN} "${CRTM_FIX}/NPOESS.VISsnow.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISsnow.EmisCoeff.bin" ${NLN} "${CRTM_FIX}/NPOESS.VISwater.EmisCoeff.bin" "./crtm_coeffs/NPOESS.VISwater.EmisCoeff.bin" ${NLN} "${CRTM_FIX}/FASTEM6.MWwater.EmisCoeff.bin" "./crtm_coeffs/FASTEM6.MWwater.EmisCoeff.bin" -${NLN} "${CRTM_FIX}/AerosolCoeff.bin" "./crtm_coeffs/AerosolCoeff.bin" -if (( imp_physics == 8 )); then - echo "using CRTM Thompson cloud optical table" - ${NLN} "${CRTM_FIX}/CloudCoeff.Thompson08.-109z-1.bin" ./crtm_coeffs/CloudCoeff.bin -elif (( imp_physics == 11 )); then - echo "using CRTM GFDL cloud optical table" - ${NLN} "${CRTM_FIX}/CloudCoeff.GFDLFV3.-109z-1.bin" ./crtm_coeffs/CloudCoeff.bin -else - echo "FATAL ERROR: INVALID imp_physics = ${imp_physics}" - export err=1 - err_exit "No valid CRTM cloud optical table found for imp_physics = ${imp_physics}" -fi - +${NLN} "${CRTM_FIX}/AerosolCoeff.bin" "./crtm_coeffs/AerosolCoeff.bin" + +case "${imp_physics}" in + 8) + echo "Using CRTM Thompson cloud optical table" + ${NLN} "${CRTM_FIX}/CloudCoeff.Thompson08.-109z-1.bin" ./crtm_coeffs/CloudCoeff.bin + ;; + 11) + echo "Using CRTM GFDL cloud optical table" + ${NLN} "${CRTM_FIX}/CloudCoeff.GFDLFV3.-109z-1.bin" ./crtm_coeffs/CloudCoeff.bin + ;; + *) + echo "FATAL ERROR: INVALID imp_physics = ${imp_physics}" + export err=1 + err_exit "No valid CRTM cloud optical table found for imp_physics = ${imp_physics}" + ;; +esac ############################################################## # Observational data -${NLN} "${PREPQC}" prepbufr -${NLN} "${PREPQCPF}" prepbufr_profl -${NLN} "${SATWND}" satwndbufr -${NLN} "${OSCATBF}" oscatbufr -${NLN} "${RAPIDSCATBF}" rapidscatbufr -${NLN} "${GSNDBF}" gsndrbufr -${NLN} "${GSNDBF1}" gsnd1bufr -${NLN} "${B1MSU}" msubufr -${NLN} "${B1AMUA}" amsuabufr -${NLN} "${B1AMUB}" amsubbufr -${NLN} "${B1MHS}" mhsbufr -${NLN} "${B1HRS2}" hirs2bufr -${NLN} "${B1HRS3}" hirs3bufr -${NLN} "${B1HRS4}" hirs4bufr -${NLN} "${ESAMUA}" amsuabufrears -${NLN} "${ESAMUB}" amsubbufrears +${NLN} "${PREPQC}" prepbufr +${NLN} "${PREPQCPF}" prepbufr_profl +${NLN} "${SATWND}" satwndbufr +${NLN} "${OSCATBF}" oscatbufr +${NLN} "${RAPIDSCATBF}" rapidscatbufr +${NLN} "${GSNDBF}" gsndrbufr +${NLN} "${GSNDBF1}" gsnd1bufr +${NLN} "${B1MSU}" msubufr +${NLN} "${B1AMUA}" amsuabufr +${NLN} "${B1AMUB}" amsubbufr +${NLN} "${B1MHS}" mhsbufr +${NLN} "${B1HRS2}" hirs2bufr +${NLN} "${B1HRS3}" hirs3bufr +${NLN} "${B1HRS4}" hirs4bufr +${NLN} "${ESAMUA}" amsuabufrears +${NLN} "${ESAMUB}" amsubbufrears #${NLN} "${ESMHS}" mhsbufrears -${NLN} "${AMUADB}" amsuabufr_db -${NLN} "${AMUBDB}" amsubbufr_db +${NLN} "${AMUADB}" amsuabufr_db +${NLN} "${AMUBDB}" amsubbufr_db #${NLN} "${MHSDB}" mhsbufr_db -${NLN} "${SBUVBF}" sbuvbufr -${NLN} "${OMPSNPBF}" ompsnpbufr -${NLN} "${OMPSLPBF}" ompslpbufr -${NLN} "${OMPSTCBF}" ompstcbufr -${NLN} "${GOMEBF}" gomebufr -${NLN} "${OMIBF}" omibufr -${NLN} "${MLSBF}" mlsbufr -${NLN} "${SMIPCP}" ssmirrbufr -${NLN} "${TMIPCP}" tmirrbufr -${NLN} "${AIRSBF}" airsbufr -${NLN} "${IASIBF}" iasibufr -${NLN} "${ESIASI}" iasibufrears -${NLN} "${IASIDB}" iasibufr_db -${NLN} "${AMSREBF}" amsrebufr -${NLN} "${AMSR2BF}" amsr2bufr -${NLN} "${GMI1CRBF}" gmibufr -${NLN} "${SAPHIRBF}" saphirbufr -${NLN} "${SEVIRIBF}" seviribufr -${NLN} "${CRISBF}" crisbufr -${NLN} "${ESCRIS}" crisbufrears -${NLN} "${CRISDB}" crisbufr_db -${NLN} "${CRISFSBF}" crisfsbufr -${NLN} "${ESCRISFS}" crisfsbufrears -${NLN} "${CRISFSDB}" crisfsbufr_db -${NLN} "${ATMSBF}" atmsbufr -${NLN} "${ESATMS}" atmsbufrears -${NLN} "${ATMSDB}" atmsbufr_db -${NLN} "${SSMITBF}" ssmitbufr -${NLN} "${SSMISBF}" ssmisbufr -${NLN} "${GPSROBF}" gpsrobufr -${NLN} "${TCVITL}" tcvitl -${NLN} "${B1AVHAM}" avhambufr -${NLN} "${B1AVHPM}" avhpmbufr -${NLN} "${AHIBF}" ahibufr -${NLN} "${ABIBF}" abibufr -${NLN} "${HDOB}" hdobbufr -${NLN} "${SSTVIIRS}" sstviirs -${NLN} "${SAILDRONE}" sdbufr -${NLN} "${GSBBF}" wbbufr +${NLN} "${SBUVBF}" sbuvbufr +${NLN} "${OMPSNPBF}" ompsnpbufr +${NLN} "${OMPSLPBF}" ompslpbufr +${NLN} "${OMPSTCBF}" ompstcbufr +${NLN} "${GOMEBF}" gomebufr +${NLN} "${OMIBF}" omibufr +${NLN} "${MLSBF}" mlsbufr +${NLN} "${SMIPCP}" ssmirrbufr +${NLN} "${TMIPCP}" tmirrbufr +${NLN} "${AIRSBF}" airsbufr +${NLN} "${IASIBF}" iasibufr +${NLN} "${ESIASI}" iasibufrears +${NLN} "${IASIDB}" iasibufr_db +${NLN} "${AMSREBF}" amsrebufr +${NLN} "${AMSR2BF}" amsr2bufr +${NLN} "${GMI1CRBF}" gmibufr +${NLN} "${SAPHIRBF}" saphirbufr +${NLN} "${SEVIRIBF}" seviribufr +${NLN} "${CRISBF}" crisbufr +${NLN} "${ESCRIS}" crisbufrears +${NLN} "${CRISDB}" crisbufr_db +${NLN} "${CRISFSBF}" crisfsbufr +${NLN} "${ESCRISFS}" crisfsbufrears +${NLN} "${CRISFSDB}" crisfsbufr_db +${NLN} "${ATMSBF}" atmsbufr +${NLN} "${ESATMS}" atmsbufrears +${NLN} "${ATMSDB}" atmsbufr_db +${NLN} "${SSMITBF}" ssmitbufr +${NLN} "${SSMISBF}" ssmisbufr +${NLN} "${GPSROBF}" gpsrobufr +${NLN} "${TCVITL}" tcvitl +${NLN} "${B1AVHAM}" avhambufr +${NLN} "${B1AVHPM}" avhpmbufr +${NLN} "${AHIBF}" ahibufr +${NLN} "${ABIBF}" abibufr +${NLN} "${HDOB}" hdobbufr +${NLN} "${SSTVIIRS}" sstviirs +${NLN} "${SAILDRONE}" sdbufr +${NLN} "${GSBBF}" wbbufr # NASA ozone (netcdf) from NNJA -${NLN} "${OMIEFFNC}" omieffnc +${NLN} "${OMIEFFNC}" omieffnc ${NLN} "${OMPSNMEFFNC}" ompsnmeffnc -${NLN} "${OMPSNPNC}" ompsnpnc -${NLN} "${OMPSLPNC}" ompslpnc -${NLN} "${MLS55NC}" mls55nc +${NLN} "${OMPSNPNC}" ompsnpnc +${NLN} "${OMPSLPNC}" ompslpnc +${NLN} "${MLS55NC}" mls55nc # NASA airs aqua amsua (bufr) from NNJA -${NLN} "${AQUAAMUA}" aquabufr +${NLN} "${AQUAAMUA}" aquabufr if [[ "${DONST}" == "YES" ]]; then ${NLN} "${NSSTBF}" nsstbufr @@ -541,8 +528,8 @@ fi ############################################################## # Required bias guess files -${NLN} "${GBIAS}" satbias_in -${NLN} "${GBIASPC}" satbias_pc +${NLN} "${GBIAS}" satbias_in +${NLN} "${GBIASPC}" satbias_pc ${NLN} "${GBIASAIR}" aircftbias_in ${NLN} "${GRADSTAT}" radstat.gdas @@ -584,186 +571,140 @@ fi if [[ "${DOHYBVAR}" == "YES" ]]; then - # Link ensemble members - mkdir -p ensemble_data + # Link ensemble members + mkdir -p ensemble_data - ENKF_SUFFIX="smooth." - if [[ "${SMOOTH_ENKF}" == "NO" ]]; then - ENKF_SUFFIX="" - fi + ENKF_SUFFIX="smooth" + if [[ "${SMOOTH_ENKF}" == "NO" ]]; then + ENKF_SUFFIX="" + fi - fhrs="06" - if [[ ${l4densvar} == ".true." ]]; then - fhrs="03 04 05 06 07 08 09" - nhr_obsbin=1 - fi + fhrs="06" + if [[ "${l4densvar}" == ".true." ]]; then + fhrs=$(seq -s ' ' -f '%02g' 3 9) + nhr_obsbin=1 + fi - for imem in $(seq 1 ${NMEM_ENS}); do - memchar="mem$(printf %03i "${imem}")" - MEMDIR=${memchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl \ - COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL + for imem in $(seq 1 "${NMEM_ENS}"); do + memchar="mem$(printf %03i "${imem}")" + MEMDIR=${memchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl \ + COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL - for fhr in ${fhrs}; do - ${NLN} "${COMIN_ATMOS_HISTORY}/${GPREFIX_ENS}${ENKF_SUFFIX}atm.f0${fhr}.nc" "./ensemble_data/sigf${fhr}_ens_${memchar}" - if [[ ${cnvw_option} == ".true." ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY}/${GPREFIX_ENS}sfc.f0${fhr}.nc" "./ensemble_data/sfcf${fhr}_ens_${memchar}" - fi - done - done + for fhr in ${fhrs}; do + ${NLN} "${COMIN_ATMOS_HISTORY}/${GPREFIX_ENS}${ENKF_SUFFIX}atm.f0${fhr}.nc" "./ensemble_data/sigf${fhr}_ens_${memchar}" + if [[ "${cnvw_option}" == ".true." ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY}/${GPREFIX_ENS}sfc.f0${fhr}.nc" "./ensemble_data/sfcf${fhr}_ens_${memchar}" + fi + done + done fi ############################################################## # Handle inconsistent surface mask between background, ensemble and analysis grids # This needs re-visiting in the context of NSST; especially references to JCAP* -if [[ ${JCAP} -ne ${JCAP_A} ]]; then - if [[ ${DOHYBVAR} == "YES" && ${JCAP_A} == "${JCAP_ENKF}" ]]; then - if [[ -e ${SFCGES_ENSMEAN} ]]; then - USE_READIN_ANL_SFCMASK=.true. - ${NLN} "${SFCGES_ENSMEAN}" sfcf06_anlgrid - else - echo "Warning: Inconsistent sfc mask between analysis and ensemble grids, GSI will interpolate" - fi +if [[ "${JCAP}" -ne "${JCAP_A}" ]]; then + if [[ "${DOHYBVAR}" == "YES" && "${JCAP_A}" == "${JCAP_ENKF}" ]]; then + if [[ -e "${SFCGES_ENSMEAN}" ]]; then + USE_READIN_ANL_SFCMASK=.true. + ${NLN} "${SFCGES_ENSMEAN}" sfcf06_anlgrid + else + echo "Warning: Inconsistent sfc mask between analysis and ensemble grids, GSI will interpolate" + fi else - echo "Warning: Inconsistent sfc mask between analysis and background grids, GSI will interpolate" - fi -fi - -############################################################## -# Diagnostic files -# if requested, link GSI diagnostic file directories for use later -if [[ ${GENDIAG} == "YES" ]] ; then - if [[ ${lrun_subdirs} == ".true." ]] ; then - if [[ -d ${DIAG_DIR} ]]; then - rm -rf "${DIAG_DIR}" - fi - ntasks_m1="$((ntasks-1))" - for pe in $(seq 0 ${ntasks_m1}); do - pedir="dir."$(printf %04i ${pe}) - mkdir -p "${DIAG_DIR}/${pedir}" - ${NLN} "${DIAG_DIR}/${pedir}" "${pedir}" - done - else - err_exit "lrun_subdirs must be true. lrun_subdirs=${lrun_subdirs}" - fi + echo "Warning: Inconsistent sfc mask between analysis and background grids, GSI will interpolate" + fi fi ############################################################## # Output files -${NLN} ${ATMANL} siganl -${NLN} ${ATMINC} siginc.nc -if [[ ${DOHYBVAR} == "YES" && ${l4densvar} == ".true." && ${lwrite4danl} == ".true." ]]; then - ${NLN} "${ATMA03}" siga03 - ${NLN} "${ATMI03}" sigi03.nc - ${NLN} "${ATMA04}" siga04 - ${NLN} "${ATMI04}" sigi04.nc - ${NLN} "${ATMA05}" siga05 - ${NLN} "${ATMI05}" sigi05.nc - ${NLN} "${ATMA07}" siga07 - ${NLN} "${ATMI07}" sigi07.nc - ${NLN} "${ATMA08}" siga08 - ${NLN} "${ATMI08}" sigi08.nc - ${NLN} "${ATMA09}" siga09 - ${NLN} "${ATMI09}" sigi09.nc -fi -${NLN} "${ABIAS}" satbias_out -${NLN} "${ABIASPC}" satbias_pc.out -${NLN} ${ABIASAIR} aircftbias_out - -if [[ ${DONST} == "YES" ]]; then - ${NLN} ${DTFANL} dtfanl +${NLN} "${ATMANL}" siganl +${NLN} "${ATMINC}" siginc.nc +if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then + ${NLN} "${ATMA03}" siga03 + ${NLN} "${ATMI03}" sigi03.nc + ${NLN} "${ATMA04}" siga04 + ${NLN} "${ATMI04}" sigi04.nc + ${NLN} "${ATMA05}" siga05 + ${NLN} "${ATMI05}" sigi05.nc + ${NLN} "${ATMA07}" siga07 + ${NLN} "${ATMI07}" sigi07.nc + ${NLN} "${ATMA08}" siga08 + ${NLN} "${ATMI08}" sigi08.nc + ${NLN} "${ATMA09}" siga09 + ${NLN} "${ATMI09}" sigi09.nc +fi +${NLN} "${ABIAS}" satbias_out +${NLN} "${ABIASPC}" satbias_pc.out +${NLN} "${ABIASAIR}" aircftbias_out + +if [[ "${DONST}" == "YES" ]]; then + ${NLN} "${DTFANL}" dtfanl fi # If requested, link (and if tarred, de-tar obsinput.tar) into obs_input.* files -if [[ ${USE_SELECT} == "YES" ]]; then - rm -f obs_input.* - nl=$(file ${SELECT_OBS} | cut -d: -f2 | grep tar | wc -l) - if [[ ${nl} -eq 1 ]]; then - rm -f obsinput.tar - ${NLN} ${SELECT_OBS} obsinput.tar - tar -xvf obsinput.tar - rm -f obsinput.tar - else - for filetop in $(ls ${SELECT_OBS}/obs_input.*); do - fileloc=$(basename ${filetop}) - ${NLN} "${filetop}" "${fileloc}" - done - fi +if [[ "${USE_SELECT}" == "YES" ]]; then + rm -f obs_input.* + # shellcheck disable=SC2312 + nl=$(file "${SELECT_OBS}" | cut -d: -f2 | grep -c tar) + if [[ ${nl} -eq 1 ]]; then + rm -f obsinput.tar + ${NLN} "${SELECT_OBS}" obsinput.tar + tar -xvf obsinput.tar + rm -f obsinput.tar + else + for filetop in "${SELECT_OBS}/"obs_input.*; do + fileloc=$(basename "${filetop}") + ${NLN} "${filetop}" "${fileloc}" + done + fi fi ############################################################## # If requested, copy and de-tar guess radstat file if [[ "${USE_RADSTAT}" == "YES" ]]; then - if [[ "${USE_CFP}" == "YES" ]]; then - if [[ -f "${DATA}/unzip.sh" ]]; then - rm -f "${DATA}/unzip.sh" - fi - if [[ -f "${DATA}/mp_unzip.sh" ]]; then - rm -f "${DATA}/mp_unzip.sh" - fi - cat > "${DATA}/unzip.sh" << EOFunzip -#!/bin/sh - diag_file=\$1 - diag_suffix=\$2 - fname=\$(echo \$diag_file | cut -d'.' -f1) - fdate=\$(echo \$diag_file | cut -d'.' -f2) - ${UNCOMPRESS} \$diag_file - fnameges=\$(echo \$fname | sed 's/_ges//g') - ${NMV} \$fname.\$fdate\$diag_suffix \$fnameges -EOFunzip - chmod 755 ${DATA}/unzip.sh - fi - - listdiag=$(tar xvf radstat.gdas | cut -d' ' -f2 | grep _ges) - for type in ${listdiag}; do - diag_file=$(echo ${type} | cut -d',' -f1) - if [[ ${USE_CFP} == "YES" ]] ; then - echo "${nm} ${DATA}/unzip.sh ${diag_file} ${DIAG_SUFFIX}" | tee -a "${DATA}/mp_unzip.sh" - if [[ ${CFP_MP:-"NO"} == "YES" ]]; then - nm=$((nm+1)) - fi - else - fname=$(echo "${diag_file}" | cut -d'.' -f1) - date=$(echo "${diag_file}" | cut -d'.' -f2) - ${UNCOMPRESS} "${diag_file}" - fnameges=$(echo "${fname}"|sed 's/_ges//g') - ${NMV} "${fname}.${date}${DIAG_SUFFIX}" "${fnameges}" - fi - done - - if [[ "${USE_CFP}" == "YES" ]] ; then - chmod 755 "${DATA}/mp_unzip.sh" - ncmd=$(wc -l < "${DATA}/mp_unzip.sh") - if [[ ${ncmd} -gt 0 ]]; then - if [[ ${ncmd} -lt ${max_tasks_per_node} ]]; then - ncmd_max=${ncmd} - else - ncmd_max=${max_tasks_per_node} - fi - APRUNCFP_UNZIP=$(eval echo "${APRUNCFP}") - ${APRUNCFP_UNZIP} "${DATA}/mp_unzip.sh" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to unzip input data files!" - fi - fi - fi + rm -f "${DATA}/unzip_radstat.sh" + cat > "${DATA}/unzip_radstat.sh" << EOF +#!/bin/bash +diag_file=\$1 +diag_suffix=\$2 +fname=\$(echo \$diag_file | cut -d'.' -f1) +fdate=\$(echo \$diag_file | cut -d'.' -f2) +${UNCOMPRESS} \$diag_file +fnameges=\$(echo \$fname | sed 's/_ges//g') +${NMV} \$fname.\$fdate\$diag_suffix \$fnameges +EOF + chmod 755 "${DATA}/unzip_radstat.sh" + + rm -f "${DATA}/cmdfile" + #shellcheck disable=SC2312 + listdiag=$(tar -xvf radstat.gdas | cut -d' ' -f2 | grep _ges) + for type in ${listdiag}; do + diag_file=$(echo "${type}" | cut -d',' -f1) + echo "${DATA}/unzip_radstat.sh ${diag_file} ${DIAG_SUFFIX:-}.nc4" >> "${DATA}/cmdfile" + done + + "${USHgfs}/run_mpmd.sh" "${DATA}/cmdfile" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to unzip radstat.gdas file!" + fi fi # if [[ $USE_RADSTAT == "YES" ] ############################################################## # GSI Namelist options -if [[ ${DOHYBVAR} == "YES" ]]; then - HYBRID_ENSEMBLE="n_ens=${NMEM_ENS},jcap_ens=${JCAP_ENKF},nlat_ens=${NLAT_ENKF},nlon_ens=${NLON_ENKF},jcap_ens_test=${JCAP_ENKF},${HYBRID_ENSEMBLE}" - if [[ ${l4densvar} == ".true." ]]; then - SETUP="niter(1)=50,niter(2)=150,niter_no_qc(1)=25,niter_no_qc(2)=0,thin4d=.true.,ens_nstarthr=3,gmi_method=4,l4densvar=${l4densvar},lwrite4danl=${lwrite4danl},${SETUP}" - JCOPTS="ljc4tlevs=.true.,${JCOPTS}" - STRONGOPTS="tlnmc_option=3,${STRONGOPTS}" - OBSQC="c_varqc=0.04,${OBSQC}" - fi +if [[ "${DOHYBVAR}" == "YES" ]]; then + HYBRID_ENSEMBLE="n_ens=${NMEM_ENS},jcap_ens=${JCAP_ENKF},nlat_ens=${NLAT_ENKF},nlon_ens=${NLON_ENKF},jcap_ens_test=${JCAP_ENKF},${HYBRID_ENSEMBLE}" + if [[ "${l4densvar}" == ".true." ]]; then + SETUP="niter(1)=50,niter(2)=150,niter_no_qc(1)=25,niter_no_qc(2)=0,thin4d=.true.,ens_nstarthr=3,gmi_method=4,l4densvar=${l4densvar},lwrite4danl=${lwrite4danl},${SETUP}" + JCOPTS="ljc4tlevs=.true.,${JCOPTS}" + STRONGOPTS="tlnmc_option=3,${STRONGOPTS}" + OBSQC="c_varqc=0.04,${OBSQC}" + fi fi -if [[ ${DONST} == "YES" ]]; then - NST="nstinfo=${NSTINFO},fac_dtl=${FAC_DTL},fac_tsl=${FAC_TSL},zsea1=${ZSEA1},zsea2=${ZSEA2},${NST}" +if [[ "${DONST}" == "YES" ]]; then + NST="nstinfo=${NSTINFO},fac_dtl=${FAC_DTL},fac_tsl=${FAC_TSL},zsea1=${ZSEA1},zsea2=${ZSEA2},${NST}" fi OBS_INPUT_TABLE=$(cat "${OBS_INPUT}") @@ -785,12 +726,12 @@ cat > gsiparm.anl << EOF use_pbl=.false.,use_compress=.true.,nsig_ext=45,gpstop=50.,commgpstop=45.,commgpserrinf=1.0, use_gfs_nemsio=.false.,use_gfs_ncio=.true.,sfcnst_comb=.true., use_readin_anl_sfcmask=${USE_READIN_ANL_SFCMASK}, - lrun_subdirs=${lrun_subdirs}, + lrun_subdirs=.true., crtm_coeffs_path='./crtm_coeffs/', newpc4pred=.true.,adp_anglebc=.true.,angord=4,passive_bc=.true.,use_edges=.false., diag_precon=.true.,step_start=1.e-3,emiss_bc=.true.,nhr_obsbin=${nhr_obsbin:-3}, cwoption=3,imp_physics=${imp_physics},lupp=${lupp},cnvw_option=${cnvw_option},cao_check=${cao_check}, - netcdf_diag=${netcdf_diag},binary_diag=${binary_diag}, + netcdf_diag=.true.,binary_diag=.false., lobsdiag_forenkf=${lobsdiag_forenkf}, write_fv3_incr=${write_fv3_increment}, nhr_anal=${IAUFHRS}, @@ -886,34 +827,32 @@ cat gsiparm.anl export OMP_NUM_THREADS=${NTHREADS_GSI} export pgm=${GSIEXEC} -. prep_step +source prep_step cpreq "${GSIEXEC}" "${DATA}" ${APRUN_GSI} "${DATA}/$(basename "${GSIEXEC}")" 1>&1 2>&2 export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run the GSI analysis!" + err_exit "Failed to run the GSI analysis!" fi - ############################################################## # If full analysis field written, calculate analysis increment # here before releasing FV3 forecast -if [[ ${DO_CALC_INCREMENT} == "YES" ]]; then - ${CALCINCPY} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to calculate the analysis increment!" - fi +if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + ${CALCINCPY} + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to calculate the analysis increment!" + fi fi - ############################################################## # For eupd if [[ -s satbias_out.int ]]; then - cpfs satbias_out.int "${ABIASe}" + cpfs satbias_out.int "${ABIASe}" else - cpfs satbias_in "${ABIASe}" + cpfs satbias_in "${ABIASe}" fi # Cat runtime output files. @@ -921,39 +860,54 @@ cat fort.2* > "${GSISTAT}" # If requested, create obsinput tarball from obs_input.* files if [[ ${RUN_SELECT} == "YES" ]]; then - echo $(date) START tar obs_input >&2 - if [[ -s obsinput.tar ]]; then - rm -f obsinput.tar - fi - ${NLN} "${SELECT_OBS}" obsinput.tar - ${CHGRP_CMD} obs_input.* - tar -cvf obsinput.tar obs_input.* - chmod 750 "${SELECT_OBS}" - ${CHGRP_CMD} "${SELECT_OBS}" - rm -f obsinput.tar - echo $(date) END tar obs_input >&2 + # shellcheck disable=SC2312 + echo "$(date) START tar obs_input" >&2 + if [[ -s obsinput.tar ]]; then + rm -f obsinput.tar + fi + ${NLN} "${SELECT_OBS}" obsinput.tar + ${CHGRP_CMD} obs_input.* + tar -cvf obsinput.tar obs_input.* + chmod 750 "${SELECT_OBS}" + ${CHGRP_CMD} "${SELECT_OBS}" + rm -f obsinput.tar + # shellcheck disable=SC2312 + echo "$(date) END tar obs_input" >&2 fi ################################################################################ # Send alerts -if [[ ${SENDDBN} == "YES" ]]; then - if [[ ${RUN} == "gfs" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL GFS_abias "${job}" "${ABIAS}" +if [[ "${SENDDBN}" == "YES" ]]; then + if [[ "${RUN}" == "gfs" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL GFS_abias "${job}" "${ABIAS}" fi fi ################################################################################ # Postprocessing -cd "${pwd}" || exit 1 +cd "${DATA}" || exit 1 ############################################################## # Add this statement to release the forecast job once the # atmopsheric analysis and updated surface RESTARTS are # available. Do not release forecast when RUN=enkf ############################################################## -if [[ ${SENDECF} == "YES" && "${RUN}" != "enkf" ]]; then - ecflow_client --event release_fcst +if [[ "${SENDECF}" == "YES" && "${RUN}" != "enkf" ]]; then + ecflow_client --event release_fcst fi + +# Diagnostic files +# if requested, GSI diagnostic file directories for use later +if [[ "${GENDIAG}" == "YES" ]]; then + tar -cvf gsidiags.tar dir.???? + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to tar GSI diagnostic directories!" + fi + cpfs gsidiags.tar "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}gsidiags${DIAG_SUFFIX:-}.tar" +fi + +# shellcheck disable=SC2312 echo "${rCDUMP} ${PDY}${cyc} atminc done at $(date)" > "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.done.txt" ################################################################################ diff --git a/dev/scripts/exglobal_atmos_analysis_calc.sh b/dev/scripts/exglobal_atmos_analysis_calc.sh new file mode 100755 index 00000000000..17f55fd75a6 --- /dev/null +++ b/dev/scripts/exglobal_atmos_analysis_calc.sh @@ -0,0 +1,187 @@ +#! /usr/bin/env bash + +################################################################################ +#### UNIX Script Documentation Block +# . . +# Script name: exglobal_atmos_analysis_calc.sh +# Script description: Runs non-diagnostic file tasks after GSI analysis is performed +# +# Author: Cory Martin Org: NCEP/EMC Date: 2020-03-03 +# +# Abstract: This script wraps up analysis-related tasks after GSI exits successfully +# +# $Id$ +# +# Attributes: +# Language: POSIX shell +# +################################################################################ + +# Set environment. + +# Directories. +pwd=$(pwd) + +# Base variables +rCDUMP=${rCDUMP:-"gdas"} +GDUMP=${GDUMP:-"gdas"} + +# Utilities +export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} +export NCLEN=${NCLEN:-"${USHgfs}/getncdimlen"} +COMPRESS=${COMPRESS:-gzip} +UNCOMPRESS=${UNCOMPRESS:-gunzip} + +# Diagnostic files options +netcdf_diag=${netcdf_diag:-".true."} +binary_diag=${binary_diag:-".false."} + +# IAU +DOIAU=${DOIAU:-"NO"} +export IAUFHRS=${IAUFHRS:-"6,"} + +# Dependent Scripts and Executables +export NTHREADS_CALCINC=${NTHREADS_CALCINC:-1} +export APRUN_CALCINC=${APRUN_CALCINC:-${APRUN:-""}} +export APRUN_CALCANL=${APRUN_CALCANL:-${APRUN:-""}} +export APRUN_CHGRES=${APRUN_CALCANL:-${APRUN:-""}} + +export CALCANLEXEC=${CALCANLEXEC:-"${EXECgfs}/calc_analysis.x"} +export CHGRESNCEXEC=${CHGRESNCEXEC:-"${EXECgfs}/enkf_chgres_recenter_nc.x"} +export CHGRESINCEXEC=${CHGRESINCEXEC:-"${EXECgfs}/interp_inc.x"} +export NTHREADS_CHGRES=${NTHREADS_CHGRES:-1} +CALCINCPY=${CALCINCPY:-"${USHgfs}/calcinc_gfs.py"} +CALCANLPY=${CALCANLPY:-"${USHgfs}/calcanl_gfs.py"} + +DOGAUSFCANL=${DOGAUSFCANL-"NO"} +GAUSFCANLSH=${GAUSFCANLSH:-"${USHgfs}/gaussian_sfcanl.sh"} +export GAUSFCANLEXE=${GAUSFCANLEXE:-"${EXECgfs}/gaussian_sfcanl.x"} +NTHREADS_GAUSFCANL=${NTHREADS_GAUSFCANL:-1} +APRUN_GAUSFCANL=${APRUN_GAUSFCANL:-${APRUN:-""}} + +# Guess files +GPREFIX=${GPREFIX:-""} + +ATMG03=${ATMG03:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f003.nc"} +ATMG04=${ATMG04:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f004.nc"} +ATMG05=${ATMG05:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f005.nc"} +ATMGES=${ATMGES:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f006.nc"} +ATMG07=${ATMG07:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f007.nc"} +ATMG08=${ATMG08:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f008.nc"} +ATMG09=${ATMG09:-"${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f009.nc"} + +# Analysis files +export APREFIX=${APREFIX:-""} +SFCANL=${SFCANL:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.sfc.a006.nc"} +DTFANL=${DTFANL:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.dtf.a006.nc"} +ATMANL=${ATMANL:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a006.nc"} + +# Increment files +ATMINC=${ATMINC:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i006.nc"} + +# Set script / GSI control parameters +DOHYBVAR=${DOHYBVAR:-"NO"} +lrun_subdirs=${lrun_subdirs:-".true."} +if [[ "${DOHYBVAR}" == "YES" ]]; then + l_hyb_ens=.true. + export l4densvar=${l4densvar:-".false."} + export lwrite4danl=${lwrite4danl:-".false."} +else + export l_hyb_ens=.false. + export l4densvar=.false. + export lwrite4danl=.false. +fi + +# Set 4D-EnVar specific variables +if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then + ATMA03=${ATMA03:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a003.nc"} + ATMI03=${ATMI03:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i003.nc"} + ATMA04=${ATMA04:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a004.nc"} + ATMI04=${ATMI04:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i004.nc"} + ATMA05=${ATMA05:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a005.nc"} + ATMI05=${ATMI05:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i005.nc"} + ATMA07=${ATMA07:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a007.nc"} + ATMI07=${ATMI07:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i007.nc"} + ATMA08=${ATMA08:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a008.nc"} + ATMI08=${ATMI08:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i008.nc"} + ATMA09=${ATMA09:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a009.nc"} + ATMI09=${ATMI09:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i009.nc"} +fi + +################################################################################ +# Clean the run-directory +rm -rf dir.* + +############################################################## +# If analysis increment is written by GSI, produce an analysis file here +if [[ "${DO_CALC_ANALYSIS}" == "YES" ]]; then + # link analysis and increment files + ${NLN} "${ATMANL}" siganl + ${NLN} "${ATMINC}" siginc.nc + if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then + ${NLN} "${ATMA03}" siga03 + ${NLN} "${ATMI03}" sigi03.nc + ${NLN} "${ATMA04}" siga04 + ${NLN} "${ATMI04}" sigi04.nc + ${NLN} "${ATMA05}" siga05 + ${NLN} "${ATMI05}" sigi05.nc + ${NLN} "${ATMA07}" siga07 + ${NLN} "${ATMI07}" sigi07.nc + ${NLN} "${ATMA08}" siga08 + ${NLN} "${ATMI08}" sigi08.nc + ${NLN} "${ATMA09}" siga09 + ${NLN} "${ATMI09}" sigi09.nc + fi + # link guess files + ${NLN} "${ATMG03}" sigf03 + ${NLN} "${ATMGES}" sigf06 + ${NLN} "${ATMG09}" sigf09 + + if [[ -f "${ATMG04}" ]]; then + ${NLN} "${ATMG04}" sigf04 + fi + if [[ -f "${ATMG05}" ]]; then + ${NLN} "${ATMG05}" sigf05 + fi + if [[ -f "${ATMG07}" ]]; then + ${NLN} "${ATMG07}" sigf07 + fi + if [[ -f "${ATMG08}" ]]; then + ${NLN} "${ATMG08}" sigf08 + fi + + # Link hourly backgrounds (if present) + if [[ -f "${ATMG04}" && -f "${ATMG05}" && -f "${ATMG07}" && -f "${ATMG08}" ]]; then + export nhr_obsbin=1 + fi + + ${CALCANLPY} + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to run ${CALCANLPY}" + fi +else + echo "WARNING Neither increment nor analysis are generated by external utils" +fi + +############################################################## +# Create gaussian grid surface analysis file at middle of window +if [[ "${DOGAUSFCANL}" == "YES" ]]; then + export APRUNSFC="${APRUN_GAUSFCANL}" + export OMP_NUM_THREADS_SFC="${NTHREADS_GAUSFCANL}" + + ${GAUSFCANLSH} + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Gaussian grid surface file was not generated!" + fi +fi + +# shellcheck disable=SC2312 +echo "${rCDUMP} ${PDY}${cyc} atmanl and sfcanl done at $(date)" > "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.done.txt" + +################################################################################ +# Postprocessing +cd "${pwd}" || true + +exit 0 diff --git a/scripts/exglobal_atmos_analysis_calc_fv3jedi.py b/dev/scripts/exglobal_atmos_analysis_calc_fv3jedi.py similarity index 100% rename from scripts/exglobal_atmos_analysis_calc_fv3jedi.py rename to dev/scripts/exglobal_atmos_analysis_calc_fv3jedi.py diff --git a/scripts/exglobal_atmos_chgres_gen_control.sh b/dev/scripts/exglobal_atmos_chgres_gen_control.sh similarity index 72% rename from scripts/exglobal_atmos_chgres_gen_control.sh rename to dev/scripts/exglobal_atmos_chgres_gen_control.sh index d07460a6ad6..368c86096cf 100755 --- a/scripts/exglobal_atmos_chgres_gen_control.sh +++ b/dev/scripts/exglobal_atmos_chgres_gen_control.sh @@ -13,16 +13,16 @@ cpreq "${SFC_FILE}" "${DATA}/sfc_input.nc" ############################################################################### # copy orography,surface, and ancillary files to DATA from the source directory for i in {1..6}; do - cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.slope_type.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.maximum_snow_albedo.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.snowfree_albedo.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_type.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_type.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.substrate_temperature.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tile${i}.nc" "${DATA}/" - cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.facsf.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.slope_type.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.maximum_snow_albedo.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.snowfree_albedo.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_type.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_type.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.substrate_temperature.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tile${i}.nc" "${DATA}/" + cpreq "${FIXgfs}/orog/${CASE}/sfc/${CASE}.mx${OCNRES}.facsf.tile${i}.nc" "${DATA}/" done ################################################################################ # add the namelist and run chgres @@ -80,13 +80,13 @@ EOF ${APRUN_CHGRES} "${HOMEgfs}/sorc/ufs_utils.fd/exec/chgres_cube" export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "chgres_cube failed to create cold start ICs, ABORT!" + err_exit "chgres_cube failed to create cold start ICs, ABORT!" fi ################################################################################ # copy output files to com for i in {1..6}; do - cpreq "out.atm.tile${i}.nc" "${COMOUT_ATMOS_INPUT_MEM}/gfs_data.tile${i}.nc" - cpreq "out.sfc.tile${i}.nc" "${COMOUT_ATMOS_INPUT_MEM}/sfc_data.tile${i}.nc" + cpreq "out.atm.tile${i}.nc" "${COMOUT_ATMOS_INPUT_MEM}/gfs_data.tile${i}.nc" + cpreq "out.sfc.tile${i}.nc" "${COMOUT_ATMOS_INPUT_MEM}/sfc_data.tile${i}.nc" done cpreq "gfs_ctrl.nc" "${COMOUT_ATMOS_INPUT_MEM}/" ################################################################################ diff --git a/scripts/exglobal_atmos_ensstat.sh b/dev/scripts/exglobal_atmos_ensstat.sh similarity index 75% rename from scripts/exglobal_atmos_ensstat.sh rename to dev/scripts/exglobal_atmos_ensstat.sh index cb08714982f..e6bccaae101 100755 --- a/scripts/exglobal_atmos_ensstat.sh +++ b/dev/scripts/exglobal_atmos_ensstat.sh @@ -2,8 +2,8 @@ fhr3=$(printf "%03d" "${FORECAST_HOUR}") -if [[ -a mpmd_script ]]; then - rm -Rf mpmd_script +if [[ -e mpmd_script ]]; then + rm -f mpmd_script fi { @@ -16,5 +16,5 @@ fi "${USHgfs}/run_mpmd.sh" mpmd_script export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "One ore more MPMD jobs failed to calculate ensemble statistics!" + err_exit "One or more MPMD jobs failed to calculate ensemble statistics!" fi diff --git a/dev/scripts/exglobal_atmos_pmgr.sh b/dev/scripts/exglobal_atmos_pmgr.sh new file mode 100755 index 00000000000..cc286ccf7e2 --- /dev/null +++ b/dev/scripts/exglobal_atmos_pmgr.sh @@ -0,0 +1,47 @@ +#! /usr/bin/env bash + +# +# Script name: exgfs_pmgr.sh.sms +# +# This script monitors the progress of the gfs_fcst job +# + +hour=0 + +case "${RUN}" in + gfs) TEND=384 ;; + gdas) TEND=9 ;; + *) + err_exit "Run ${RUN} not supported at this time" + ;; +esac + +declare -a posthours +while [[ "${hour}" -le "${TEND}" ]]; do + posthours+=("${hour}") + if [[ ${hour} -lt 120 ]]; then + hour=$((hour + 1)) + else + hour=$((hour + 3)) + fi +done + +# +# Wait for all fcst hours to finish +# +sleep_interval=10 +max_tries=1000 +for fhr in "${posthours[@]}"; do + fhr3=$(sprintf "%03d" "${fhr}") + log_file="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.logf${fhr3}.txt" + if ! wait_for_file "${log_file}" "${sleep_interval}" "${max_tries}"; then + export err=1 + err_exit "After 2 hours of waiting for GFS FCST hour ${fhr3}." + fi + if [[ ${fhr} -eq 0 ]]; then + ecflow_client --event release_postanl + fi + ecflow_client --event "release_post${fhr3}" +done + +exit diff --git a/dev/scripts/exglobal_atmos_products.sh b/dev/scripts/exglobal_atmos_products.sh new file mode 100755 index 00000000000..f7f6bf44280 --- /dev/null +++ b/dev/scripts/exglobal_atmos_products.sh @@ -0,0 +1,273 @@ +#! /usr/bin/env bash + +cd "${DATA}" || exit 1 + +# Set paramlist files based on FORECAST_HOUR (-1, 0, 3, 6, etc.) +# Determine if supplemental products (PGBS) (1-degree and 1/2-degree) should be generated +if [[ "${FORECAST_HOUR}" -le 0 ]]; then + if [[ "${FORECAST_HOUR}" -lt 0 ]]; then + fhr3="analysis" + # shellcheck disable=SC2034 # paramlista is used later indirectly + paramlista="${paramlista_anl}" + FLXGF="NO" + elif [[ "${FORECAST_HOUR}" -eq 0 ]]; then + fhr3=$(printf "f%03d" "${FORECAST_HOUR}") + # shellcheck disable=SC2034 # paramlista is used later indirectly + paramlista="${paramlista_f000}" + fi + PGBS="YES" +else + fhr3=$(printf "f%03d" "${FORECAST_HOUR}") + if ((FORECAST_HOUR % FHOUT_PGBS == 0)); then + PGBS="YES" + fi +fi + +#----------------------------------------------------- +# Section creating pressure grib2 interpolated products + +# Determine grids once and save them as a string and an array for processing +grid_string="0p25" +if [[ "${PGBS:-}" == "YES" ]]; then + grid_string="${grid_string}:0p50:1p00" +else + echo "INFO: Supplemental product generation is disabled for fhr = ${fhr3}" + PGBS="NO" # Can't generate supplemental products if PGBS is not YES +fi +# Also transform the ${grid_string} into an array for processing +IFS=':' read -ra grids <<< "${grid_string}" + +# Files needed by ${USHgfs}/interp_atmos_master.sh +MASTER_FILE="${COMIN_ATMOS_MASTER}/${PREFIX}master.${fhr3}.grib2" + +for ((nset = 1; nset <= downset; nset++)); do + + echo "INFO: Begin processing nset = ${nset}" + + # Each set represents a group of files + if [[ "${nset}" == 1 ]]; then + grp="a" + elif [[ "${nset}" == 2 ]]; then + grp="b" + fi + + # Get inventory from ${MASTER_FILE} that matches patterns from ${paramlist} + # Extract this inventory from ${MASTER_FILE} into a smaller tmpfile based on paramlist + + tmpfile="tmpfile${grp}_${fhr3}" + paramlist="paramlist${grp}" + parmfile="${!paramlist}" + + # shellcheck disable=SC2312 + ${WGRIB2} "${MASTER_FILE}" | grep -F -f "${parmfile}" | ${WGRIB2} -i -grib "${tmpfile}" "${MASTER_FILE}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "FATAL ERROR: wgrib2 failed to create intermediate grib2 file from '${MASTER_FILE}' using '${parmfile}'" + fi + + # Number of processors available to process $nset + nproc=${ntasks} + + # shellcheck disable=SC2312 + ncount=$(${WGRIB2} "${tmpfile}" | wc -l) + if [[ "${nproc}" -gt "${ncount}" ]]; then + echo "WARNING: Total no. of available processors '${nproc}' exceeds no. of records '${ncount}' in ${tmpfile}" + echo "WARNING: Reduce nproc to ${ncount} (or less) to not waste resources" + fi + + inv=$((ncount / nproc)) + rm -f "${DATA}/cmdfile" + + last=0 + for ((iproc = 1; iproc <= nproc; iproc++)); do + first=$((last + 1)) + last=$((last + inv)) + if [[ ${last} -gt ${ncount} ]]; then + last=${ncount} + fi + + # if final record of is u-component, add next record v-component + # if final record is land, add next record icec + # grep returns 1 if no match is found, so temporarily turn off exit on non-zero rc + set +e + # shellcheck disable=SC2312 + ${WGRIB2} -d "${last}" "${tmpfile}" | grep -E -i "ugrd|ustm|uflx|u-gwd|land|maxuw" + rc=$? + set_strict + if [[ ${rc} == 0 ]]; then # Matched the grep + last=$((last + 1)) + fi + if [[ ${iproc} -eq ${nproc} ]]; then + last=${ncount} + fi + + # Break tmpfile into processor specific chunks in preparation for MPMD + ${WGRIB2} "${tmpfile}" -for "${first}":"${last}" -grib "${tmpfile}_${iproc}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "wgrib2 failed to geneate an intermediate grib2 file from ${tmpfile} records ${first} to ${last}" + fi + input_file="${tmpfile}_${iproc}" + output_file_prefix="pgb2${grp}file_${fhr3}_${iproc}" + echo "${USHgfs}/interp_atmos_master.sh ${input_file} ${output_file_prefix} ${grid_string}" >> "${DATA}/cmdfile" + + # if at final record and have not reached the final processor then write echo's to + # cmdfile for remaining processors + if [[ "${last}" -eq "${ncount}" ]]; then + for ((pproc = iproc + 1; pproc < nproc; pproc++)); do + echo "/bin/echo ${pproc}" >> "${DATA}/cmdfile" + done + break + fi + done # for (( iproc = 1 ; iproc <= nproc ; iproc++ )); do + + # Run with MPMD or serial + "${USHgfs}/run_mpmd.sh" "${DATA}/cmdfile" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "FATAL ERROR: Some or all interpolations of the master grib file failed during MPMD execution!" + fi + + # We are in a loop over downset, save output from mpmd into nset specific output + mv mpmd.out "mpmd_${nset}.out" + + # Concatenate grib files from each processor into a single one + # and clean-up as you go + echo "INFO: Concatenating processor-specific grib2 files into a single product file" + for ((iproc = 1; iproc <= nproc; iproc++)); do + for grid in "${grids[@]}"; do + if [[ -s "pgb2${grp}file_${fhr3}_${iproc}_${grid}" ]]; then + cat "pgb2${grp}file_${fhr3}_${iproc}_${grid}" >> "pgb2${grp}file_${fhr3}_${grid}" + rm -f "pgb2${grp}file_${fhr3}_${iproc}_${grid}" + fi + done + # There is no further use of the processor specific tmpfile; delete it + rm -f "${tmpfile}_${iproc}" + done + + # Move to COM and index the product grib files + for grid in "${grids[@]}"; do + ${WGRIB2} -s "pgb2${grp}file_${fhr3}_${grid}" > "pgb2${grp}file_${fhr3}_${grid}.idx" + prod_dir="COMOUT_ATMOS_GRIB_${grid}" + cpfs "pgb2${grp}file_${fhr3}_${grid}" "${!prod_dir}/${PREFIX}pres_${grp}.${grid}.${fhr3}.grib2" + cpfs "pgb2${grp}file_${fhr3}_${grid}.idx" "${!prod_dir}/${PREFIX}pres_${grp}.${grid}.${fhr3}.grib2.idx" + done + + echo "INFO: Finished processing nset = ${nset}" + +done # for (( nset=1 ; nset <= downset ; nset++ )) + +#--------------------------------------------------------------- + +# Create the index file for the sflux master, if it exists. +FLUX_FILE="${COMIN_ATMOS_MASTER}/${PREFIX}sflux.${fhr3}.grib2" +if [[ -s "${FLUX_FILE}" ]]; then + ${WGRIB2} -s "${FLUX_FILE}" > "${FLUX_FILE}.idx" +fi + +# Section creating sflux grib2 interpolated products +# Create 1-degree sflux grib2 output +# move to COM and index it +if [[ "${FLXGF:-}" == "YES" ]]; then + # Files needed by ${INTERP_ATMOS_SFLUXSH} + input_file="${FLUX_FILE}" + output_file_prefix="sflux_${fhr3}" + grid_string="1p00" + "${USHgfs}/interp_atmos_sflux.sh" "${input_file}" "${output_file_prefix}" "${grid_string}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "FATAL ERROR: Unable to interpolate the surface flux grib2 files!" + fi + + # Move to COM and index the product sflux file + IFS=':' read -ra grids <<< "${grid_string}" + for grid in "${grids[@]}"; do + ${WGRIB2} -s "sflux_${fhr3}_${grid}" > "sflux_${fhr3}_${grid}.idx" + prod_dir="COMOUT_ATMOS_GRIB_${grid}" + cpfs "sflux_${fhr3}_${grid}" "${!prod_dir}/${PREFIX}flux.${grid}.${fhr3}.grib2" + cpfs "sflux_${fhr3}_${grid}.idx" "${!prod_dir}/${PREFIX}flux.${grid}.${fhr3}.grib2.idx" + done +fi + +# Section creating 0.25 degree WGNE products for nset=1, and fhr <= FHMAX_WGNE +if [[ "${WGNE:-}" == "YES" ]]; then + grp="a" + if [[ "${FORECAST_HOUR}" -gt 0 && "${FORECAST_HOUR}" -le ${FHMAX_WGNE:-0} ]]; then + # 598 is the message number for APCP in GFSv17 (it was 597 in GFSv16) + ${WGRIB2} "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_${grp}.0p25.${fhr3}.grib2" \ + -d "${APCP_MSG:-598}" \ + -grib "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" + fi +fi + +#--------------------------------------------------------------- + +# Start sending DBN alerts +# Everything below this line is for sending files to DBN (SENDDBN=YES) +if [[ "${SENDDBN:-}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P25" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_a.0p25.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P25_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_a.0p25.${fhr3}.grib2.idx" + if [[ "${RUN}" == "gfs" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P25" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_b.0p25.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P25_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_b.0p25.${fhr3}.grib2.idx" + if [[ -s "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P5" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P5_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2.idx" + fi + if [[ -s "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P5" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P5_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2.idx" + fi + if [[ -s "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_1P0" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_1P0_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" + fi + if [[ -s "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_1P0" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_1P0_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2.idx" + fi + if [[ "${WGNE:-}" == "YES" ]] && [[ -s "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WGNE" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" + fi + fi + + if [[ "${fhr3}" == "analysis" ]]; then + + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_MSC_sfcanl" "${job}" "${COMIN_ATMOS_ANALYSIS}/${PREFIX}analysis.sfc.a006.nc" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SA" "${job}" "${COMIN_ATMOS_ANALYSIS}/${PREFIX}analysis.atm.a006.nc" + + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGA_GB2" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGA_GB2_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" + + else # forecast hours f000, f003, f006, etc. + + case "${RUN}" in + gdas) + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB_GB2" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB_GB2_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" + if ((FORECAST_HOUR % 3 == 0)); then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.${fhr3}.nc" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_BF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.${fhr3}.nc" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2_WIDX" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2.idx" + fi + ;; + gfs) + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.${fhr3}.nc" + if [[ ${fhr} -gt 0 && ${fhr} -le 84 || ${fhr} -eq 120 ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_BF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.${fhr3}.nc" + fi + + if [[ -s "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" ]]; then + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2_WIDX" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2.idx" + fi + ;; + *) + err_exit "Unsupported RUN value '${RUN}' for SENDDBN section" + ;; + esac + fi +fi # end if SENDDBN=YES + +exit 0 diff --git a/dev/scripts/exglobal_atmos_sfcanl.sh b/dev/scripts/exglobal_atmos_sfcanl.sh new file mode 100755 index 00000000000..ed52df19c3d --- /dev/null +++ b/dev/scripts/exglobal_atmos_sfcanl.sh @@ -0,0 +1,195 @@ +#! /usr/bin/env bash + +################################################################################ +#### UNIX Script Documentation Block +# . . +# Script name: exglobal_atmos_sfcanl.sh +# Script description: Makes global model surface analysis files +# +# Author: Russ Treadon Org: NCEP/EMC Date: 2021-12-13 +# +# Abstract: This script makes global model surface analysis files +# +# $Id$ +# +# Attributes: +# Language: POSIX shell +# +################################################################################ + +# Set environment. + +# Derived base variables + +# Dependent Scripts and Executables +CYCLESH=${CYCLESH:-"${USHgfs}/global_cycle.sh"} +REGRIDSH=${REGRIDSH:-"${USHgfs}/regrid_gsiSfcIncr_to_tile.sh"} +export CYCLEXEC=${CYCLEXEC:-"${EXECgfs}/global_cycle"} +NTHREADS_CYCLE=${NTHREADS_CYCLE:-24} +APRUN_CYCLE=${APRUN_CYCLE:-${APRUN:-""}} + +# Surface cycle related parameters +export SNOW_NUDGE_COEFF=${SNOW_NUDGE_COEFF:--2.} +export CYCLVARS=${CYCLVARS:-""} +export FHOUR=${FHOUR:-0} +export DELTSFC=${DELTSFC:-6} +export COUPLED=${COUPLED:-".false."} + +# Other info used in this script +# Ignore possible spelling error (nothing is misspelled) +# shellcheck disable=SC2153 +GPREFIX="gdas.t${GDATE:8:2}z." +OPREFIX="${RUN/enkf/}.t${cyc}z." +APREFIX="${RUN/enkf/}.t${cyc}z." + +ntiles=6 + +############################################################## +# Get dimension information based on CASE +res=${CASE:1} +JCAP_CASE=$((res * 2 - 2)) +LATB_CASE=$((res * 2)) +LONB_CASE=$((res * 4)) + +# Global cycle requires these files +export FNTSFA=${FNTSFA:-"${COMIN_OBS}/${OPREFIX}rtgssthr.grb"} +export FNACNA=${FNACNA:-"${COMIN_OBS}/${OPREFIX}seaice.5min.blend.grb"} +export FNSNOA=${FNSNOA:-"${COMIN_OBS}/${OPREFIX}snogrb_t${JCAP_CASE}.${LONB_CASE}.${LATB_CASE}"} +# Check if resolution specific FNSNOA exists, if not use t1534 version +if [[ ! -f "${FNSNOA}" ]]; then + export FNSNOA="${COMIN_OBS}/${OPREFIX}snogrb_t1534.3072.1536" +fi +if [[ ! -f "${FNSNOA}" ]]; then + echo "WARNING: Current cycle snow file ${FNSNOA} is missing. Snow coverage will not be updated." +else + echo "INFO: Current cycle snow file is ${FNSNOA}" +fi +export FNSNOG=${FNSNOG:-"${COMIN_OBS_PREV}/${GPREFIX}snogrb_t${JCAP_CASE}.${LONB_CASE}.${LATB_CASE}"} +# Check if resolution specific FNSNOG exists, if not use t1534 version +if [[ ! -f "${FNSNOG}" ]]; then + export FNSNOG="${COMIN_OBS_PREV}/${GPREFIX}snogrb_t1534.3072.1536" +fi +if [[ ! -f "${FNSNOG}" ]]; then + echo "WARNING: Previous cycle snow file ${FNSNOG} is missing. Snow coverage will not be updated." +else + echo "INFO: Previous cycle snow file is ${FNSNOG}" +fi + +# If any snow files are missing, don't apply snow in the global_cycle step. +# shellcheck disable=SC2312 +if [[ ! -f "${FNSNOA}" ]] || [[ ! -f "${FNSNOG}" ]]; then + export FNSNOA=" " + export CYCLVARS=FSNOL=99999.,FSNOS=99999., +# Set CYCLVARS by checking grib date of current snogrb vs that of prev cycle +elif [[ "$(${WGRIB} -4yr "${FNSNOA}" 2> /dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}')" -le "$(${WGRIB} -4yr "${FNSNOG}" 2> /dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}')" ]]; then + export FNSNOA=" " + export CYCLVARS=FSNOL=99999.,FSNOS=99999., +else + export CYCLVARS="FSNOL=${SNOW_NUDGE_COEFF},${CYCLVARS}" +fi + +# determine where the input snow restart files come from +snow_prefix="" +if [[ "${DO_JEDISNOWDA:-}" == "YES" ]]; then + sfcdata_dir="${COMIN_SNOW_ANALYSIS}" + snow_prefix="snow_analysis." +else + sfcdata_dir="${COMIN_ATMOS_RESTART_PREV}" +fi + +# global_cycle executable specific variables +export APRUNCY="${APRUN_CYCLE}" +export OMP_NUM_THREADS_CY="${NTHREADS_CYCLE}" +export MAX_TASKS_CY="${ntiles}" + +# Copy fix files required by global_cycle to DATA just once +for ((nn = 1; nn <= ntiles; nn++)); do + cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${nn}.nc" "${DATA}/fngrid.00${nn}" + cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${nn}.nc" "${DATA}/fnorog.00${nn}" +done + +# Copy the NSST analysis file for global_cycle +# There is only a single NSST analysis at the middle of the window +# For now use/assume it is the same at the beginning of the window if doing IAU +if [[ "${DONST}" == "YES" ]]; then + export NST_FILE=${NST_FILE:-${COMIN_ATMOS_ANALYSIS}/${APREFIX}analysis.dtf.a006.nc} + if [[ -s "${NST_FILE}" ]]; then + cpreq "${NST_FILE}" "${DATA}/dtfanl" + export NST_FILE="dtfanl" + else + export NST_FILE="NULL" + fi +else + export NST_FILE="NULL" +fi + +# Collect the dates in the window to update surface restarts +gcycle_dates=("${PDY}${cyc}") # Always update surface restarts at middle of window +soilinc_fhrs=("${assim_freq}") # increment file at middle of window +LFHR="${assim_freq}" +if [[ "${DOIAU:-}" == "YES" ]]; then # Update surface restarts at beginning of window + half_window=$((assim_freq / 2)) + soilinc_fhrs+=("${half_window}") + LFHR=-1 + BDATE=$(date --utc -d "${PDY} ${cyc} - ${half_window} hours" +%Y%m%d%H) + gcycle_dates+=("${BDATE}") +fi + +# if doing GSI soil anaysis, copy increment file and re-grid it to native model resolution +if [[ "${DO_GSISOILDA}" == "YES" ]]; then + + export COMIN_SOIL_ANALYSIS_MEM="${COMIN_ATMOS_ENKF_ANALYSIS_STAT}" + export COMOUT_ATMOS_ANALYSIS_MEM="${COMIN_ATMOS_ANALYSIS}" + export CASE_IN="${CASE_ENS}" + export CASE_OUT="${CASE}" + export OCNRES_OUT="${OCNRES}" + export LFHR + + "${REGRIDSH}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Soil increment file was not regridded correctly!" + fi + +fi + +# Loop over the dates in the window to update the surface restarts +for hr in "${!gcycle_dates[@]}"; do + + gcycle_date="${gcycle_dates[hr]}" + FHR="${soilinc_fhrs[hr]}" + echo "Updating surface restarts for ${gcycle_date} ..." + + datestr="${gcycle_date:0:8}.${gcycle_date:8:2}0000" + + if [[ "${DO_GSISOILDA}" == "YES" ]] && [[ "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then + for ((nn = 1; nn <= ntiles; nn++)); do + cpreq "${COMIN_ATMOS_ANALYSIS}/increment.sfc.i00${FHR}.tile${nn}.nc" \ + "${DATA}/soil_xainc.00${nn}" + done + fi + + # Copy inputs from COMIN to DATA + for ((nn = 1; nn <= ntiles; nn++)); do + cpreq "${sfcdata_dir}/${datestr}.${snow_prefix}sfc_data.tile${nn}.nc" "${DATA}/fnbgsi.00${nn}" + cpreq "${DATA}/fnbgsi.00${nn}" "${DATA}/fnbgso.00${nn}" + done + + "${CYCLESH}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Unable to update surface data from guess and analysis!" + fi + + # Copy outputs from DATA to COMOUT + for ((nn = 1; nn <= ntiles; nn++)); do + cpfs "${DATA}/fnbgso.00${nn}" "${COMOUT_ATMOS_RESTART}/${datestr}.sfcanl_data.tile${nn}.nc" + done + +done + +################################################################################ + +exit "${err}" + +################################################################################ diff --git a/dev/scripts/exglobal_atmos_tropcy_qc_reloc.sh b/dev/scripts/exglobal_atmos_tropcy_qc_reloc.sh new file mode 100755 index 00000000000..f85bb2adc43 --- /dev/null +++ b/dev/scripts/exglobal_atmos_tropcy_qc_reloc.sh @@ -0,0 +1,162 @@ +#! /usr/bin/env bash + +############################################################################ +# echo "---------------------------------------------------------------------" +# echo "exglobal_atmos_tropcy_qc_reloc.sh - Tropical Cyclone QC/Relocation Prcocessing" +# echo "---------------------------------------------------------------------" +# echo "History: Jun 13 2006 - Original script." +# echo " March 2013 - No changes needed for WCOSS transition" +# echo " MP_LABELIO default added" +# echo " Oct 2013 - Use main USH vars as part of minor pkg cleanup" +############################################################################ + +# Make sure we are in the $DATA directory +cd "${DATA}" || exit 1 + +tmhr=${tmmark:2:2} +cdate10=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${tmhr} hours") + +NET_uc=${RUN^^} +tmmark_uc=${tmmark^^} + +if [[ "${RUN}" = ndas ]]; then + if [[ "${DO_RELOCATE}" = NO ]]; then + echo "CENTER PROCESSING TIME FOR NDAS TROPICAL CYCLONE QC IS ${cdate10}" + echo "Output tcvitals files will be copied forward in time to proper \ +output file directory path locations" + else + echo "CENTER PROCESSING TIME FOR ${tmmark_uc} NDAS TROPICAL CYCLONE \ +RELOCATION IS ${cdate10}" + fi +else + echo "CENTER PROCESSING TIME FOR ${tmmark_uc} ${NET_uc} TROPICAL CYCLONE QC/\ +RELOCATION IS ${cdate10}" +fi + +if [[ "${PROCESS_TROPCY}" = 'YES' ]]; then + + #################################### + #################################### + # QC tcvitals for tropical cyclones + #################################### + #################################### + + #echo $PDY + + "${USHgfs}/syndat_qctropcy.sh" "${cdate10}" + errsc=$? + if [[ ${errsc} -ne 0 ]]; then + echo "syndat_qctropcy.sh failed. exit" + exit "${errsc}" + fi + + cd "${COMOUT_OBS}" || exit 1 + pwd + ls -ltr ./*syndata* + cd "${ARCHSYND}" || exit 1 + pwd + ls -ltr + cat syndat_dateck + cd "${HOMENHC}" || exit 1 + pwd + ls -ltr + cd "${DATA}" || exit 1 + +else + + # Copy null files into "syndata.tcvitals" and "jtwc-fnoc.tcvitals" + # (Note: Only do so if files don't already exist - need because in NDAS this + # script is run twice, first time with DO_RELOCATE=NO, copying these + # files, and second time with PROCESS_TROPCY=NO and thus coming here - + # don't want to wipe out these files) + # + + if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.syndata.tcvitals.${tmmark}" ]]; then + cpfs "/dev/null" "${COMOUT_OBS}/${RUN}.t${cyc}z.syndata.tcvitals.${tmmark}" + fi + if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.jtwc-fnoc.tcvitals.${tmmark}" ]]; then + cpfs "/dev/null" "${COMOUT_OBS}/${RUN}.t${cyc}z.jtwc-fnoc.tcvitals.${tmmark}" + fi + +# endif loop $PROCESS_TROPCY +fi + +if [[ "${DO_RELOCATE}" = 'YES' ]]; then + + ################################################### + ################################################### + # Relocate tropical cyclones in global sigma guess + ################################################### + ################################################### + + export MP_LABELIO=${MP_LABELIO:-yes} + "${USHgfs}/tropcy_relocate.sh" "${cdate10}" + export err=$? + + if [[ ${err} -ne 0 ]]; then + err_exit "Failed while updating tropical cyclone data!" + fi + + # save global sigma guess file(s) possibly updated by tropical cyclone + # relocation processing in COMSP path + qual_last=".${tmmark}" # need this because gfs and gdas don't add $tmmark + # qualifer to end of output sigma guess files + if [[ "${RUN}" == gfs || "${RUN}" == gdas || "${NET}" == cfs ]]; then + qual_last="" + fi + + if [[ ${BKGFREQ} -eq 1 ]]; then + if [[ -s sgm3prep ]]; then + cpfs "sgm3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm3prep${qual_last}" + fi + if [[ -s sgm2prep ]]; then + cpfs "sgm2prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm2prep${qual_last}" + fi + if [[ -s sgm1prep ]]; then + cpfs "sgm1prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm1prep${qual_last}" + fi + if [[ -s sgesprep ]]; then + cpfs "sgesprep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgesprep${qual_last}" + fi + if [[ -s sgp1prep ]]; then + cpfs "sgp1prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp1prep${qual_last}" + fi + if [[ -s sgp2prep ]]; then + cpfs "sgp2prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp2prep${qual_last}" + fi + if [[ -s sgp3prep ]]; then + cpfs "sgp3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp3prep${qual_last}" + fi + elif [[ ${BKGFREQ} -eq 3 ]]; then + if [[ -s sgm3prep ]]; then + cpfs "sgm3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm3prep${qual_last}" + fi + if [[ -s sgesprep ]]; then + cpfs "sgesprep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgesprep${qual_last}" + fi + if [[ -s sgp3prep ]]; then + cpfs "sgp3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp3prep${qual_last}" + fi + fi + + # The existence of ${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.$tmmark file will tell the + # subsequent PREP processing that RELOCATION processing occurred, if this file + # does not already exist at this point, echo "RECORDS PROCESSED" into it to + # further tell PREP processing that records were processed by relocation and + # the global sigma guess was modified by tropical cyclone relocation + # Note: If ${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.$tmmark already exists at this + # point it means that it contains the string "NO RECORDS to process" + # and was created by the child script tropcy_relocate.sh because records + # were not processed by relocation and the global sigma guess was NOT + # modified by tropical cyclone relocation (because no tcvitals records + # were found in the relocation step) + # ---------------------------------------------------------------------------- + + if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.${tmmark}" ]]; then + echo "RECORDS PROCESSED" > "${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.${tmmark}" + fi + +# endif loop $DO_RELOCATE +fi + +################## END OF SCRIPT ####################### diff --git a/scripts/exglobal_atmos_upp.py b/dev/scripts/exglobal_atmos_upp.py similarity index 100% rename from scripts/exglobal_atmos_upp.py rename to dev/scripts/exglobal_atmos_upp.py diff --git a/scripts/exglobal_atmos_vminmon.sh b/dev/scripts/exglobal_atmos_vminmon.sh similarity index 87% rename from scripts/exglobal_atmos_vminmon.sh rename to dev/scripts/exglobal_atmos_vminmon.sh index 79990001009..aa399f58a3f 100755 --- a/scripts/exglobal_atmos_vminmon.sh +++ b/dev/scripts/exglobal_atmos_vminmon.sh @@ -19,8 +19,8 @@ if [[ ! -s "${gsistat}" ]]; then - export err=1 - err_exit "Required GSI statistics file is missing!" + export err=1 + err_exit "Required GSI statistics file is missing!" fi @@ -34,12 +34,11 @@ fi # data into ${cyc} subdirectories (elif condition). #----------------------------------------------------------------------- if [[ -s "${M_TANKverf}/gnorm_data.txt" ]]; then - cpreq "${M_TANKverf}/gnorm_data.txt" gnorm_data.txt + cpreq "${M_TANKverf}/gnorm_data.txt" gnorm_data.txt elif [[ -s "${M_TANKverfM1}/gnorm_data.txt" ]]; then - cpreq "${M_TANKverfM1}/gnorm_data.txt" gnorm_data.txt + cpreq "${M_TANKverfM1}/gnorm_data.txt" gnorm_data.txt fi - #------------------------------------------------------------------ # Run the child sccripts. #------------------------------------------------------------------ @@ -58,9 +57,9 @@ echo "rc_reduct = ${rc_reduct}" ##################################################################### # Postprocessing -err=$(( rc_costs + rc_gnorms + rc_reduct )) +err=$((rc_costs + rc_gnorms + rc_reduct)) export err=${err} if [[ ${err} -ne 0 ]]; then - err_exit "One or more minimization monitor subjobs failed!!" + err_exit "One or more minimization monitor subjobs failed!!" fi diff --git a/dev/scripts/exglobal_cleanup.sh b/dev/scripts/exglobal_cleanup.sh new file mode 100755 index 00000000000..1e5d51f8c78 --- /dev/null +++ b/dev/scripts/exglobal_cleanup.sh @@ -0,0 +1,169 @@ +#! /usr/bin/env bash + +############################################################### +echo "Begin Cleanup ${DATAROOT}!" + +# Remove DATAoutput from the forecast model run +# TODO: Handle this better +DATAfcst="${DATAROOT}/${RUN}fcst.${PDY:-}${cyc}" +if [[ -d "${DATAfcst}" ]]; then + rm -rf "${DATAfcst}" +fi +#DATAefcs="${DATAROOT}/${RUN}efcs???${PDY:-}${cyc}" +rm -rf "${DATAROOT}/${RUN}efcs"*"${PDY:-}${cyc}" +############################################################### + +if [[ "${CLEANUP_COM:-YES}" == NO ]]; then + exit 0 +fi + +SELECTIVE_CLEANUP_MIN=${SELECTIVE_CLEANUP_MIN:-24} +SELECTIVE_CLEANUP_MAX=${SELECTIVE_CLEANUP_MAX:-120} +RTOFS_CLEANUP=${RTOFS_CLEANUP:-24} +GEMPAK_CLEANUP=${GEMPAK_CLEANUP:-240} +############################################################### +# Clean up previous cycles; various depths + +# Step back every assim_freq hours and remove old rotating directories +# for successful cycles (defaults from 24h to 120h). +# Retain files needed by Fit2Obs +first_selective_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${SELECTIVE_CLEANUP_MAX} hours") +last_selective_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${SELECTIVE_CLEANUP_MIN} hours") +gempak_cutoff_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${GEMPAK_CLEANUP} hours") +# Selective exclude list +selective_exclude_string="${selective_exclude_string:-}" +# Gempak exclude list +gempak_exclude_string+=", gfs_1p00_*" + +# RTOFS is cleaned separately (for all RUNs) +rtofs_cutoff_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${RTOFS_CLEANUP} hours") + +# Find the first and last date among all cleanup targets +max_cleanup_max="${SELECTIVE_CLEANUP_MAX:-120}" +max_list="${SELECTIVE_CLEANUP_MAX}" +if [[ "${RUN}" == "gfs" && "${DO_GEMPAK}" == "YES" ]]; then + max_list+=" ${GEMPAK_CLEANUP}" +fi + +for cleanup_max in ${max_list}; do + if [[ ${cleanup_max} -gt ${max_cleanup_max} ]]; then + max_cleanup_max=${cleanup_max} + fi +done + +# Start 4 cycles before the earliest exclusion target so we actually remove older files +max_cleanup_max=$((max_cleanup_max + 4 * assim_freq)) +first_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${max_cleanup_max} hours") + +# Cleanup starts on SELECTIVE_CLEANUP_MIN +last_date=${last_selective_date} + +# Declare remove_files(), which will be called in a loop to selectively remove files +function remove_files() { + local directory=$1 + shift + if [[ ! -d ${directory} ]]; then + echo "No directory ${directory} to remove files from, skiping" + return + fi + local find_exclude_string="" + for exclude in "$@"; do + if [[ -n "${exclude}" ]]; then + find_exclude_string+=" -name ${exclude} -or" + fi + done + # Chop off any trailing or + find_exclude_string="${find_exclude_string[*]/%-or/}" + # Remove all regular files and symlinks that do not match + # shellcheck disable=SC2086 + if [[ -n "${find_exclude_string}" ]]; then + # String is non-empty → use exclusion + find "${directory}" \( -type f -o -type l \) -not \( ${find_exclude_string} \) -ignore_readdir_race -delete + else + # String is empty → no exclusion + find "${directory}" \( -type f -o -type l \) -ignore_readdir_race -delete + fi + + # Remove any empty directories + find "${directory}" -type d -empty -delete +} + +# Now start removing old COM files/directories +for ((current_date = first_date; current_date <= last_date; \ +current_date = $(date --utc +%Y%m%d%H -d "${current_date:0:8} ${current_date:8:2} +${assim_freq} hours"))); do + current_PDY="${current_date:0:8}" + current_cyc="${current_date:8:2}" + rocotolog="${EXPDIR}/logs/${current_date}.log" + + # Build the exclude list based on the 'current_date' + exclude_string="" + if [[ ${current_date} -ge ${first_selective_date} && ${current_date} -le ${last_selective_date} ]]; then + exclude_string+="${selective_exclude_string}" + fi + + # Extend the exclude list for gempak files if needed + if [[ "${RUN}" == "gfs" && ${current_date} -ge ${gempak_cutoff_date} && "${DO_GEMPAK}" == "YES" ]]; then + # Provide the gempak exclude pattern(s) + exclude_string+="${gempak_exclude_string}" + fi + + # Check if the cycle completed successfully by looking at the rocoto log + if [[ -f "${rocotolog}" ]]; then + # TODO: This needs to be revamped to not look at the rocoto log. + tail_log=$(tail -n 1 "${rocotolog}") || true + # Test if the last line of rocotolog indicates success + if [[ ${tail_log} =~ "This cycle is complete: Success" ]]; then + YMD="${current_PDY}" HH="${current_cyc}" declare_from_tmpl \ + COMOUT_TOP:COM_TOP_TMPL + if [[ -d "${COMOUT_TOP}" ]]; then + IFS=", " read -r -a exclude_list <<< "${exclude_string}" + remove_files "${COMOUT_TOP}" "${exclude_list[@]:-}" + fi + # Remove all rtofs directories in each RUN older than last_rtofs_date + rtofs_dir="${ROTDIR}/rtofs.${current_PDY}" + if [[ -d "${rtofs_dir}" && ${current_date} -lt ${rtofs_cutoff_date} ]]; then + rm -rf "${rtofs_dir}" + fi + fi + fi +done + +# Remove archived gaussian files used for Fit2Obs in $VFYARC that are +# $FHMAX_FITS plus a delta before ${PDY}${cyc}. Touch existing archived +# gaussian files to prevent the files from being removed by automatic +# scrubber present on some machines. + +if [[ "${RUN}" == "gfs" ]]; then + fhmax=$((FHMAX_FITS + 36)) + RDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${fhmax} hours") + verify_dir="${ROTDIR}/vrfyarch/${RUN}.${RDATE:0:8}" + if [[ -d "${verify_dir}" ]]; then + rm -rf "${verify_dir}" + fi + + touch_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${FHMAX_FITS} hours") + while ((touch_date < "${PDY}${cyc}")); do + touch_PDY="${touch_date:0:8}" + touch_cyc="${touch_date:8:2}" + touch_dir="${ROTDIR}/vrfyarch/${RUN}.${touch_PDY}/${touch_cyc}" + if [[ -d "${touch_dir}" ]]; then + touch "${touch_dir}"/* + fi + touch_date=$(date --utc +%Y%m%d%H -d "${touch_PDY} ${touch_cyc} +6 hours") + done +fi + +# Remove $RUN.$rPDY for the older of GDATE or RDATE if it is empty +GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${max_cleanup_max} hours") +RDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${FHMAX_GFS} hours") +if ((GDATE < RDATE)); then + RDATE=${GDATE} +fi + +deletion_target="${ROTDIR}/${RUN}.${RDATE:0:8}" +if [[ -d "${deletion_target}" ]]; then + find "${deletion_target}" -maxdepth 0 -type d -empty -delete +fi + +# sync and wait to avoid filesystem synchronization issues +sync && sleep 1 diff --git a/dev/scripts/exglobal_diag.sh b/dev/scripts/exglobal_diag.sh new file mode 100755 index 00000000000..68231b6fb72 --- /dev/null +++ b/dev/scripts/exglobal_diag.sh @@ -0,0 +1,235 @@ +#! /usr/bin/env bash + +################################################################################ +#### UNIX Script Documentation Block +# . . +# Script name: exglobal_diag.sh +# Script description: Creates diagnostic files after GSI analysis is performed +# +# Author: Cory Martin Org: NCEP/EMC Date: 2020-03-03 +# +# Abstract: This script creates GSI diagnostic files after GSI exits successfully +# +# $Id$ +# +# Attributes: +# Language: POSIX shell +# +################################################################################ + +# Set environment. +cd "${DATA}" || exit 8 + +# Base variables + +# Utilities +CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} +CATEXEC=${CATEXEC:-${ncdiag_ROOT:-${gsi_ncdiag_ROOT}}/bin/ncdiag_cat_serial.x} +COMPRESS=${COMPRESS:-gzip} + +# Analysis files +APREFIX=${APREFIX:-"${RUN}.t${cyc}z."} +CNVSTAT=${CNVSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat.tar} +PCPSTAT=${PCPSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}pcpstat} +OZNSTAT=${OZNSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat.tar} +RADSTAT=${RADSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat.tar} + +# Remove stat file if file already exists +rm -f "${RADSTAT}" "${PCPSTAT}" "${CNVSTAT}" "${OZNSTAT}" + +# Obs diag +GENDIAG=${GENDIAG:-"YES"} +GSIDIAG=${GSIDIAG:-"${COMIN_ATMOS_ANALYSIS}/${APREFIX}gsidiags${DIAG_SUFFIX:-}.tar"} +USE_BUILD_GSINFO=${USE_BUILD_GSINFO:-"NO"} +DIAG_COMPRESS=${DIAG_COMPRESS:-"YES"} +if [[ "${DIAG_COMPRESS:-}" == "YES" ]]; then + COMPRESS_SUFFIX=".gz" +fi +DIAG_TARBALL=${DIAG_TARBALL:-"YES"} + +# Set script / GSI control parameters + +################################################################################ +if [[ "${GENDIAG}" != "YES" ]]; then + echo "INFO: GENDIAG set to NO. Skipping diagnostic file generation." + exit 0 +fi + +################################################################################ +# Copy gsidiags.tar file from COMIN to DATA and untar +cpreq "${GSIDIAG}" ./gsidiags.tar +tar -xvf gsidiags.tar +export err=$? +if [[ ${err} -ne 0 ]]; then + err_exit "Unable to unpack gsidiags.tar file!" +fi + +# Set up lists and variables for various types of diagnostic files. +ntype=3 + +diagtype[0]="conv conv_gps conv_ps conv_pw conv_q conv_sst conv_t conv_tcp conv_uv conv_spd" +diagtype[1]="pcp_ssmi_dmsp pcp_tmi_trmm" +if [[ ${USE_BUILD_GSINFO} == "YES" ]]; then + diagtype[2]=$(cat "${BUILD_GSINFO_DIR}/ozinfo/satellites") + diagtype[3]=$(cat "${BUILD_GSINFO_DIR}/satinfo/satellites") +else + diagtype[2]="sbuv2_n16 sbuv2_n17 sbuv2_n18 sbuv2_n19 gome_metop-a gome_metop-b omi_aura mls30_aura ompsnp_npp ompstc8_npp ompstc8_n20 ompsnp_n20 ompstc8_n21 ompsnp_n21 ompslp_npp gome_metop-c" + diagtype[3]="msu_n14 sndr_g08 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g12 sndrd2_g12 sndrd3_g12 sndrd4_g12 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 sndrd1_g14 sndrd2_g14 sndrd3_g14 sndrd4_g14 sndrd1_g15 sndrd2_g15 sndrd3_g15 sndrd4_g15 amsua_n15 amsua_n16 amsua_n17 amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 imgr_g14 imgr_g15 ssmi_f13 ssmi_f15 amsua_n18 amsua_metop-a mhs_n18 mhs_metop-a amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_f16 ssmis_f17 ssmis_f18 ssmis_f19 ssmis_f20 iasi_metop-a amsua_n19 mhs_n19 seviri_m08 seviri_m09 seviri_m10 seviri_m11 cris_npp cris-fsr_npp cris-fsr_n20 atms_npp atms_n20 amsua_metop-b mhs_metop-b iasi_metop-b avhrr_metop-b avhrr_n18 avhrr_n19 avhrr_metop-a amsr2_gcom-w1 gmi_gpm saphir_meghat ahi_himawari8 abi_g16 abi_g17 amsua_metop-c mhs_metop-c iasi_metop-c avhrr_metop-c viirs-m_npp viirs-m_j1 abi_g18 ahi_himawari9 viirs-m_j2 cris-fsr_n21 atms_n21 abi_g19" +fi + +diaglist[0]=listcnv +diaglist[1]=listpcp +diaglist[2]=listozn +diaglist[3]=listrad + +diagfile[0]="${CNVSTAT}" +diagfile[1]="${PCPSTAT}" +diagfile[2]="${OZNSTAT}" +diagfile[3]="${RADSTAT}" + +numfile[0]=0 +numfile[1]=0 +numfile[2]=0 +numfile[3]=0 + +rm -f "${DATA}/diag.sh" +cat > "${DATA}/diag.sh" << EOF +#!/bin/bash +set -x + +type=\$1 +loop=\$2 +string=\$3 +count=\$4 +suffix=\$5 + +# Match files with this prefix +diag_files=dir.*/\${type}_\${loop} + +# Name of combined diagnostic file from matched files +out_diag_file=diag_\${type}_\${string}.${PDY}${cyc}\${suffix} + +# Combine diagnostic files +if [[ \${count} -gt 1 ]]; then + ${CATEXEC} -o \${out_diag_file} \${diag_files}* +else + cat \${diag_files}* > "\${out_diag_file}" +fi + +# Compress diagnostic file if requested +if [[ "${DIAG_COMPRESS:-}" == "YES" ]]; then + ${COMPRESS} "\${out_diag_file}" +fi + +exit 0 +EOF +chmod 755 "${DATA}/diag.sh" + +# Collect diagnostic files as a function of loop and type. +# Loop over first and last outer loops to generate innovation +# diagnostic files for indicated observation types (groups) +# +# NOTE: Since we set miter=2 in GSI namelist SETUP, outer +# loop 03 will contain innovations with respect to +# the analysis. Creation of o-a innovation files +# is triggered by write_diag(3)=.true. The setting +# write_diag(1)=.true. turns on creation of o-g +# innovation files. + +rm -f cmdfile +touch cmdfile +loops="01 03" +for loop in ${loops}; do + case ${loop} in + 01) string=ges ;; + 03) string=anl ;; + *) string=${loop} ;; + esac + echo "START loop ${string}" + n=-1 + while [[ ${n} -lt ${ntype} ]]; do + n=$((n + 1)) + for type in ${diagtype[n]}; do + #shellcheck disable=SC2012,SC2312 + count=$(ls dir.*/"${type}_${loop}"* 2> /dev/null | wc -l) + if [[ ${count} -eq 0 ]]; then + continue + fi + echo "${DATA}/diag.sh ${type} ${loop} ${string} ${count} ${DIAG_SUFFIX:-}.nc4" >> cmdfile + echo "diag_${type}_${string}.${PDY}${cyc}${DIAG_SUFFIX:-}.nc4${COMPRESS_SUFFIX:-}" >> "${diaglist[n]}" + numfile[n]=$((numfile[n] + 1)) + done + done + echo "END loop ${string}" +done + +ncmd=$(wc -l < cmdfile) +if [[ ${ncmd} -eq 0 ]]; then + echo "WARNING: No diagnostic files found to process!" + exit 0 +fi + +# MPMD can only be executed on a single node, +# so break up cmdfile into parts of tasks_per_node size files +# and run them sequentially +split -l "${tasks_per_node}" ./cmdfile cmdfile_part_ +cmdfile_parts=$(ls cmdfile_part_*) +for partfile in ${cmdfile_parts}; do + "${USHgfs}/run_mpmd.sh" "${partfile}" && true + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to create one or more observation diagnostic files for ${partfile}!" + fi +done + +# Restrict diagnostic files containing rstprod data +if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then + rlist="conv_gps conv_ps conv_pw conv_q conv_sst conv_t conv_uv saphir" + for rtype in ${rlist}; do + for rfile in *"${rtype}"*; do + if [[ -s "${rfile}" ]]; then + ${CHGRP_CMD} "${rfile}" + fi + done + done +fi + +# If requested, create diagnostic file tarballs +if [[ "${DIAG_TARBALL}" == "YES" ]]; then + echo "START tar diagnostic files" + n=-1 + while [[ ${n} -lt ${ntype} ]]; do + n=$((n + 1)) + TAROPTS="-uvf" + if [[ ! -s "${diagfile[n]}" ]]; then + TAROPTS="-cvf" + fi + if [[ ${numfile[n]} -gt 0 ]]; then + tar "${TAROPTS}" "${diagfile[n]}" -T "${diaglist[n]}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Unable to create ${diagfile[n]}!" + fi + fi + done + echo "END tar diagnostic files" + + # Restrict CNVSTAT + chmod 750 "${CNVSTAT}" + if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then + ${CHGRP_CMD} "${CNVSTAT}" + fi + + # Restrict RADSTAT + if [[ -s "${RADSTAT}" ]]; then + chmod 750 "${RADSTAT}" + if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then + ${CHGRP_CMD} "${RADSTAT}" + fi + fi +fi + +################################################################################ +# Postprocessing + +exit 0 diff --git a/scripts/exgdas_enkf_earc_tars.py b/dev/scripts/exglobal_enkf_earc_tars.py similarity index 100% rename from scripts/exgdas_enkf_earc_tars.py rename to dev/scripts/exglobal_enkf_earc_tars.py diff --git a/dev/scripts/exglobal_enkf_earc_vrfy.py b/dev/scripts/exglobal_enkf_earc_vrfy.py new file mode 100755 index 00000000000..4315cf0ca69 --- /dev/null +++ b/dev/scripts/exglobal_enkf_earc_vrfy.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import os + +from pygfs.task.archive import Archive +from pygfs.utils.archive_vars import ArchiveVrfyVars +from wxflow import AttrDict, Logger, cast_strdict_as_dtypedict, chdir, logit + +# initialize root logger +logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) + + +@logit(logger) +def main(): + + config = cast_strdict_as_dtypedict(os.environ) + + # Instantiate the Archive task object + archive = Archive(config) + + # Collect all archive variables in complete arch_dict for YAML templates + # Use static utility methods from ArchiveVrfyVars + arch_dict = ArchiveVrfyVars.get_all_yaml_vars(archive.task_config) + + # Pass arch_dict to configure_vrfy which will render the Jinja2 YAML + arcdir_set = archive.configure_vrfy(arch_dict) + + with chdir(config.ROTDIR): + + # Populate the product archive (ARCDIR) + archive.execute_store_products(arcdir_set) + + +if __name__ == '__main__': + main() diff --git a/dev/scripts/exglobal_enkf_ecen.sh b/dev/scripts/exglobal_enkf_ecen.sh new file mode 100755 index 00000000000..b20099bfe2c --- /dev/null +++ b/dev/scripts/exglobal_enkf_ecen.sh @@ -0,0 +1,348 @@ +#! /usr/bin/env bash + +################################################################################ +#### UNIX Script Documentation Block +# . . +# Script name: exgdas_enkf_ecen.sh +# Script description: recenter ensemble around hi-res deterministic analysis +# +# Author: Rahul Mahajan Org: NCEP/EMC Date: 2017-03-02 +# +# Abstract: This script recenters ensemble around hi-res deterministic analysis +# +# $Id$ +# +# Attributes: +# Language: POSIX shell +# +################################################################################ + +# Directories. +pwd=$(pwd) + +# Base variables +ntiles=${ntiles:-6} + +# Utilities +NCLEN=${NCLEN:-${USHgfs}/getncdimlen} + +# Scripts + +# Executables. +GETATMENSMEANEXEC=${GETATMENSMEANEXEC:-${EXECgfs}/getsigensmeanp_smooth.x} +GETSFCENSMEANEXEC=${GETSFCENSMEANEXEC:-${EXECgfs}/getsfcensmeanp.x} +RECENATMEXEC=${RECENATMEXEC:-${EXECgfs}/recentersigp.x} +CALCINCNEMSEXEC=${CALCINCNEMSEXEC:-${EXECgfs}/calc_increment_ens.x} +CALCINCNCEXEC=${CALCINCEXEC:-${EXECgfs}/calc_increment_ens_ncio.x} + +# Files. +OPREFIX=${OPREFIX:-""} +OSUFFIX=${OSUFFIX:-""} +APREFIX=${APREFIX:-""} +APREFIX_ENS=${APREFIX_ENS:-${APREFIX}} +GPREFIX=${GPREFIX:-""} +GPREFIX_ENS=${GPREFIX_ENS:-${GPREFIX}} + +# Variables +imp_physics=${imp_physics:-99} +INCREMENTS_TO_ZERO=${INCREMENTS_TO_ZERO:-"'NONE'"} +export DOIAU=${DOIAU_ENKF:-"NO"} +FHMIN=${FHMIN_ECEN:-3} +FHMAX=${FHMAX_ECEN:-9} +FHOUT=${FHOUT_ECEN:-3} +export FHSFC=${FHSFC_ECEN:-${FHMIN}} +NMEM_ENS_MAX=${NMEM_ENS:-80} +if [[ "${RUN}" = "enkfgfs" ]]; then + DO_CALC_INCREMENT=${DO_CALC_INCREMENT_ENKF_GFS:-"NO"} + NMEM_ENS=${NMEM_ENS_GFS:-30} + ec_offset=${NMEM_ENS_GFS_OFFSET:-20} + mem_offset=$((ec_offset * cyc / 6)) +else + DO_CALC_INCREMENT=${DO_CALC_INCREMENT:-"NO"} + NMEM_ENS=${NMEM_ENS:-80} + mem_offset=0 +fi + +# global_chgres stuff +CHGRESNEMS=${CHGRESNEMS:-${EXECgfs}/enkf_chgres_recenter.x} +CHGRESNC=${CHGRESNC:-${EXECgfs}/enkf_chgres_recenter_nc.x} +NTHREADS_CHGRES=${NTHREADS_CHGRES:-24} +APRUN_CHGRES=${APRUN_CHGRES:-""} + +# global_cycle stuff +CYCLESH=${CYCLESH:-${USHgfs}/global_cycle.sh} +export CYCLEXEC=${CYCLEXEC:-${EXECgfs}/global_cycle} +APRUN_CYCLE=${APRUN_CYCLE:-${APRUN:-""}} +NTHREADS_CYCLE=${NTHREADS_CYCLE:-${NTHREADS:-1}} +export CYCLVARS=${CYCLVARS:-"FSNOL=-2.,FSNOS=99999.,"} +export FHOUR=${FHOUR:-0} +export DELTSFC=${DELTSFC:-6} + +RECENTER_ENKF=${RECENTER_ENKF:-"YES"} +SMOOTH_ENKF=${SMOOTH_ENKF:-"YES"} + +APRUN_ECEN=${APRUN_ECEN:-${APRUN:-""}} +NTHREADS_ECEN=${NTHREADS_ECEN:-${NTHREADS:-1}} +APRUN_CALCINC=${APRUN_CALCINC:-${APRUN:-""}} +NTHREADS_CALCINC=${NTHREADS_CALCINC:-${NTHREADS:-1}} + +################################################################################ +# Preprocessing + +ENKF_SUFFIX="s" +if [[ "${SMOOTH_ENKF}" == "NO" ]]; then + ENKF_SUFFIX="" +fi + +################################################################################ +# Link ensemble member guess, analysis and increment files +for FHR in $(seq "${FHMIN}" "${FHOUT}" "${FHMAX}"); do + + for imem in $(seq 1 "${NMEM_ENS}"); do + smem=$((imem + mem_offset)) + if ((smem > NMEM_ENS_MAX)); then + smem=$((smem - NMEM_ENS_MAX)) + fi + gmemchar="mem"$(printf %03i "${smem}") + memchar="mem"$(printf %03i "${imem}") + + MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ + COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL + + MEMDIR=${gmemchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -x \ + COMIN_ATMOS_HISTORY_MEM_PREV:COM_ATMOS_HISTORY_TMPL + + ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX_ENS}atm.f00${FHR}${ENKF_SUFFIX}.nc" "./atmges_${memchar}" + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}analysis.atm.a00${FHR}.nc" "./atmanl_${memchar}" + fi + mkdir -p "${COMOUT_ATMOS_ANALYSIS_MEM}" + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}increment.atm.i00${FHR}.nc" "./atminc_${memchar}" + if [[ "${RECENTER_ENKF}" == "YES" ]]; then + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}recentered_analysis.atm.a006.nc" "./ratmanl_${memchar}" + else + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}recentered_increment.atm.i00${FHR}.nc" "./ratminc_${memchar}" + fi + fi + done + + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + # Link ensemble mean analysis + ${NLN} "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX_ENS}ensmean_analysis.atm.a00${FHR}.nc" "./atmanl_ensmean" + + # Compute ensemble mean analysis + DATAPATH="./" + ATMANLNAME="atmanl" + ATMANLMEANNAME="atmanl_ensmean" + + export OMP_NUM_THREADS=${NTHREADS_ECEN} + export pgm=${GETATMENSMEANEXEC} + source prep_step + + cpreq "${GETATMENSMEANEXEC}" "${DATA}" + ${APRUN_ECEN} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" "${DATAPATH}" "${ATMANLMEANNAME}" "${ATMANLNAME}" "${NMEM_ENS}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "FATAL ERROR: Failed to recenter the ensemble analyses!" + fi + else + # Link ensemble mean increment + ${NLN} "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX_ENS}ensmean_increment.atm.i00${FHR}.nc" "./atminc_ensmean" + + # Compute ensemble mean increment + DATAPATH="./" + ATMINCNAME="atminc" + ATMINCMEANNAME="atminc_ensmean" + + export OMP_NUM_THREADS=${NTHREADS_ECEN} + export pgm=${GETATMENSMEANEXEC} + source prep_step + + cpreq "${GETATMENSMEANEXEC}" "${DATA}" + ${APRUN_ECEN} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" "${DATAPATH}" "${ATMINCMEANNAME}" "${ATMINCNAME}" "${NMEM_ENS}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to recenter the ensemble increments!" + fi + + # If available, link to ensemble mean guess. Otherwise, compute ensemble mean guess + if [[ -s "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX_ENS}ensmean.atm.f00${FHR}.nc" ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX_ENS}ensmean.atm.f00${FHR}.nc" "./atmges_ensmean" + else + DATAPATH="./" + ATMGESNAME="atmges" + ATMGESMEANNAME="atmges_ensmean" + + export OMP_NUM_THREADS=${NTHREADS_ECEN} + export pgm=${GETATMENSMEANEXEC} + source prep_step + + cpreq "${GETATMENSMEANEXEC}" "${DATA}" + ${APRUN_ECEN} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" "${DATAPATH}" "${ATMGESMEANNAME}" "${ATMGESNAME}" "${NMEM_ENS}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to recenter the ensemble mean guess!" + fi + fi + fi + + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + LONB_ENKF=${LONB_ENKF:-$(${NCLEN} atmanl_ensmean grid_xt)} # get LONB + LATB_ENKF=${LATB_ENKF:-$(${NCLEN} atmanl_ensmean grid_yt)} # get LATB + LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} atmanl_ensmean pfull)} # get LEVS + else + LONB_ENKF=${LONB_ENKF:-$(${NCLEN} atminc_ensmean lon)} # get LONB + LATB_ENKF=${LATB_ENKF:-$(${NCLEN} atminc_ensmean lat)} # get LATB + LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} atminc_ensmean lev)} # get LEVS + fi + JCAP_ENKF=${JCAP_ENKF:--9999} # there is no jcap in these files + if [[ "${JCAP_ENKF}" -eq -9999 && "${LATB_ENKF}" -ne -9999 ]]; then + JCAP_ENKF=$((LATB_ENKF - 2)) + fi + if [[ "${LONB_ENKF}" -eq -9999 || "${LATB_ENKF}" -eq -9999 || "${LEVS_ENKF}" -eq -9999 || "${JCAP_ENKF}" -eq -9999 ]]; then + export err=9 + err_exit "One or more EnKF background parameters are undefined!" + fi + + ################################################################################ + # This is to give the user the option to recenter, default is YES + if [[ "${RECENTER_ENKF}" == "YES" ]]; then + # GSI EnVar analysis + ATMANL_GSI="${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}analysis.atm.a00${FHR}.nc" + ATMANL_GSI_ENSRES="${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}ensres_analysis.atm.a00${FHR}.nc" + + # if we already have a ensemble resolution GSI analysis then just link to it + if [[ -f ${ATMANL_GSI_ENSRES} ]]; then + ${NLN} "${ATMANL_GSI_ENSRES}" atmanl_gsi_ensres + else + ${NLN} "${ATMANL_GSI}" atmanl_gsi + ${NLN} "${ATMANL_GSI_ENSRES}" atmanl_gsi_ensres + SIGLEVEL="${SIGLEVEL:-"${FIXgfs}/am/global_hyblev.l${LEVS}.txt"}" + ${NLN} "${CHGRESNC}" chgres.x + chgresnml=chgres_nc_gauss.nml + nmltitle=chgres + + export OMP_NUM_THREADS=${NTHREADS_CHGRES} + + rm -f "${chgresnml}" + cat > "${chgresnml}" << EOF +&${nmltitle}_setup + i_output=${LONB_ENKF} + j_output=${LATB_ENKF} + input_file="atmanl_gsi" + output_file="atmanl_gsi_ensres" + terrain_file="atmanl_ensmean" + vcoord_file="${SIGLEVEL}" +/ +EOF + cat "${chgresnml}" + ${APRUN_CHGRES} ./chgres.x + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to change the resolution of the deterministic analysis to the ensemble resolution!" + fi + fi + + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + ################################################################################ + # Recenter ensemble member atmospheric analyses about hires analysis + + FILENAMEIN="atmanl" + FILENAME_MEANIN="atmanl_ensmean" # EnKF ensemble mean analysis + FILENAME_MEANOUT="atmanl_gsi_ensres" # recenter around GSI analysis at ensemble resolution + FILENAMEOUT="ratmanl" + + export OMP_NUM_THREADS=${NTHREADS_ECEN} + export pgm=${RECENATMEXEC} + source prep_step + + cpreq "${RECENATMEXEC}" "${DATA}" + ${APRUN_ECEN} "${DATA}/$(basename "${RECENATMEXEC}")" "${FILENAMEIN}" "${FILENAME_MEANIN}" "${FILENAME_MEANOUT}" "${FILENAMEOUT}" "${NMEM_ENS}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to recenter the ensemble resolution mean analysis" + fi + else + ################################################################################ + # Recenter ensemble member atmospheric increments about hires analysis + + FILENAMEIN="atminc" + FILENAME_INCMEANIN="atminc_ensmean" # EnKF ensemble mean increment + FILENAME_GESMEANIN="atmges_ensmean" # EnKF ensemble mean guess + FILENAME_GSIDET="atmanl_gsi_ensres" # recenter around GSI analysis at ensemble resolution + FILENAMEOUT="ratminc" + + export OMP_NUM_THREADS=${NTHREADS_ECEN} + + # make the small namelist file for incvars_to_zero + + rm -f recenter.nml + cat > recenter.nml << EOF +&recenter + incvars_to_zero = ${INCREMENTS_TO_ZERO} +/ +EOF + cat recenter.nml + + export pgm=${RECENATMEXEC} + source prep_step + + cpreq "${RECENATMEXEC}" "${DATA}" + ${APRUN_ECEN} "${DATA}/$(basename "${RECENATMEXEC}")" "${FILENAMEIN}" "${FILENAME_INCMEANIN}" "${FILENAME_GSIDET}" "${FILENAMEOUT}" "${NMEM_ENS}" "${FILENAME_GESMEANIN}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to recenter the mean ensemble resolution increments!" + fi + fi + fi + + ################################################################################ + # Calculate ensemble analysis increment + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + if [[ "${RECENTER_ENKF}" == "YES" ]]; then + ATMANLNAME='ratmanl' + else + ATMANLNAME='atmanl' + fi + + export OMP_NUM_THREADS=${NTHREADS_CALCINC} + CALCINCEXEC=${CALCINCNCEXEC} + + export pgm=${CALCINCEXEC} + source prep_step + + cpreq "${CALCINCEXEC}" "${DATA}" + rm -f calc_increment.nml + + cat > calc_increment.nml << EOF +&setup + datapath = './' + analysis_filename = '${ATMANLNAME}' + firstguess_filename = 'atmges' + increment_filename = 'atminc' + debug = .false. + nens = ${NMEM_ENS} + imp_physics = ${imp_physics} +/ +&zeroinc + incvars_to_zero = ${INCREMENTS_TO_ZERO} +/ +EOF + cat calc_increment.nml + + ${APRUN_CALCINC} "${DATA}/$(basename "${CALCINCEXEC}")" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "Failed to calculate the increment from the ensemble guess!" + fi + fi +done # loop over analysis times in window + +################################################################################ + +################################################################################ +# Postprocessing +cd "${pwd}" || exit 1 + +exit "${err}" diff --git a/scripts/exgdas_enkf_ecen_fv3jedi.py b/dev/scripts/exglobal_enkf_ecen_fv3jedi.py similarity index 100% rename from scripts/exgdas_enkf_ecen_fv3jedi.py rename to dev/scripts/exglobal_enkf_ecen_fv3jedi.py diff --git a/scripts/exgdas_enkf_select_obs.sh b/dev/scripts/exglobal_enkf_select_obs.sh similarity index 95% rename from scripts/exgdas_enkf_select_obs.sh rename to dev/scripts/exglobal_enkf_select_obs.sh index c6dc219e098..921057bb3f9 100755 --- a/scripts/exgdas_enkf_select_obs.sh +++ b/dev/scripts/exglobal_enkf_select_obs.sh @@ -50,11 +50,11 @@ ${NLN} "${SELECT_OBS}" obsinput.tar # Whether to save or skip obs if [[ "${RUN_SELECT}" == "YES" && "${USE_SELECT}" == "NO" ]]; then - lread_obs_save=".true." - lread_obs_skip=".false." + lread_obs_save=".true." + lread_obs_skip=".false." elif [[ "${RUN_SELECT}" == "NO" && "${USE_SELECT}" == "YES" ]]; then - lread_obs_save=".false." - lread_obs_skip=".true." + lread_obs_save=".false." + lread_obs_skip=".true." fi ################################################################################ @@ -90,11 +90,11 @@ export CHEM="${CHEM_INVOBS}" "${ANALYSISSH}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run the GSI!" + err_exit "Failed to run the GSI!" fi ################################################################################ # Postprocessing cd "${pwd}" || exit 1 -exit ${err} +exit "${err}" diff --git a/scripts/exgdas_enkf_sfc.sh b/dev/scripts/exglobal_enkf_sfc.sh similarity index 70% rename from scripts/exgdas_enkf_sfc.sh rename to dev/scripts/exglobal_enkf_sfc.sh index 9215edcd5f7..e0fa15ab5ee 100755 --- a/scripts/exgdas_enkf_sfc.sh +++ b/dev/scripts/exglobal_enkf_sfc.sh @@ -38,19 +38,19 @@ NCLEN=${NCLEN:-${USHgfs}/getncdimlen} OPREFIX=${OPREFIX:-""} OSUFFIX=${OSUFFIX:-""} APREFIX=${APREFIX:-""} -APREFIX_ENS=${APREFIX_ENS:-$APREFIX} +APREFIX_ENS=${APREFIX_ENS:-${APREFIX}} GPREFIX=${GPREFIX:-""} GPREFIX_ENS=${GPREFIX_ENS:-${GPREFIX}} # Variables NMEM_ENS_MAX=${NMEM_ENS:-80} if [[ "${RUN}" == "enkfgfs" ]]; then - NMEM_ENS=${NMEM_ENS_GFS:-30} - ec_offset=${NMEM_ENS_GFS_OFFSET:-20} - mem_offset=$((ec_offset * cyc/6)) + NMEM_ENS=${NMEM_ENS_GFS:-30} + ec_offset=${NMEM_ENS_GFS_OFFSET:-20} + mem_offset=$((ec_offset * cyc / 6)) else - NMEM_ENS=${NMEM_ENS:-80} - mem_offset=0 + NMEM_ENS=${NMEM_ENS:-80} + mem_offset=0 fi DOIAU=${DOIAU_ENKF:-"NO"} @@ -79,9 +79,9 @@ bcyc=${BDATE:8:2} # Get dimension information based on CASE res=${CASE:1} -JCAP_CASE=$((res*2-2)) -LATB_CASE=$((res*2)) -LONB_CASE=$((res*4)) +JCAP_CASE=$((res * 2 - 2)) +LATB_CASE=$((res * 2)) +LONB_CASE=$((res * 4)) # Global cycle requires these files export FNTSFA=${FNTSFA:-' '} @@ -92,42 +92,44 @@ if [[ ! -f "${FNSNOA}" ]]; then export FNSNOA="${COMIN_OBS}/${OPREFIX}snogrb_t1534.3072.1536" fi if [[ ! -f "${FNSNOA}" ]]; then - echo "WARNING: Current cycle snow file ${FNSNOA} is missing. Snow coverage will not be updated." + echo "WARNING: Current cycle snow file ${FNSNOA} is missing. Snow coverage will not be updated." else - echo "INFO: Current cycle snow file is ${FNSNOA}" + echo "INFO: Current cycle snow file is ${FNSNOA}" fi export FNSNOG=${FNSNOG:-${COMIN_OBS_PREV}/${GPREFIX}snogrb_t${JCAP_CASE}.${LONB_CASE}.${LATB_CASE}} # Check if resolution specific FNSNOG exists, if not use t1534 version if [[ ! -f "${FNSNOG}" ]]; then - export FNSNOG="${COMIN_OBS_PREV}/${GPREFIX}snogrb_t1534.3072.1536" + export FNSNOG="${COMIN_OBS_PREV}/${GPREFIX}snogrb_t1534.3072.1536" fi if [[ ! -f "${FNSNOG}" ]]; then - echo "WARNING: Previous cycle snow file ${FNSNOG} is missing. Snow coverage will not be updated." + echo "WARNING: Previous cycle snow file ${FNSNOG} is missing. Snow coverage will not be updated." else - echo "INFO: Previous cycle snow file is ${FNSNOG}" + echo "INFO: Previous cycle snow file is ${FNSNOG}" fi # If any snow files are missing, don't apply snow in the global_cycle step. if [[ ! -f "${FNSNOA}" || ! -f "${FNSNOG}" ]]; then - export FNSNOA=" " - export CYCLVARS="FSNOL=99999.,FSNOS=99999.," -else - # Set CYCLVARS by checking grib date of current snogrb vs that of prev cycle - snoa_count=$("${WGRIB}" -4yr "${FNSNOA}" 2>/dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') - snog_count=$("${WGRIB}" -4yr "${FNSNOG}" 2>/dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') - if [[ ${snoa_count} -le ${snog_count} ]]; then export FNSNOA=" " export CYCLVARS="FSNOL=99999.,FSNOS=99999.," - else - export SNOW_NUDGE_COEFF=${SNOW_NUDGE_COEFF:-0.} - export CYCLVARS="FSNOL=${SNOW_NUDGE_COEFF},$CYCLVARS" - fi +else + # Set CYCLVARS by checking grib date of current snogrb vs that of prev cycle + # shellcheck disable=SC2312 + snoa_count=$("${WGRIB}" -4yr "${FNSNOA}" 2> /dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') + # shellcheck disable=SC2312 + snog_count=$("${WGRIB}" -4yr "${FNSNOG}" 2> /dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') + if [[ ${snoa_count} -le ${snog_count} ]]; then + export FNSNOA=" " + export CYCLVARS="FSNOL=99999.,FSNOS=99999.," + else + export SNOW_NUDGE_COEFF=${SNOW_NUDGE_COEFF:-0.} + export CYCLVARS="FSNOL=${SNOW_NUDGE_COEFF},${CYCLVARS}" + fi fi if [[ "${DONST}" == "YES" ]]; then - export NST_FILE=${NST_FILE:-${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}analysis.dtf.a006.nc} + export NST_FILE=${NST_FILE:-${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}analysis.dtf.a006.nc} else - export NST_FILE="NULL" + export NST_FILE="NULL" fi # regrid the surface increment files @@ -139,39 +141,39 @@ if [[ "${DO_GSISOILDA}" == "YES" ]]; then export NMEM_REGRID=${NMEM_ENS} if [[ "${DOIAU}" == "YES" ]]; then export LFHR=3 # match BDATE - else # DOSFCANL_ENKF + else # DOSFCANL_ENKF export LFHR=6 # PDYcyc fi "${REGRIDSH}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to regrid the surface inrement file!" + err_exit "Failed to regrid the surface inrement file!" fi fi -export APRUNCY=${APRUN_CYCLE:-$APRUN_ESFC} -export OMP_NUM_THREADS_CY=${NTHREADS_CYCLE:-$NTHREADS_ESFC} -export MAX_TASKS_CY=$NMEM_ENS +export APRUNCY=${APRUN_CYCLE:-${APRUN_ESFC}} +export OMP_NUM_THREADS_CY=${NTHREADS_CYCLE:-${NTHREADS_ESFC}} +export MAX_TASKS_CY=${NMEM_ENS} -if [[ "$DOIAU" == "YES" ]]; then +if [[ "${DOIAU}" == "YES" ]]; then # Update surface restarts at beginning of window when IAU is ON # For now assume/hold analysis.dtf.nc is valid at beginning of window. - for n in $(seq 1 $ntiles); do + for n in $(seq 1 "${ntiles}"); do - export TILE_NUM=$n + export TILE_NUM=${n} # Copy inputs from COMIN to DATA - for imem in $(seq 1 $NMEM_ENS); do + for imem in $(seq 1 "${NMEM_ENS}"); do smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) + if ((smem > NMEM_ENS_MAX)); then + smem=$((smem - NMEM_ENS_MAX)) fi - gmemchar="mem"$(printf %03i "$smem") - cmem=$(printf %03i $imem) - memchar="mem$cmem" + gmemchar="mem"$(printf %03i "${smem}") + cmem=$(printf %03i "${imem}") + memchar="mem${cmem}" MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl \ COMOUT_ATMOS_RESTART_MEM:COM_ATMOS_RESTART_TMPL @@ -200,12 +202,12 @@ if [[ "$DOIAU" == "YES" ]]; then cpreq "${sfcdata_dir}/${bPDY}.${bcyc}0000.${snow_prefix}sfc_data.tile${n}.nc" \ "${DATA}/fnbgsi.${cmem}" cpreq "${DATA}/fnbgsi.${cmem}" "${DATA}/fnbgso.${cmem}" - cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${n}.nc" "${DATA}/fngrid.${cmem}" + cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${n}.nc" "${DATA}/fngrid.${cmem}" cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${n}.nc" "${DATA}/fnorog.${cmem}" - if [[ "${DO_GSISOILDA}" == "YES" && "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then - cpreq "${COMIN_ATMOS_ANALYSIS_MEM}/increment.sfc.i00${LFHR}.tile${n}.nc" \ - "${DATA}/soil_xainc.${cmem}" + if [[ "${DO_GSISOILDA}" == "YES" ]] && [[ "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then + cpreq "${COMIN_ATMOS_ANALYSIS_MEM}/increment.sfc.i00${LFHR}.tile${n}.nc" \ + "${DATA}/soil_xainc.${cmem}" fi done # ensembles @@ -213,18 +215,18 @@ if [[ "$DOIAU" == "YES" ]]; then "${CYCLESH}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to update surface fields!" + err_exit "Failed to update surface fields!" fi # Copy outputs from DATA to COMOUT - for imem in $(seq 1 $NMEM_ENS); do + for imem in $(seq 1 "${NMEM_ENS}"); do smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) + if ((smem > NMEM_ENS_MAX)); then + smem=$((smem - NMEM_ENS_MAX)) fi - gmemchar="mem"$(printf %03i "$smem") - cmem=$(printf %03i $imem) - memchar="mem$cmem" + gmemchar="mem"$(printf %03i "${smem}") + cmem=$(printf %03i "${imem}") + memchar="mem${cmem}" MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl \ COMOUT_ATMOS_RESTART_MEM:COM_ATMOS_RESTART_TMPL @@ -242,18 +244,18 @@ if [[ "$DOIAU" == "YES" ]]; then fi if [[ "${DOSFCANL_ENKF}" == "YES" ]]; then - for n in $(seq 1 $ntiles); do + for n in $(seq 1 "${ntiles}"); do - export TILE_NUM=$n + export TILE_NUM=${n} # Copy inputs from COMIN to DATA - for imem in $(seq 1 $NMEM_ENS); do + for imem in $(seq 1 "${NMEM_ENS}"); do smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) + if ((smem > NMEM_ENS_MAX)); then + smem=$((smem - NMEM_ENS_MAX)) fi - gmemchar="mem"$(printf %03i "$smem") - cmem=$(printf %03i ${imem}) + gmemchar="mem"$(printf %03i "${smem}") + cmem=$(printf %03i "${imem}") memchar="mem${cmem}" RUN="${GDUMP_ENS}" MEMDIR=${gmemchar} YMD=${PDY} HH=${cyc} declare_from_tmpl \ @@ -277,26 +279,26 @@ if [[ "${DOSFCANL_ENKF}" == "YES" ]]; then cpreq "${sfcdata_dir}/${PDY}.${cyc}0000.${snow_prefix}sfc_data.tile${n}.nc" \ "${DATA}/fnbgsi.${cmem}" cpreq "${DATA}/fnbgsi.${cmem}" "${DATA}/fnbgso.${cmem}" - cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${n}.nc" "${DATA}/fngrid.${cmem}" + cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${n}.nc" "${DATA}/fngrid.${cmem}" cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${n}.nc" "${DATA}/fnorog.${cmem}" - if [[ "${DO_GSISOILDA}" == "YES" && "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then - cpreq "${COMIN_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.sfc.i00${LFHR}.tile${n}.nc" \ - "${DATA}/soil_xainc.${cmem}" + if [[ "${DO_GSISOILDA}" == "YES" ]] && [[ "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then + cpreq "${COMIN_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.sfc.i00${LFHR}.tile${n}.nc" \ + "${DATA}/soil_xainc.${cmem}" fi done "${CYCLESH}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to update surface increment!" + err_exit "Failed to update surface increment!" fi # Copy outputs from DATA to COMOUT for imem in $(seq 1 "${NMEM_ENS}"); do smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) + if ((smem > NMEM_ENS_MAX)); then + smem=$((smem - NMEM_ENS_MAX)) fi gmemchar="mem"$(printf %03i "${smem}") cmem=$(printf %03i "${imem}") @@ -322,5 +324,4 @@ fi # Postprocessing cd "${pwd}" || exit 1 - exit "${err}" diff --git a/scripts/exgdas_enkf_update.sh b/dev/scripts/exglobal_enkf_update.sh similarity index 59% rename from scripts/exgdas_enkf_update.sh rename to dev/scripts/exglobal_enkf_update.sh index b6fdb47098b..c44ba3e2bb9 100755 --- a/scripts/exgdas_enkf_update.sh +++ b/dev/scripts/exglobal_enkf_update.sh @@ -18,71 +18,43 @@ ################################################################################ # Directories. -pwd=$(pwd) +cd "${DATA}" || exit 1 # Utilities NCLEN=${NCLEN:-${USHgfs}/getncdimlen} -USE_CFP=${USE_CFP:-"NO"} -CFP_MP=${CFP_MP:-"NO"} -nm="" -if [[ "${CFP_MP}" == "YES" ]]; then - nm=0 -fi -APRUNCFP=${APRUNCFP:-""} APRUN_ENKF=${APRUN_ENKF:-${APRUN:-""}} NTHREADS_ENKF=${NTHREADS_ENKF:-${NTHREADS:-1}} # Executables ENKFEXEC=${ENKFEXEC:-${EXECgfs}/enkf.x} -# Filenames. -GPREFIX=${GPREFIX:-""} -APREFIX=${APREFIX:-""} - -SMOOTH_ENKF=${SMOOTH_ENKF:-"YES"} +APREFIX=${APREFIX:-${RUN}.t${cyc}z.} +GPREFIX=${GPREFIX:-${RUN}.t${GDATE:8:2}z.} -GBIASe=${GBIASe:-${APREFIX}abias_int.ensmean.txt} -CNVSTAT=${CNVSTAT:-${APREFIX}cnvstat.tar} -OZNSTAT=${OZNSTAT:-${APREFIX}oznstat.tar} -RADSTAT=${RADSTAT:-${APREFIX}radstat.tar} -ENKFSTAT=${ENKFSTAT:-${APREFIX}enkfstat.txt} +# GBIASe=${GBIASe:-${APREFIX}abias_int.ensmean.txt} # TODO: remove (see comment and TODO below) Also, this is not a "G"BIAS (See the name, it has APREFIX in its name) +CNVSTAT="${APREFIX}cnvstat_ensmean.tar" +OZNSTAT="${APREFIX}oznstat_ensmean.tar" +RADSTAT="${APREFIX}radstat_ensmean.tar" # Namelist parameters -USE_CORRELATED_OBERRS=${USE_CORRELATED_OBERRS:-"NO"} -NAM_ENKF=${NAM_ENKF:-""} -SATOBS_ENKF=${SATOBS_ENKF:-""} -OZOBS_ENKF=${OZOBS_ENKF:-""} -use_correlated_oberrs=${use_correlated_oberrs:-".false."} -if [[ "${USE_CORRELATED_OBERRS}" == "YES" ]]; then - use_correlated_oberrs=".true." +if [[ "${USE_CORRELATED_OBERRS:-}" == "YES" ]]; then + use_correlated_oberrs=".true." fi -imp_physics=${imp_physics:-"99"} -lupp=${lupp:-".true."} corrlength=${corrlength:-1250} lnsigcutoff=${lnsigcutoff:-2.5} analpertwt=${analpertwt:-0.85} -readin_localization_enkf=${readin_localization_enkf:-".true."} -reducedgrid=${reducedgrid:-".false."} -letkf_flag=${letkf_flag:-".false."} -getkf=${getkf:-".false."} -denkf=${denkf:-".false."} -nobsl_max=${nobsl_max:-10000} -write_spread_diag=${write_spread_diag:-".false."} cnvw_option=${cnvw_option:-".false."} -netcdf_diag=${netcdf_diag:-".true."} -modelspace_vloc=${modelspace_vloc:-".false."} # if true, 'vlocal_eig.dat' is needed -taperanalperts=${taperanalperts:-".false."} IAUFHRS_ENKF=${IAUFHRS_ENKF:-"6,"} NMEM_ENS_MAX=${NMEM_ENS:-80} if [[ "${RUN}" == "enkfgfs" ]]; then - DO_CALC_INCREMENT=${DO_CALC_INCREMENT_ENKF_GFS:-"NO"} - NMEM_ENS=${NMEM_ENS_GFS:-30} - ec_offset=${NMEM_ENS_GFS_OFFSET:-20} - mem_offset=$((ec_offset * cyc/6)) + DO_CALC_INCREMENT=${DO_CALC_INCREMENT_ENKF_GFS:-"NO"} + NMEM_ENS=${NMEM_ENS_GFS:-30} + ec_offset=${NMEM_ENS_GFS_OFFSET:-20} + mem_offset=$((ec_offset * cyc / 6)) else - DO_CALC_INCREMENT=${DO_CALC_INCREMENT:-"NO"} - NMEM_ENS=${NMEM_ENS:-80} - mem_offset=0 + DO_CALC_INCREMENT=${DO_CALC_INCREMENT:-"NO"} + NMEM_ENS=${NMEM_ENS:-80} + mem_offset=0 fi INCREMENTS_TO_ZERO=${INCREMENTS_TO_ZERO:-"'NONE'"} DO_GSISOILDA=${DO_GSISOILDA:-"NO"} @@ -93,15 +65,12 @@ hofx_2m_sfcfile=${hofx_2m_sfcfile:-".false."} ATMGES_ENSMEAN="${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.atm.f006.nc" LONB_ENKF=${LONB_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" grid_xt)} # get LONB_ENKF LATB_ENKF=${LATB_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" grid_yt)} # get LATB_ENFK -LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" pfull)} # get LEVS_ENFK -use_gfs_ncio=".true." -use_gfs_nemsio=".false." -paranc=${paranc:-".true."} +LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} "${ATMGES_ENSMEAN}" pfull)} # get LEVS_ENFK WRITE_INCR_ZERO="incvars_to_zero= ${INCREMENTS_TO_ZERO}," if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then - write_fv3_incr=".false." + write_fv3_incr=".false." else - write_fv3_incr=".true." + write_fv3_incr=".true." fi LATA_ENKF=${LATA_ENKF:-${LATB_ENKF}} LONA_ENKF=${LONA_ENKF:-${LONB_ENKF}} @@ -114,145 +83,105 @@ HYBENSINFO=${HYBENSINFO:-${FIXgfs}/gsi/global_hybens_info.l${LEVS_ENKF}.txt} ANAVINFO=${ANAVINFO:-${FIXgfs}/gsi/global_anavinfo.l${LEVS_ENKF}.txt} VLOCALEIG=${VLOCALEIG:-${FIXgfs}/gsi/vlocal_eig_l${LEVS_ENKF}.dat} ENKF_SUFFIX="s" -if [[ "${SMOOTH_ENKF}" == "NO" ]]; then +if [[ "${SMOOTH_ENKF:-YES}" == "NO" ]]; then ENKF_SUFFIX="" fi ################################################################################ # Fixed files -${NLN} "${SATANGL}" satbias_angle +cpreq "${SATANGL}" satbias_angle +cpreq "${SCANINFO}" scaninfo +cpreq "${HYBENSINFO}" hybens_info +cpreq "${ANAVINFO}" anavinfo +cpreq "${VLOCALEIG}" vlocal_eig.dat if [[ "${SATINFO}" == "generate" ]]; then - "${USHgfs}/create_gsi_info.sh" sat "${PDY}${cyc}" "${DATA}" + "${USHgfs}/create_gsi_info.sh" sat "${PDY}${cyc}" "${DATA}" else - ${NLN} "${SATINFO}" satinfo + cpreq "${SATINFO}" satinfo fi if [[ "${CONVINFO}" == "generate" ]]; then - "${USHgfs}/create_gsi_info.sh" conv "${PDY}${cyc}" "${DATA}" "${USE_2M_OBS}" + "${USHgfs}/create_gsi_info.sh" conv "${PDY}${cyc}" "${DATA}" "${USE_2M_OBS}" else - ${NLN} "${CONVINFO}" convinfo + cpreq "${CONVINFO}" convinfo fi if [[ "${OZINFO}" == "generate" ]]; then - "${USHgfs}/create_gsi_info.sh" oz "${PDY}${cyc}" "${DATA}" + "${USHgfs}/create_gsi_info.sh" oz "${PDY}${cyc}" "${DATA}" else - ${NLN} "${OZINFO}" ozinfo + cpreq "${OZINFO}" ozinfo fi -${NLN} "${SCANINFO}" scaninfo -${NLN} "${HYBENSINFO}" hybens_info -${NLN} "${ANAVINFO}" anavinfo -${NLN} "${VLOCALEIG}" vlocal_eig.dat # Bias correction coefficients based on the ensemble mean -${NLN} "${COMIN_ATMOS_ANALYSIS_STAT}/${GBIASe}" "satbias_in" +#${NLN} "${COMIN_ATMOS_ANALYSIS_STAT}/${GBIASe}" "satbias_in" # This file does not exist when test was run # TODO: remove ################################################################################ +# Ensemble guess, observational data and analyses/increments -if [[ "${USE_CFP}" == "YES" ]]; then - rm -f "${DATA}/untar.sh" "${DATA}/mp_untar.sh" - cat > "${DATA}/untar.sh" << EOFuntar -#!/bin/sh -memchar=\$1 -COMOUT_ATMOS_ANALYSIS=\$2 flist="${CNVSTAT} ${OZNSTAT} ${RADSTAT}" -for ftype in \$flist; do - if [[ "\${memchar}" == "ensmean" ]]; then - fname=\${COMOUT_ATMOS_ANALYSIS}/\${ftype%.tar}.ensmean.tar - else - fname=\${COMOUT_ATMOS_ANALYSIS}/\${ftype} - fi - tar -xvf \$fname +for ftype in ${flist}; do + fname="${COMIN_ATMOS_ANALYSIS_STAT}/${ftype}" + tar -xvf "${fname}" done -EOFuntar - chmod 755 "${DATA}/untar.sh" -fi -################################################################################ -# Ensemble guess, observational data and analyses/increments +nfhrs="${IAUFHRS_ENKF//,/ }" +for imem in $(seq 1 "${NMEM_ENS}"); do + smem=$((imem + mem_offset)) + if [[ ${smem} -gt ${NMEM_ENS_MAX} ]]; then + smem=$((smem - NMEM_ENS_MAX)) + fi + gmemchar="mem"$(printf "%03i" "${smem}") + memchar="mem"$(printf "%03i" "${imem}") -flist="${CNVSTAT} ${OZNSTAT} ${RADSTAT}" -if [[ "${USE_CFP}" == "YES" ]]; then - echo "${nm} ${DATA}/untar.sh ensmean ${COMIN_ATMOS_ANALYSIS_STAT}" | tee -a "${DATA}/mp_untar.sh" - if [[ "${CFP_MP:-NO}" == "YES" ]]; then - nm=$((nm+1)) - fi -else - for ftype in ${flist}; do - fname="${COMIN_ATMOS_ANALYSIS_STAT}/${ftype}.tar" - tar -xvf "${fname}" - done -fi -nfhrs=$(echo "${IAUFHRS_ENKF}" | sed 's/,/ /g') -for imem in $(seq 1 ${NMEM_ENS}); do - smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) - fi - gmemchar="mem"$(printf "%03i" "${smem}") - memchar="mem"$(printf "%03i" "${imem}") + MEMDIR=${gmemchar} RUN=${GDUMP} YMD=${GDATE:0:8} HH=${GDATE:8:2} declare_from_tmpl -x \ + COMIN_ATMOS_HISTORY_MEM_PREV:COM_ATMOS_HISTORY_TMPL + + MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ + COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL - MEMDIR=${gmemchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -x \ - COMIN_ATMOS_HISTORY_MEM_PREV:COM_ATMOS_HISTORY_TMPL + mkdir -p "${COMOUT_ATMOS_ANALYSIS_MEM}" - MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ - COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL + for FHR in ${nfhrs}; do + ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}atm.f00${FHR}${ENKF_SUFFIX}.nc" \ + "sfg_${PDY}${cyc}_fhr0${FHR}_${memchar}" + if [[ "${hofx_2m_sfcfile}" == ".true." ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}sfc.f00${FHR}${ENKF_SUFFIX}.nc" \ + "bfg_${PDY}${cyc}_fhr0${FHR}_${memchar}" + fi + if [[ "${cnvw_option}" == ".true." ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}sfc.f00${FHR}.nc" \ + "sfgsfc_${PDY}${cyc}_fhr0${FHR}_${memchar}" + fi - mkdir -p "${COMOUT_ATMOS_ANALYSIS_MEM}" + if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}analysis.atm.a00${FHR}.nc" \ + "sanl_${PDY}${cyc}_fhr0${FHR}_${memchar}" + else + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.atm.i00${FHR}.nc" \ + "incr_${PDY}${cyc}_fhr0${FHR}_${memchar}" + fi - for FHR in ${nfhrs}; do - ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}atm.f00${FHR}${ENKF_SUFFIX}.nc" \ - "sfg_${PDY}${cyc}_fhr0${FHR}_${memchar}" - if [[ "${hofx_2m_sfcfile}" == ".true." ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}sfc.f00${FHR}${ENKF_SUFFIX}.nc" \ - "bfg_${PDY}${cyc}_fhr0${FHR}_${memchar}" - fi - if [[ "${cnvw_option}" == ".true." ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX}sfc.f00${FHR}.nc" \ - "sfgsfc_${PDY}${cyc}_fhr0${FHR}_${memchar}" - fi - if [[ "${DO_CALC_INCREMENT}" == "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}analysis.atm.a00${FHR}.nc" \ - "sanl_${PDY}${cyc}_fhr0${FHR}_${memchar}" - else - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.atm.i00${FHR}.nc" \ - "incr_${PDY}${cyc}_fhr0${FHR}_${memchar}" - fi - if [[ "${DO_GSISOILDA}" == "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.sfc.i00${FHR}.nc" \ - "sfcincr_${PDY}${cyc}_fhr0${FHR}_${memchar}" - fi - done + if [[ "${DO_GSISOILDA}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX}increment.sfc.i00${FHR}.nc" \ + "sfcincr_${PDY}${cyc}_fhr0${FHR}_${memchar}" + fi + done done # Ensemble mean guess for FHR in ${nfhrs}; do - - ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.atm.f00${FHR}.nc" \ - "sfg_${PDY}${cyc}_fhr0${FHR}_ensmean" - if [[ "${cnvw_option}" == ".true." ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.sfc.f00${FHR}.nc" \ - "sfgsfc_${PDY}${cyc}_fhr0${FHR}_ensmean" - fi - if [[ "${DO_GSISOILDA}" == "YES" ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.sfc.f00${FHR}.nc" \ - "bfg_${PDY}${cyc}_fhr0${FHR}_ensmean" - ${NLN} "${COMIN_ATMOS_ANALYSIS_STAT}/${APREFIX}increment.sfc.i00${FHR}.nc" \ - "sfcincr_${PDY}${cyc}_fhr0${FHR}_ensmean" - fi + ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.atm.f00${FHR}.nc" \ + "sfg_${PDY}${cyc}_fhr0${FHR}_ensmean" + if [[ "${cnvw_option}" == ".true." ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.sfc.f00${FHR}.nc" \ + "sfgsfc_${PDY}${cyc}_fhr0${FHR}_ensmean" + fi + if [[ "${DO_GSISOILDA}" == "YES" ]]; then + ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX}ensmean.sfc.f00${FHR}.nc" \ + "bfg_${PDY}${cyc}_fhr0${FHR}_ensmean" + ${NLN} "${COMIN_ATMOS_ANALYSIS_STAT}/${APREFIX}ensmean_increment.sfc.i00${FHR}.nc" \ + "sfcincr_${PDY}${cyc}_fhr0${FHR}_ensmean" + fi done -if [[ "${USE_CFP}" == "YES" ]]; then - chmod 755 "${DATA}/mp_untar.sh" - ncmd=$(wc -l < "${DATA}/mp_untar.sh") - if [[ ${ncmd} -gt 0 ]]; then - ncmd_max=$((ncmd < max_tasks_per_node ? ncmd : max_tasks_per_node)) - APRUNCFP=$(eval echo "${APRUNCFP}") - ${APRUNCFP} "${DATA}/mp_untar.sh" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to untar input data!" - fi - fi -fi - ################################################################################ # Create global_enkf namelist cat > enkf.nml << EOFnml @@ -269,19 +198,19 @@ cat > enkf.nml << EOFnml sprd_tol=1.e30,paoverpb_thresh=0.98, nlons=${LONA_ENKF},nlats=${LATA_ENKF},nlevs=${LEVS_ENKF},nanals=${NMEM_ENS}, deterministic=.true.,sortinc=.true.,lupd_satbiasc=.false., - reducedgrid=${reducedgrid},readin_localization=${readin_localization_enkf}., - use_gfs_nemsio=${use_gfs_nemsio},use_gfs_ncio=${use_gfs_ncio},imp_physics=${imp_physics},lupp=${lupp}, + reducedgrid=${reducedgrid:-.false.},readin_localization=${readin_localization_enkf:-.true.}, + use_gfs_nemsio=.false.,use_gfs_ncio=.true.,imp_physics=${imp_physics:-99},lupp=${lupp:-.true.}, univaroz=.false.,adp_anglebc=.true.,angord=4,use_edges=.false.,emiss_bc=.true., - letkf_flag=${letkf_flag},nobsl_max=${nobsl_max},denkf=${denkf},getkf=${getkf}., + letkf_flag=${letkf_flag:-.false.},nobsl_max=${nobsl_max:-10000},denkf=${denkf:-.false.},getkf=${getkf:-.false.}, nhr_anal=${IAUFHRS_ENKF},nhr_state=${IAUFHRS_ENKF}, - lobsdiag_forenkf=.true.,taperanalperts=${taperanalperts}, - write_spread_diag=${write_spread_diag}, - modelspace_vloc=${modelspace_vloc}, - use_correlated_oberrs=${use_correlated_oberrs}, - netcdf_diag=${netcdf_diag},cnvw_option=${cnvw_option}, - paranc=${paranc},write_fv3_incr=${write_fv3_incr}, + lobsdiag_forenkf=.true.,taperanalperts=${taperanalperts:-.false.}, + write_spread_diag=${write_spread_diag:-".false."}, + modelspace_vloc=${modelspace_vloc:-.false.}, + use_correlated_oberrs=${use_correlated_oberrs:-.false.}, + netcdf_diag=.true.,cnvw_option=${cnvw_option}, + paranc=${paranc:-.true.},write_fv3_incr=${write_fv3_incr}, ${WRITE_INCR_ZERO} - ${NAM_ENKF} + ${NAM_ENKF:-} / &satobs_enkf sattypes_rad(1) = 'amsua_n15', dsis(1) = 'amsua_n15', @@ -364,7 +293,7 @@ cat > enkf.nml << EOFnml sattypes_rad(78)= 'atms_n21', dsis(78)= 'atms_n21', sattypes_rad(79)= 'cris-fsr_n21', dsis(79)= 'cris-fsr_n21', sattypes_rad(80)= 'abi_g19', dsis(80)= 'abi_g19', - ${SATOBS_ENKF} + ${SATOBS_ENKF:-} / &ozobs_enkf sattypes_oz(1) = 'sbuv2_n16', @@ -383,7 +312,7 @@ cat > enkf.nml << EOFnml sattypes_oz(14) = 'ompstc8_n21', sattypes_oz(15) = 'ompsnp_n21', sattypes_oz(16) = 'gome_metop-c', - ${OZOBS_ENKF} + ${OZOBS_ENKF:-} / EOFnml @@ -395,17 +324,17 @@ export pgm=${ENKFEXEC} source prep_step cpreq "${ENKFEXEC}" "${DATA}" -${APRUN_ENKF} "${DATA}/$(basename ${ENKFEXEC})" 1>stdout 2>stderr && true +${APRUN_ENKF} "${DATA}/$(basename "${ENKFEXEC}")" 1> stdout 2> stderr && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run the EnKF!" + err_exit "Failed to run the EnKF!" fi # Cat runtime output files. -cat stdout stderr > "${COMOUT_ATMOS_ANALYSIS_STAT}/${ENKFSTAT}" +cat stdout stderr > enkfstat.txt +cpfs enkfstat.txt "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX}enkfstat.txt" ################################################################################ # Postprocessing -cd "${pwd}" || exit 1 -exit "${err}" +exit 0 diff --git a/scripts/exglobal_extractvars.sh b/dev/scripts/exglobal_extractvars.sh similarity index 64% rename from scripts/exglobal_extractvars.sh rename to dev/scripts/exglobal_extractvars.sh index d735db6310a..952bf83f694 100755 --- a/scripts/exglobal_extractvars.sh +++ b/dev/scripts/exglobal_extractvars.sh @@ -17,36 +17,36 @@ EXTRCTVARO="${USHgfs}/ocnice_extractvars.sh" EXTRCTVARW="${USHgfs}/wave_extractvars.sh" # Set FHMAX_HF_GFS equal to FHMAX_GFS if FHMAX_HF_GFS is greater than FHMAX_GFS -if (( FHMAX_GFS < FHMAX_HF_GFS )); then - export FHMAX_HF_GFS=${FHMAX_GFS} +if ((FHMAX_GFS < FHMAX_HF_GFS)); then + export FHMAX_HF_GFS=${FHMAX_GFS} fi # Set FHOUT_WAV_EXTRACT equal to FHOUT_WAV if FHOUT_WAV is not a factor of FHOUT_WAV_EXTRACT -if (( FHOUT_WAV_EXTRACT % FHOUT_WAV != 0 )); then - FHOUT_WAV_EXTRACT=${FHOUT_WAV} +if ((FHOUT_WAV_EXTRACT % FHOUT_WAV != 0)); then + FHOUT_WAV_EXTRACT=${FHOUT_WAV} fi # Extract variables for atmosphere if [[ "${DO_ATM}" == "YES" ]]; then - ${EXTRCTVARA} "${DATA}/atmos" + ${EXTRCTVARA} "${DATA}/atmos" fi # Extract variables for ocean if [[ "${DO_OCN}" == "YES" ]]; then - export component_name="ocn" - ${EXTRCTVARO} "${DATA}/ocn" "${varlist_ocn_netcdf}" "${ocnres}" "${compress_ocn}" "${FHOUT_OCN_GFS}" "${ARC_RFCST_PROD_OCN}" + export component_name="ocn" + ${EXTRCTVARO} "${DATA}/ocn" "${varlist_ocn_netcdf}" "${ocnres}" "${compress_ocn}" "${FHOUT_OCN_GFS}" "${ARC_RFCST_PROD_OCN}" fi # Extract variables for ice if [[ "${DO_ICE}" == "YES" ]]; then - export component_name="ice" - ${EXTRCTVARO} "${DATA}/ice" "${varlist_ice_netcdf}" "${iceres}" "${compress_ice}" "${FHOUT_ICE_GFS}" "${ARC_RFCST_PROD_ICE}" + export component_name="ice" + ${EXTRCTVARO} "${DATA}/ice" "${varlist_ice_netcdf}" "${iceres}" "${compress_ice}" "${FHOUT_ICE_GFS}" "${ARC_RFCST_PROD_ICE}" fi # Extract variables for wave if [[ "${DO_WAVE}" == "YES" ]]; then - export component_name="wav" - ${EXTRCTVARW} "${DATA}/wav" + export component_name="wav" + ${EXTRCTVARW} "${DATA}/wav" fi exit 0 diff --git a/scripts/exglobal_fetch.py b/dev/scripts/exglobal_fetch.py similarity index 100% rename from scripts/exglobal_fetch.py rename to dev/scripts/exglobal_fetch.py diff --git a/scripts/exglobal_forecast.py b/dev/scripts/exglobal_forecast.py similarity index 100% rename from scripts/exglobal_forecast.py rename to dev/scripts/exglobal_forecast.py diff --git a/scripts/exglobal_forecast.sh b/dev/scripts/exglobal_forecast.sh similarity index 89% rename from scripts/exglobal_forecast.sh rename to dev/scripts/exglobal_forecast.sh index bbdef1aee20..6367cefdb62 100755 --- a/scripts/exglobal_forecast.sh +++ b/dev/scripts/exglobal_forecast.sh @@ -78,12 +78,12 @@ ####################### # include all subroutines. Executions later. -source "${USHgfs}/forecast_predet.sh" # include functions for variable definition -source "${USHgfs}/forecast_det.sh" # include functions for run type determination -source "${USHgfs}/forecast_postdet.sh" # include functions for variables after run type determination -source "${USHgfs}/parsing_ufs_configure.sh" # include functions for ufs_configure processing +source "${USHgfs}/forecast_predet.sh" # include functions for variable definition +source "${USHgfs}/forecast_det.sh" # include functions for run type determination +source "${USHgfs}/forecast_postdet.sh" # include functions for variables after run type determination +source "${USHgfs}/parsing_ufs_configure.sh" # include functions for ufs_configure processing -source "${USHgfs}/atparse.bash" # include function atparse for parsing @[XYZ] templated files +source "${USHgfs}/atparse.bash" # include function atparse for parsing @[XYZ] templated files # Coupling control switches, for coupling purpose, off by default cpl=${cpl:-.false.} @@ -165,21 +165,21 @@ echo "MAIN: Name lists and model configuration written" # run the executable if [[ "${esmf_profile:-}" == ".true." ]]; then - export ESMF_RUNTIME_PROFILE=ON - export ESMF_RUNTIME_PROFILE_OUTPUT=SUMMARY + export ESMF_RUNTIME_PROFILE=ON + export ESMF_RUNTIME_PROFILE_OUTPUT=SUMMARY fi if [[ "${USE_ESMF_THREADING:-}" == "YES" ]]; then - unset OMP_NUM_THREADS + unset OMP_NUM_THREADS else - export OMP_NUM_THREADS=${UFS_THREADS:-1} + export OMP_NUM_THREADS=${UFS_THREADS:-1} fi cpreq "${EXECgfs}/${FCSTEXEC}" "${DATA}/" ${APRUN_UFS} "${DATA}/${FCSTEXEC}" 1>&1 2>&2 && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "The forecast failed to run to completion!" + err_exit "The forecast failed to run to completion!" fi FV3_out diff --git a/scripts/exglobal_globus_arch.py b/dev/scripts/exglobal_globus_arch.py similarity index 100% rename from scripts/exglobal_globus_arch.py rename to dev/scripts/exglobal_globus_arch.py diff --git a/scripts/exglobal_globus_earc.py b/dev/scripts/exglobal_globus_earc.py similarity index 100% rename from scripts/exglobal_globus_earc.py rename to dev/scripts/exglobal_globus_earc.py diff --git a/scripts/exglobal_marine_analysis_checkpoint.py b/dev/scripts/exglobal_marine_analysis_checkpoint.py similarity index 100% rename from scripts/exglobal_marine_analysis_checkpoint.py rename to dev/scripts/exglobal_marine_analysis_checkpoint.py diff --git a/scripts/exglobal_marine_analysis_ecen.py b/dev/scripts/exglobal_marine_analysis_ecen.py similarity index 100% rename from scripts/exglobal_marine_analysis_ecen.py rename to dev/scripts/exglobal_marine_analysis_ecen.py diff --git a/scripts/exglobal_marine_analysis_finalize.py b/dev/scripts/exglobal_marine_analysis_finalize.py similarity index 100% rename from scripts/exglobal_marine_analysis_finalize.py rename to dev/scripts/exglobal_marine_analysis_finalize.py diff --git a/scripts/exglobal_marine_analysis_initialize.py b/dev/scripts/exglobal_marine_analysis_initialize.py similarity index 100% rename from scripts/exglobal_marine_analysis_initialize.py rename to dev/scripts/exglobal_marine_analysis_initialize.py diff --git a/scripts/exglobal_marine_analysis_letkf.py b/dev/scripts/exglobal_marine_analysis_letkf.py similarity index 100% rename from scripts/exglobal_marine_analysis_letkf.py rename to dev/scripts/exglobal_marine_analysis_letkf.py diff --git a/scripts/exglobal_marine_analysis_variational.py b/dev/scripts/exglobal_marine_analysis_variational.py similarity index 100% rename from scripts/exglobal_marine_analysis_variational.py rename to dev/scripts/exglobal_marine_analysis_variational.py diff --git a/scripts/exglobal_marinebmat.py b/dev/scripts/exglobal_marinebmat.py similarity index 100% rename from scripts/exglobal_marinebmat.py rename to dev/scripts/exglobal_marinebmat.py diff --git a/scripts/exglobal_marinebmat_initialize.py b/dev/scripts/exglobal_marinebmat_initialize.py similarity index 100% rename from scripts/exglobal_marinebmat_initialize.py rename to dev/scripts/exglobal_marinebmat_initialize.py diff --git a/scripts/exglobal_oceanice_products.py b/dev/scripts/exglobal_oceanice_products.py similarity index 100% rename from scripts/exglobal_oceanice_products.py rename to dev/scripts/exglobal_oceanice_products.py diff --git a/scripts/exglobal_offline_atmos_analysis.py b/dev/scripts/exglobal_offline_atmos_analysis.py similarity index 100% rename from scripts/exglobal_offline_atmos_analysis.py rename to dev/scripts/exglobal_offline_atmos_analysis.py diff --git a/scripts/exglobal_prep_emissions.py b/dev/scripts/exglobal_prep_emissions.py similarity index 100% rename from scripts/exglobal_prep_emissions.py rename to dev/scripts/exglobal_prep_emissions.py diff --git a/scripts/exglobal_prep_sfc.sh b/dev/scripts/exglobal_prep_sfc.sh similarity index 74% rename from scripts/exglobal_prep_sfc.sh rename to dev/scripts/exglobal_prep_sfc.sh index 961b09e5511..ad0fdfa92a1 100755 --- a/scripts/exglobal_prep_sfc.sh +++ b/dev/scripts/exglobal_prep_sfc.sh @@ -106,13 +106,13 @@ export err=$? #----------------------------------------------------------------------- if [[ ${err} -ne 0 ]]; then - if [[ -s "${BLENDED_ICE_FILE_PREV}" ]]; then - echo "Copy old ice blend file to current directory" - cpfs "${BLENDED_ICE_FILE_PREV}" "${COMOUT_OBS}/${BLENDED_ICE_FILE}" - export err=0 - else - err_exit "FATAL ERROR: CURRENT ICE FILE AND 6-HR OLD ICE FILE MISSING" - fi + if [[ -s "${BLENDED_ICE_FILE_PREV}" ]]; then + echo "Copy old ice blend file to current directory" + cpfs "${BLENDED_ICE_FILE_PREV}" "${COMOUT_OBS}/${BLENDED_ICE_FILE}" + export err=0 + else + err_exit "FATAL ERROR: CURRENT ICE FILE AND 6-HR OLD ICE FILE MISSING" + fi fi #----------------------------------------------------------------------- @@ -122,8 +122,8 @@ fi export SNOW2MDLEXEC="${EXECgfs}/emcsfc_snow2mdl" -LONB_CASE=$((4*${CASE:1})) -LATB_CASE=$((2*${CASE:1})) +LONB_CASE=$((4 * ${CASE:1})) +LATB_CASE=$((2 * ${CASE:1})) export MODEL_SLMASK_FILE=${SLMASK:-${FIXgfs}/am/global_slmask.t${CASE:1}.${LONB_CASE}.${LATB_CASE}.grb} export MODEL_LATITUDE_FILE=${MDL_LATS:-${FIXgfs}/am/global_latitudes.t${CASE:1}.${LONB_CASE}.${LATB_CASE}.grb} @@ -148,14 +148,14 @@ export err=$? #----------------------------------------------------------------------- if [[ ${err} -ne 0 ]]; then - if [[ -s "${MODEL_SNOW_FILE_PREV}" ]]; then - echo "COPY OLD ${CASE} SNOW FILE TO CURRENT DIRECTORY" - cpfs "${MODEL_SNOW_FILE_PREV}" "${COMOUT_OBS}/${MODEL_SNOW_FILE}" - export err=0 - else - err_exit "CURRENT AND 6-HR OLD ${CASE} SNOW MISSING, ABORT!" - fi # check of missing 6-hr snow file -fi # return code check + if [[ -s "${MODEL_SNOW_FILE_PREV}" ]]; then + echo "COPY OLD ${CASE} SNOW FILE TO CURRENT DIRECTORY" + cpfs "${MODEL_SNOW_FILE_PREV}" "${COMOUT_OBS}/${MODEL_SNOW_FILE}" + export err=0 + else + err_exit "CURRENT AND 6-HR OLD ${CASE} SNOW MISSING, ABORT!" + fi # check of missing 6-hr snow file +fi # return code check #----------------------------------------------------------------------- # Create enkf snow file if EUPD_CYC is RUN or BOTH @@ -163,34 +163,34 @@ fi # return code check if [[ "${EUPD_CYC}" = "${RUN}" ]] || [[ "${EUPD_CYC^^}" = "BOTH" ]]; then - LONB_CASE_ENS=$((4*${CASE_ENS:1})) - LATB_CASE_ENS=$((2*${CASE_ENS:1})) - - export MODEL_SLMASK_FILE=${SLMASK_ENKF:-${FIXgfs}/am/global_slmask.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} - export MODEL_LATITUDE_FILE=${MDL_LATS_ENKF:-${FIXgfs}/am/global_latitudes.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} - export MODEL_LONGITUDE_FILE=${MDL_LONS_ENKF:-${FIXgfs}/am/global_longitudes.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} - export GFS_LONSPERLAT_FILE=${LONSPERLAT_ENKF:-${FIXgfs}/am/global_lonsperlat.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.txt} - export MODEL_SNOW_FILE=${RUN}.t${cyc}z.snogrb_t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS} - export MODEL_SNOW_FILE_PREV=${COMINobsproc_PREV}/${RUN}.t${gcyc}z.snogrb_t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS} - - echo "Create enkf snow data." - "${USHgfs}/prep_sfc_snow.sh" - export err=$? - - #----------------------------------------------------------------------- - # Check for errors creating enkf snow. Use 6-hour old data - # as backup. If old data not available, abort. - #----------------------------------------------------------------------- - - if [[ ${err} -ne 0 ]]; then - if [[ -s "${MODEL_SNOW_FILE_PREV}" ]]; then - echo "COPY OLD ENKF SNOW FILE TO CURRENT DIRECTORY" - cpfs "${MODEL_SNOW_FILE_PREV}" "${COMOUT_OBS}/${MODEL_SNOW_FILE}" - export err=0 - else - err_exit "CURRENT AND 6-HR OLD ENKF SNOW MISSING" - fi # check of missing 6-hr snow file - fi # return code check + LONB_CASE_ENS=$((4 * ${CASE_ENS:1})) + LATB_CASE_ENS=$((2 * ${CASE_ENS:1})) + + export MODEL_SLMASK_FILE=${SLMASK_ENKF:-${FIXgfs}/am/global_slmask.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} + export MODEL_LATITUDE_FILE=${MDL_LATS_ENKF:-${FIXgfs}/am/global_latitudes.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} + export MODEL_LONGITUDE_FILE=${MDL_LONS_ENKF:-${FIXgfs}/am/global_longitudes.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.grb} + export GFS_LONSPERLAT_FILE=${LONSPERLAT_ENKF:-${FIXgfs}/am/global_lonsperlat.t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS}.txt} + export MODEL_SNOW_FILE=${RUN}.t${cyc}z.snogrb_t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS} + export MODEL_SNOW_FILE_PREV=${COMINobsproc_PREV}/${RUN}.t${gcyc}z.snogrb_t${CASE_ENS:1}.${LONB_CASE_ENS}.${LATB_CASE_ENS} + + echo "Create enkf snow data." + "${USHgfs}/prep_sfc_snow.sh" + export err=$? + + #----------------------------------------------------------------------- + # Check for errors creating enkf snow. Use 6-hour old data + # as backup. If old data not available, abort. + #----------------------------------------------------------------------- + + if [[ ${err} -ne 0 ]]; then + if [[ -s "${MODEL_SNOW_FILE_PREV}" ]]; then + echo "COPY OLD ENKF SNOW FILE TO CURRENT DIRECTORY" + cpfs "${MODEL_SNOW_FILE_PREV}" "${COMOUT_OBS}/${MODEL_SNOW_FILE}" + export err=0 + else + err_exit "CURRENT AND 6-HR OLD ENKF SNOW MISSING" + fi # check of missing 6-hr snow file + fi # return code check fi # If ENKF runs for RUN diff --git a/scripts/exglobal_snow_analysis.py b/dev/scripts/exglobal_snow_analysis.py similarity index 100% rename from scripts/exglobal_snow_analysis.py rename to dev/scripts/exglobal_snow_analysis.py diff --git a/scripts/exglobal_snowens_analysis.py b/dev/scripts/exglobal_snowens_analysis.py similarity index 100% rename from scripts/exglobal_snowens_analysis.py rename to dev/scripts/exglobal_snowens_analysis.py diff --git a/dev/scripts/exglobal_stage_ic.py b/dev/scripts/exglobal_stage_ic.py new file mode 100755 index 00000000000..9504faebed2 --- /dev/null +++ b/dev/scripts/exglobal_stage_ic.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +import os + +from pygfs.task.stage_ic import Stage +from wxflow import Logger, cast_strdict_as_dtypedict, logit + +# Initialize root logger +logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) + + +@logit(logger) +def main(): + + config = cast_strdict_as_dtypedict(os.environ) + # Set a default value for ATMINC_GRID if it is not in the environment + # This MUST be done *before* config is passed to the Stage constructor. + config.setdefault('ATMINC_GRID', '') + + # Instantiate the Stage object + stage = Stage(config) + + # Create staging dictionary with all necessary variables + stage_dict = stage.create_stage_dict() + + # Loop through members and stage ICs for each + for member in stage_dict.member_list: + logger.info(f"Staging initial conditions for member: {member}") + + # Get member-specific COM paths + member_com_paths = stage.get_member_com_paths(stage_dict, member) + + # Create member-specific staging dict to avoid modifying base stage_dict + stage_mem_dict = stage_dict.deepcopy() + stage_mem_dict.update(member_com_paths) + stage_mem_dict.update({'member': member}) + + # Execute staging + stage.execute_stage(stage_mem_dict) + + +if __name__ == '__main__': + main() diff --git a/dev/ush/fetch_gdas_for_gcafs.sh b/dev/ush/fetch_gdas_for_gcafs.sh new file mode 100755 index 00000000000..b8e1513493f --- /dev/null +++ b/dev/ush/fetch_gdas_for_gcafs.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# This script fetches GDAS data for GCAFS from HPSS +# and places it in a new tar file. +set -e +set -u + +# Get arguments from command line +if [[ "${#}" -ne 2 ]]; then + echo "Usage: ${0} " + exit 1 +fi +YYYYMMDDHH=${1} +OUTPUT_DIR=${2} +# Create output directory if it doesn't exist +mkdir -p "${OUTPUT_DIR}" +mkdir -p "${OUTPUT_DIR}/tmp" + +# determine GDAS version based on date +if [[ "${YYYYMMDDHH}" -ge "2022112900" ]]; then + gdas_version="v16.3" +elif [[ "${YYYYMMDDHH}" -ge "2022062700" ]]; then + gdas_version="v16.2" +else + gdas_version="prod" +fi + +# break date and time into components +cycle_Y=${YYYYMMDDHH:0:4} +cycle_M=${YYYYMMDDHH:4:2} +cycle_D=${YYYYMMDDHH:6:2} +cyc=${YYYYMMDDHH:8:2} +# cycle_YM is YYYYMM +cycle_YM="${cycle_Y}${cycle_M}" +# PDY is YYYYMMDD +PDY="${cycle_Y}${cycle_M}${cycle_D}" + +# HPSS path for the two tar files +hpss_path_root="/NCEPPROD/hpssprod/runhistory/rh${cycle_Y}/${cycle_YM}/${PDY}" +hpss_file_nc="com_gfs_${gdas_version}_gdas.${PDY}_${cyc}.gdas_nc.tar" +hpss_file_restart="com_gfs_${gdas_version}_gdas.${PDY}_${cyc}.gdas_restart.tar" + +# get the names of the files to extract +atmanl="./gdas.${PDY}/${cyc}/atmos/gdas.t${cyc}z.atmanl.nc" +dtfanl="./gdas.${PDY}/${cyc}/atmos/gdas.t${cyc}z.dtfanl.nc" + +# Fetch the tar files from HPSS +cd "${OUTPUT_DIR}/tmp" + +htar -xvf "${hpss_path_root}/${hpss_file_nc}" "${atmanl}" +htar -xvf "${hpss_path_root}/${hpss_file_restart}" "${dtfanl}" + +# create the output tar files +echo "creating output tar files" +tar cvf "${hpss_file_nc}" "${atmanl}" +tar cvf "${hpss_file_restart}" "${dtfanl}" + +# Move the tar files to the output directory +echo "moving tar files to ${OUTPUT_DIR}" +mv "${hpss_file_nc}" "${OUTPUT_DIR}/" +mv "${hpss_file_restart}" "${OUTPUT_DIR}/" + +# Clean up temporary directory +rm -rf "${OUTPUT_DIR}/tmp" +echo "GDAS data for ${YYYYMMDDHH} has been successfully fetched and stored in ${OUTPUT_DIR}." +# End of script +exit 0 diff --git a/dev/ush/get_warm_s2sw_restart_tarballs.sh b/dev/ush/get_warm_s2sw_restart_tarballs.sh index 6adba89a21c..44a968b08f3 100755 --- a/dev/ush/get_warm_s2sw_restart_tarballs.sh +++ b/dev/ush/get_warm_s2sw_restart_tarballs.sh @@ -33,9 +33,9 @@ fi cd "${untar_dir}" -ptargets=( "enkfgdas_restartb_grp1.tar" "enkfgdas_restartb_grp2.tar" "enkfgdas_restartb_grp3.tar" "enkfgdas_restartb_grp4.tar" "enkfgdas_restartb_grp5.tar" "enkfgdas_restartb_grp6.tar" "enkfgdas_restartb_grp7.tar" "enkfgdas_restartb_grp8.tar" "gdas_restartb.tar" "gdasocean_restart.tar" "gdaswave_restart.tar" ) +ptargets=("enkfgdas_restartb_grp1.tar" "enkfgdas_restartb_grp2.tar" "enkfgdas_restartb_grp3.tar" "enkfgdas_restartb_grp4.tar" "enkfgdas_restartb_grp5.tar" "enkfgdas_restartb_grp6.tar" "enkfgdas_restartb_grp7.tar" "enkfgdas_restartb_grp8.tar" "gdas_restartb.tar" "gdasocean_restart.tar" "gdaswave_restart.tar") -targets=( "enkfgdas_restarta_grp1.tar" "enkfgdas_restarta_grp2.tar" "enkfgdas_restarta_grp3.tar" "enkfgdas_restarta_grp4.tar" "enkfgdas_restarta_grp5.tar" "enkfgdas_restarta_grp6.tar" "enkfgdas_restarta_grp7.tar" "enkfgdas_restarta_grp8.tar" "gdas_restarta.tar" "gdasocean_analysis.tar") +targets=("enkfgdas_restarta_grp1.tar" "enkfgdas_restarta_grp2.tar" "enkfgdas_restarta_grp3.tar" "enkfgdas_restarta_grp4.tar" "enkfgdas_restarta_grp5.tar" "enkfgdas_restarta_grp6.tar" "enkfgdas_restarta_grp7.tar" "enkfgdas_restarta_grp8.tar" "gdas_restarta.tar" "gdasocean_analysis.tar") # This is all specific to Gaea C6 clusters="es" @@ -48,7 +48,7 @@ tasks=1 # Construct a wrapper script in a loop to submit to the sbatch system for tarball in "${targets[@]}"; do - sbatch << EOF + sbatch << EOF #!/bin/bash #SBATCH --job-name=get_retro_${tarball} #SBATCH --output=get_retro_${tarball}.out @@ -81,7 +81,7 @@ done # Now do the same for the previous cycle tarballs for tarball in "${ptargets[@]}"; do - sbatch << EOF + sbatch << EOF #!/bin/bash #SBATCH --job-name=get_retro_${tarball} #SBATCH --output=get_retro_${tarball}.out diff --git a/dev/ush/gw_setup.sh b/dev/ush/gw_setup.sh index 5b70b9b4fce..04d9433f819 100755 --- a/dev/ush/gw_setup.sh +++ b/dev/ush/gw_setup.sh @@ -11,10 +11,10 @@ # Determine if HOMEgfs is already set unset_homegfs=NO if [[ -z "${HOMEgfs+x}" ]]; then - script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )" - HOMEgfs=$(cd "${script_dir}" && git rev-parse --show-toplevel) - export HOMEgfs - unset_homegfs=YES + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)" + HOMEgfs=$(cd "${script_dir}" && git rev-parse --show-toplevel) + export HOMEgfs + unset_homegfs=YES fi source "${HOMEgfs}/ush/detect_machine.sh" source "${HOMEgfs}/ush/module-setup.sh" @@ -23,18 +23,16 @@ module use "${HOMEgfs}/modulefiles" module load "gw_setup.${MACHINE_ID}" err=$? if [[ "${err}" -ne 0 ]]; then - echo "FATAL ERROR: Failed to load module_gwsetup.${MACHINE_ID}" - exit 1 + echo "FATAL ERROR: Failed to load module_gwsetup.${MACHINE_ID}" + exit 1 fi # Set up the PYTHONPATH to include wxflow from HOMEgfs if [[ -d "${HOMEgfs}/sorc/wxflow/src" ]]; then - PYTHONPATH="${HOMEgfs}/sorc/wxflow/src${PYTHONPATH:+:${PYTHONPATH}}" - export PYTHONPATH + PYTHONPATH="${HOMEgfs}/sorc/wxflow/src${PYTHONPATH:+:${PYTHONPATH}}" + export PYTHONPATH fi - if [[ ${unset_homegfs} == "YES" ]]; then - unset HOMEgfs + unset HOMEgfs fi - diff --git a/dev/ush/load_modules.sh b/dev/ush/load_modules.sh index d049bcf92ce..263549f9f6c 100755 --- a/dev/ush/load_modules.sh +++ b/dev/ush/load_modules.sh @@ -8,14 +8,14 @@ ############################################################### if [[ "$-" == *x* ]]; then - set_x=YES + set_x=YES else - set_x=NO + set_x=NO fi if [[ "${DEBUG_WORKFLOW:-NO}" == "NO" ]]; then - echo "Loading modules quietly..." - set +x + echo "Loading modules quietly..." + set +x fi # Parse module type argument @@ -24,11 +24,11 @@ MODULE_TYPE="${1:-run}" # For backwards compatibility, handle ufsda options UFSDA_MODS="GDAS" if [[ "${MODULE_TYPE}" == "--eva" ]]; then - MODULE_TYPE="ufsda" - UFSDA_MODS="EVA" + MODULE_TYPE="ufsda" + UFSDA_MODS="EVA" elif [[ "${MODULE_TYPE}" == "--gdas" ]]; then - MODULE_TYPE="ufsda" - UFSDA_MODS="GDAS" + MODULE_TYPE="ufsda" + UFSDA_MODS="GDAS" fi # Setup runtime environment by loading modules @@ -37,25 +37,25 @@ ulimit_s=$(ulimit -S -s) # Test if HOMEgfs is defined. If not, then try to determine it with git rev-parse _unset_homegfs="NO" if [[ -z ${HOMEgfs+x} ]]; then - echo "INFO: HOMEgfs is not defined. Attempting to find the global-workflow root directory" - # HOMEgfs will be removed from the environment at the end of this script - _unset_homegfs="YES" - - script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) - HOMEgfs=$(cd "${script_dir}" && git rev-parse --show-toplevel) - export HOMEgfs - err=$? - if [[ ${err} -ne 0 ]]; then - is_git_dir=$(cd -- "${script_dir}" &> /dev/null && git rev-parse --is-inside-work-tree) - git_stat=$? - if [[ ${git_stat} -ne 0 || ${is_git_dir} != "true" ]]; then - echo "FATAL ERROR: unable to determine the root because it is not a git repository." - else - echo "FATAL ERROR: unable to determine the root because git rev-parse --show-toplevel failed for an unknown reason" + echo "INFO: HOMEgfs is not defined. Attempting to find the global-workflow root directory" + # HOMEgfs will be removed from the environment at the end of this script + _unset_homegfs="YES" + + script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) + HOMEgfs=$(cd "${script_dir}" && git rev-parse --show-toplevel) + export HOMEgfs + err=$? + if [[ ${err} -ne 0 ]]; then + is_git_dir=$(cd -- "${script_dir}" &> /dev/null && git rev-parse --is-inside-work-tree) + git_stat=$? + if [[ ${git_stat} -ne 0 || ${is_git_dir} != "true" ]]; then + echo "FATAL ERROR: unable to determine the root because it is not a git repository." + else + echo "FATAL ERROR: unable to determine the root because git rev-parse --show-toplevel failed for an unknown reason" + fi + echo "FATAL ERROR: Unable to load modules. Exiting" + exit 1 fi - echo "FATAL ERROR: Unable to load modules. Exiting" - exit 1 - fi fi # Find module command and purge: @@ -64,162 +64,162 @@ source "${HOMEgfs}/ush/module-setup.sh" # Handle different module types case "${MODULE_TYPE}" in - "ufswm") - # UFS Weather Model modules - special handling - module use "${HOMEgfs}/sorc/ufs_model.fd/modulefiles" - module load "ufs_${MACHINE_ID}.intel" - export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Failed to load ufs_${MACHINE_ID}.intel" - exit 1 - fi - module load prod_util - if [[ "${MACHINE_ID}" = "wcoss2" ]]; then - module load cray-pals - module load cfp - module load libjpeg - module load craype-network-ucx - module load cray-mpich-ucx - module load python/3.8.6 - module load wgrib2 - else - export UTILROOT=${prod_util_ROOT} - source "${HOMEgfs}/versions/run.ver" - module load "wgrib2/${wgrib2_ver}" - fi - export WGRIB2=wgrib2 - - module list - unset MACHINE_ID - ;; - - "ufsda") - # UFSDA modules - special handling - module use "${HOMEgfs}/sorc/gdas.cd/modulefiles" - - case "${MACHINE_ID}" in - ("hera" | "orion" | "hercules" | "wcoss2" | "gaeac5" | "gaeac6" | "ursa" | "noaacloud") - #TODO: Remove LMOD_TMOD_FIND_FIRST line when spack-stack on WCOSS2 - if [[ "${MACHINE_ID}" == "wcoss2" ]]; then - export LMOD_TMOD_FIND_FIRST=yes - # TODO: Add path to GDASApp libraries and cray-mpich as temporary patches - export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${HOMEgfs}/sorc/gdas.cd/build/lib" - # TODO: Remove LD_LIBRARY_PATH line as soon as permanent solution is available - export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/cray/pe/mpich/8.1.29/ofi/intel/2022.1/lib" - fi - module load "${UFSDA_MODS}/${MACHINE_ID}" + "ufswm") + # UFS Weather Model modules - special handling + module use "${HOMEgfs}/sorc/ufs_model.fd/modulefiles" + module load "ufs_${MACHINE_ID}.intel" export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Failed to load ${UFSDA_MODS}/${MACHINE_ID}" - exit 1 + echo "FATAL ERROR: Failed to load ufs_${MACHINE_ID}.intel" + exit 1 fi - ncdump=$(command -v ncdump) - NETCDF=$(echo "${ncdump}" | cut -d " " -f 3) - export NETCDF - ;; - ("acorn") - echo WARNING: UFSDA NOT SUPPORTED ON 'acorn' - ;; - *) - echo "WARNING: UNKNOWN PLATFORM" + module load prod_util + if [[ "${MACHINE_ID}" == "wcoss2" ]]; then + module load cray-pals + module load cfp + module load libjpeg + module load craype-network-ucx + module load cray-mpich-ucx + module load python/3.8.6 + module load wgrib2 + else + export UTILROOT=${prod_util_ROOT} + source "${HOMEgfs}/versions/run.ver" + module load "wgrib2/${wgrib2_ver}" + fi + export WGRIB2=wgrib2 + + module list + unset MACHINE_ID ;; - esac - module list + "ufsda") + # UFSDA modules - special handling + module use "${HOMEgfs}/sorc/gdas.cd/modulefiles" + + case "${MACHINE_ID}" in + "hera" | "orion" | "hercules" | "wcoss2" | "gaeac5" | "gaeac6" | "ursa" | "noaacloud") + #TODO: Remove LMOD_TMOD_FIND_FIRST line when spack-stack on WCOSS2 + if [[ "${MACHINE_ID}" == "wcoss2" ]]; then + export LMOD_TMOD_FIND_FIRST=yes + # TODO: Add path to GDASApp libraries and cray-mpich as temporary patches + export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${HOMEgfs}/sorc/gdas.cd/build/lib" + # TODO: Remove LD_LIBRARY_PATH line as soon as permanent solution is available + export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/cray/pe/mpich/8.1.29/ofi/intel/2022.1/lib" + fi + module load "${UFSDA_MODS}/${MACHINE_ID}" + export err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: Failed to load ${UFSDA_MODS}/${MACHINE_ID}" + exit 1 + fi + ncdump=$(command -v ncdump) + NETCDF=$(echo "${ncdump}" | cut -d " " -f 3) + export NETCDF + ;; + "acorn") + echo WARNING: UFSDA NOT SUPPORTED ON 'acorn' + ;; + *) + echo "WARNING: UNKNOWN PLATFORM" + ;; + esac + + module list + + ftype=$(type -t set_trace || echo "") + if [[ "${ftype}" == "function" ]]; then + set_trace + elif [[ "${set_x}" == "YES" ]]; then + set -x + fi - ftype=$(type -t set_trace || echo "") - if [[ "${ftype}" == "function" ]]; then - set_trace - elif [[ "${set_x}" == "YES" ]]; then - set -x - fi + pip list - pip list + # Detect the Python major.minor version + _regex="[0-9]+\.[0-9]+" + # shellcheck disable=SC2312 + if [[ $(python --version) =~ ${_regex} ]]; then + export PYTHON_VERSION="${BASH_REMATCH[0]}" + else + echo "FATAL ERROR: Could not detect the python version" + exit 1 + fi - # Detect the Python major.minor version - _regex="[0-9]+\.[0-9]+" - # shellcheck disable=SC2312 - if [[ $(python --version) =~ ${_regex} ]]; then - export PYTHON_VERSION="${BASH_REMATCH[0]}" - else - echo "FATAL ERROR: Could not detect the python version" - exit 1 - fi + ############################################################### + # setup python path for ioda utilities + # TODO: a better solution should be created for setting paths to package python scripts + # shellcheck disable=SC2311 + pyiodaPATH="${HOMEgfs}/sorc/gdas.cd/build/lib/python${PYTHON_VERSION}/" + pybufrPATH="${HOMEgfs}/sorc/gdas.cd/build/lib/python${PYTHON_VERSION}/site-packages/" + PYTHONPATH="${pyiodaPATH}:${pybufrPATH}${PYTHONPATH:+:${PYTHONPATH}}" + export PYTHONPATH + ;; - ############################################################### - # setup python path for ioda utilities - # TODO: a better solution should be created for setting paths to package python scripts - # shellcheck disable=SC2311 - pyiodaPATH="${HOMEgfs}/sorc/gdas.cd/build/lib/python${PYTHON_VERSION}/" - pybufrPATH="${HOMEgfs}/sorc/gdas.cd/build/lib/python${PYTHON_VERSION}/site-packages/" - PYTHONPATH="${pyiodaPATH}:${pybufrPATH}${PYTHONPATH:+:${PYTHONPATH}}" - export PYTHONPATH - ;; - - "run" | "gsi" | "verif" | "setup" | "upp") - - # Test that the version file exists - if [[ ! -f "${HOMEgfs}/versions/run.ver" ]]; then - echo "FATAL ERROR: ${HOMEgfs}/versions/run.ver does not exist!" - echo "HINT: Run link_workflow.sh first." - exit 1 - fi + "run" | "gsi" | "verif" | "setup" | "upp") - # Load our modules: - module use "${HOMEgfs}/modulefiles" - - # Determine target module based on type and machine - target_module="gw_${MODULE_TYPE}.${MACHINE_ID}" - - # Check if the target module file exists, fall back to gw_run if not - if ! module is-avail "${target_module}" 2>/dev/null; then - if [[ "${MODULE_TYPE}" != "run" ]]; then - echo "INFO: ${target_module} module not available, falling back to gw_run.${MACHINE_ID}" - mod_type="run" - fi - target_module="gw_run.${MACHINE_ID}" - else - mod_type="${MODULE_TYPE}" - fi + # Test that the version file exists + if [[ ! -f "${HOMEgfs}/versions/run.ver" ]]; then + echo "FATAL ERROR: ${HOMEgfs}/versions/run.ver does not exist!" + echo "HINT: Run link_workflow.sh first." + exit 1 + fi - # Source versions file (except for upp) - if [[ "${mod_type}" != "upp" ]]; then - source "${HOMEgfs}/versions/run.ver" - fi + # Load our modules: + module use "${HOMEgfs}/modulefiles" + + # Determine target module based on type and machine + target_module="gw_${MODULE_TYPE}.${MACHINE_ID}" + + # Check if the target module file exists, fall back to gw_run if not + if ! module is-avail "${target_module}" 2> /dev/null; then + if [[ "${MODULE_TYPE}" != "run" ]]; then + echo "INFO: ${target_module} module not available, falling back to gw_run.${MACHINE_ID}" + mod_type="run" + fi + target_module="gw_run.${MACHINE_ID}" + else + mod_type="${MODULE_TYPE}" + fi - if [[ -n "${target_module}" ]]; then - module load "${target_module}" - export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Failed to load ${target_module}" - exit 1 - fi - else - echo "FATAL ERROR: Could not determine target module for MODULE_TYPE='${MODULE_TYPE}' and MACHINE_ID='${MACHINE_ID}'" - exit 1 - fi + # Source versions file (except for upp) + if [[ "${mod_type}" != "upp" ]]; then + source "${HOMEgfs}/versions/run.ver" + fi - module list + if [[ -n "${target_module}" ]]; then + module load "${target_module}" + export err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: Failed to load ${target_module}" + exit 1 + fi + else + echo "FATAL ERROR: Could not determine target module for MODULE_TYPE='${MODULE_TYPE}' and MACHINE_ID='${MACHINE_ID}'" + exit 1 + fi - # If this function exists in the environment, run it; else set -x if it was set on entering this script - ftype=$(type -t set_trace || echo "") - if [[ "${ftype}" == "function" ]]; then - set_trace - elif [[ "${set_x}" == "YES" ]]; then - set -x - fi - ;; + module list + + # If this function exists in the environment, run it; else set -x if it was set on entering this script + ftype=$(type -t set_trace || echo "") + if [[ "${ftype}" == "function" ]]; then + set_trace + elif [[ "${set_x}" == "YES" ]]; then + set -x + fi + ;; + + *) + echo "FATAL ERROR: Unknown module type '${MODULE_TYPE}'" + echo "Valid types: run, gsi, verif, ufsda, ufswm, setup" + ;; - *) - echo "FATAL ERROR: Unknown module type '${MODULE_TYPE}'" - echo "Valid types: run, gsi, verif, ufsda, ufswm, setup" - exit 1 - ;; esac # Set up the PYTHONPATH to include wxflow from HOMEgfs if [[ -d "${HOMEgfs}/sorc/wxflow/src" ]]; then - PYTHONPATH="${HOMEgfs}/sorc/wxflow/src${PYTHONPATH:+:${PYTHONPATH}}" + PYTHONPATH="${HOMEgfs}/sorc/wxflow/src${PYTHONPATH:+:${PYTHONPATH}}" fi # Add HOMEgfs/ush/python to PYTHONPATH @@ -232,5 +232,5 @@ unset ulimit_s # Unset HOMEgfs if it was not set at the beginning of this script if [[ ${_unset_homegfs} == "YES" ]]; then - unset HOMEgfs + unset HOMEgfs fi diff --git a/dev/ush/make_ee2_links.sh b/dev/ush/make_ee2_links.sh index 674e83a5013..9704dc553bd 100755 --- a/dev/ush/make_ee2_links.sh +++ b/dev/ush/make_ee2_links.sh @@ -14,7 +14,6 @@ set -eux # WARNING: This script does not create all links needed for EE2 compatibility. It only creates links needed to # restart an existing experiment. - if [[ $# -ne 1 ]]; then echo "Usage: $0 " exit 1 @@ -43,18 +42,18 @@ link_file() { return 0 } -gdas_list=($(ls -d gdas.* || true )) -gfs_list=($(ls -d gfs.* || true )) -gcdas_list=($(ls -d gcdas.* || true )) -gcafs_list=($(ls -d gcafs.* || true )) -enkfgdas_list=($(ls -d enkfgdas.* || true )) -enkfgfs_list=($(ls -d enkfgfs.* || true )) -enkfgcdas_list=($(ls -d enkfgcdas.* || true )) +gdas_list=($(ls -d gdas.* || true)) +gfs_list=($(ls -d gfs.* || true)) +gcdas_list=($(ls -d gcdas.* || true)) +gcafs_list=($(ls -d gcafs.* || true)) +enkfgdas_list=($(ls -d enkfgdas.* || true)) +enkfgfs_list=($(ls -d enkfgfs.* || true)) +enkfgcdas_list=($(ls -d enkfgcdas.* || true)) # If the length of all of the arrays is zero, exit with a message if [[ ${#gdas_list[@]} -eq 0 && ${#gfs_list[@]} -eq 0 && ${#gcdas_list[@]} -eq 0 && - ${#gcafs_list[@]} -eq 0 && ${#enkfgdas_list[@]} -eq 0 && - ${#enkfgfs_list[@]} -eq 0 && ${#enkfgcdas_list[@]} -eq 0 ]]; then + ${#gcafs_list[@]} -eq 0 && ${#enkfgdas_list[@]} -eq 0 && + ${#enkfgfs_list[@]} -eq 0 && ${#enkfgcdas_list[@]} -eq 0 ]]; then echo "No gdas, gfs, gcdas, gcafs, enkfgdas, enkfgfs, or enkfgcdas directories found. Exiting." exit 0 fi @@ -70,10 +69,13 @@ for dir in "${gdas_list[@]}" "${gfs_list[@]}" "${gcdas_list[@]}" "${gcafs_list[@ gfs.*) system_prefix="gfs" ;; gcdas.*) system_prefix="gcdas" ;; gcafs.*) system_prefix="gcafs" ;; - *) echo "Unknown directory prefix: ${dir}"; exit 1 ;; + *) + echo "Unknown directory prefix: ${dir}" + exit 1 + ;; esac - cycle_list=($(ls -d -- ?? || true )) + cycle_list=($(ls -d -- ?? || true)) for cyc in "${cycle_list[@]}"; do if [[ -d "${cwd}/${dir}/${cyc}/analysis/atmos" ]]; then cd "${cwd}/${dir}/${cyc}/analysis/atmos" @@ -82,93 +84,93 @@ for dir in "${gdas_list[@]}" "${gfs_list[@]}" "${gcdas_list[@]}" "${gcafs_list[@ link_file "${system_prefix}.t${cyc}z.${abias_type}" "${system_prefix}.t${cyc}z.${abias_type}.txt" fi done - if [[ -f "${system_prefix}.t${cyc}z.radstat" ]]; then - link_file "${system_prefix}.t${cyc}z.radstat" "${system_prefix}.t${cyc}z.radstat.tar" - fi - if [[ -f "${system_prefix}.t${cyc}z.atmi003.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atmi003.nc" "${system_prefix}.t${cyc}z.increment.atm.i003.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atminc.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atminc.nc" "${system_prefix}.t${cyc}z.increment.atm.i006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atmi009.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atmi009.nc" "${system_prefix}.t${cyc}z.increment.atm.i009.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atma003.ensres.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atma003.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a003.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atmanl.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atmanl.nc" "${system_prefix}.t${cyc}z.analysis.atm.a006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atmanl.ensres.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atmanl.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.atma009.ensres.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.atma009.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a009.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.cnvstat" ]]; then - link_file "${system_prefix}.t${cyc}z.cnvstat" "${system_prefix}.t${cyc}z.cnvstat.tar" - fi - if [[ -f "${system_prefix}.t${cyc}z.dtfanl.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.dtfanl.nc" "${system_prefix}.t${cyc}z.analysis.dtf.a006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.gsistat" ]]; then - link_file "${system_prefix}.t${cyc}z.gsistat" "${system_prefix}.t${cyc}z.gsistat.txt" - fi - if [[ -f "${system_prefix}.t${cyc}z.oznstat" ]]; then - link_file "${system_prefix}.t${cyc}z.oznstat" "${system_prefix}.t${cyc}z.oznstat.tar" - fi - if [[ -f "${system_prefix}.t${cyc}z.loginc.txt" ]]; then - link_file "${system_prefix}.t${cyc}z.loginc.txt" "${system_prefix}.t${cyc}z.increment.done.txt" - fi - if [[ -f "${system_prefix}.t${cyc}z.loganl.txt" ]]; then - link_file "${system_prefix}.t${cyc}z.loganl.txt" "${system_prefix}.t${cyc}z.analysis.done.txt" - fi - if [[ -f "${system_prefix}.t${cyc}z.sfci003.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.sfci003.nc" "${system_prefix}.t${cyc}z.increment.sfc.i003.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.sfci006.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.sfci006.nc" "${system_prefix}.t${cyc}z.increment.sfc.i006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.sfci009.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.sfci009.nc" "${system_prefix}.t${cyc}z.increment.sfc.i009.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.sfcanl.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.sfcanl.nc" "${system_prefix}.t${cyc}z.analysis.sfc.a006.nc" - fi - if [[ -f "${system_prefix}.t${cyc}z.sfcinc.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.sfcinc.nc" "${system_prefix}.t${cyc}z.increment.sfc.i006.nc" - fi - if [[ -f "sfc_inc.tile1.nc" ]]; then - for tile in {1..6}; do - link_file "sfc_inc.tile${tile}.nc" "increment.sfc.tile${tile}.nc" - done - fi - if [[ -f "${system_prefix}.t${cyc}z.cubed_sphere_grid_atminc.tile1.nc" ]]; then - for tile in {1..6}; do - link_file "${system_prefix}.t${cyc}z.cubed_sphere_grid_atminc.tile${tile}.nc" "${system_prefix}.t${cyc}z.jedi_increment.atm.i006.tile${tile}.nc" - done - fi - fi - cd "${cwd}" - if [[ -d "${cwd}/${dir}/${cyc}/analysis/ocean" ]]; then - cd "${cwd}/${dir}/${cyc}/analysis/ocean" - if [[ -f "${system_prefix}.t${cyc}z.ocninc.nc" ]]; then - link_file "${system_prefix}.t${cyc}z.ocninc.nc" "${system_prefix}.t${cyc}z.mom6_increment.i006.nc" - fi - fi - cd "${cwd}" - if [[ -d "${cwd}/${dir}/${cyc}/analysis/ice" ]]; then - cd "${cwd}/${dir}/${cyc}/analysis/ice" - for ice_file in *.cice_model_anl.res.nc; do - if [[ -f "${ice_file}" ]]; then - # This gets the first two fields of the filename separated by dots - prefix=$(echo "${ice_file}" | cut -d. -f1-2) - link_file "${ice_file}" "${prefix}.analysis.cice_model.res.nc" - fi - done - fi - cd "${cwd}" + if [[ -f "${system_prefix}.t${cyc}z.radstat" ]]; then + link_file "${system_prefix}.t${cyc}z.radstat" "${system_prefix}.t${cyc}z.radstat.tar" + fi + if [[ -f "${system_prefix}.t${cyc}z.atmi003.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atmi003.nc" "${system_prefix}.t${cyc}z.increment.atm.i003.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atminc.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atminc.nc" "${system_prefix}.t${cyc}z.increment.atm.i006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atmi009.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atmi009.nc" "${system_prefix}.t${cyc}z.increment.atm.i009.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atma003.ensres.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atma003.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a003.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atmanl.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atmanl.nc" "${system_prefix}.t${cyc}z.analysis.atm.a006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atmanl.ensres.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atmanl.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.atma009.ensres.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.atma009.ensres.nc" "${system_prefix}.t${cyc}z.ensres_analysis.atm.a009.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.cnvstat" ]]; then + link_file "${system_prefix}.t${cyc}z.cnvstat" "${system_prefix}.t${cyc}z.cnvstat.tar" + fi + if [[ -f "${system_prefix}.t${cyc}z.dtfanl.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.dtfanl.nc" "${system_prefix}.t${cyc}z.analysis.dtf.a006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.gsistat" ]]; then + link_file "${system_prefix}.t${cyc}z.gsistat" "${system_prefix}.t${cyc}z.gsistat.txt" + fi + if [[ -f "${system_prefix}.t${cyc}z.oznstat" ]]; then + link_file "${system_prefix}.t${cyc}z.oznstat" "${system_prefix}.t${cyc}z.oznstat.tar" + fi + if [[ -f "${system_prefix}.t${cyc}z.loginc.txt" ]]; then + link_file "${system_prefix}.t${cyc}z.loginc.txt" "${system_prefix}.t${cyc}z.increment.done.txt" + fi + if [[ -f "${system_prefix}.t${cyc}z.loganl.txt" ]]; then + link_file "${system_prefix}.t${cyc}z.loganl.txt" "${system_prefix}.t${cyc}z.analysis.done.txt" + fi + if [[ -f "${system_prefix}.t${cyc}z.sfci003.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.sfci003.nc" "${system_prefix}.t${cyc}z.increment.sfc.i003.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.sfci006.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.sfci006.nc" "${system_prefix}.t${cyc}z.increment.sfc.i006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.sfci009.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.sfci009.nc" "${system_prefix}.t${cyc}z.increment.sfc.i009.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.sfcanl.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.sfcanl.nc" "${system_prefix}.t${cyc}z.analysis.sfc.a006.nc" + fi + if [[ -f "${system_prefix}.t${cyc}z.sfcinc.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.sfcinc.nc" "${system_prefix}.t${cyc}z.increment.sfc.i006.nc" + fi + if [[ -f "sfc_inc.tile1.nc" ]]; then + for tile in {1..6}; do + link_file "sfc_inc.tile${tile}.nc" "increment.sfc.tile${tile}.nc" + done + fi + if [[ -f "${system_prefix}.t${cyc}z.cubed_sphere_grid_atminc.tile1.nc" ]]; then + for tile in {1..6}; do + link_file "${system_prefix}.t${cyc}z.cubed_sphere_grid_atminc.tile${tile}.nc" "${system_prefix}.t${cyc}z.jedi_increment.atm.i006.tile${tile}.nc" + done + fi + fi + cd "${cwd}" + if [[ -d "${cwd}/${dir}/${cyc}/analysis/ocean" ]]; then + cd "${cwd}/${dir}/${cyc}/analysis/ocean" + if [[ -f "${system_prefix}.t${cyc}z.ocninc.nc" ]]; then + link_file "${system_prefix}.t${cyc}z.ocninc.nc" "${system_prefix}.t${cyc}z.mom6_increment.i006.nc" + fi + fi + cd "${cwd}" + if [[ -d "${cwd}/${dir}/${cyc}/analysis/ice" ]]; then + cd "${cwd}/${dir}/${cyc}/analysis/ice" + for ice_file in *.cice_model_anl.res.nc; do + if [[ -f "${ice_file}" ]]; then + # This gets the first two fields of the filename separated by dots + prefix=$(echo "${ice_file}" | cut -d. -f1-2) + link_file "${ice_file}" "${prefix}.analysis.cice_model.res.nc" + fi + done + fi + cd "${cwd}" if [[ -d "${cwd}/${dir}/${cyc}/analysis/snow" ]]; then cd "${cwd}/${dir}/${cyc}/analysis/snow" for snow_file in snowinc*.sfc_data.tile1.nc; do @@ -189,18 +191,21 @@ done for dir in "${enkfgdas_list[@]}" "${enkfgfs_list[@]}"; do cd "${dir}" - cycle_list=($(ls -d -- ?? || true )) + cycle_list=($(ls -d -- ?? || true)) # Determine the system prefix system_prefix="" case "${dir}" in enkfgdas.*) system_prefix="enkfgdas" ;; enkfgfs.*) system_prefix="enkfgfs" ;; enkfgcdas.*) system_prefix="enkfgcdas" ;; - *) echo "Unknown directory prefix: ${dir}"; exit 1 ;; + *) + echo "Unknown directory prefix: ${dir}" + exit 1 + ;; esac for cyc in "${cycle_list[@]}"; do cd "${cwd}/${dir}/${cyc}" - mem_list=($(ls -d mem* || true )) + mem_list=($(ls -d mem* || true)) for mem in "${mem_list[@]}"; do # atmos if [[ -d "${cwd}/${dir}/${cyc}/${mem}/analysis/atmos" ]]; then @@ -280,12 +285,12 @@ for dir in "${enkfgdas_list[@]}" "${enkfgfs_list[@]}"; do cd "${cwd}/${dir}/${cyc}/${mem}/analysis/snow" # The old snow analysis files start with YYYYMMDD.HHMMSS, which we want to keep for snow_file in ????????.??????.sfc_data.tile1.nc; do - if [[ -f "${snow_file}" ]]; then - prefix=$(echo "${snow_file}" | cut -d. -f1-2) - for tile in {1..6}; do - link_file "${prefix}.sfc_data.tile${tile}.nc" "${prefix}.snow_analysis.sfc_data.tile${tile}.nc" - done - fi + if [[ -f "${snow_file}" ]]; then + prefix=$(echo "${snow_file}" | cut -d. -f1-2) + for tile in {1..6}; do + link_file "${prefix}.sfc_data.tile${tile}.nc" "${prefix}.snow_analysis.sfc_data.tile${tile}.nc" + done + fi done fi cd "${cwd}" diff --git a/dev/workflow/applications/applications.py b/dev/workflow/applications/applications.py index e49d053c1e9..3d0ebc6e36c 100644 --- a/dev/workflow/applications/applications.py +++ b/dev/workflow/applications/applications.py @@ -198,7 +198,7 @@ def _get_run_options(self, conf: Configuration) -> Dict[str, Any]: run_options[run]['use_aero_anl'] = run_base.get('USE_AERO_ANL', False) run_options[run]['do_aero_fcst'] = run_base.get('DO_AERO_FCST', False) - if run_base.get('GEFSTYPE', "") == "near-real-time": + if run_base.get('GEFSTYPE', "") == "gefs-real-time": run_options[run]['do_gefs_real_time'] = True elif run_base.get('GEFSTYPE', "") == "gefs-offline": run_options[run]['do_gefs_real_time'] = False diff --git a/dev/workflow/applications/gcafs_cycled.py b/dev/workflow/applications/gcafs_cycled.py index e205fe1709f..7a96b0437aa 100644 --- a/dev/workflow/applications/gcafs_cycled.py +++ b/dev/workflow/applications/gcafs_cycled.py @@ -135,7 +135,7 @@ def _get_app_configs(self, run): if options['do_aero_anl']: configs += ['aeroanlgenb', 'aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] - configs += ['prepobsaero'] + configs += ['prep'] if options['do_anlstat']: configs += ['anlstat'] @@ -203,7 +203,7 @@ def get_task_names(self): if options['do_aero_anl']: task_names[run] += ['aeroanlgenb'] task_names[run] += ['aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] - task_names[run] += ['prepobsaero'] + task_names[run] += ['prep'] if options['do_anlstat']: task_names[run] += ['anlstat'] diff --git a/dev/workflow/applications/gfs_cycled.py b/dev/workflow/applications/gfs_cycled.py index 8a5114c1f82..0d51aed74b4 100644 --- a/dev/workflow/applications/gfs_cycled.py +++ b/dev/workflow/applications/gfs_cycled.py @@ -110,7 +110,10 @@ def _get_app_configs(self, run): configs += ['prep_sfc'] if options['do_jediatmvar']: - configs += ['prepatmiodaobs', 'atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc_fv3jedi'] + if options['do_jediatmens']: + configs += ['atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc_fv3jedi'] + else: + configs += ['atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc'] else: configs += ['anal', 'analdiag', 'analcalc'] @@ -192,8 +195,6 @@ def _get_app_configs(self, run): if options['do_aero_anl']: configs += ['aeroanlgenb', 'aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] - if options['do_prep_obs_aero']: - configs += ['prepobsaero'] if options['do_jedisnowda']: configs += ['snowanl'] @@ -250,7 +251,10 @@ def get_task_names(self): if options['do_prep_sfc']: task_names[run] += ['prep_sfc'] if options['do_jediatmvar']: - task_names[run] += ['prepatmiodaobs', 'atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc_fv3jedi'] + if options['do_jediatmens']: + task_names[run] += ['atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc_fv3jedi'] + else: + task_names[run] += ['atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'analcalc'] else: task_names[run] += ['anal', 'analcalc'] @@ -283,9 +287,6 @@ def get_task_names(self): if options['do_aero_anl']: task_names[run] += ['aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] - if options['do_prep_obs_aero']: - task_names[run] += ['prepobsaero'] - # Staging is gdas-specific if run == 'gdas': task_names[run] += ['stage_ic'] diff --git a/dev/workflow/applications/sfs.py b/dev/workflow/applications/sfs.py index d08e028fdcc..89c6f4e9788 100644 --- a/dev/workflow/applications/sfs.py +++ b/dev/workflow/applications/sfs.py @@ -93,6 +93,8 @@ def _get_app_configs(self, run): if options['do_archcom']: configs += ['arch_tars'] + if options['do_globusarch']: + configs += ['globus'] configs += ['arch_vrfy', 'cleanup'] @@ -164,7 +166,12 @@ def get_task_names(self): if options['do_extractvars']: tasks += ['extractvars'] - # TODO: Add archive + # TODO add archiving for SFS + # if options['do_archcom']: + # tasks += ['arch_tars'] + # if options['do_globusarch']: + # tasks += ['globus'] + tasks += ['cleanup'] return {f"{self.run}": tasks} diff --git a/dev/workflow/build_compute.py b/dev/workflow/build_compute.py index a1d29f679df..c4a6c985390 100755 --- a/dev/workflow/build_compute.py +++ b/dev/workflow/build_compute.py @@ -185,12 +185,6 @@ def main(*argv): user_yaml_dict = AttrDict(parse_yaml(user_inputs.yaml)) build_specs = get_build_specs(user_yaml_dict, host_specs) - # Temporarily prevent the GDASApp from building on the compute node - # TODO restore the GDASApp when it can be built on compute nodes again and/or 'compute' builds are enabled on head nodes. - # See issue 3933 - if "gdas" in build_specs.build: - build_specs.build.pop("gdas") - systems = user_inputs.systems.split() if "all" not in user_inputs.systems else ["all"] # Determine systems to build diff --git a/dev/workflow/hosts/awspw.yaml b/dev/workflow/hosts/awspw.yaml index 39feb618b12..1f2aca56e40 100644 --- a/dev/workflow/hosts/awspw.yaml +++ b/dev/workflow/hosts/awspw.yaml @@ -1,15 +1,16 @@ # Paths -DMPDIR: '/bucket/dump' +IODADIR: '/lustre/dump_ur' +DMPDIR: '/lustre/dump_ur' BASE_GIT: '/contrib/git' -BASE_DATA: '/bucket/global-workflow-shared-data' -BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' +BASE_DATA: '/lustre/data' +BASE_IC: '/lustre/data/ICSDIR' AERO_INPUTS_DIR: '/contrib/global-workflow-shared-data/data/GEFS_ExtData/20250310' PACKAGEROOT: '' #TODO: This does not yet exist. HOMEDIR: '/contrib/${USER}' STMP: '/lustre/${USER}/stmp/' PTMP: '/lustre/${USER}/ptmp/' NOSCRUB: '${HOMEDIR}' -COMINsyn: '/bucket/syndat' +COMINsyn: '/lustre/syndat' # BQS properties SCHEDULER: slurm QUEUE: batch diff --git a/dev/workflow/hosts/azurepw.yaml b/dev/workflow/hosts/azurepw.yaml index badc062f880..6b446eab034 100644 --- a/dev/workflow/hosts/azurepw.yaml +++ b/dev/workflow/hosts/azurepw.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '' # TODO: This does not yet exist. +IODADIR: '' #TODO: This does not yet exist. BASE_GIT: '' #TODO: This does not yet exist. BASE_DATA: '/bucket/global-workflow-shared-data' BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' diff --git a/dev/workflow/hosts/container.yaml b/dev/workflow/hosts/container.yaml index cc3d1540356..4868d02d936 100644 --- a/dev/workflow/hosts/container.yaml +++ b/dev/workflow/hosts/container.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/home/${USER}' +IODADIR: '/home/${USER}' BASE_GIT: '' PACKAGEROOT: '' HOMEDIR: '/home/${USER}' diff --git a/dev/workflow/hosts/gaeac5.yaml b/dev/workflow/hosts/gaeac5.yaml index be872943e72..785f0c61149 100644 --- a/dev/workflow/hosts/gaeac5.yaml +++ b/dev/workflow/hosts/gaeac5.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/dump' +IODADIR: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/dump' BASE_GIT: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/git' BASE_DATA: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data' BASE_IC: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/ICSDIR' diff --git a/dev/workflow/hosts/gaeac6.yaml b/dev/workflow/hosts/gaeac6.yaml index 4a0055208d5..20486fbf38b 100644 --- a/dev/workflow/hosts/gaeac6.yaml +++ b/dev/workflow/hosts/gaeac6.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/dump' +IODADIR: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/dump_ioda' BASE_GIT: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/git' BASE_DATA: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data' BASE_IC: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data/ICSDIR' diff --git a/dev/workflow/hosts/googlepw.yaml b/dev/workflow/hosts/googlepw.yaml index 4a0610d7f7d..74c73d2542a 100644 --- a/dev/workflow/hosts/googlepw.yaml +++ b/dev/workflow/hosts/googlepw.yaml @@ -1,6 +1,7 @@ # Paths DMPDIR: '' # TODO: This does not yet exist. +IODADIR: '' #TODO: This does not yet exist. BASE_GIT: '' #TODO: This does not yet exist. BASE_DATA: '/bucket/global-workflow-shared-data' BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' diff --git a/dev/workflow/hosts/hera.yaml b/dev/workflow/hosts/hera.yaml index 60527625805..1bf18ce67d5 100644 --- a/dev/workflow/hosts/hera.yaml +++ b/dev/workflow/hosts/hera.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/scratch3/NCEPDEV/global/role.glopara/dump' +IODADIR: '/scratch3/NCEPDEV/global/role.glopara/dump_ioda' BASE_GIT: '/scratch3/NCEPDEV/global/role.glopara/git_hera' BASE_DATA: '/scratch3/NCEPDEV/global/role.glopara/data' BASE_IC: '/scratch3/NCEPDEV/global/role.glopara/data/ICSDIR' diff --git a/dev/workflow/hosts/hercules.yaml b/dev/workflow/hosts/hercules.yaml index ce971749e4d..4436589b880 100644 --- a/dev/workflow/hosts/hercules.yaml +++ b/dev/workflow/hosts/hercules.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/work/noaa/rstprod/dump' +IODADIR: '/work/noaa/rstprod/dump_ioda' BASE_GIT: '/work2/noaa/global/role-global/git' BASE_DATA: '/work2/noaa/global/role-global/data' BASE_IC: '/work2/noaa/global/role-global/data/ICSDIR' diff --git a/dev/workflow/hosts/orion.yaml b/dev/workflow/hosts/orion.yaml index caadd3d41e2..ee012819f31 100644 --- a/dev/workflow/hosts/orion.yaml +++ b/dev/workflow/hosts/orion.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/work/noaa/rstprod/dump' +IODADIR: '/work/noaa/rstprod/dump_ioda' BASE_GIT: '/work2/noaa/global/role-global/git' BASE_DATA: '/work2/noaa/global/role-global/data' BASE_IC: '/work2/noaa/global/role-global/data/ICSDIR' diff --git a/dev/workflow/hosts/ursa.yaml b/dev/workflow/hosts/ursa.yaml index 51d42a8bb22..05c2d4bb8ee 100644 --- a/dev/workflow/hosts/ursa.yaml +++ b/dev/workflow/hosts/ursa.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/scratch3/NCEPDEV/global/role.glopara/dump' +IODADIR: '/scratch3/NCEPDEV/global/role.glopara/dump_ioda' BASE_GIT: '/scratch3/NCEPDEV/global/role.glopara/git' BASE_DATA: '/scratch3/NCEPDEV/global/role.glopara/data' BASE_IC: '/scratch3/NCEPDEV/global/role.glopara/data/ICSDIR' diff --git a/dev/workflow/hosts/wcoss2.yaml b/dev/workflow/hosts/wcoss2.yaml index 1b534f7d13e..9f82d8e9e81 100644 --- a/dev/workflow/hosts/wcoss2.yaml +++ b/dev/workflow/hosts/wcoss2.yaml @@ -1,5 +1,6 @@ # Paths DMPDIR: '/lfs/h2/emc/dump/noscrub/dump' +IODADIR: '/lfs/h2/emc/dump/noscrub/dump_ioda' BASE_GIT: '/lfs/h2/emc/global/save/emc.global/git' BASE_DATA: '/lfs/h2/emc/global/noscrub/emc.global/data' BASE_IC: '/lfs/h2/emc/global/noscrub/emc.global/data/ICSDIR' diff --git a/dev/workflow/rocoto/gcafs_tasks.py b/dev/workflow/rocoto/gcafs_tasks.py index 0b13140b06b..c6687399697 100644 --- a/dev/workflow/rocoto/gcafs_tasks.py +++ b/dev/workflow/rocoto/gcafs_tasks.py @@ -61,7 +61,7 @@ def fetch(self): 'resources': resources, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/fetch.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fetch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -101,7 +101,7 @@ def stage_ic(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/stage_ic.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/stage_ic.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -110,6 +110,50 @@ def stage_ic(self): return task + def prep(self): + + dump_suffix = self._base["DUMP_SUFFIX"] + iodadir = self._base["IODADIR"] + atm_hist_path = self._template_to_rocoto_cycstring(self._base["COM_ATMOS_HISTORY_TMPL"], {'RUN': 'gcdas'}) + ioda_path = self._template_to_rocoto_cycstring(self._base["COM_OBSFORGE_TMPL"], + {'IODADIR': iodadir, 'DUMP_SUFFIX': dump_suffix}) + + deps = [] + + dep_dict = {'type': 'metatask', 'name': 'gcdas_atmos_prod', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} + deps.append(rocoto.add_dependency(dep_dict)) + data = f'{atm_hist_path}/gcdas.t@Hz.atm.f009.nc' + dep_dict = {'type': 'data', 'data': data, 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} + deps.append(rocoto.add_dependency(dep_dict)) + data = f'{ioda_path}/chem/{self.run}.t@Hz.obsforge_aod_status.log' + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + dep_dict = {'type': 'metatask', 'name': 'gcdas_fcst', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} + deps.append(rocoto.add_dependency(dep_dict)) + if self.options['do_prep_sfc']: + dep_dict = {'type': 'task', 'name': f'{self.run}_prep_sfc'} + deps.append(rocoto.add_dependency(dep_dict)) + dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) + + cycledef = self.run + + resources = self.get_resource('prep') + task_name = f'{self.run}_prep' + task_dict = {'task_name': task_name, + 'resources': resources, + 'dependency': dependencies, + 'envars': self.envars, + 'cycledef': cycledef, + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep.sh', + 'job_name': f'{self.pslot}_{task_name}_@H', + 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', + 'maxtries': '&MAXTRIES;' + } + + task = rocoto.create_task(task_dict) + + return task + def prep_emissions(self): """ Create a task for preparing emissions data. @@ -128,7 +172,7 @@ def prep_emissions(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/prep_emissions.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep_emissions.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -164,7 +208,7 @@ def offlineanl(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': 'gcdas', - 'command': f'{self.HOMEgfs}/dev/jobs/offlineanl.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/offlineanl.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -190,31 +234,7 @@ def sfcanl(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': 'gcdas', - 'command': f'{self.HOMEgfs}/dev/jobs/sfcanl.sh', - 'job_name': f'{self.pslot}_{task_name}_@H', - 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', - 'maxtries': '&MAXTRIES;' - } - - task = rocoto.create_task(task_dict) - - return task - - def prepatmiodaobs(self): - - deps = [] - dep_dict = {'type': 'task', 'name': f'gcdas_prep'} - deps.append(rocoto.add_dependency(dep_dict)) - dependencies = rocoto.create_dependency(dep=deps) - - resources = self.get_resource('prepatmiodaobs') - task_name = f'{self.run}_prepatmiodaobs' - task_dict = {'task_name': task_name, - 'resources': resources, - 'dependency': dependencies, - 'envars': self.envars, - 'cycledef': 'gcdas', - 'command': f'{self.HOMEgfs}/dev/jobs/prepatmiodaobs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/sfcanl.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -227,7 +247,7 @@ def prepatmiodaobs(self): def atmanlinit(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_prepatmiodaobs'} + dep_dict = {'type': 'task', 'name': f'{self.run}_prep'} deps.append(rocoto.add_dependency(dep_dict)) if self.options['do_hybvar']: dep_dict = {'type': 'metatask', 'name': 'enkfgdas_epmn', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} @@ -250,7 +270,7 @@ def atmanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -274,7 +294,7 @@ def atmanlvar(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlvar.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlvar.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -298,7 +318,7 @@ def atmanlfv3inc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlfv3inc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlfv3inc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -322,37 +342,7 @@ def atmanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlfinal.sh', - 'job_name': f'{self.pslot}_{task_name}_@H', - 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', - 'maxtries': '&MAXTRIES;' - } - - task = rocoto.create_task(task_dict) - - return task - - def prepobsaero(self): - - dump_suffix = self._base["DUMP_SUFFIX"] - dmpdir = self._base["DMPDIR"] - dump_path = self._template_to_rocoto_cycstring(self._base["COM_OBSPROC_TMPL"], - {'DMPDIR': dmpdir, 'DUMP_SUFFIX': dump_suffix, 'RUN': 'gdas'}) - - deps = [] - data = f'{dump_path}/gdas.t@Hz.updated.status.tm00.bufr_d' - dep_dict = {'type': 'data', 'data': data} - deps.append(rocoto.add_dependency(dep_dict)) - dependencies = rocoto.create_dependency(dep=deps) - - resources = self.get_resource('prepobsaero') - task_name = f'{self.run}_prepobsaero' - task_dict = {'task_name': task_name, - 'resources': resources, - 'dependency': dependencies, - 'envars': self.envars, - 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/prepobsaero.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -376,7 +366,7 @@ def aeroanlgenb(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': 'gcdas_half,gcdas', - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlgenb.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlgenb.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -391,7 +381,7 @@ def aeroanlinit(self): deps = [] dep_dict = {'type': 'task', 'name': 'gcdas_aeroanlgenb', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} deps.append(rocoto.add_dependency(dep_dict)) - dep_dict = {'type': 'task', 'name': 'gcdas_prepobsaero'} + dep_dict = {'type': 'task', 'name': 'gcdas_prep'} deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) @@ -402,7 +392,7 @@ def aeroanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -428,7 +418,7 @@ def aeroanlvar(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlvar.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlvar.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -452,7 +442,7 @@ def aeroanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlfinal.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -514,7 +504,7 @@ def aerosol_init(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/aerosol_init.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aerosol_init.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -591,7 +581,7 @@ def _fcst_forecast_only(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -649,7 +639,7 @@ def _fcst_cycled(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -718,7 +708,7 @@ def efcs(self): 'dependency': dependencies, 'envars': efcsenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -774,7 +764,7 @@ def atmanlupp(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/upp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/upp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -792,7 +782,7 @@ def atmanlprod(self): atm_master_path = self._template_to_rocoto_cycstring(self._base["COM_ATMOS_MASTER_TMPL"]) deps = [] - data = f'{atm_master_path}/{self.run}.t@Hz.master.grb2anl' + data = f'{atm_master_path}/{self.run}.t@Hz.master.analysis.grib2' dep_dict = {'type': 'data', 'data': data, 'age': 120} deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep=deps) @@ -803,7 +793,7 @@ def atmanlprod(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmos_products.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmos_products.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -852,7 +842,7 @@ def _upptask(self, upp_run="forecast", task_id="atmupp"): 'dependency': dependencies, 'envars': postenvars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/upp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/upp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -904,7 +894,7 @@ def _atmosoceaniceprod(self, component: str): fhout_ice_gfs = self._configs['base']['FHOUT_ICE_GFS'] products_dict = {'atmos': {'config': 'atmos_products', 'history_path_tmpl': 'COM_ATMOS_MASTER_TMPL', - 'history_file_tmpl': f'{self.run}.t@Hz.master.grb2f#fhr3_last#'}} + 'history_file_tmpl': f'{self.run}.t@Hz.master.f#fhr3_last#.grib2'}} component_dict = products_dict[component] config = component_dict['config'] @@ -948,7 +938,7 @@ def _atmosoceaniceprod(self, component: str): 'dependency': dependencies, 'envars': postenvars, 'cycledef': cycledef, - 'command': f"{self.HOMEgfs}/dev/jobs/{config}.sh", + 'command': f"{self.HOMEgfs}/dev/job_cards/rocoto/{config}.sh", 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1004,7 +994,7 @@ def atmos_ensstat(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/atmos_ensstat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmos_ensstat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -1058,7 +1048,7 @@ def metp(self): 'dependency': dependencies, 'envars': metpenvars, 'cycledef': 'metp,last_gfs', - 'command': f'{self.HOMEgfs}/dev/jobs/metp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/metp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1089,7 +1079,7 @@ def anlstat(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/anlstat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/anlstat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1138,7 +1128,7 @@ def extractvars(self): 'dependency': dependencies, 'envars': extractvars_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/extractvars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/extractvars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1199,7 +1189,7 @@ def arch_vrfy(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/arch_vrfy.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_vrfy.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1252,7 +1242,7 @@ def arch_tars(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/arch_tars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_tars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1285,7 +1275,7 @@ def globus(self): 'envars': self.envars, 'cycledef': 'gefs', 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/globus_arch.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/globus_arch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1328,7 +1318,7 @@ def cleanup(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/cleanup.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/cleanup.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' diff --git a/dev/workflow/rocoto/gefs_tasks.py b/dev/workflow/rocoto/gefs_tasks.py index 61438252e58..dcede32b627 100644 --- a/dev/workflow/rocoto/gefs_tasks.py +++ b/dev/workflow/rocoto/gefs_tasks.py @@ -16,7 +16,7 @@ def stage_ic(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/stage_ic.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/stage_ic.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -37,7 +37,7 @@ def gen_control_ic(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/gen_control_ic.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gen_control_ic.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -54,7 +54,7 @@ def waveinit(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/waveinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -71,7 +71,7 @@ def prep_emissions(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/prep_emissions.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep_emissions.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -85,7 +85,7 @@ def fcst(self): if self.app_config.gefstype in ['gefs-offline']: dep_dict = {'type': 'task', 'name': f'{self.run}_stage_ic'} dependencies.append(rocoto.add_dependency(dep_dict)) - elif self.app_config.gefstype in ['near-real-time']: + elif self.app_config.gefstype in ['gefs-real-time']: dep_dict = {'type': 'task', 'name': f'{self.run}_gen_control_ic'} dependencies.append(rocoto.add_dependency(dep_dict)) @@ -112,7 +112,7 @@ def fcst(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -167,7 +167,7 @@ def efcs(self): 'dependency': dependencies, 'envars': efcsenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -212,7 +212,7 @@ def _atmosoceaniceprod(self, component: str): fhout_ice_gfs = self._configs['base']['FHOUT_ICE_GFS'] products_dict = {'atmos': {'config': 'atmos_products', 'history_path_tmpl': 'COM_ATMOS_MASTER_TMPL', - 'history_file_tmpl': f'{self.run}.t@Hz.master.grb2f#fhr3_last#'}, + 'history_file_tmpl': f'{self.run}.t@Hz.master.f#fhr3_last#.grib2'}, 'ocean': {'config': 'oceanice_products', 'history_path_tmpl': 'COM_OCEAN_HISTORY_TMPL', 'history_file_tmpl': f'{self.run}.ocean.t@Hz.{fhout_ocn_gfs}hr_avg.f#fhr3_next#.nc'}, @@ -263,7 +263,7 @@ def _atmosoceaniceprod(self, component: str): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/{config}.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/{config}.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -305,7 +305,7 @@ def postsnd(self): 'dependency': dependencies, 'envars': postsnd_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/postsnd.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/postsnd.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -355,7 +355,7 @@ def gempak(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/gempak.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempak.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -407,7 +407,7 @@ def atmos_ensstat(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/atmos_ensstat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmos_ensstat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -449,7 +449,7 @@ def awips(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/awips.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/awips.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -498,7 +498,7 @@ def wavepostsbs(self): 'dependency': dependencies, 'envars': wave_post_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostsbs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostsbs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -556,7 +556,7 @@ def wave_stat(self): 'dependency': dependencies, 'envars': wave_stat_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wave_stat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wave_stat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -585,7 +585,7 @@ def wave_stat_pnt(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wave_stat_pnt.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wave_stat_pnt.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -624,7 +624,7 @@ def extractvars(self): 'dependency': dependencies, 'envars': extractvars_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/extractvars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/extractvars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -669,7 +669,7 @@ def arch_vrfy(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/arch_vrfy.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_vrfy.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -708,7 +708,7 @@ def arch_tars(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/arch_tars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_tars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -731,7 +731,7 @@ def globus(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/globus_arch.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/globus_arch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -762,7 +762,7 @@ def cleanup(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/cleanup.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/cleanup.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' diff --git a/dev/workflow/rocoto/gfs_cycled_xml.py b/dev/workflow/rocoto/gfs_cycled_xml.py index 6b4542251de..f3792ad43eb 100644 --- a/dev/workflow/rocoto/gfs_cycled_xml.py +++ b/dev/workflow/rocoto/gfs_cycled_xml.py @@ -100,7 +100,6 @@ def get_cycledefs(self): interval_metp_str = interval_gfs_str strings.append(f'\t{sdate_metp_str} {edate_metp_str} {interval_metp_str}') - strings.append(f'\t{edate_gfs_str} {edate_gfs_str} 24:00:00') strings.append('') strings.append('') diff --git a/dev/workflow/rocoto/gfs_tasks.py b/dev/workflow/rocoto/gfs_tasks.py index 2eb76eea6cc..690bc3cb16a 100644 --- a/dev/workflow/rocoto/gfs_tasks.py +++ b/dev/workflow/rocoto/gfs_tasks.py @@ -26,7 +26,7 @@ def fetch(self): 'resources': resources, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/fetch.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fetch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -55,7 +55,7 @@ def stage_ic(self): 'resources': resources, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/stage_ic.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/stage_ic.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;', @@ -84,7 +84,7 @@ def prep_sfc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/prep_sfc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep_sfc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -98,9 +98,12 @@ def prep(self): dump_suffix = self._base["DUMP_SUFFIX"] dmpdir = self._base["DMPDIR"] + iodadir = self._base["IODADIR"] atm_hist_path = self._template_to_rocoto_cycstring(self._base["COM_ATMOS_HISTORY_TMPL"], {'RUN': 'gdas'}) dump_path = self._template_to_rocoto_cycstring(self._base["COM_OBSPROC_TMPL"], {'DMPDIR': dmpdir, 'DUMP_SUFFIX': dump_suffix}) + ioda_path = self._template_to_rocoto_cycstring(self._base["COM_OBSFORGE_TMPL"], + {'IODADIR': iodadir, 'DUMP_SUFFIX': dump_suffix}) gfs_enkf = True if self.options['do_hybvar'] and 'gfs' in self.app_config.ens_runs else False @@ -113,6 +116,19 @@ def prep(self): deps.append(rocoto.add_dependency(dep_dict)) data = f'{dump_path}/{self.run}.t@Hz.updated.status.tm00.bufr_d' dep_dict = {'type': 'data', 'data': data} + if self.options['do_jediatmvar']: + data = f'{ioda_path}/atmos/{self.run}.t@Hz.obsforge_atmos_bufr_status.log' + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + # TODO enable this for marine observations when ready + # if self.options['do_jediocnvar']: + # data = f'{ioda_path}/ocean/{self.run}.t@Hz.obsforge_marine_status.log' + # dep_dict = {'type': 'data', 'data': data} + # deps.append(rocoto.add_dependency(dep_dict)) + if self.options['do_aero_anl']: + data = f'{ioda_path}/chem/{self.run}.t@Hz.obsforge_aod_status.log' + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) deps.append(rocoto.add_dependency(dep_dict)) dep_dict = {'type': 'metatask', 'name': 'gdas_fcst', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} deps.append(rocoto.add_dependency(dep_dict)) @@ -132,7 +148,7 @@ def prep(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/prep.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -162,7 +178,7 @@ def waveinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/waveinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -186,7 +202,7 @@ def waveprep(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/waveprep.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveprep.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -238,7 +254,7 @@ def aerosol_init(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/aerosol_init.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aerosol_init.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -266,7 +282,7 @@ def anal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/anal.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/anal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -302,7 +318,7 @@ def sfcanl(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/sfcanl.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/sfcanl.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -315,7 +331,10 @@ def sfcanl(self): def analcalc(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_anal'} + if self.options['do_jediatmvar'] and not self.options['do_jediatmens']: + dep_dict = {'type': 'task', 'name': f'{self.run}_atmanlfinal'} + else: + dep_dict = {'type': 'task', 'name': f'{self.run}_anal'} deps.append(rocoto.add_dependency(dep_dict)) dep_dict = {'type': 'task', 'name': f'{self.run}_sfcanl'} deps.append(rocoto.add_dependency(dep_dict)) @@ -331,7 +350,7 @@ def analcalc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/analcalc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/analcalc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -355,31 +374,7 @@ def analdiag(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/analdiag.sh', - 'job_name': f'{self.pslot}_{task_name}_@H', - 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', - 'maxtries': '&MAXTRIES;' - } - - task = rocoto.create_task(task_dict) - - return task - - def prepatmiodaobs(self): - - deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_prep'} - deps.append(rocoto.add_dependency(dep_dict)) - dependencies = rocoto.create_dependency(dep=deps) - - resources = self.get_resource('prepatmiodaobs') - task_name = f'{self.run}_prepatmiodaobs' - task_dict = {'task_name': task_name, - 'resources': resources, - 'dependency': dependencies, - 'envars': self.envars, - 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/prepatmiodaobs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/analdiag.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -392,7 +387,7 @@ def prepatmiodaobs(self): def atmanlinit(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_prepatmiodaobs'} + dep_dict = {'type': 'task', 'name': f'{self.run}_prep'} deps.append(rocoto.add_dependency(dep_dict)) if self.options['do_hybvar']: dep_dict = {'type': 'metatask', 'name': 'enkfgdas_epmn', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} @@ -415,7 +410,7 @@ def atmanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -439,7 +434,7 @@ def atmanlvar(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlvar.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlvar.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -463,7 +458,7 @@ def atmanlfv3inc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlfv3inc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlfv3inc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -487,30 +482,7 @@ def atmanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmanlfinal.sh', - 'job_name': f'{self.pslot}_{task_name}_@H', - 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', - 'maxtries': '&MAXTRIES;' - } - - task = rocoto.create_task(task_dict) - - return task - - def prepobsaero(self): - deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_prep'} - deps.append(rocoto.add_dependency(dep_dict)) - dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) - - resources = self.get_resource('prepobsaero') - task_name = f'{self.run}_prepobsaero' - task_dict = {'task_name': task_name, - 'resources': resources, - 'dependency': dependencies, - 'envars': self.envars, - 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/prepobsaero.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -534,7 +506,7 @@ def aeroanlgenb(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': 'gdas_half,gdas', - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlgenb.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlgenb.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -552,9 +524,6 @@ def aeroanlinit(self): dep_dict = {'type': 'task', 'name': f'{self.run}_prep'} deps.append(rocoto.add_dependency(dep_dict)) - if self.options['do_prep_obs_aero']: - dep_dict = {'type': 'task', 'name': f'{self.run}_prepobsaero'} - deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) resources = self.get_resource('aeroanlinit') @@ -564,7 +533,7 @@ def aeroanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -595,7 +564,7 @@ def aeroanlvar(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlvar.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlvar.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -619,7 +588,7 @@ def aeroanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/aeroanlfinal.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/aeroanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -643,7 +612,7 @@ def snowanl(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/snowanl.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/snowanl.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -668,7 +637,7 @@ def esnowanl(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/esnowanl.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/esnowanl.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -701,7 +670,7 @@ def prepoceanobs(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/prepoceanobs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prepoceanobs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -727,7 +696,7 @@ def marineanlletkf(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlletkf.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlletkf.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -757,7 +726,7 @@ def marinebmatinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marinebmatinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marinebmatinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -781,7 +750,7 @@ def marinebmat(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marinebmat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marinebmat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -809,7 +778,7 @@ def marineanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -833,7 +802,7 @@ def marineanlvar(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlvar.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlvar.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -858,7 +827,7 @@ def marineanlecen(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlecen.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlecen.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -893,7 +862,7 @@ def marineanlchkpt(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlchkpt.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlchkpt.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -917,7 +886,7 @@ def marineanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/marineanlfinal.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/marineanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -986,7 +955,7 @@ def _fcst_forecast_only(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1066,7 +1035,7 @@ def _fcst_cycled(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1092,13 +1061,13 @@ def atmanlupp(self): atm_anl_path = self._template_to_rocoto_cycstring(self._base["COM_ATMOS_ANALYSIS_TMPL"]) deps = [] - if self.options['do_jediatmvar']: + if self.options['do_jediatmvar'] and self.options['do_jediatmens']: data = f'{atm_anl_path}/{self.run}.t@Hz.jedi_analysis.atm.a006.nc' else: data = f'{atm_anl_path}/{self.run}.t@Hz.analysis.atm.a006.nc' dep_dict = {'type': 'data', 'data': data, 'age': 120} deps.append(rocoto.add_dependency(dep_dict)) - if self.options['do_jediatmvar']: + if self.options['do_jediatmvar'] and self.options['do_jediatmens']: data = f'{atm_anl_path}/{self.run}.t@Hz.jedi_analysis.sfc.a006.nc' else: data = f'{atm_anl_path}/{self.run}.t@Hz.analysis.sfc.a006.nc' @@ -1115,7 +1084,7 @@ def atmanlupp(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/upp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/upp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1144,7 +1113,7 @@ def atmanlprod(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmos_products.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmos_products.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1193,7 +1162,7 @@ def _upptask(self, upp_run="forecast", task_id="atmupp"): 'dependency': dependencies, 'envars': postenvars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/upp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/upp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1281,7 +1250,7 @@ def _atmosoceaniceprod(self, component: str): 'dependency': dependencies, 'envars': postenvars, 'cycledef': cycledef, - 'command': f"{self.HOMEgfs}/dev/jobs/{config}.sh", + 'command': f"{self.HOMEgfs}/dev/job_cards/rocoto/{config}.sh", 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1326,7 +1295,7 @@ def wavepostsbs(self): 'dependency': dependencies, 'envars': wave_post_envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostsbs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostsbs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1365,7 +1334,7 @@ def _wavepostbndpnt(self, name_in): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/{name_in}.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/{name_in}.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1388,7 +1357,7 @@ def wavepostpnt(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostpnt.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostpnt.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1438,7 +1407,7 @@ def wavegempak(self): 'dependency': dependencies, 'envars': wave_post_envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/wavegempak.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavegempak.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1467,7 +1436,7 @@ def waveawipsbulls(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/waveawipsbulls.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveawipsbulls.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1490,7 +1459,7 @@ def waveawipsgridded(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/waveawipsgridded.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveawipsgridded.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1513,7 +1482,7 @@ def postsnd(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/postsnd.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/postsnd.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1550,7 +1519,7 @@ def fbwind(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/fbwind.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fbwind.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1622,7 +1591,7 @@ def awips_20km_1p0deg(self): 'dependency': dependencies, 'envars': awipsenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/awips_20km_1p0deg.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/awips_20km_1p0deg.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1677,7 +1646,7 @@ def gempak(self): 'dependency': dependencies, 'envars': gempak_vars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/gempak.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempak.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1704,7 +1673,7 @@ def gempakmeta(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/gempakmeta.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempakmeta.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1727,7 +1696,7 @@ def gempakmetancdc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/gempakmetancdc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempakmetancdc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1750,7 +1719,7 @@ def gempakncdcupapgif(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/gempakncdcupapgif.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempakncdcupapgif.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1778,7 +1747,7 @@ def gempakpgrb2spec(self): 'dependency': dependencies, 'envars': gempak_vars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/gempakgrb2spec.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/gempakgrb2spec.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1820,7 +1789,7 @@ def npoess_pgrb2_0p5deg(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/npoess.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/npoess.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1843,7 +1812,7 @@ def verfozn(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/verfozn.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/verfozn.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1866,7 +1835,7 @@ def verfrad(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/verfrad.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/verfrad.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1889,7 +1858,7 @@ def vminmon(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/vminmon.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/vminmon.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1926,7 +1895,7 @@ def anlstat(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/anlstat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/anlstat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1949,7 +1918,7 @@ def tracker(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/tracker.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/tracker.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1972,7 +1941,7 @@ def genesis(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/genesis.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/genesis.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -1995,7 +1964,7 @@ def genesis_fsu(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/genesis_fsu.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/genesis_fsu.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2018,7 +1987,7 @@ def fit2obs(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/fit2obs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fit2obs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2032,24 +2001,48 @@ def metp(self): deps = [] dep_dict = {'type': 'task', 'name': f'{self.run}_arch_vrfy'} deps.append(rocoto.add_dependency(dep_dict)) - if self._base["interval_gfs"] < to_timedelta("24H"): - n_lookback = self._base["interval_gfs"] // to_timedelta("6H") - for lookback in range(1, n_lookback + 1): - deps2 = [] + interval_gfs = self._base.get('interval_gfs') + assim_freq = self._base['assim_freq'] + + if interval_gfs < to_timedelta("24H"): + n_lookback = int(interval_gfs // to_timedelta(f"{assim_freq}H")) - 1 + # Check if the previous up to `n_lookback` arch_vrfy tasks have completed + # For interval=6, there are no lookbacks + # For interval=12, check lookback=1 + # For interval=18, check lookback=1,2 + # Only lookback if arch_vrfy is not valid for this cycle + if n_lookback > 0: dep_dict = {'type': 'taskvalid', 'name': f'{self.run}_arch_vrfy', 'condition': 'not'} + deps2 = [] deps2.append(rocoto.add_dependency(dep_dict)) - for lookback2 in range(1, lookback): - offset = timedelta_to_HMS(-to_timedelta(f'{6 * lookback2}H')) - dep_dict = {'type': 'cycleexist', 'condition': 'not', 'offset': offset} - deps2.append(rocoto.add_dependency(dep_dict)) - - edate_gfs = self._base['EDATE'] - edate_metp = edate_gfs.replace(hour=18) - edate_metp_diff = edate_metp - edate_gfs - offset = timedelta_to_HMS(-to_timedelta(f'{edate_metp_diff}H')) - dep_dict = {'type': 'task', 'name': f'{self.run}_arch_vrfy', 'offset': offset} + deps3 = [] + for lookback in range(n_lookback): + offset = timedelta_to_HMS(-to_timedelta(f'{assim_freq * (lookback+1)}H')) + dep_dict = {'type': 'task', 'name': f'{self.run}_arch_vrfy', 'offset': offset} + deps3.append(rocoto.add_dependency(dep_dict)) + + deps2.append(rocoto.create_dependency(dep=deps3, dep_condition='or')) + deps.append(rocoto.create_dependency(dep=deps2, dep_condition='and')) + + # Lastly, check that the last arch_vrfy job is done + # This only happens if the metp cycle is not aligned with the last_gfs cycle + sdate_gfs = self._base.get('SDATE_GFS') + edate = self._base.get('EDATE') + edate_metp = self._base.get('EDATE').replace(hour=(24 - assim_freq)) + n_intervals = int((edate - sdate_gfs) // interval_gfs) + edate_gfs = sdate_gfs + n_intervals * interval_gfs + metp_gfs_offset = edate_metp - edate_gfs + if metp_gfs_offset > to_timedelta("0H") and metp_gfs_offset < to_timedelta("24H"): + deps2 = [] + dep_dict = {'type': 'taskvalid', 'name': f'{self.run}_arch_vrfy', 'condition': 'not'} + deps2.append(rocoto.add_dependency(dep_dict)) + dep_dict = {'type': 'task', 'name': f'{self.run}_arch_vrfy', 'offset': timedelta_to_HMS(-metp_gfs_offset)} + deps2.append(rocoto.add_dependency(dep_dict)) + for i in range(1, int((metp_gfs_offset.seconds / 3600) // assim_freq)): + dep_dict = {'type': 'cycleexist', 'offset': timedelta_to_HMS(-to_timedelta(f'{assim_freq * i}H')), 'condition': 'not'} deps2.append(rocoto.add_dependency(dep_dict)) - deps.append(rocoto.create_dependency(dep_condition='and', dep=deps2)) + + deps.append(rocoto.create_dependency(dep=deps2, dep_condition='and')) dependencies = rocoto.create_dependency(dep_condition='or', dep=deps) @@ -2072,7 +2065,7 @@ def metp(self): 'dependency': dependencies, 'envars': metpenvars, 'cycledef': 'metp,last_gfs', - 'command': f'{self.HOMEgfs}/dev/jobs/metp.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/metp.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2140,7 +2133,7 @@ def arch_vrfy(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/arch_vrfy.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_vrfy.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2259,12 +2252,12 @@ def arch_tars(self): tarball_types.append('chem') if self.options['do_ocean']: - tarball_types.extend(['ocean_6hravg', 'ocean_grib2', 'gfs_flux_1p00']) + tarball_types.extend(['ocean_6hravg', 'ocean_native', 'gfs_flux_1p00']) if self.options.get('do_jediocnvar', False) and self.app_config.mode == 'cycled': tarball_types.append('gfsocean_analysis') if self.options['do_ice']: - tarball_types.extend(['ice_6hravg', 'ice_grib2']) + tarball_types.extend(['ice_6hravg', 'ice_native']) if self.options['do_bufrsnd']: tarball_types.append('gfs_downstream') @@ -2313,7 +2306,7 @@ def arch_tars(self): 'dependency': dependencies, 'envars': archenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/arch_tars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_tars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2342,7 +2335,7 @@ def globus_arch(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/globus_arch.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/globus_arch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2375,7 +2368,7 @@ def globus_earc(self): 'dependency': dependencies, 'envars': earcenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/globus_earc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/globus_earc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2392,14 +2385,37 @@ def globus_earc(self): # Cleanup def cleanup(self): - deps = [] - dep_dict = {'type': 'task', 'name': 'gfs_fcst_seg0', 'offset': - f"{timedelta_to_HMS(self._base['interval_gfs'])}"} - deps.append(rocoto.add_dependency(dep_dict)) - dep_dict = {'type': 'cycleexist', 'condition': 'not', - 'offset': f"{timedelta_to_HMS(self._base['interval_gfs'])}"} - deps.append(rocoto.add_dependency(dep_dict)) - dep_next_fcst_seg = rocoto.create_dependency(dep_condition='or', dep=deps) + + # Build a dependency on the next GFS forecast. + # This will only be used for GDAS/ENKFGDAS cycles with 6-hourly GFS intervals + # to prevent clobbering files needed by the GFS forecast prematurely. + assim_freq = self._base.get('assim_freq', 6) + interval_gfs = int(self._base.get('INTERVAL_GFS', 0)) + if interval_gfs >= assim_freq: + deps = [] + dep_dict = {'type': 'task', 'name': 'gfs_fcst_seg0', 'offset': + f"{timedelta_to_HMS(self._base['interval_gfs'])}"} + deps.append(rocoto.add_dependency(dep_dict)) + dep_dict = {'type': 'cycleexist', 'condition': 'not', + 'offset': f"{timedelta_to_HMS(self._base['interval_gfs'])}"} + deps.append(rocoto.add_dependency(dep_dict)) + # Only start checking this if we are at/past the first GFS cycle + sdate_gfs = self._base.get('SDATE_GFS') + sdate = self._base.get('SDATE') + if sdate_gfs: + n_cycles = int((sdate_gfs - sdate).total_seconds() // 3600 // assim_freq) + # Start at the first full cycle (1 cycle after SDATE) + # End two cycles before SDATE_gfs + # One cycle before SDATE_gfs must depend on the next forecast segment. + for cycle in range(1, n_cycles - 1): + offset = timedelta_to_HMS(to_timedelta(f'{cycle * assim_freq}H')) + skip_date = (sdate + to_timedelta(f'{cycle * assim_freq}H')).strftime("%Y%m%d%H") + dep_dict = {'type': 'streq', 'left': '@Y@m@d@H', 'right': skip_date} + deps.append(rocoto.add_dependency(dep_dict)) + + dep_next_fcst_seg = rocoto.create_dependency(dep_condition='or', dep=deps) + + # Now start building RUN-specific dependencies deps = [] if 'enkf' in self.run: dep_dict = {'type': 'task', 'name': f'{self.run}_earc_vrfy'} @@ -2410,7 +2426,7 @@ def cleanup(self): else: dep_dict = {'type': 'metatask', 'name': f'{self.run}_earc_tars'} deps.append(rocoto.add_dependency(dep_dict)) - if self.run in ['enkfgdas'] and self._base["INTERVAL_GFS"] == 6: + if self.run in ['enkfgdas'] and interval_gfs == assim_freq: deps.append(dep_next_fcst_seg) else: @@ -2422,7 +2438,7 @@ def cleanup(self): dep_dict = {'type': 'task', 'name': f'{self.run}_vminmon'} deps.append(rocoto.add_dependency(dep_dict)) elif self.run in ['gdas']: - if self._base["INTERVAL_GFS"] == 6: + if interval_gfs == assim_freq: deps.append(dep_next_fcst_seg) dep_dict = {'type': 'task', 'name': f'{self.run}_atmanlprod'} deps.append(rocoto.add_dependency(dep_dict)) @@ -2528,7 +2544,7 @@ def cleanup(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/cleanup.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/cleanup.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2554,7 +2570,7 @@ def eobs(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/eobs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/eobs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2577,7 +2593,7 @@ def ediag(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/ediag.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/ediag.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2600,7 +2616,7 @@ def eupd(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/eupd.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/eupd.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2612,7 +2628,7 @@ def eupd(self): def atmensanlinit(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run.replace("enkf", "")}_prepatmiodaobs'} + dep_dict = {'type': 'task', 'name': f'{self.run.replace("enkf", "")}_prep'} deps.append(rocoto.add_dependency(dep_dict)) dep_dict = {'type': 'metatask', 'name': 'enkfgdas_epmn', 'offset': f"-{timedelta_to_HMS(self._base['interval_gdas'])}"} deps.append(rocoto.add_dependency(dep_dict)) @@ -2626,7 +2642,7 @@ def atmensanlinit(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2652,7 +2668,7 @@ def atmensanlobs(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlobs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlobs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2678,7 +2694,7 @@ def atmensanlsol(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlsol.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlsol.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2704,7 +2720,7 @@ def atmensanlletkf(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlletkf.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlletkf.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2733,7 +2749,7 @@ def atmensanlfv3inc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlfv3inc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlfv3inc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2757,7 +2773,7 @@ def atmensanlfinal(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/atmensanlfinal.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmensanlfinal.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2817,7 +2833,7 @@ def _get_ecengroups(): 'dependency': dependencies, 'envars': ecenenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/ecen.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/ecen.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2847,7 +2863,7 @@ def ecen_fv3jedi(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/ecen_fv3jedi.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/ecen_fv3jedi.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2877,7 +2893,7 @@ def analcalc_fv3jedi(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/analcalc_fv3jedi.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/analcalc_fv3jedi.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2910,7 +2926,7 @@ def esfc(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/esfc.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/esfc.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2955,7 +2971,7 @@ def efcs(self): 'dependency': dependencies, 'envars': efcsenvars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -2991,7 +3007,7 @@ def echgres(self): 'dependency': dependencies, 'envars': self.envars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/echgres.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/echgres.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -3050,7 +3066,7 @@ def _get_eposgroups(epos): 'dependency': dependencies, 'envars': eposenvars, 'cycledef': cycledef, - 'command': f'{self.HOMEgfs}/dev/jobs/epos.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/epos.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -3090,7 +3106,7 @@ def earc_vrfy(self): 'dependency': dependencies, 'envars': earcenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/earc_vrfy.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/earc_vrfy.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -3106,7 +3122,7 @@ def earc_tars(self): if 'enkfgdas' in self.run: dep_dict = {'type': 'metatask', 'name': f'{self.run}_epmn'} deps.append(rocoto.add_dependency(dep_dict)) - if not self.options['do_jediatmvar']: + if not self.options['do_jediatmens']: dep_dict = {'type': 'task', 'name': f'{self.run}_echgres'} deps.append(rocoto.add_dependency(dep_dict)) if self._base.get('DOLETKF_OCN', True): @@ -3145,7 +3161,7 @@ def earc_tars(self): 'dependency': dependencies, 'envars': earcenvars, 'cycledef': self.run.replace('enkf', ''), - 'command': f'{self.HOMEgfs}/dev/jobs/earc_tars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/earc_tars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' diff --git a/dev/workflow/rocoto/sfs_tasks.py b/dev/workflow/rocoto/sfs_tasks.py index 9113a5d9bb4..0d29390e945 100644 --- a/dev/workflow/rocoto/sfs_tasks.py +++ b/dev/workflow/rocoto/sfs_tasks.py @@ -16,7 +16,7 @@ def stage_ic(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/stage_ic.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/stage_ic.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -33,7 +33,7 @@ def waveinit(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/waveinit.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/waveinit.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -50,7 +50,7 @@ def prep_emissions(self): 'resources': resources, 'envars': self.envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/prep_emissions.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/prep_emissions.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -88,7 +88,7 @@ def fcst(self): 'dependency': dependencies, 'envars': fcst_vars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -145,7 +145,7 @@ def efcs(self): 'dependency': dependencies, 'envars': efcsenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/fcst.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/fcst.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -190,7 +190,7 @@ def _atmosoceaniceprod(self, component: str): fhout_ice_gfs = self._configs['base']['FHOUT_ICE_GFS'] products_dict = {'atmos': {'config': 'atmos_products', 'history_path_tmpl': 'COM_ATMOS_MASTER_TMPL', - 'history_file_tmpl': f'{self.run}.t@Hz.master.grb2f#fhr3_last#'}, + 'history_file_tmpl': f'{self.run}.t@Hz.master.f#fhr3_last#.grib2'}, 'ocean': {'config': 'oceanice_products', 'history_path_tmpl': 'COM_OCEAN_HISTORY_TMPL', 'history_file_tmpl': f'{self.run}.ocean.t@Hz.{fhout_ocn_gfs}hr_avg.f#fhr3_next#.nc'}, @@ -241,7 +241,7 @@ def _atmosoceaniceprod(self, component: str): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/{config}.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/{config}.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -291,7 +291,7 @@ def atmos_ensstat(self): 'dependency': dependencies, 'envars': postenvars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/atmos_ensstat.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/atmos_ensstat.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;'} @@ -340,7 +340,7 @@ def wavepostsbs(self): 'dependency': dependencies, 'envars': wave_post_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostsbs.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostsbs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -379,7 +379,7 @@ def wavepostbndpnt(self): 'dependency': dependencies, 'envars': wave_post_bndpnt_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostbndpnt.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostbndpnt.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -424,7 +424,7 @@ def wavepostbndpntbll(self): 'dependency': dependencies, 'envars': wave_post_bndpnt_bull_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostbndpntbll.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostbndpntbll.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -463,7 +463,7 @@ def wavepostpnt(self): 'dependency': dependencies, 'envars': wave_post_pnt_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/wavepostpnt.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/wavepostpnt.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -508,7 +508,7 @@ def extractvars(self): 'dependency': dependencies, 'envars': extractvars_envars, 'cycledef': self.run, - 'command': f'{self.HOMEgfs}/dev/jobs/extractvars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/extractvars.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -558,7 +558,7 @@ def arch_vrfy(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/arch_vrfy.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_vrfy.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -602,7 +602,31 @@ def arch_tars(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/arch_tars.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/arch_tars.sh', + 'job_name': f'{self.pslot}_{task_name}_@H', + 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', + 'maxtries': '&MAXTRIES;' + } + + task = rocoto.create_task(task_dict) + + return task + + # Globus transfer for HPSS archiving + def globus(self): + deps = [] + dep_dict = {'type': 'task', 'name': f'{self.run}_arch_tars'} + deps.append(rocoto.add_dependency(dep_dict)) + dependencies = rocoto.create_dependency(dep=deps) + + resources = self.get_resource('globus') + task_name = f'{self.run}_globus_arch' + task_dict = {'task_name': task_name, + 'resources': resources, + 'dependency': dependencies, + 'envars': self.envars, + 'cycledef': self.run, + 'command': f'{self.HOMEgfs}/dev/jobs/globus_arch.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' @@ -637,6 +661,13 @@ def cleanup(self): if self.options['do_extractvars']: dep_dict = {'type': 'metatask', 'name': f'{self.run}_extractvars'} deps.append(rocoto.add_dependency(dep_dict)) + if self.options['do_archcom']: + if self.options['do_globusarch']: + dep_dict = {'type': 'task', 'name': f'{self.run}_globus_arch'} + else: + dep_dict = {'type': 'task', 'name': f'{self.run}_arch_tars'} + deps.append(rocoto.add_dependency(dep_dict)) + dependencies = rocoto.create_dependency(dep=deps) dependencies = rocoto.create_dependency(dep=deps, dep_condition='and') resources = self.get_resource('cleanup') task_name = f'{self.run}_cleanup' @@ -645,7 +676,7 @@ def cleanup(self): 'envars': self.envars, 'cycledef': self.run, 'dependency': dependencies, - 'command': f'{self.HOMEgfs}/dev/jobs/cleanup.sh', + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/cleanup.sh', 'job_name': f'{self.pslot}_{task_name}_@H', 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', 'maxtries': '&MAXTRIES;' diff --git a/dev/workflow/rocoto/tasks.py b/dev/workflow/rocoto/tasks.py index 79c380ffeb2..b5d48e994bb 100644 --- a/dev/workflow/rocoto/tasks.py +++ b/dev/workflow/rocoto/tasks.py @@ -16,14 +16,14 @@ class Tasks: VALID_TASKS = ['aerosol_init', 'stage_ic', 'gen_control_ic', 'fetch', 'globus', 'ens_globus', 'prep_sfc', 'prep', 'anal', 'sfcanl', 'analcalc', 'analdiag', 'arch_vrfy', 'arch_tars', 'cleanup', 'ecen_fv3jedi', 'analcalc_fv3jedi', 'cleanup', - 'prepatmiodaobs', 'atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', + 'atmanlinit', 'atmanlvar', 'atmanlfv3inc', 'atmanlfinal', 'prep_emissions', 'prepoceanobs', 'marineanlinit', 'marineanlletkf', 'marinebmatinit', 'marinebmat', 'marineanlvar', 'marineanlecen', 'marineanlchkpt', 'marineanlfinal', 'ocnanalvrfy', 'eobs', 'epos', 'esfc', 'eupd', 'earc_vrfy', 'earc_tars', 'ecen', 'echgres', 'ediag', 'efcs', 'atmensanlinit', 'atmensanlobs', 'atmensanlsol', 'atmensanlletkf', 'atmensanlfv3inc', 'atmensanlfinal', 'atmos_ensstat', - 'aeroanlinit', 'aeroanlvar', 'aeroanlfinal', 'aeroanlgenb', 'prepobsaero', + 'aeroanlinit', 'aeroanlvar', 'aeroanlfinal', 'aeroanlgenb', 'snowanl', 'esnowanl', 'offlineanl', 'fcst', @@ -415,7 +415,7 @@ def get_resource(self, task_name): service_task = task_name in Tasks.SERVICE_TASKS if task_name not in Tasks.VALID_TASKS: - raise KeyError(f"ERROR {task_name} is not a valid tasks!") + raise KeyError(f"ERROR {task_name} is not a valid task!") # Combine the task configuration with the system configuration if service_task: diff --git a/dev/workflow/setup_expt.py b/dev/workflow/setup_expt.py index 1cd9ad1785c..d668ea415a5 100755 --- a/dev/workflow/setup_expt.py +++ b/dev/workflow/setup_expt.py @@ -244,7 +244,7 @@ def _common_args(parser): parser.add_argument('--interval', help='frequency of forecast (in hours); must be a multiple of 6 or 0 for no forecasts', type=_validate_interval, required=False, default=6) parser.add_argument('--icsdir', help='full path to user initial condition directory', type=str, required=False, default='') - parser.add_argument('--gefstype', help='type of the gefs experiment: near-real-time or gefs-offline', type=str, required=False, default='') + parser.add_argument('--gefstype', help='type of the gefs experiment: gefs-real-time or gefs-offline', type=str, required=False, default='') parser.add_argument('--overwrite', help='overwrite previously created experiment (if it exists)', action='store_true', required=False) return parser diff --git a/env/GAEAC5.env b/env/GAEAC5.env index 83813f447c5..9f84a8b46ef 100755 --- a/env/GAEAC5.env +++ b/env/GAEAC5.env @@ -102,11 +102,7 @@ case ${step} in export NTHREADS_AEROANLGENB=${NTHREADSmax} export APRUN_AEROANLGENB="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLGENB}" ;; - "prepobsaero") - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - ;; "snowanl") export APRUN_CALCFIMS="${launcher} -n 1" diff --git a/env/GAEAC6.env b/env/GAEAC6.env index b37572ba7cf..5ab863acb16 100755 --- a/env/GAEAC6.env +++ b/env/GAEAC6.env @@ -105,11 +105,7 @@ case ${step} in export NTHREADS_AEROANLGENB=${NTHREADSmax} export APRUN_AEROANLGENB="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLGENB}" ;; - "prepobsaero") - - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - ;; + "snowanl") export APRUN_CALCFIMS="${launcher} -n 1" @@ -203,7 +199,10 @@ case ${step} in ntasks_gausfcanl=${ntasks_gausfcanl:-1} export APRUN_GAUSFCANL="${launcher} -n ${ntasks_gausfcanl} --cpus-per-task=${NTHREADS_GAUSFCANL}" ;; - "offlineanl") + "analdiag" | "ediag") + export USE_CFP="YES" + ;; + "offlineanl") export NTHREADS_CHGRES=${threads_per_task_chgres:-12} if [[ ${NTHREADS_CHGRES} -gt ${max_tasks_per_node} ]]; then diff --git a/env/HERA.env b/env/HERA.env index 57aefcc66af..76af27e6748 100755 --- a/env/HERA.env +++ b/env/HERA.env @@ -113,11 +113,6 @@ elif [[ "${step}" = "anlstat" ]]; then export NTHREADS_ANLSTAT=${NTHREADSmax} export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" -elif [[ "${step}" = "prepobsaero" ]]; then - - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - elif [[ "${step}" = "snowanl" ]]; then export APRUN_CALCFIMS="${launcher} -n 1" @@ -208,6 +203,10 @@ elif [[ "${step}" = "anal" ]] || [[ "${step}" = "analcalc" ]]; then ntasks_gausfcanl=${ntasks_gausfcanl:-1} export APRUN_GAUSFCANL="${launcher} -n ${ntasks_gausfcanl} --cpus-per-task=${NTHREADS_GAUSFCANL}" +elif [[ "${step}" = "analdiag" ]] || [[ "${step}" = "ediag" ]]; then + + export USE_CFP="YES" + elif [[ "${step}" = "offlineanl" ]]; then export NTHREADS_CHGRES=${threads_per_task_chgres:-12} diff --git a/env/HERCULES.env b/env/HERCULES.env index 46a6db49216..493e23db4a3 100755 --- a/env/HERCULES.env +++ b/env/HERCULES.env @@ -108,11 +108,7 @@ case ${step} in export NTHREADS_AEROANLGENB=${NTHREADSmax} export APRUN_AEROANLGENB="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLGENB}" ;; - "prepobsaero") - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - ;; "snowanl") export APRUN_CALCFIMS="${launcher} -n 1" @@ -162,7 +158,7 @@ case ${step} in "anlstat") export NTHREADS_ANLSTAT=${NTHREADSmax} - export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" + export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" ;; "ecen_fv3jedi") @@ -222,6 +218,9 @@ case ${step} in # REGRID requires 6 tasks for reproducibility ntasks_regrid=6 export APRUN_REGRID="${launcher} -n ${ntasks_regrid} " + ;; + "analdiag" | "ediag") + export USE_CFP="YES" ;; "offlineanl") diff --git a/env/ORION.env b/env/ORION.env index 10f896037ab..6634fda665f 100755 --- a/env/ORION.env +++ b/env/ORION.env @@ -99,11 +99,6 @@ elif [[ "${step}" = "aeroanlgenb" ]]; then export NTHREADS_AEROANLGENB=${NTHREADSmax} export APRUN_AEROANLGENB="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLGENB}" -elif [[ "${step}" = "prepobsaero" ]]; then - - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - elif [[ "${step}" = "snowanl" ]]; then export APRUN_CALCFIMS="${launcher} -n 1" @@ -162,7 +157,7 @@ elif [[ "${step}" = "marineanlletkf" ]]; then elif [[ "${step}" = "anlstat" ]]; then export NTHREADS_ANLSTAT=${NTHREADSmax} - export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" + export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" elif [[ "${step}" = "ecen_fv3jedi" ]]; then @@ -221,6 +216,10 @@ elif [[ "${step}" = "sfcanl" ]]; then ntasks_regrid=6 export APRUN_REGRID="${launcher} -n ${ntasks_regrid} " +elif [[ "${step}" = "analdiag" ]] || [[ "${step}" = "ediag" ]]; then + + export USE_CFP="YES" + elif [[ "${step}" = "offlineanl" ]]; then export NTHREADS_CHGRES=${threads_per_task:-12} diff --git a/env/URSA.env b/env/URSA.env index 1b952df431c..80711ea2b3b 100644 --- a/env/URSA.env +++ b/env/URSA.env @@ -107,11 +107,6 @@ elif [[ "${step}" = "anlstat" ]]; then export NTHREADS_ANLSTAT=${NTHREADSmax} export APRUN_ANLSTAT="${APRUN_default} --cpus-per-task=${NTHREADS_ANLSTAT}" -elif [[ "${step}" = "prepobsaero" ]]; then - - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --cpus-per-task=${NTHREADS_PREPOBSAERO}" - elif [[ "${step}" = "snowanl" ]]; then export APRUN_CALCFIMS="${launcher} -n 1" @@ -197,6 +192,10 @@ elif [[ "${step}" = "anal" ]] || [[ "${step}" = "analcalc" ]]; then ntasks_gausfcanl=${ntasks_gausfcanl:-1} export APRUN_GAUSFCANL="${launcher} -n ${ntasks_gausfcanl} --cpus-per-task=${NTHREADS_GAUSFCANL}" +elif [[ "${step}" = "analdiag" ]] || [[ "${step}" = "ediag" ]]; then + + export USE_CFP="YES" + elif [[ "${step}" = "offlineanl" ]]; then export NTHREADS_CHGRES=${threads_per_task_chgres:-12} diff --git a/env/WCOSS2.env b/env/WCOSS2.env index b0da0aa559a..867c0a4eab2 100755 --- a/env/WCOSS2.env +++ b/env/WCOSS2.env @@ -85,11 +85,6 @@ elif [[ "${step}" = "aeroanlgenb" ]]; then export NTHREADS_AEROANLGENB=${NTHREADSmax} export APRUN_AEROANLGENB="${APRUN_default}" -elif [[ "${step}" = "prepobsaero" ]]; then - - export NTHREADS_PREPOBSAERO=${NTHREADS1} - export APRUN_PREPOBSAERO="${APRUN_default} --ppn ${tasks_per_node} --cpu-bind depth --depth ${NTHREADS_PREPOBSAERO}" - elif [[ "${step}" = "snowanl" ]]; then export APRUN_CALCFIMS="${launcher} -n 1" @@ -210,6 +205,10 @@ elif [[ "${step}" = "sfcanl" ]]; then ntasks_regrid=6 export APRUN_REGRID="${launcher} -n ${ntasks_regrid} " +elif [[ "${step}" = "analdiag" ]] || [[ "${step}" = "ediag" ]]; then + + export USE_CFP="YES" + elif [[ "${step}" = "offlineanl" ]]; then export NTHREADS_CHGRES=${threads_per_task_chgres:-14} diff --git a/jobs/JGDAS_ENKF_DIAG b/jobs/JGDAS_ENKF_DIAG deleted file mode 100755 index 70567283f2f..00000000000 --- a/jobs/JGDAS_ENKF_DIAG +++ /dev/null @@ -1,119 +0,0 @@ -#! /usr/bin/env bash - -source "${HOMEgfs}/ush/jjob_header.sh" -e "eobs" -c "base anal eobs analdiag ediag" - -############################################## -# Set variables used in the script -############################################## - -############################################## -# Begin JOB SPECIFIC work -############################################## -# shellcheck disable=SC2153 -GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") -export gPDY=${GDATE:0:8} -export gcyc=${GDATE:8:2} -export GDUMP="gdas" -export GDUMP_ENS="enkf${GDUMP}" - -export CASE=${CASE_ENS} - -export OPREFIX="${RUN/enkf/}.t${cyc}z." -export APREFIX="${RUN}.t${cyc}z." -export GPREFIX="${GDUMP_ENS}.t${gcyc}z." -GPREFIX_DET="${GDUMP}.t${gcyc}z." - -RUN=${RUN/enkf/} YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ - COMIN_OBS:COM_OBS_TMPL -MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ - COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL - -RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ - COMIN_OBS_PREV:COM_OBS_TMPL \ - COMIN_ATMOS_ANALYSIS_DET_PREV:COM_ATMOS_ANALYSIS_TMPL - -MEMDIR="ensstat" RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ - COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL - -export ATMGES_ENSMEAN="${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}ensmean.atm.f006.nc" -if [[ ! -f "${ATMGES_ENSMEAN}" ]]; then - export err=1 - err_exit "FILE MISSING: ATMGES_ENSMEAN == ${ATMGES_ENSMEAN}" -fi - -# Link observational data -export PREPQC="${COMIN_OBS}/${OPREFIX}prepbufr" -if [[ ! -f ${PREPQC} ]]; then - echo "WARNING: Global PREPBUFR FILE ${PREPQC} MISSING" -fi -export TCVITL="${COMIN_OBS}/${OPREFIX}syndata.tcvitals.tm00" -if [[ ${DONST} == "YES" ]]; then - export NSSTBF="${COMIN_OBS}/${OPREFIX}nsstbufr" -fi -export PREPQCPF="${COMIN_OBS}/${OPREFIX}prepbufr.acft_profiles" - -# Guess Bias correction coefficients related to control -export GBIAS=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias.txt -export GBIASPC=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias_pc.txt -export GBIASAIR=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}abias_air.txt -export GRADSTAT=${COMIN_ATMOS_ANALYSIS_DET_PREV}/${GPREFIX_DET}radstat.tar - -# Bias correction coefficients related to ensemble mean -export ABIAS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias.txt" -export ABIASPC="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_pc.txt" -export ABIASAIR="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_air.txt" -export ABIASe="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}abias_int.txt" - -# Diagnostics related to ensemble mean -export GSISTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}gsistat.ensmean.tar" -export CNVSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat.ensmean.tar" -export OZNSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat.ensmean.tar" -export RADSTAT="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat.ensmean.tar" - -# Select observations based on ensemble mean -export RUN_SELECT="YES" -export USE_SELECT="NO" -export SELECT_OBS="${COMOUT_ATMOS_ANALYSIS}/${APREFIX}obsinput.ensmean" - -export DIAG_SUFFIX="_ensmean" -export DIAG_COMPRESS="NO" - -# GSI namelist options specific to eobs -export SETUP_INVOBS="passive_bc=.false.,${SETUP_INVOBS}" - -# Ensure clean stat tarballs for ensemble mean -for fstat in ${CNVSTAT} ${OZNSTAT} ${RADSTAT}; do - if [[ -f "${fstat}" ]]; then - rm -f "${fstat}" - fi -done - -############################################################### -# Run relevant script - -${ANALDIAGSH:-${SCRgfs}/exglobal_diag.sh} && true -export err=$? -if [[ ${err} -ne 0 ]]; then - err_exit -fi - -############################################## -# End JOB SPECIFIC work -############################################## - -############################################## -# Final processing -############################################## -if [[ -e "${pgmout}" ]]; then - cat "${pgmout}" -fi - -########################################## -# Remove the Temporary working directory -########################################## -cd "${DATAROOT}" || true -if [[ "${KEEPDATA}" == "NO" ]]; then - rm -rf "${DATA}" -fi - -exit 0 diff --git a/jobs/JGLOBAL_ATM_PREP_IODA_OBS b/jobs/JGLOBAL_ATM_PREP_IODA_OBS deleted file mode 100755 index ca0006f11b5..00000000000 --- a/jobs/JGLOBAL_ATM_PREP_IODA_OBS +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/env bash - -source "${HOMEgfs}/ush/jjob_header.sh" -e "prepatmiodaobs" -c "base prepatmiodaobs" - -############################################## -# Set variables used in the script -############################################## - -############################################## -# Begin JOB SPECIFIC work -############################################## -# Generate COM variables from templates -YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ - COMOUT_OBS:COM_OBS_TMPL - -############################################################### -# Run relevant script -EXSCRIPT=${BUFR2IODASH:-${USHgfs}/run_bufr2ioda.py} # FIXME: A j-job should call ex-script, not an ush-script! See EE2 standards -${EXSCRIPT} "${PDY}${cyc}" "${RUN}" "${DMPDIR}" "${PARMgfs}/gdas/ioda/bufr2ioda" "${COMOUT_OBS}/" && true -export err=$? -set +x -if [[ ${err} -ne 0 ]]; then - err_exit "Error executing ${EXSCRIPT}" -fi -set_trace - -############################################## -# End JOB SPECIFIC work -############################################## - -############################################## -# Final processing -############################################## -if [[ -e "${pgmout}" ]]; then - cat "${pgmout}" -fi - -exit 0 diff --git a/jobs/JGLOBAL_PREP_OBS_AERO b/jobs/JGLOBAL_PREP_OBS_AERO deleted file mode 100755 index 7b1d19cf084..00000000000 --- a/jobs/JGLOBAL_PREP_OBS_AERO +++ /dev/null @@ -1,45 +0,0 @@ -#! /usr/bin/env bash - -source "${HOMEgfs}/ush/jjob_header.sh" -e "prepobsaero" -c "base prepobsaero" - -############################################## -# Set variables used in the script -############################################## - -YMD=${PDY} HH=${cyc} declare_from_tmpl -rx COMOUT_OBS:COM_OBS_TMPL -YMD=${PDY} HH=${cyc} RUN='gdas' declare_from_tmpl -rx COMIN_OBSPROC:COM_OBSPROC_TMPL - -############################################## -# Begin JOB SPECIFIC work -############################################## - -############################################################### -# Run relevant script - -EXSCRIPT=${GDASPREPAEROOBSPY:-${SCRgfs}/exglobal_prep_obs_aero.py} -${EXSCRIPT} && true -export err=$? -if [[ ${err} -ne 0 ]]; then - err_exit -fi - -############################################## -# End JOB SPECIFIC work -############################################## - -############################################## -# Final processing -############################################## -if [[ -e "${pgmout}" ]]; then - cat "${pgmout}" -fi - -########################################## -# Remove the Temporary working directory -########################################## -cd "${DATAROOT}" || true -if [[ "${KEEPDATA}" == "NO" ]]; then - rm -rf "${DATA}" -fi - -exit 0 diff --git a/modulefiles/gw_run.noaacloud.lua b/modulefiles/gw_run.noaacloud.lua index 4f7da7cd202..99eb924bed1 100644 --- a/modulefiles/gw_run.noaacloud.lua +++ b/modulefiles/gw_run.noaacloud.lua @@ -24,6 +24,6 @@ load(pathJoin("fit2obs", (os.getenv("fit2obs_ver") or "None"))) load(pathJoin("imagemagick", (os.getenv("imagemagick_ver") or "None"))) -setenv("CRTM_FIX", "/contrib/global-workflow-shared-data/fix/crtm/v2.4.0.2") +setenv("CRTM_FIX", "/lustre/fix/crtm/v2.4.0.2") whatis("Description: GFS run environment") diff --git a/modulefiles/gw_setup.gaeac6.lua b/modulefiles/gw_setup.gaeac6.lua index 2967cd13990..942884fd109 100644 --- a/modulefiles/gw_setup.gaeac6.lua +++ b/modulefiles/gw_setup.gaeac6.lua @@ -17,8 +17,6 @@ load("py-jinja2") load("py-pyyaml") load("py-numpy") load("git-lfs") -prepend_path("MODULEPATH", "/ncrc/proj/epic/spack-stack/c6/spack-stack-1.9.2/envs/ue-intel-2023.2.0/install/modulefiles/gcc/12.3.0") -load("gh") unload("cray-libsci") diff --git a/modulefiles/gw_setup.hera.lua b/modulefiles/gw_setup.hera.lua index 7e7debc259a..56f8c50e665 100644 --- a/modulefiles/gw_setup.hera.lua +++ b/modulefiles/gw_setup.hera.lua @@ -16,6 +16,5 @@ load(pathJoin("python", python_ver)) load("py-jinja2") load("py-pyyaml") load("py-numpy") -load("gh") whatis("Description: GFS run setup environment") diff --git a/modulefiles/gw_setup.hercules.lua b/modulefiles/gw_setup.hercules.lua index 8e9870f5b0a..fdc3a02c9d5 100644 --- a/modulefiles/gw_setup.hercules.lua +++ b/modulefiles/gw_setup.hercules.lua @@ -17,6 +17,5 @@ load("py-jinja2") load("py-pyyaml") load("py-numpy") try_load("globus-cli") -load("gh") whatis("Description: GFS run setup environment") diff --git a/modulefiles/gw_setup.orion.lua b/modulefiles/gw_setup.orion.lua index c387a366f0f..1580cc57369 100644 --- a/modulefiles/gw_setup.orion.lua +++ b/modulefiles/gw_setup.orion.lua @@ -19,6 +19,5 @@ load("py-pyyaml") load("py-numpy") load(pathJoin("cmake", cmake_ver)) try_load("globus-cli") -load("gh") whatis("Description: GFS run setup environment") diff --git a/modulefiles/gw_setup.ursa.lua b/modulefiles/gw_setup.ursa.lua index a38c5f53e77..c7706764ff7 100644 --- a/modulefiles/gw_setup.ursa.lua +++ b/modulefiles/gw_setup.ursa.lua @@ -16,6 +16,5 @@ load(pathJoin("cmake", cmake_ver)) load("py-jinja2") load("py-pyyaml") load("py-numpy") -load("gh") whatis("Description: GFS run setup environment") diff --git a/parm/archive/enkf.yaml.j2 b/parm/archive/enkf.yaml.j2 index ab60a2b86dc..73c92aeb806 100644 --- a/parm/archive/enkf.yaml.j2 +++ b/parm/archive/enkf.yaml.j2 @@ -7,8 +7,10 @@ enkf: {% for mem in range(1, nmem_ens + 1) %} - "logs/{{ cycle_YMDH }}/{{ RUN }}_fcst_mem{{ '%03d' % mem }}.log" {% endfor %} - {% for fhr in range(fhmin, fhmax + 1, fhout) %} - - "logs/{{ cycle_YMDH }}/{{ RUN }}_epos{{ '%03d' % (fhr - fhmin) }}.log" + {% set fhrs = range(fhmin, fhmax + fhout, fhout) %} + {% set ngrps = fhrs | length %} + {% for grp in range(0, ngrps) %} + - "logs/{{ cycle_YMDH }}/{{ RUN }}_epos{{ '%03d' % grp }}.log" {% endfor %} {% if not DO_JEDIATMENS %} - "logs/{{ cycle_YMDH }}/{{ RUN }}_echgres.log" @@ -67,10 +69,10 @@ enkf: # Ensemble mean state {% if not DO_JEDIATMENS %} {% set da_stat_files = ["enkfstat.txt", - "gsistat.ensmean.txt", - "cnvstat.ensmean.tar", - "oznstat.ensmean.tar", - "radstat.ensmean.tar"] %} + "gsistat_ensmean.txt", + "cnvstat_ensmean.tar", + "oznstat_ensmean.tar", + "radstat_ensmean.tar"] %} {% set da_conf_files = [] %} {% else %} {% if lobsdiag_forenkf %} @@ -107,7 +109,7 @@ enkf: # soil DA increments {% if DO_GSISOILDA %} {% for fhr in IAUFHRS %} - - "{{ COMIN_ATMOS_ANALYSIS_ENSSTAT | relpath(ROTDIR) }}/{{ head }}increment.sfc.i{{ '%03d' % fhr }}.nc" + - "{{ COMIN_ATMOS_ANALYSIS_ENSSTAT | relpath(ROTDIR) }}/{{ head }}ensmean_increment.sfc.i{{ '%03d' % fhr }}.nc" {% endfor %} {% endif %} diff --git a/parm/archive/enkf_arcdir.yaml.j2 b/parm/archive/enkf_arcdir.yaml.j2 new file mode 100644 index 00000000000..5219f035610 --- /dev/null +++ b/parm/archive/enkf_arcdir.yaml.j2 @@ -0,0 +1,25 @@ +# Variables provided by archive_vars.py: +# - cycle_HH, cycle_YMDH, cycle_YMD, head +# - ARCDIR +# - All COMIN_* paths + +# Ensemble (EnKF) archiving template +# Used for: enkfgdas, enkfgfs, enkfgcafs, enkfgcdas + +# Build head string (e.g., 'gfs.t00z.') +{% set head = RUN + ".t" + cycle_HH + "z." %} + +mkdir: + - "{{ ARCDIR }}" + +copy_opt: + # Ensemble analysis statistics + {% if DO_JEDIATMENS == True %} + - ["{{ COMIN_ATMOS_ANALYSIS_ENSSTAT }}/{{ head }}stat.atm.tar", + "{{ ARCDIR }}/atmensstat.{{ RUN }}.{{ cycle_YMDH }}"] + {% else %} + - ["{{ COMIN_ATMOS_ANALYSIS_ENSSTAT }}/{{ head }}enkfstat.txt", + "{{ ARCDIR }}/enkfstat.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_ANALYSIS_ENSSTAT }}/{{ head }}gsistat_ensmean.txt", + "{{ ARCDIR }}/gsistat.{{ RUN }}.{{ cycle_YMDH }}.ensmean"] + {% endif %} diff --git a/parm/archive/gcafs_arcdir.yaml.j2 b/parm/archive/gcafs_arcdir.yaml.j2 index c4a548c4e94..c7b3d8dff65 100644 --- a/parm/archive/gcafs_arcdir.yaml.j2 +++ b/parm/archive/gcafs_arcdir.yaml.j2 @@ -1,107 +1,58 @@ -{% set cycle_HH = current_cycle | strftime("%H") %} -{% set cycle_YMDH = current_cycle | to_YMDH %} -{% set cycle_YMD = current_cycle | to_YMD %} -{% set head = RUN + ".t" + cycle_HH + "z." %} - -# Select data to store in the ARCDIR and VFYARC from deterministic runs -# This file set will contain all source-destination pairs to send to the FileHandler for copying -{% set file_set = [] %} - -# Declare the VFYARC where Fit2Obs data will be sent -{% set VFYARC = ROTDIR ~ "/vrfyarch" %} +# Variables provided by archive_vars.py: +# - cycle_HH, cycle_YMDH, cycle_YMD, head +# - VFYARC +# - All COMIN_* paths -# Deterministic files -{% if "enkf" not in RUN %} - # Common files to be added to both the gcafs and gcdas keys below - {% set det_files = [] %} +# Deterministic GCAFS/GCDAS archiving template +# Used for: gcafs, gcdas - # Deterministic analysis files (generated for cycled experiments) - {% set det_anl_files = [] %} - - {% if DO_AERO_ANL %} - {% do det_anl_files.append([COMIN_CHEM_ANALYSIS ~ "/" ~ head ~ "aerostat.tgz", - ARCDIR ~ "/aerostat." ~ RUN ~ "." ~ cycle_YMDH ~ ".tgz"]) %} - {% endif %} +# Build head string (e.g., 'gfs.t00z.') +{% set head = RUN + ".t" + cycle_HH + "z." %} - {% if DO_PREP_OBS_AERO == True %} - {% do det_anl_files.append([COMIN_OBS ~ "/" ~ head ~ "aeroobs", - ARCDIR ~ "/aeroobs." ~ RUN ~ "." ~ cycle_YMDH]) %} - {% do det_anl_files.append([COMIN_OBS ~ "/" ~ head ~ "aeroawobs", - ARCDIR ~ "/aeroawobs." ~ RUN ~ "." ~ cycle_YMDH]) %} - {% endif %} +mkdir: + - "{{ ARCDIR }}" +{% if DO_FIT2OBS == True %} + - "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}" +{% endif %} - # GCAFS-specific files - {% set gfs_files = [] %} +copy_req: +{% if RUN == "gcafs" %} + # GCAFS forecast files - REQUIRED {% for fhr in range(0, FHMAX_GFS + 1, FHOUT_GFS) %} - {% do gfs_files.append([COMIN_ATMOS_GRIB_1p00 ~ "/" ~ head ~ "pres_a.1p00.f" ~ '%03d'|format(fhr) ~ ".grib2", - ARCDIR ~ "/pgbf" ~ '%02d'|format(fhr) ~ "." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} + - ["{{ COMIN_ATMOS_GRIB_1p00 }}/{{ head }}pres_a.1p00.f{{ '%03d'|format(fhr) }}.grib2", + "{{ ARCDIR }}/pgbf{{ '%02d'|format(fhr) }}.{{ RUN }}.{{ cycle_YMDH }}.grib2"] {% endfor %} - # GCAFS Fit2Obs data - {% set fit2obs_files = [] %} - {% for fhr in range(0, FHMAX_FITS + 1, 6) %} - {% set sfcfile = "/" + head + "sfc.f" + '%03d'|format(fhr) + ".nc" %} - {% set sigfile = "/" + head + "atm.f" + '%03d'|format(fhr) + ".nc" %} - {% do fit2obs_files.append([COMIN_ATMOS_HISTORY ~ "/" ~ sfcfile, - VFYARC ~ "/" ~ RUN ~ "." ~ cycle_YMD ~ "/" ~ cycle_HH ~ "/" ~ sfcfile ]) %} - {% do fit2obs_files.append([COMIN_ATMOS_HISTORY ~ "/" ~ sigfile, - VFYARC ~ "/" ~ RUN ~ "." ~ cycle_YMD ~ "/" ~ cycle_HH ~ "/" ~ sigfile ]) %} - {% endfor %} + {% if DO_FIT2OBS == True %} + # GCAFS Fit2Obs data - REQUIRED if DO_FIT2OBS is enabled + {% for fhr in range(0, FHMAX_FITS + 1, 6) %} + - ["{{ COMIN_ATMOS_HISTORY }}/{{ head }}sfc.f{{ '%03d'|format(fhr) }}.nc", + "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}/{{ head }}sfc.f{{ '%03d'|format(fhr) }}.nc"] + - ["{{ COMIN_ATMOS_HISTORY }}/{{ head }}atm.f{{ '%03d'|format(fhr) }}.nc", + "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}/{{ head }}atm.f{{ '%03d'|format(fhr) }}.nc"] + {% endfor %} + {% endif %} +{% endif %} - # GCDAS-specific files - {% set gdas_files = [] %} +{% if RUN == "gcdas" %} + # GCDAS forecast files - REQUIRED {% for fhr in range(0, FHMAX + 1, FHOUT) %} - {% do gdas_files.append([COMIN_ATMOS_GRIB_1p00 ~ "/" ~ head ~ "pres_a.1p00.f" ~ '%03d'|format(fhr) ~ ".grib2", - ARCDIR ~ "/pgbf" ~ '%02d'|format(fhr) ~ "." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} + - ["{{ COMIN_ATMOS_GRIB_1p00 }}/{{ head }}pres_a.1p00.f{{ '%03d'|format(fhr) }}.grib2", + "{{ ARCDIR }}/pgbf{{ '%02d'|format(fhr) }}.{{ RUN }}.{{ cycle_YMDH }}.grib2"] {% endfor %} +{% endif %} - # Now append the necessary file pairs to file_set - # Common deterministic files - {% set file_set = file_set + det_files %} - {% if MODE == "cycled" %} - {% set file_set = file_set + det_anl_files %} - {% endif %} - - # Run-specific deterministic files - {% if RUN == "gcafs" %} - {% set file_set = file_set + gfs_files %} - # Fit2Obs files - {% if DO_FIT2OBS == True %} - {% set file_set = file_set + fit2obs_files %} - {% endif %} - {% elif RUN == "gcdas" %} - {% set file_set = file_set + gdas_files %} +{% if MODE == "cycled" %} + # Deterministic analysis files (cycled mode only) - REQUIRED + {% if DO_AERO_ANL %} + - ["{{ COMIN_CHEM_ANALYSIS }}/{{ head }}aerostat.tgz", + "{{ ARCDIR }}/aerostat.{{ RUN }}.{{ cycle_YMDH }}.tgz"] {% endif %} -{% else %} # End of deterministic files - - # Ensemble analysis files - {% set enkf_files = [] %} - {% if DO_JEDIATMENS == True %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "atmensstat", - ARCDIR ~ "/atmensstat." ~ RUN ~ "." ~ cycle_YMDH ]) %} - {% else %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "enkfstat.txt", - ARCDIR ~ "/enkfstat." ~ RUN ~ "." ~ cycle_YMDH ]) %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "gsistat.ensmean.txt", - ARCDIR ~ "/gsistat." ~ RUN ~ "." ~ cycle_YMDH ~ ".ensmean"]) %} + {% if DO_PREP_OBS_AERO == True %} + - ["{{ COMIN_OBS }}/{{ head }}aeroobs", + "{{ ARCDIR }}/aeroobs.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_OBS }}/{{ head }}aeroawobs", + "{{ ARCDIR }}/aeroawobs.{{ RUN }}.{{ cycle_YMDH }}"] {% endif %} - - # Construct the final file set - {% set file_set = file_set + enkf_files %} - {% endif %} - - -# Actually write the yaml -mkdir: - - "{{ ARCDIR }}" - - {% if DO_FIT2OBS == True %} - - "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}" - {% endif %} - -copy: - {% for source_dest_pair in file_set %} - - {{ source_dest_pair }} - {% endfor %} diff --git a/parm/archive/gdas.yaml.j2 b/parm/archive/gdas.yaml.j2 index a3f764a96fc..c0be51bad2a 100644 --- a/parm/archive/gdas.yaml.j2 +++ b/parm/archive/gdas.yaml.j2 @@ -8,7 +8,6 @@ gdas: - "logs/{{ cycle_YMDH }}/{{ RUN }}_atmanlprod.log" - "logs/{{ cycle_YMDH }}/{{ RUN }}_prep.log" {% if DO_JEDIATMVAR %} - - "logs/{{ cycle_YMDH }}/{{ RUN }}_prepatmiodaobs.log" - "logs/{{ cycle_YMDH }}/{{ RUN }}_atmanlinit.log" - "logs/{{ cycle_YMDH }}/{{ RUN }}_atmanlprod.log" - "logs/{{ cycle_YMDH }}/{{ RUN }}_atmanlfinal.log" @@ -57,8 +56,13 @@ gdas: # Analysis netCDF (raw) data {% if DO_JEDIATMVAR %} + {% if ATMINC_GRID == 'gaussian' %} + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.atm.a006.nc" + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.sfc.a006.nc" + {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_analysis.atm.a006.nc" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_analysis.sfc.a006.nc" + {% endif %} {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.atm.a006.nc" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.sfc.a006.nc" @@ -82,11 +86,10 @@ gdas: - "{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}anlvar.atm.yaml" - "{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}anlvar.fv3.atm.yaml" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}stat.atm.tar" + - "{{ COMIN_ATMOS_ANLMON | relpath(ROTDIR) }}/{{ head }}atmos_analysis.ioda_hofx_stats.tar.gz" {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}gsistat.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}cnvstat.tar" - - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}oznstat.tar" - - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}radstat.tar" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias_air.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias_pc.txt" @@ -178,6 +181,9 @@ gdas: - "{{ COMIN_ATMOS_MASTER | relpath(ROTDIR) }}/{{ head }}master.f006.grib2" optional: {% if MODE == "cycled" %} + # Ozone and Radiance diagnostic files may not always be created + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}oznstat.tar" + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}radstat.tar" # Radiance verification (only created if there are problems) {% if DO_VERFRAD %} - "{{ COMIN_ATMOS_RADMON | relpath(ROTDIR) }}/bad_diag.{{ cycle_YMDH }}" diff --git a/parm/archive/gdas_restarta.yaml.j2 b/parm/archive/gdas_restarta.yaml.j2 index b581c76b986..94074d2239b 100644 --- a/parm/archive/gdas_restarta.yaml.j2 +++ b/parm/archive/gdas_restarta.yaml.j2 @@ -4,7 +4,7 @@ gdas_restarta: target: "{{ ATARDIR }}/{{ cycle_YMDH }}/gdas_restarta.tar" required: # Deterministic analysis increments - {% if DO_JEDIATMVAR %} + {% if DO_JEDIATMVAR and not (ATMINC_GRID == 'gaussian') %} {% for iaufhr in IAUFHRS %} {% for itile in range(6) %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_increment.atm.i{{ "%03d" % iaufhr }}.tile{{ itile+1 }}.nc" @@ -43,11 +43,10 @@ gdas_restarta: - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias_air.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias_pc.txt" - - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}radstat.tar" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}cnvstat.tar" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}abias_int.txt" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.dtf.a006.nc" - - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}increment.done.txt" + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.done.txt" {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}rad_varbc_params.tar" {% endif %} @@ -56,3 +55,5 @@ gdas_restarta: - "{{ COMIN_OBS | relpath(ROTDIR) }}/{{ head }}nsstbufr" - "{{ COMIN_OBS | relpath(ROTDIR) }}/{{ head }}prepbufr" - "{{ COMIN_OBS | relpath(ROTDIR) }}/{{ head }}prepbufr.acft_profiles" + optional: + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}radstat.tar" diff --git a/parm/archive/gefs_arcdir.yaml.j2 b/parm/archive/gefs_arcdir.yaml.j2 index 2f8da8bd444..8be329861ec 100644 --- a/parm/archive/gefs_arcdir.yaml.j2 +++ b/parm/archive/gefs_arcdir.yaml.j2 @@ -1,36 +1,20 @@ -{% set cycle_HH = current_cycle | strftime("%H") %} -{% set cycle_YMDH = current_cycle | to_YMDH %} -{% set cycle_YMD = current_cycle | to_YMD %} -{% set head = RUN + ".t" + cycle_HH + "z." %} - -# Declare the GEFS_ARCH where atmos data will be sent -{% set GEFS_ARCH = ROTDIR ~ "/gefsarch" %} - -{% set file_set = [] %} +# Variables provided by archive_vars.py: +# - cycle_HH, cycle_YMDH, cycle_YMD, head +# - VFYARC (archive directory) +# - COMIN_ATMOS_ENSSTAT_1p00 (calculated in Python with MEMDIR='ensstat') -{% set tmpl_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':cycle_YMD, - '${HH}':cycle_HH, - '${GRID}': '1p00', - '${MEMDIR}': 'ensstat' }) %} +# Build head string (e.g., 'gfs.t00z.') +{% set head = RUN + ".t" + cycle_HH + "z." %} -{% set COMIN_ATMOS_ENSSTAT_1p00 = COM_ATMOS_GRIB_GRID_TMPL | replace_tmpl(tmpl_dict) %} +# Create directories first +mkdir: + - "{{ VFYARC }}" -# Select ensstat files to copy to the arcdir -{% set ensstat_files = [] %} -{% if path_exists(COMIN_ATMOS_ENSSTAT_1p00) %} +# Define all source-destination pairs for archiving +# Use copy_req for files that MUST exist (raise error if missing) +copy_req: + # GEFS ensemble mean forecast files - REQUIRED {% for fhr in range(FHMIN_GFS, FHMAX_GFS + FHOUT_GFS, FHOUT_GFS) %} - {% do ensstat_files.append([COMIN_ATMOS_ENSSTAT_1p00 ~ "/" ~ head ~ "mean.pres_." ~ - "1p00" ~ ".f" ~ '%03d'|format(fhr) ~ ".grib2", - GEFS_ARCH]) %} + - ["{{ COMIN_ATMOS_ENSSTAT_1p00 }}/{{ head }}mean.pres_.1p00.f{{ '%03d'|format(fhr) }}.grib2", + "{{ VFYARC }}/{{ head }}mean.pres_.1p00.f{{ '%03d'|format(fhr) }}.grib2"] {% endfor %} -{% endif %} -{% set file_set = ensstat_files %} -# Actually write the yaml -mkdir: - - "{{ GEFS_ARCH }}" -copy: - {% for source_dest_pair in file_set %} - - {{ source_dest_pair }} - {% endfor %} diff --git a/parm/archive/gfs_arcdir.yaml.j2 b/parm/archive/gfs_arcdir.yaml.j2 index 82402cdb54f..9fffe5a1b7e 100644 --- a/parm/archive/gfs_arcdir.yaml.j2 +++ b/parm/archive/gfs_arcdir.yaml.j2 @@ -1,154 +1,108 @@ -{% set cycle_HH = current_cycle | strftime("%H") %} -{% set cycle_YMDH = current_cycle | to_YMDH %} -{% set cycle_YMD = current_cycle | to_YMD %} -{% set head = RUN + ".t" + cycle_HH + "z." %} +# Variables provided by archive_vars.py: +# - cycle_HH, cycle_YMDH, cycle_YMD, head +# - VFYARC, GEFS_ARCH +# - All COMIN_* paths -# Select data to store in the ARCDIR and VFYARC from deterministic runs -# This file set will contain all source-destination pairs to send to the FileHandler for copying -{% set file_set = [] %} +# Deterministic GFS/GDAS archiving template +# Used for: gfs, gdas -# Declare the VFYARC where Fit2Obs data will be sent -{% set VFYARC = ROTDIR ~ "/vrfyarch" %} +# Build head string (e.g., 'gfs.t00z.') +{% set head = RUN + ".t" + cycle_HH + "z." %} -# Deterministic files -{% if "enkf" not in RUN %} - # Common files to be added to both the gfs and gdas keys below - {% set det_files = [] %} - # Cyclone forecasts, produced for both gdas and gfs cycles - ## Only created if tracking is on and there were systems to track - {% if path_exists(COMIN_ATMOS_TRACK ~ "/atcfunix." ~ RUN ~ "." ~ cycle_YMDH) %} - {% do det_files.append([COMIN_ATMOS_TRACK ~ "/atcfunix." ~ RUN ~ "." ~ cycle_YMDH, - ARCDIR ~"/atcfunix." ~ RUN ~ "." ~ cycle_YMDH ]) %} - {% do det_files.append([COMIN_ATMOS_TRACK ~ "/atcfunixp." ~ RUN ~ "." ~ cycle_YMDH, - ARCDIR ~ "/atcfunixp." ~ RUN ~ "." ~ cycle_YMDH]) %} - {% endif %} +mkdir: + - "{{ ARCDIR }}" +{% if DO_FIT2OBS == True %} + - "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}" +{% endif %} - # Cyclone tracking data - {% for basin in ["epac", "natl"] %} - {% if path_exists(COMIN_ATMOS_TRACK + "/" + basin) %} - {% do det_files.append([COMIN_ATMOS_TRACK ~ "/" ~ basin, - ARCDIR ~ "/" ~ basin ]) %} - {% endif %} - {% endfor %} +copy_opt: +# Cyclone tracking files (optional - only exist when storms are tracked) + - ["{{ COMIN_ATMOS_TRACK }}/atcfunix.{{ RUN }}.{{ cycle_YMDH }}", + "{{ ARCDIR }}/atcfunix.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_TRACK }}/atcfunixp.{{ RUN }}.{{ cycle_YMDH }}", + "{{ ARCDIR }}/atcfunixp.{{ RUN }}.{{ cycle_YMDH }}"] + +# Cyclone tracking data by basin +{% for basin in ["epac", "natl"] %} + - ["{{ COMIN_ATMOS_TRACK }}/{{ basin }}", + "{{ ARCDIR }}/{{ basin }}"] +{% endfor %} - # Deterministic analysis files (generated for cycled experiments) - {% set det_anl_files = [] %} - # Analysis data (if we are running in cycled mode) - {% do det_anl_files.append([COMIN_ATMOS_GRIB_1p00 ~ "/" ~ head ~ "pres_a.1p00.analysis.grib2", - ARCDIR ~ "/pgbanl." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} +{% if MODE == "cycled" %} + # Deterministic analysis files (cycled mode only) + - ["{{ COMIN_ATMOS_GRIB_1p00 }}/{{ head }}pres_a.1p00.analysis.grib2", + "{{ ARCDIR }}/pgbanl.{{ RUN }}.{{ cycle_YMDH }}.grib2"] {% if DO_JEDIATMVAR == True %} - {% do det_anl_files.append([COMIN_ATMOS_ANALYSIS ~ "/" ~ head ~ "stat.atm.tar", - ARCDIR ~ "/atmstat." ~ RUN ~ "." ~ cycle_YMDH ]) %} + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}stat.atm.tar", + "{{ ARCDIR }}/atmstat.{{ RUN }}.{{ cycle_YMDH }}"] {% else %} - {% do det_anl_files.append([COMIN_ATMOS_ANALYSIS ~ "/" ~ head ~ "gsistat.txt", - ARCDIR ~ "/gsistat." ~ RUN ~ "." ~ cycle_YMDH ]) %} + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}gsistat.txt", + "{{ ARCDIR }}/gsistat.{{ RUN }}.{{ cycle_YMDH }}"] {% endif %} {% if DO_JEDISNOWDA == True %} - {% do det_anl_files.append([COMIN_SNOW_ANALYSIS ~ "/" ~ head ~ "snow_analysis.ioda_hofx.tar", - ARCDIR ~ "/snowstat." ~ RUN ~ "." ~ cycle_YMDH ~ ".tar"]) %} + - ["{{ COMIN_SNOW_ANALYSIS }}/{{ head }}snow_analysis.ioda_hofx.tar", + "{{ ARCDIR }}/snowstat.{{ RUN }}.{{ cycle_YMDH }}.tar"] {% endif %} {% if DO_AERO_ANL %} - {% do det_anl_files.append([COMIN_CHEM_ANALYSIS ~ "/" ~ head ~ "aerostat.tgz", - ARCDIR ~ "/aerostat." ~ RUN ~ "." ~ cycle_YMDH ~ ".tgz"]) %} + - ["{{ COMIN_CHEM_ANALYSIS }}/{{ head }}aerostat.tgz", + "{{ ARCDIR }}/aerostat.{{ RUN }}.{{ cycle_YMDH }}.tgz"] {% endif %} {% if DO_PREP_OBS_AERO == True %} - {% do det_anl_files.append([COMIN_OBS ~ "/" ~ head ~ "aeroobs", - ARCDIR ~ "/aeroobs." ~ RUN ~ "." ~ cycle_YMDH]) %} - {% do det_anl_files.append([COMIN_OBS ~ "/" ~ head ~ "aeroawobs", - ARCDIR ~ "/aeroawobs." ~ RUN ~ "." ~ cycle_YMDH]) %} + - ["{{ COMIN_OBS }}/{{ head }}aeroobs", + "{{ ARCDIR }}/aeroobs.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_OBS }}/{{ head }}aeroawobs", + "{{ ARCDIR }}/aeroawobs.{{ RUN }}.{{ cycle_YMDH }}"] {% endif %} +{% endif %} - # GFS-specific files - {% set gfs_files = [] %} +{% if RUN == "gfs" %} + # GFS forecast files {% for fhr in range(0, FHMAX_GFS + 1, FHOUT_GFS) %} - {% do gfs_files.append([COMIN_ATMOS_GRIB_1p00 ~ "/" ~ head ~ "pres_a.1p00.f" ~ '%03d'|format(fhr) ~ ".grib2", - ARCDIR ~ "/pgbf" ~ '%02d'|format(fhr) ~ "." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} + - ["{{ COMIN_ATMOS_GRIB_1p00 }}/{{ head }}pres_a.1p00.f{{ '%03d'|format(fhr) }}.grib2", + "{{ ARCDIR }}/pgbf{{ '%02d'|format(fhr) }}.{{ RUN }}.{{ cycle_YMDH }}.grib2"] {% endfor %} - # Cyclone genesis data (only present if there are storms) - {% if path_exists(COMIN_ATMOS_GENESIS ~ "/storms.gfso.atcf_gen." ~ cycle_YMDH) %} - {% do gfs_files.append([COMIN_ATMOS_GENESIS ~ "/storms.gfso.atcf_gen." ~ cycle_YMDH, - ARCDIR ~ "/storms.gfso.atcf_gen." ~ cycle_YMDH ]) %} - {% do gfs_files.append([COMIN_ATMOS_GENESIS ~ "/storms.gfso.atcf_gen.altg." ~ cycle_YMDH, - ARCDIR ~ "/storms.gfso.atcf_gen.altg." ~ cycle_YMDH ]) %} - {% endif %} - - {% if path_exists(COMIN_ATMOS_GENESIS ~ "/trak.gfso.atcfunix." ~ cycle_YMDH) %} - {% do gfs_files.append([COMIN_ATMOS_GENESIS ~ "/trak.gfso.atcfunix." ~ cycle_YMDH, - ARCDIR ~ "/trak.gfso.atcfunix." ~ cycle_YMDH ]) %} - {% do gfs_files.append([COMIN_ATMOS_GENESIS ~ "/trak.gfso.atcfunix.altg." ~ cycle_YMDH, - ARCDIR ~ "/trak.gfso.atcfunix.altg." ~ cycle_YMDH ]) %} - {% endif %} + - ["{{ COMIN_ATMOS_GENESIS }}/storms.gfso.atcf_gen.{{ cycle_YMDH }}", + "{{ ARCDIR }}/storms.gfso.atcf_gen.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_GENESIS }}/storms.gfso.atcf_gen.altg.{{ cycle_YMDH }}", + "{{ ARCDIR }}/storms.gfso.atcf_gen.altg.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_GENESIS }}/trak.gfso.atcfunix.{{ cycle_YMDH }}", + "{{ ARCDIR }}/trak.gfso.atcfunix.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_GENESIS }}/trak.gfso.atcfunix.altg.{{ cycle_YMDH }}", + "{{ ARCDIR }}/trak.gfso.atcfunix.altg.{{ cycle_YMDH }}"] + {% if DO_FIT2OBS == True %} # GFS Fit2Obs data - {% set fit2obs_files = [] %} - {% for fhr in range(0, FHMAX_FITS + 1, 6) %} - {% set sfcfile = "/" + head + "sfc.f" + '%03d'|format(fhr) + ".nc" %} - {% set sigfile = "/" + head + "atm.f" + '%03d'|format(fhr) + ".nc" %} - {% do fit2obs_files.append([COMIN_ATMOS_HISTORY ~ "/" ~ sfcfile, - VFYARC ~ "/" ~ RUN ~ "." ~ cycle_YMD ~ "/" ~ cycle_HH ~ "/" ~ sfcfile ]) %} - {% do fit2obs_files.append([COMIN_ATMOS_HISTORY ~ "/" ~ sigfile, - VFYARC ~ "/" ~ RUN ~ "." ~ cycle_YMD ~ "/" ~ cycle_HH ~ "/" ~ sigfile ]) %} - {% endfor %} + {% for fhr in range(0, FHMAX_FITS + 1, 6) %} + {% set sfcfile = head + "sfc.f" + '%03d'|format(fhr) + ".nc" %} + {% set sigfile = head + "atm.f" + '%03d'|format(fhr) + ".nc" %} + - ["{{ COMIN_ATMOS_HISTORY }}/{{ sfcfile }}", + "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}/{{ sfcfile }}"] + - ["{{ COMIN_ATMOS_HISTORY }}/{{ sigfile }}", + "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}/{{ sigfile }}"] + {% endfor %} + {% endif %} - # GDAS-specific files - {% set gdas_files = [] %} +{% elif RUN == "gdas" %} + # GDAS forecast files {% for fhr in range(0, FHMAX + 1, FHOUT) %} - {% do gdas_files.append([COMIN_ATMOS_GRIB_1p00 ~ "/" ~ head ~ "pres_a.1p00.f" ~ '%03d'|format(fhr) ~ ".grib2", - ARCDIR ~ "/pgbf" ~ '%02d'|format(fhr) ~ "." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} + - ["{{ COMIN_ATMOS_GRIB_1p00 }}/{{ head }}pres_a.1p00.f{{ '%03d'|format(fhr) }}.grib2", + "{{ ARCDIR }}/pgbf{{ '%02d'|format(fhr) }}.{{ RUN }}.{{ cycle_YMDH }}.grib2"] {% endfor %} - # Now append the necessary file pairs to file_set - # Common deterministic files - {% set file_set = file_set + det_files %} - {% if MODE == "cycled" %} - {% set file_set = file_set + det_anl_files %} - {% endif %} - - # Run-specific deterministic files - {% if RUN == "gfs" %} - {% set file_set = file_set + gfs_files %} - # Fit2Obs files - {% if DO_FIT2OBS == True %} - {% set file_set = file_set + fit2obs_files %} - {% endif %} - {% elif RUN == "gdas" %} - {% set file_set = file_set + gdas_files %} - {% endif %} - -{% else %} # End of deterministic files - - # Ensemble analysis files - {% set enkf_files = [] %} - {% if DO_JEDIATMENS == True %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "stat.atm.tar", - ARCDIR ~ "/atmensstat." ~ RUN ~ "." ~ cycle_YMDH ]) %} - {% else %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "enkfstat.txt", - ARCDIR ~ "/enkfstat." ~ RUN ~ "." ~ cycle_YMDH ]) %} - {% do enkf_files.append([COMIN_ATMOS_ANALYSIS_ENSSTAT ~ "/" ~ head ~ "gsistat.ensmean.txt", - ARCDIR ~ "/gsistat." ~ RUN ~ "." ~ cycle_YMDH ~ ".ensmean"]) %} - {% endif %} - - # Construct the final file set - {% set file_set = file_set + enkf_files %} - + # GDAS bias correction files + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}abias.txt", + "{{ ARCDIR }}/abias.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}abias_pc.txt", + "{{ ARCDIR }}/abias_pc.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}abias_air.txt", + "{{ ARCDIR }}/abias_air.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}abias_int.txt", + "{{ ARCDIR }}/abias_int.{{ RUN }}.{{ cycle_YMDH }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ head }}analysis.dtf.a006.nc", + "{{ ARCDIR }}/dtfanl.{{ RUN }}.{{ cycle_YMDH }}.nc"] {% endif %} - - -# Actually write the yaml -mkdir: - - "{{ ARCDIR }}" - - {% if DO_FIT2OBS == True %} - - "{{ VFYARC }}/{{ RUN }}.{{ cycle_YMD }}/{{ cycle_HH }}" - {% endif %} - -copy: - {% for source_dest_pair in file_set %} - - {{ source_dest_pair }} - {% endfor %} diff --git a/parm/archive/gfs_downstream.yaml.j2 b/parm/archive/gfs_downstream.yaml.j2 index 040292b7dd8..6bc663cb5b4 100644 --- a/parm/archive/gfs_downstream.yaml.j2 +++ b/parm/archive/gfs_downstream.yaml.j2 @@ -3,7 +3,7 @@ gfs_downstream: name: "GFS_DOWNSTREAM" target: "{{ ATARDIR }}/{{ cycle_YMDH }}/gfs_downstream.tar" required: - {% if DO_GEMPAK %} + {% if DO_GEMPAK and DO_BUFRSND %} - "{{ COMIN_ATMOS_GEMPAK | relpath(ROTDIR) }}/gfs_{{ cycle_YMDH }}.sfc.bufr" - "{{ COMIN_ATMOS_GEMPAK | relpath(ROTDIR) }}/gfs_{{ cycle_YMDH }}.soundings.bufr" {% endif %} diff --git a/parm/archive/gfs_netcdfa.yaml.j2 b/parm/archive/gfs_netcdfa.yaml.j2 index 0b9a1b12b02..7d23ad30a77 100644 --- a/parm/archive/gfs_netcdfa.yaml.j2 +++ b/parm/archive/gfs_netcdfa.yaml.j2 @@ -4,14 +4,19 @@ gfs_netcdfa: target: "{{ ATARDIR }}/{{ cycle_YMDH }}/gfs_netcdfa.tar" required: {% if DO_JEDIATMVAR %} + {% if ATMINC_GRID == 'gaussian' %} + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.atm.a006.nc" + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.sfc.a006.nc" + {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_analysis.atm.a006.nc" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_analysis.sfc.a006.nc" + {% endif %} {% else %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.atm.a006.nc" - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.sfc.a006.nc" {% endif %} {% for iaufhr in IAUFHRS %} - {% if DO_JEDIATMVAR %} + {% if DO_JEDIATMVAR and not (ATMINC_GRID == 'gaussian') %} {% for itile in range(6) %} - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}jedi_increment.atm.i{{ "%03d" % iaufhr }}.tile{{ itile+1 }}.nc" {% endfor %} diff --git a/parm/archive/gfsocean_analysis.yaml.j2 b/parm/archive/gfsocean_analysis.yaml.j2 index dd94b3e8019..d8a84c07c4a 100644 --- a/parm/archive/gfsocean_analysis.yaml.j2 +++ b/parm/archive/gfsocean_analysis.yaml.j2 @@ -23,7 +23,16 @@ gfsocean_analysis: - '{{ COMIN_ICE_BMATRIX | relpath(ROTDIR) }}/{{ head }}bkgerr_parametric_stddev.nc' # runtime configs - - '{{ COMIN_CONF | relpath(ROTDIR) }}/*.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}soca_setcorscales.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}soca_chgres.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}soca_diagb.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}gridgen.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}soca_vtscales.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}bmat_fields_metadata.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/var.yaml' + # soca_parameters_diffusion_vt, and soca_parameters_diffusion_hz when present + - '{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}soca_parameters_diffusion_??.yaml' + - '{{ COMIN_CONF | relpath(ROTDIR) }}/soca_incpostproc.yaml' optional: # obs space diags - '{{ COMIN_OCEAN_ANALYSIS | relpath(ROTDIR) }}/diags/{{ head }}ocn.*.stats.csv' diff --git a/parm/archive/ice_native.yaml.j2 b/parm/archive/ice_native.yaml.j2 new file mode 100644 index 00000000000..546650a0225 --- /dev/null +++ b/parm/archive/ice_native.yaml.j2 @@ -0,0 +1,7 @@ +ice_native: + name: "ICE_NATIVE" + target: "{{ ATARDIR }}/{{ cycle_YMDH }}/ice_native_subset.tar" + required: + {% for fhr in range(FHOUT_ICE_GFS, FHMAX_GFS + FHOUT_ICE_GFS, FHOUT_ICE_GFS) %} + - "{{ COMIN_ICE_NETCDF | relpath(ROTDIR) }}/native/{{ RUN }}.t{{ cycle_HH }}z.native.f{{ '%03d' % fhr }}.nc" + {% endfor %} diff --git a/parm/archive/ocean_native.yaml.j2 b/parm/archive/ocean_native.yaml.j2 new file mode 100644 index 00000000000..51c039c06bb --- /dev/null +++ b/parm/archive/ocean_native.yaml.j2 @@ -0,0 +1,7 @@ +ocean_native: + name: "OCEAN_NATIVE" + target: "{{ ATARDIR }}/{{ cycle_YMDH }}/ocean_native_subset.tar" + required: + {% for fhr in range(FHOUT_OCN_GFS, FHMAX_GFS + FHOUT_OCN_GFS, FHOUT_OCN_GFS) %} + - "{{ COMIN_OCEAN_NETCDF | relpath(ROTDIR) }}/native/{{ RUN }}.t{{ cycle_HH }}z.native.f{{ '%03d' % fhr }}.nc" + {% endfor %} diff --git a/parm/fetch/gcafs_ATMA_gdas-anl_msu.yaml.j2 b/parm/fetch/gcafs_ATMA_gdas-anl_msu.yaml.j2 new file mode 100644 index 00000000000..f7175996d14 --- /dev/null +++ b/parm/fetch/gcafs_ATMA_gdas-anl_msu.yaml.j2 @@ -0,0 +1,12 @@ +{% set cycle_YMDH = current_cycle | to_YMDH %} +{% set cycle_Y = current_cycle | strftime("%Y") %} +{% set cycle_YM = current_cycle | strftime("%Y%m") %} +{% set cycle_YMD = current_cycle | to_YMD %} +{% set cycle_HH = current_cycle | strftime("%H") %} +target: + tarball: "/work2/noaa/global/role-global/data/GCAFS_ExtData/com_gfs_{{ gdas_version }}_gdas.{{ cycle_YMD }}_{{ cycle_HH }}.gdas_nc.tar" + on_hpss: False + contents: + # Atmospheric analysis + - ./gdas.{{ cycle_YMD }}/{{ cycle_HH }}/atmos/gdas.t{{ cycle_HH }}z.atmanl.nc + destination: "{{ ROTDIR }}" diff --git a/parm/fetch/gcafs_ATMA_gdas-dtfanl_msu.yaml.j2 b/parm/fetch/gcafs_ATMA_gdas-dtfanl_msu.yaml.j2 new file mode 100644 index 00000000000..30fe9534a1d --- /dev/null +++ b/parm/fetch/gcafs_ATMA_gdas-dtfanl_msu.yaml.j2 @@ -0,0 +1,12 @@ +{% set cycle_YMDH = current_cycle | to_YMDH %} +{% set cycle_Y = current_cycle | strftime("%Y") %} +{% set cycle_YM = current_cycle | strftime("%Y%m") %} +{% set cycle_YMD = current_cycle | to_YMD %} +{% set cycle_HH = current_cycle | strftime("%H") %} +target: + tarball: "/work2/noaa/global/role-global/data/GCAFS_ExtData/com_gfs_{{ gdas_version }}_gdas.{{ cycle_YMD }}_{{ cycle_HH }}.gdas_restart.tar" + on_hpss: False + contents: + # NSST analysis + - ./gdas.{{ cycle_YMD }}/{{ cycle_HH }}/atmos/gdas.t{{ cycle_HH }}z.dtfanl.nc + destination: "{{ ROTDIR }}" diff --git a/parm/post/oceanice_products_gefs.yaml b/parm/post/oceanice_products_gefs.yaml index b2651fdc331..a797efa6364 100644 --- a/parm/post/oceanice_products_gefs.yaml +++ b/parm/post/oceanice_products_gefs.yaml @@ -1,16 +1,17 @@ ocnicepost: executable: "ocnicepost.x" namelist: - write_grib2: True - write_netcdf: False + write_grib2: {{ write_grib2 }} + write_netcdf: {{ write_netcdf }} debug: False fix_data: mkdir: - "{{ DATA }}" copy: - - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ PARMgfs }}/post/ocnicepost.nml.jinja2", "{{ DATA }}/"] - - ["{{ PARMgfs }}/post/{{ component }}_gefs.csv", "{{ DATA }}/{{ component }}.csv"] + {% if write_grib2 or write_netcdf %} + - ["{{ PARMgfs }}/post/{{ component }}_{{ RUN }}.csv", "{{ DATA }}/{{ component }}.csv"] + - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Bu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cv.to.Ct.bilinear.nc", "{{ DATA }}/"] @@ -19,6 +20,7 @@ ocnicepost: - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Ct.to.rect.{{ grid }}.conserve.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/template.global.{{ grid }}.gb2", "{{ DATA }}/"] {% endfor %} + {% endif %} ocean: namelist: @@ -28,11 +30,15 @@ ocean: cosvar: "cos_rot" angvar: "" {% if model_grid == 'mx025' or model_grid == 'mx050' or model_grid == 'mx100' %} - ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267, 309, 374, 467, 594, 757, 960, 1204, 1490, 1817, 2184, 2587, 3024, 3489, 3977, 4481] + ocean_levels: [1, 3, 5, 10, 20, 30, 50, 100, 200, 500, 1000] {% elif model_grid == 'mx500' %} - ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267] + ocean_levels: [2.5, 7.5, 12.5, 17.5, 116] {% endif %} - subset: ['SSH', 'SST', 'SSS', 'speed', 'MLD_003', 'latent', 'sensible', 'SW', 'LW', 'LwLatSens', 'Heat_PmE', 'SSU', 'SSV', 'taux', 'tauy', 'temp', 'tob', 'so', 'uo', 'vo'] + subset: + variables: ['SSH', 'SST', 'SSS', 'speed', 'MLD_003', 'latent', 'sensible', 'SW', 'LW', 'LwLatSens', 'Heat_PmE', 'SSU', 'SSV', 'taux', 'tauy', 'temp', 'tob', 'so', 'uo', 'vo'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - ["{{ COMIN_OCEAN_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ocean.nc"] @@ -40,14 +46,23 @@ ocean: mkdir: - "{{ COMOUT_OCEAN_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} - "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ocean.{{ grid }}.nc", "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ocean.{{ grid }}.grib2", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ocean.{{ grid }}.grib2.idx", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} ice: @@ -57,7 +72,11 @@ ice: sinvar: "" cosvar: "" angvar: "ANGLET" - subset: ['hi_1', 'hs_1', 'aice_1', 'Tsfc_1', 'uvel_1', 'vvel_1', 'frzmlt_1', 'albsni_1'] + subset: + variables: ['hi_1', 'hs_1', 'aice_1', 'Tsfc_1', 'uvel_1', 'vvel_1', 'frzmlt_1', 'albsni_1', 'tmask', 'tarea'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - ["{{ COMIN_ICE_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ice.nc"] @@ -65,12 +84,21 @@ ice: mkdir: - "{{ COMOUT_ICE_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} - "{{ COMOUT_ICE_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_ICE_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ice.{{ grid }}.nc", "{{ COMOUT_ICE_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ice.{{ grid }}.grib2", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ice.{{ grid }}.grib2.idx", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} diff --git a/parm/post/oceanice_products_gfs.yaml b/parm/post/oceanice_products_gfs.yaml index 9604b71560e..6d8355fb491 100644 --- a/parm/post/oceanice_products_gfs.yaml +++ b/parm/post/oceanice_products_gfs.yaml @@ -1,16 +1,17 @@ ocnicepost: executable: "ocnicepost.x" namelist: - write_grib2: True - write_netcdf: False + write_grib2: {{ write_grib2 }} + write_netcdf: {{ write_netcdf }} debug: False fix_data: mkdir: - "{{ DATA }}" copy: - - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ PARMgfs }}/post/ocnicepost.nml.jinja2", "{{ DATA }}/"] - - ["{{ PARMgfs }}/post/{{ component }}_gfs.csv", "{{ DATA }}/{{ component }}.csv"] + {% if write_grib2 or write_netcdf %} + - ["{{ PARMgfs }}/post/{{ component }}_{{ RUN }}.csv", "{{ DATA }}/{{ component }}.csv"] + - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Bu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cv.to.Ct.bilinear.nc", "{{ DATA }}/"] @@ -19,6 +20,7 @@ ocnicepost: - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Ct.to.rect.{{ grid }}.conserve.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/template.global.{{ grid }}.gb2", "{{ DATA }}/"] {% endfor %} + {% endif %} ocean: namelist: @@ -28,25 +30,39 @@ ocean: cosvar: "cos_rot" angvar: "" {% if model_grid == 'mx025' or model_grid == 'mx050' or model_grid == 'mx100' %} - ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267, 309, 374, 467, 594, 757, 960, 1204, 1490, 1817, 2184, 2587, 3024, 3489, 3977, 4481] + ocean_levels: [1, 3, 5, 10, 20, 30, 50, 100, 200, 500, 1000] {% elif model_grid == 'mx500' %} - ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267] + ocean_levels: [2.5, 7.5, 12.5, 17.5, 116] {% endif %} - subset: ['SSH', 'SST', 'SSS', 'speed', 'MLD_003', 'latent', 'sensible', 'SW', 'LW', 'LwLatSens', 'Heat_PmE', 'SSU', 'SSV', 'taux', 'tauy', 'temp', 'so', 'uo', 'vo'] + subset: + variables: ['SSH', 'MLD_003', 'SST', 'SSS', 'temp', 'tob', 'so', 'uo', 'vo'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - - ["{{ COMIN_OCEAN_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.6hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ocean.nc"] + - ["{{ COMIN_OCEAN_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ocean.nc"] data_out: mkdir: - - "{{ COMOUT_OCEAN_NETCDF }}" + - "{{ COMOUT_OCEAN_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} + - "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ocean.{{ grid }}.nc", "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ocean.{{ grid }}.grib2", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ocean.{{ grid }}.grib2.idx", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} ice: @@ -56,19 +72,33 @@ ice: sinvar: "" cosvar: "" angvar: "ANGLET" - subset: ['hi_h', 'hs_h', 'aice_h', 'Tsfc_h', 'uvel_h', 'vvel_h', 'frzmlt_h', 'albsni_h'] + subset: + variables: ['hi_h', 'hs_h', 'aice_h', 'Tsfc_h', 'uvel_h', 'vvel_h', 'albsni_h', 'tarea', 'tmask'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - - ["{{ COMIN_ICE_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.6hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ice.nc"] + - ["{{ COMIN_ICE_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ice.nc"] data_out: mkdir: - - "{{ COMOUT_ICE_NETCDF }}" + - "{{ COMOUT_ICE_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} + - "{{ COMOUT_ICE_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_ICE_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ice.{{ grid }}.nc", "{{ COMOUT_ICE_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ice.{{ grid }}.grib2", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ice.{{ grid }}.grib2.idx", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} diff --git a/parm/post/oceanice_products_sfs.yaml b/parm/post/oceanice_products_sfs.yaml index e38e545dce3..086af354844 100644 --- a/parm/post/oceanice_products_sfs.yaml +++ b/parm/post/oceanice_products_sfs.yaml @@ -1,16 +1,17 @@ ocnicepost: executable: "ocnicepost.x" namelist: - write_grib2: True - write_netcdf: False + write_grib2: {{ write_grib2 }} + write_netcdf: {{ write_netcdf }} debug: False fix_data: mkdir: - "{{ DATA }}" copy: - - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ PARMgfs }}/post/ocnicepost.nml.jinja2", "{{ DATA }}/"] - - ["{{ PARMgfs }}/post/{{ component }}_gfs.csv", "{{ DATA }}/{{ component }}.csv"] + {% if write_grib2 or write_netcdf %} + - ["{{ PARMgfs }}/post/{{ component }}_{{ RUN }}.csv", "{{ DATA }}/{{ component }}.csv"] + - ["{{ EXECgfs }}/ocnicepost.x", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Bu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cu.to.Ct.bilinear.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Cv.to.Ct.bilinear.nc", "{{ DATA }}/"] @@ -19,6 +20,7 @@ ocnicepost: - ["{{ FIXgfs }}/mom6/post/{{ model_grid }}/tripole.{{ model_grid }}.Ct.to.rect.{{ grid }}.conserve.nc", "{{ DATA }}/"] - ["{{ FIXgfs }}/mom6/post/template.global.{{ grid }}.gb2", "{{ DATA }}/"] {% endfor %} + {% endif %} ocean: namelist: @@ -28,11 +30,15 @@ ocean: cosvar: "cos_rot" angvar: "" {% if model_grid == 'mx025' or model_grid == 'mx050' or model_grid == 'mx100' %} - ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267, 309, 374, 467, 594, 757, 960, 1204, 1490, 1817, 2184, 2587, 3024, 3489, 3977, 4481] + ocean_levels: [1, 3, 5, 10, 20, 30, 50, 100, 200, 500, 1000] {% elif model_grid == 'mx500' %} ocean_levels: [5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 226, 241, 267] {% endif %} - subset: ['SSH', 'SST', 'SSS', 'speed', 'MLD_003', 'latent', 'sensible', 'SW', 'LW', 'LwLatSens', 'Heat_PmE', 'SSU', 'SSV', 'taux', 'tauy', 'temp', 'tob', 'so', 'uo', 'vo'] + subset: + variables: ['SSH', 'MLD_003', 'temp', 'tob', 'so', 'uo', 'vo'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - ["{{ COMIN_OCEAN_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ocean.nc"] @@ -40,14 +46,23 @@ ocean: mkdir: - "{{ COMOUT_OCEAN_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} - "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ocean_subset.nc", "{{ COMOUT_OCEAN_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ocean.{{ grid }}.nc", "{{ COMOUT_OCEAN_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ocean.{{ grid }}.grib2", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ocean.{{ grid }}.grib2.idx", "{{ COMOUT_OCEAN_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} ice: @@ -57,7 +72,11 @@ ice: sinvar: "" cosvar: "" angvar: "ANGLET" - subset: ['hi_h', 'hs_h', 'aice_h', 'Tsfc_h', 'uvel_h', 'vvel_h', 'frzmlt_h', 'albsni_h'] + subset: + variables: ['hi_h', 'hs_h', 'aice_h', 'Tsfc_h', 'uvel_h', 'vvel_h', 'albsni_h', 'tmask', 'tarea'] + compress_with: 'zlib' + compress: True + compress_level: 9 data_in: copy: - ["{{ COMIN_ICE_HISTORY }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ interval }}hr_avg.f{{ '%03d' % forecast_hour }}.nc", "{{ DATA }}/ice.nc"] @@ -65,12 +84,21 @@ ice: mkdir: - "{{ COMOUT_ICE_NETCDF }}/native" {% for grid in product_grids %} + {% if write_netcdf %} - "{{ COMOUT_ICE_NETCDF }}/{{ grid }}" + {% endif %} + {% if write_grib2 %} - "{{ COMOUT_ICE_GRIB }}/{{ grid }}" + {% endif %} {% endfor %} copy: - - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.tripolar.f{{ '%03d' % forecast_hour }}.nc"] + - ["{{ DATA }}/ice_subset.nc", "{{ COMOUT_ICE_NETCDF }}/native/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.native.f{{ '%03d' % forecast_hour }}.nc"] {% for grid in product_grids %} + {% if write_netcdf %} + - ["{{ DATA }}/ice.{{ grid }}.nc", "{{ COMOUT_ICE_NETCDF }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.nc"] + {% endif %} + {% if write_grib2 %} - ["{{ DATA }}/ice.{{ grid }}.grib2", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2"] - ["{{ DATA }}/ice.{{ grid }}.grib2.idx", "{{ COMOUT_ICE_GRIB }}/{{ grid }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.{{ grid }}.f{{ '%03d' % forecast_hour }}.grib2.idx"] + {% endif %} {% endfor %} diff --git a/parm/post/upp.yaml b/parm/post/upp.yaml index c4935104ae4..4c1bd6d889b 100644 --- a/parm/post/upp.yaml +++ b/parm/post/upp.yaml @@ -20,8 +20,13 @@ analysis: copy: - ["{{ PARMgfs }}/post/gfs/postxconfig-NT-gfs-anl.txt", "{{ DATA }}/postxconfig-NT.txt"] {% if DO_JEDIATMVAR %} + {% if ATMINC_GRID == 'gaussian' %} + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.atm.a006.nc", "{{ DATA }}/{{ atmos_filename }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.sfc.a006.nc", "{{ DATA }}/{{ flux_filename }}"] + {% else %} - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.jedi_analysis.atm.a006.nc", "{{ DATA }}/{{ atmos_filename }}"] - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.jedi_analysis.sfc.a006.nc", "{{ DATA }}/{{ flux_filename }}"] + {% endif %} {% else %} - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.atm.a006.nc", "{{ DATA }}/{{ atmos_filename }}"] - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.sfc.a006.nc", "{{ DATA }}/{{ flux_filename }}"] diff --git a/parm/stage/aero.yaml.j2 b/parm/stage/aero.yaml.j2 index 422c67a0852..6a9aca30bbc 100644 --- a/parm/stage/aero.yaml.j2 +++ b/parm/stage/aero.yaml.j2 @@ -1,17 +1,9 @@ aero: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_CHEM_ANALYSIS_MEM = COMOUT_CHEM_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_CHEM_ANALYSIS_MEM }}" - {% endfor %} + - "{{ COMOUT_CHEM_ANALYSIS }}" + link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_CHEM_ANALYSIS_MEM = COMOUT_CHEM_ANALYSIS_MEM_list[imem] %} - {% for ftype in ["aero_varbc_params.tar"] %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_CHEM_ANALYSIS_MEM | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} - - ["{{ ICSDIR }}/{{ COMOUT_CHEM_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_CHEM_ANALYSIS_MEM }}"] + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_CHEM_ANALYSIS | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} + - ["{{ ICSDIR }}/{{ COMOUT_CHEM_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.aero_varbc_params.tar", + "{{ COMOUT_CHEM_ANALYSIS }}"] {% endif %} - {% endfor %} - {% endfor %} # mem loop diff --git a/parm/stage/analysis.yaml.j2 b/parm/stage/analysis.yaml.j2 index 58a61ae3182..6494a3a1b8a 100644 --- a/parm/stage/analysis.yaml.j2 +++ b/parm/stage/analysis.yaml.j2 @@ -1,67 +1,99 @@ -{% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS_MEM_list[0] | relpath(ROTDIR)) %} +{# ============================================================================ #} +{# Analysis Staging Configuration #} +{# ============================================================================ #} +{% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR)) %} analysis: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COMOUT_ATMOS_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_ANALYSIS_MEM }}" - {% endfor %} - link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COMOUT_ATMOS_ANALYSIS_MEM_list[imem] %} + - "{{ COMOUT_ATMOS_ANALYSIS }}" + link_req: + {# -------------------------------------------------------------------- #} + {# JEDI Atmospheric Variational Data Assimilation #} + {# -------------------------------------------------------------------- #} {% if DO_JEDIATMVAR %} - {% for itile in range(6) %} - {% if mem == -1 %} - {% if DOIAU %} - {% set ftypes = ["jedi_increment.atm.i003", "jedi_increment.atm.i006", "jedi_increment.atm.i009" ] %} - {% else %} - {% set ftypes = ["jedi_increment.atm.i006" ] %} - {% endif %} - {% else %} - {% if DOIAU_ENKF %} - {% set ftypes = ["recentered_jedi_increment.atm.i003", "recentered_jedi_increment.atm.i006", "recentered_jedi_increment.atm.i009" ] %} - {% else %} - {% set ftypes = ["recentered_jedi_increment.atm.i006" ] %} - {% endif %} - {% endif %} - {% for ftype in ftypes %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}.tile{{ itile+1 }}.nc", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}"] - {% endfor %} - {% endfor %} - {% for ftype in ["abias.txt", "abias_air.txt", "abias_int.txt", "abias_pc.txt", "rad_varbc_params.tar"] %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}"] - {% endif %} - {% endfor %} + {# Cubed Sphere Grid Configuration #} + {% if ATMINC_GRID == "cubed_sphere_grid" %} + + {% for itile in range(ntiles) %} + + {# Deterministic Member (member == -1) #} + {% if member == -1 %} + {% if DOIAU %} + {% set ftypes = ["jedi_increment.atm.i003", "jedi_increment.atm.i006", "jedi_increment.atm.i009" ] %} + {% else %} + {% set ftypes = ["jedi_increment.atm.i006" ] %} + {% endif %} + + {# Ensemble Members (member != -1) #} + {% else %} + {% if DOIAU_ENKF %} + {% set ftypes = ["recentered_jedi_increment.atm.i003", "recentered_jedi_increment.atm.i006", "recentered_jedi_increment.atm.i009" ] %} + {% else %} + {% set ftypes = ["recentered_jedi_increment.atm.i006" ] %} + {% endif %} + {% endif %} + + {% for ftype in ftypes %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}.tile{{ itile+1 }}.nc", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endfor %} + {% endfor %} + + {# Non-Cubed Sphere Grid Configuration #} + {% else %} + + {# Atmospheric Increments #} + {% for ftype in ["increment.atm.i006.nc", "increment.atm.i009.nc", "increment.atm.i003.nc", + "recentered_increment.atm.i006.nc", "recentered_increment.atm.i009.nc", "recentered_increment.atm.i003.nc"] %} + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endif %} + {% endfor %} + + {% endif %} + + {# Bias Correction Files #} + {% for ftype in ["abias.txt", "abias_air.txt", "abias_int.txt", "abias_pc.txt", "rad_varbc_params.tar"] %} + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endif %} + {% endfor %} + {# -------------------------------------------------------------------- #} + {# GSI Data Assimilation (Non-JEDI) #} + {# -------------------------------------------------------------------- #} {% else %} - {% for ftype in ["abias.txt", "abias_air.txt", "abias_int.txt", "abias_pc.txt", - "increment.atm.i006.nc", "increment.atm.i009.nc", "increment.atm.i003.nc", "radstat.tar", - "recentered_increment.atm.i006.nc", "recentered_increment.atm.i009.nc", "recentered_increment.atm.i003.nc", "rad_varbc_params.tar"] %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}"] - {% endif %} - {% endfor %} + + {# All GSI Analysis Files #} + {% for ftype in ["abias.txt", "abias_air.txt", "abias_int.txt", "abias_pc.txt", + "increment.atm.i006.nc", "increment.atm.i009.nc", "increment.atm.i003.nc", "radstat.tar", + "recentered_increment.atm.i006.nc", "recentered_increment.atm.i009.nc", "recentered_increment.atm.i003.nc", "rad_varbc_params.tar"] %} + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endif %} + {% endfor %} {% endif %} + {# -------------------------------------------------------------------- #} + {# GSI Soil Analysis (Land DA) #} + {# -------------------------------------------------------------------- #} {% if DO_GSISOILDA %} - {% for ftype in ["increment.sfc.i003.nc", "increment.sfc.i006.nc", "increment.sfc.i009.nc"] %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}"] - {% endif %} - {% endfor %} + {# Surface Increments #} + {% for ftype in ["increment.sfc.i003.nc", "increment.sfc.i006.nc", "increment.sfc.i009.nc"] %} + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) ~ "/" ~ RUN ~ ".t" ~ current_cycle_HH ~ "z." ~ ftype) %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.{{ ftype }}", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endif %} + {% endfor %} + + {# Land IAU Increments (Tiled) #} + {% if DO_LAND_IAU %} + {% for itile in range(1,7) %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/increment.sfc.tile{{ itile }}.nc", "{{ COMOUT_ATMOS_ANALYSIS }}"] + {% endfor %} + {% endif %} - {% if DO_LAND_IAU %} - {% for itile in range(1,7) %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/increment.sfc.tile{{ itile }}.nc", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}"] - {% endfor %} - {% endif %} {% endif %} - {% endfor %} # mem loop {% endif %} diff --git a/parm/stage/atmosphere_cold.yaml.j2 b/parm/stage/atmosphere_cold.yaml.j2 index c742b28c8d3..40acd8ee080 100644 --- a/parm/stage/atmosphere_cold.yaml.j2 +++ b/parm/stage/atmosphere_cold.yaml.j2 @@ -1,18 +1,10 @@ atmosphere_cold: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_INPUT_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ATMOS_INPUT }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_INPUT_MEM | relpath(ROTDIR) }}/gfs_ctrl.nc", "{{ COMOUT_ATMOS_INPUT_MEM }}"] + - ["{{ ICSDIR }}/{{ COMIN_ATMOS_INPUT | relpath(ROTDIR) }}/gfs_ctrl.nc", "{{ COMOUT_ATMOS_INPUT }}"] {% for ftype in ["gfs_data", "sfc_data"] %} {% for ntile in range(1, ntiles + 1) %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_INPUT_MEM | relpath(ROTDIR) }}/{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_INPUT_MEM }}"] + - ["{{ ICSDIR }}/{{ COMIN_ATMOS_INPUT | relpath(ROTDIR) }}/{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_INPUT }}"] {% endfor %} # ntile {% endfor %} # ftype - {% endfor %} # mem loop diff --git a/parm/stage/atmosphere_cold_RT.yaml.j2 b/parm/stage/atmosphere_cold_RT.yaml.j2 index f6a1c0d118b..7b22285d5c2 100644 --- a/parm/stage/atmosphere_cold_RT.yaml.j2 +++ b/parm/stage/atmosphere_cold_RT.yaml.j2 @@ -1,17 +1,17 @@ atmosphere_cold_RT: mkdir: - - "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}" - - "{{ COMOUT_ATMOS_ANALYSIS_MEM }}" - - "{{ COMOUT_ATMOS_HISTORY_MEM }}" + - "{{ COMOUT_ATMOS_RESTART_PREV }}" + - "{{ COMOUT_ATMOS_ANALYSIS }}" + - "{{ COMOUT_ATMOS_HISTORY }}" link_req: {% set DIAU_cold_previous_file = ICSDIR ~ '/' ~ 'gdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/analysis/atmos/gdas.t' ~ previous_cycle_HH ~ 'z.ensres_analysis.atm.a003.nc' %} {% set DIAU_cold_current_file = ICSDIR ~ '/' ~ 'gfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/analysis/atmos/gfs.t' ~ current_cycle_HH ~ 'z.increment.atm.i006.nc' %} {% set DIAU_current_file= ICSDIR ~ '/' ~ 'gfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/analysis/atmos/gfs.t' ~ current_cycle_HH ~ 'z.analysis.atm.a006.nc' %} {% set atm_file = ICSDIR ~ '/' ~ 'gdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/model/atmos/history/gdas.t' ~ previous_cycle_HH ~ 'z.ensres.atm.f006.nc' %} {% set surface_file = ICSDIR ~ '/' ~ 'gdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/model/atmos/history/gdas.t' ~ previous_cycle_HH ~ 'z.sfc.f003.nc' %} - {% set current_path = COMOUT_ATMOS_ANALYSIS_MEM %} - {% set previous_path = COMOUT_ATMOS_RESTART_PREV_MEM %} - {% set surface_atm_path = COMOUT_ATMOS_HISTORY_MEM %} + {% set current_path = COMOUT_ATMOS_ANALYSIS %} + {% set previous_path = COMOUT_ATMOS_RESTART_PREV %} + {% set surface_atm_path = COMOUT_ATMOS_HISTORY %} - ["{{ DIAU_cold_previous_file }}", "{{ previous_path}}"] - ["{{ DIAU_cold_current_file }}", "{{ current_path }}"] - ["{{ DIAU_current_file }}", "{{ current_path }}"] diff --git a/parm/stage/atmosphere_ens_perturbations.yaml.j2 b/parm/stage/atmosphere_ens_perturbations.yaml.j2 index 8f9fc857042..15496e8d53a 100644 --- a/parm/stage/atmosphere_ens_perturbations.yaml.j2 +++ b/parm/stage/atmosphere_ens_perturbations.yaml.j2 @@ -1,13 +1,5 @@ atmosphere_ens_perturbation: mkdir: - {% for mem in range(first_mem + 1, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COMOUT_ATMOS_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_ANALYSIS_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ATMOS_ANALYSIS }}" link_req: - {% for mem in range(first_mem + 1, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COMOUT_ATMOS_ANALYSIS_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.fv3_perturbation.nc", "{{ COMOUT_ATMOS_ANALYSIS_MEM }}/{{ RUN }}.t{{ current_cycle_HH }}z.increment.atm.i006.nc"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ m_prefix }}.fv3_perturbation.nc", "{{ COMOUT_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle_HH }}z.increment.atm.i006.nc"] diff --git a/parm/stage/atmosphere_nest.yaml.j2 b/parm/stage/atmosphere_nest.yaml.j2 index 3ef8a7c3919..b1aeca637b6 100644 --- a/parm/stage/atmosphere_nest.yaml.j2 +++ b/parm/stage/atmosphere_nest.yaml.j2 @@ -2,35 +2,19 @@ atmosphere_nest: {% set ntile = 7 %} {% if EXP_WARM_START == True %} mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COMOUT_ATMOS_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ATMOS_RESTART_PREV }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COMOUT_ATMOS_RESTART_PREV_MEM_list[imem] %} {% for ftype in ["fv_core.res", "fv_srf_wnd.res", "fv_tracer.res", "phy_data", "sfc_data"] %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}/{{ m_prefix }}.{{ ftype }}.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV }}/{{ m_prefix }}.{{ ftype }}.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] {% if DO_CA %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.ca_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}/{{ m_prefix }}.ca_data.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.ca_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV }}/{{ m_prefix }}.ca_data.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] {% endif %} {% endfor %} - {% endfor %} # mem loop {% else %} # cold start mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_INPUT_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ATMOS_INPUT }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} {% for ftype in ["gfs_data", "sfc_data"] %} - - ["{{ COMOUT_ATMOS_INPUT_MEM }}/{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_INPUT_MEM }}/{{ ftype }}.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] + - ["{{ COMOUT_ATMOS_INPUT }}/{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_INPUT }}/{{ ftype }}.nest0{{ ntile-5 }}.tile{{ ntile }}.nc"] {% endfor %} - {% endfor %} # mem loop {% endif %} diff --git a/parm/stage/atmosphere_warm.yaml.j2 b/parm/stage/atmosphere_warm.yaml.j2 index 501826391ce..c943fe57545 100644 --- a/parm/stage/atmosphere_warm.yaml.j2 +++ b/parm/stage/atmosphere_warm.yaml.j2 @@ -1,34 +1,24 @@ atmosphere_warm: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COMOUT_ATMOS_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}" - {% set COMOUT_ATMOS_RESTART_MEM = COMOUT_ATMOS_RESTART_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_RESTART_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ATMOS_RESTART_PREV }}" + - "{{ COMOUT_ATMOS_RESTART }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COMOUT_ATMOS_RESTART_PREV_MEM_list[imem] %} - {% set COMOUT_ATMOS_RESTART_MEM = COMOUT_ATMOS_RESTART_MEM_list[imem] %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".atm_stoch.res.nc") %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.atm_stoch.res.nc", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}"] + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".atm_stoch.res.nc") %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.atm_stoch.res.nc", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% endif %} # path_exists {% for ftype in ["coupler.res", "fv_core.res.nc"] %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}"] + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% endfor %} {% for ntile in range(1, ntiles + 1) %} {% for ftype in ["fv_core.res", "fv_srf_wnd.res", "fv_tracer.res", "phy_data", "sfc_data"] %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}"] + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% endfor %} # ftype {% if DO_CA %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.ca_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}"] + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.ca_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% endif %} {% endfor %} # ntile {% for ntile in range(1, ntiles + 1) %} - {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_RESTART_MEM | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".sfcanl_data.tile" ~ ntile ~ ".nc") %} - - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.sfcanl_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART_MEM }}"] + {% if path_exists(ICSDIR ~ "/" ~ COMOUT_ATMOS_RESTART | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".sfcanl_data.tile" ~ ntile ~ ".nc") %} + - ["{{ ICSDIR }}/{{ COMOUT_ATMOS_RESTART | relpath(ROTDIR) }}/{{ m_prefix }}.sfcanl_data.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_RESTART }}"] {% endif %} # path_exists {% endfor %} # ntile - {% endfor %} # mem loop diff --git a/parm/stage/atmosphere_warm_RT.yaml.j2 b/parm/stage/atmosphere_warm_RT.yaml.j2 index 0aee0d3a2be..afc69d1f5e6 100644 --- a/parm/stage/atmosphere_warm_RT.yaml.j2 +++ b/parm/stage/atmosphere_warm_RT.yaml.j2 @@ -1,14 +1,11 @@ atmosphere_warm_RT: mkdir: - - "{{ COMOUT_ATMOS_RESTART_PREV_MEM }}" - - "{{ COMOUT_ATMOS_ANALYSIS_MEM }}" + - "{{ COMOUT_ATMOS_RESTART_PREV }}" + - "{{ COMOUT_ATMOS_ANALYSIS }}" link_req: # select restart members files (80) specific to the cycle - {% set mid_cyc = ("%02d" | format(previous_cycle_HH | int + half_window)) ~ "0000" %} - {% set restart_mem_path = ICSDIR ~ '/' ~ 'enkfgdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/' ~ 'mem%03d' | format(gfs_member) ~ '/model/atmos/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '.' %} - {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(gfs_member) ~ '/analysis/atmos/enkfgfs.t' ~ current_cycle_HH ~ 'z.' %} - {% set restart_destination_path = COMOUT_ATMOS_RESTART_PREV_MEM %} - {% set increment_destination_path = COMOUT_ATMOS_ANALYSIS_MEM %} + {% set restart_mem_path = ICSDIR ~ '/' ~ 'enkfgdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/' ~ 'mem%03d' | format(member) ~ '/model/atmos/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '0000.' %} + {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(member) ~ '/analysis/atmos/enkfgfs.t' ~ current_cycle_HH ~ 'z.' %} # Include increment files {% for ftype in ["recentered_increment.atm.i003.nc", "recentered_increment.atm.i009.nc", "recentered_increment.atm.i006.nc"] %} @@ -18,15 +15,15 @@ atmosphere_warm_RT: {% if path_exists(ICSDIR) %} {% set file = restart_mem_path ~ 'coupler.res' %} - - ["{{ file }}", "{{ restart_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% set file = restart_mem_path ~ 'fv_core.res.nc' %} - - ["{{ file }}", "{{ restart_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% set ntiles = 6 %} {% for ftype in ["fv_core.res", "fv_srf_wnd.res", "phy_data", "sfc_data"] %} # Include restart tile files (e.g., .tile1 to .tile6) {% for tile in range(1, ntiles + 1) %} {% set file = restart_mem_path ~ ftype ~ '.tile' ~ tile ~ '.nc' %} - - ["{{ file }}", "{{ restart_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_ATMOS_RESTART_PREV }}"] {% endfor %} {% endfor %} {% endif %} diff --git a/parm/stage/ice.yaml.j2 b/parm/stage/ice.yaml.j2 index 56f5e4eea33..88e8f826ff8 100644 --- a/parm/stage/ice.yaml.j2 +++ b/parm/stage/ice.yaml.j2 @@ -1,35 +1,12 @@ -{% set START_ICE_FROM_ANA = False %} -{% if DO_JEDIOCNVAR == True and RUN == 'gdas' %} - {% set START_ICE_FROM_ANA = True %} -{% endif %} -{% if DO_STARTMEM_FROM_JEDIICE == True and RUN == 'enkfgdas' %} - {% set START_ICE_FROM_ANA = True %} -{% endif %} ice: {% if START_ICE_FROM_ANA == True %} mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ICE_ANALYSIS_MEM = COMOUT_ICE_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_ICE_ANALYSIS_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ICE_ANALYSIS }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ICE_ANALYSIS_MEM = COMOUT_ICE_ANALYSIS_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_ICE_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.analysis.cice_model.res.nc", "{{ COMOUT_ICE_ANALYSIS_MEM }}"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_ICE_ANALYSIS | relpath(ROTDIR) }}/{{ m_prefix }}.analysis.cice_model.res.nc", "{{ COMOUT_ICE_ANALYSIS }}"] {% else %} mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ICE_RESTART_PREV_MEM = COMOUT_ICE_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_ICE_RESTART_PREV_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_ICE_RESTART_PREV }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ICE_RESTART_PREV_MEM = COMOUT_ICE_RESTART_PREV_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_ICE_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.cice_model.res.nc", "{{ COMOUT_ICE_RESTART_PREV_MEM }}"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_ICE_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.cice_model.res.nc", "{{ COMOUT_ICE_RESTART_PREV }}"] {% endif %} diff --git a/parm/stage/ice_RT.yaml.j2 b/parm/stage/ice_RT.yaml.j2 index e5ceaaea480..6699d8f9c70 100644 --- a/parm/stage/ice_RT.yaml.j2 +++ b/parm/stage/ice_RT.yaml.j2 @@ -1,12 +1,10 @@ ice_RT: mkdir: - - "{{ COMOUT_ICE_ANALYSIS_MEM }}" + - "{{ COMOUT_ICE_ANALYSIS }}" link_req: # select restart members files (80) specific to the cycle - {% set mid_cyc = ("%02d" | format(previous_cycle_HH | int + half_window)) ~ "0000" %} - {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(gfs_member) ~ '/analysis/ice/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '.analysis.cice_model.res.nc' %} - {% set increment_destination_path = COMOUT_ICE_ANALYSIS_MEM %} + {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(member) ~ '/analysis/ice/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '0000.analysis.cice_model.res.nc' %} + {% set increment_destination_path = COMOUT_ICE_ANALYSIS %} # Include increment files - {% set file = increment_mem_path %} - - ["{{ file }}", "{{ increment_destination_path }}"] + - ["{{ increment_mem_file }}", "{{ COMOUT_ICE_ANALYSIS }}"] diff --git a/parm/stage/ice_control_RT.yaml.j2 b/parm/stage/ice_control_RT.yaml.j2 index ab55623f341..fd335bb646e 100644 --- a/parm/stage/ice_control_RT.yaml.j2 +++ b/parm/stage/ice_control_RT.yaml.j2 @@ -1,8 +1,7 @@ ice_control_RT: mkdir: - - "{{ COMOUT_ICE_ANALYSIS_MEM }}" + - "{{ COMOUT_ICE_ANALYSIS }}" link_req: - {% set mid_cyc = ("%02d" | format(previous_cycle_HH | int + half_window)) ~ "0000" %} - {% set increment_file = ICSDIR ~ '/' ~ 'gfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/analysis/ice/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '.analysis.cice_model.res.nc' %} - {% set increment_destination_path = COMOUT_ICE_ANALYSIS_MEM %} + {% set increment_file = ICSDIR ~ '/' ~ 'gfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/analysis/ice/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '0000.analysis.cice_model.res.nc' %} + {% set increment_destination_path = COMOUT_ICE_ANALYSIS %} - ["{{ increment_file }}", "{{ increment_destination_path }}"] diff --git a/parm/stage/master_gcafs.yaml.j2 b/parm/stage/master_gcafs.yaml.j2 index 5faf462a95c..36cc43f4714 100644 --- a/parm/stage/master_gcafs.yaml.j2 +++ b/parm/stage/master_gcafs.yaml.j2 @@ -26,111 +26,14 @@ # - DO_ATM, DO_OCN, DO_ICE, etc. # For a full list see scripts/exglobal_stage_ic.py ################################################################### +# Initial condition to stage - include components based on switches +################################################################### -# Set cycle date variables -# ------------------------ -{% set half_window = assim_freq // 2 %} -{% set half_window_begin = (-half_window | string + "H") | to_timedelta %} -{% set half_window_end = (half_window | string + "H") | to_timedelta %} -{% if DOIAU and MODE == "cycled" %} - {% set model_start_date_current_cycle = current_cycle | add_to_datetime(half_window_begin) %} -{% else %} - {% set model_start_date_current_cycle = current_cycle %} -{% endif %} - -{% set current_cycle_YMD = current_cycle | to_YMD %} -{% set current_cycle_HH = current_cycle | strftime("%H") %} -{% set previous_cycle_YMD = previous_cycle | to_YMD %} -{% set previous_cycle_HH = previous_cycle | strftime("%H") %} -{% set p_prefix = previous_cycle | strftime("%Y%m%d.%H0000") %} -{% set m_prefix = model_start_date_current_cycle | strftime("%Y%m%d.%H0000") %} - -# Determine restart RUN -# --------------------- # always use GDAS for now, fix once we have staged GCDAS/GCAFS ICs +# TODO: move this to stage_ic.py +# once GCDAS/GCAFS ICs are available {% set rRUN = "gdas" %} -# Set first/last mem for loop -# --------------------------- -{% if RUN == "enkfgdas" %} # Ensemble RUN - {% set first_mem = 1 %} - {% set last_mem = NMEM_ENS %} -{% else %} # Deterministic RUN - {% set first_mem = -1 %} - {% set last_mem = -1 %} -{% endif %} - -# Declare to-be-filled lists of member COM directories -# ---------------------------------------------------- -{% set COMIN_ATMOS_INPUT_MEM_list = [] %} -{% set COMOUT_ATMOS_INPUT_MEM_list = [] %} -{% set COMOUT_ATMOS_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_ATMOS_RESTART_MEM_list = [] %} -{% set COMOUT_ATMOS_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_ANALYSIS_MEM_list = [] %} -{% set COMOUT_MED_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_WAVE_RESTART_PREV_MEM_list = [] %} - -# Construct member COM directory lists -# ------------------------------------ -{% for mem in range(first_mem, last_mem + 1) %} - - {% if mem >= 0 %} - {% set mem_char = 'mem%03d' | format(mem) %} - {% else %} - {% set mem_char = '' %} - {% endif %} - - {% set current_cycle_dict_in = ({ '${ROTDIR}':ROTDIR, - '${RUN}':rRUN, - '${YMD}':current_cycle_YMD, - '${HH}':current_cycle_HH, - '${MEMDIR}': mem_char }) %} - {% set current_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':current_cycle_YMD, - '${HH}':current_cycle_HH, - '${MEMDIR}': mem_char }) %} - {% set previous_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':rRUN, - '${YMD}':previous_cycle_YMD, - '${HH}':previous_cycle_HH, - '${MEMDIR}': mem_char }) %} - - {% set COMIN_ATMOS_INPUT_MEM = COM_ATMOS_INPUT_TMPL | replace_tmpl(current_cycle_dict_in) %} - {% set COMOUT_ATMOS_INPUT_MEM = COM_ATMOS_INPUT_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_ATMOS_RESTART_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COM_ATMOS_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_ANALYSIS_MEM = COM_ICE_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_RESTART_PREV_MEM = COM_ICE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_RESTART_PREV_MEM = COM_OCEAN_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COM_OCEAN_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_MED_RESTART_PREV_MEM = COM_MED_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_WAVE_RESTART_PREV_MEM = COM_WAVE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - - # Append the member COM directories - {% do COMIN_ATMOS_INPUT_MEM_list.append(COMIN_ATMOS_INPUT_MEM)%} - {% do COMOUT_ATMOS_INPUT_MEM_list.append(COMOUT_ATMOS_INPUT_MEM)%} - {% do COMOUT_ATMOS_RESTART_PREV_MEM_list.append(COMOUT_ATMOS_RESTART_PREV_MEM)%} - {% do COMOUT_ATMOS_RESTART_MEM_list.append(COMOUT_ATMOS_RESTART_MEM)%} - {% do COMOUT_ATMOS_ANALYSIS_MEM_list.append(COMOUT_ATMOS_ANALYSIS_MEM)%} - {% do COMOUT_ICE_ANALYSIS_MEM_list.append(COMOUT_ICE_ANALYSIS_MEM)%} - {% do COMOUT_ICE_RESTART_PREV_MEM_list.append(COMOUT_ICE_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_RESTART_PREV_MEM_list.append(COMOUT_OCEAN_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_ANALYSIS_MEM_list.append(COMOUT_OCEAN_ANALYSIS_MEM)%} - {% do COMOUT_MED_RESTART_PREV_MEM_list.append(COMOUT_MED_RESTART_PREV_MEM)%} - {% do COMOUT_WAVE_RESTART_PREV_MEM_list.append(COMOUT_WAVE_RESTART_PREV_MEM)%} - -{% endfor %} - -################################################################### -# Initial condition to stage - include components based on switches -################################################################### - {% if MODE == "cycled" %} {% filter indent(width=4) %} {% include "analysis.yaml.j2" %} @@ -142,25 +45,9 @@ {% include "atmosphere_warm.yaml.j2" %} {% endfilter %} {% else %} # cold start - atmosphere_cold: - mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} - - "{{ COMOUT_ATMOS_INPUT_MEM }}" - {% endfor %} # mem loop - link: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMIN_ATMOS_INPUT_MEM = COMIN_ATMOS_INPUT_MEM_list[imem] %} - {% set COMOUT_ATMOS_INPUT_MEM = COMOUT_ATMOS_INPUT_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMIN_ATMOS_INPUT_MEM | relpath(ROTDIR) }}/gfs_ctrl.nc", "{{ COMOUT_ATMOS_INPUT_MEM }}"] - {% for ftype in ["gfs_data", "sfc_data"] %} - {% for ntile in range(1, ntiles + 1) %} - - ["{{ ICSDIR }}/{{ COMIN_ATMOS_INPUT_MEM | relpath(ROTDIR) }}/{{ ftype }}.tile{{ ntile }}.nc", "{{ COMOUT_ATMOS_INPUT_MEM }}"] - {% endfor %} # ntile - {% endfor %} # ftype - {% endfor %} # mem loop +{% filter indent(width=4) %} +{% include "atmosphere_cold.yaml.j2" %} +{% endfilter %} {% endif %} {% if DO_NEST %} diff --git a/parm/stage/master_gefs.yaml.j2 b/parm/stage/master_gefs.yaml.j2 index 4b848ba30aa..d778eff23dd 100644 --- a/parm/stage/master_gefs.yaml.j2 +++ b/parm/stage/master_gefs.yaml.j2 @@ -25,81 +25,6 @@ # - COMOUT_ # - DO_ATM, DO_OCN, DO_ICE, etc. # For a full list see scripts/exglobal_stage_ic.py -################################################################### - -# Set cycle variables -# ------------------------ -{% set half_window = assim_freq // 2 %} -{% set half_window_begin = (-half_window | string + "H") | to_timedelta %} -{% set half_window_end = (half_window | string + "H") | to_timedelta %} -{% if DOIAU and MODE == "cycled" %} - {% set model_start_date_current_cycle = current_cycle | add_to_datetime(half_window_begin) %} -{% else %} - {% set model_start_date_current_cycle = current_cycle %} -{% endif %} - -{% set current_cycle_YMD = current_cycle | to_YMD %} -{% set current_cycle_HH = current_cycle | strftime("%H") %} -{% set previous_cycle_YMD = previous_cycle | to_YMD %} -{% set previous_cycle_HH = previous_cycle | strftime("%H") %} -{% set p_prefix = previous_cycle | strftime("%Y%m%d.%H0000") %} -{% set m_prefix = model_start_date_current_cycle | strftime("%Y%m%d.%H0000") %} - -# Set first/last mem for loop -# --------------------------- -{% set first_mem = 0 %} -{% set last_mem = NMEM_ENS %} - -# Declare to-be-filled lists of member COM directories -# ---------------------------------------------------- -{% set COMOUT_ATMOS_INPUT_MEM_list = [] %} -{% set COMOUT_ATMOS_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_ATMOS_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_ANALYSIS_MEM_list = [] %} -{% set COMOUT_MED_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_WAVE_RESTART_PREV_MEM_list = [] %} - -# Construct member COM directory lists -# ------------------------------------ -{% for mem in range(first_mem, last_mem + 1) %} - - {% set current_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':current_cycle_YMD, - '${HH}':current_cycle_HH, - '${MEMDIR}': 'mem%03d' | format(mem) }) %} - {% set previous_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':previous_cycle_YMD, - '${HH}':previous_cycle_HH, - '${MEMDIR}': 'mem%03d' | format(mem) }) %} - - {% set COMOUT_ATMOS_INPUT_MEM = COM_ATMOS_INPUT_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COM_ATMOS_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_ANALYSIS_MEM = COM_ICE_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_RESTART_PREV_MEM = COM_ICE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_RESTART_PREV_MEM = COM_OCEAN_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COM_OCEAN_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_MED_RESTART_PREV_MEM = COM_MED_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_WAVE_RESTART_PREV_MEM = COM_WAVE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - - # Append the member COM directories - {% do COMOUT_ATMOS_INPUT_MEM_list.append(COMOUT_ATMOS_INPUT_MEM)%} - {% do COMOUT_ATMOS_RESTART_PREV_MEM_list.append(COMOUT_ATMOS_RESTART_PREV_MEM)%} - {% do COMOUT_ATMOS_ANALYSIS_MEM_list.append(COMOUT_ATMOS_ANALYSIS_MEM)%} - {% do COMOUT_ICE_ANALYSIS_MEM_list.append(COMOUT_ICE_ANALYSIS_MEM)%} - {% do COMOUT_ICE_RESTART_PREV_MEM_list.append(COMOUT_ICE_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_RESTART_PREV_MEM_list.append(COMOUT_OCEAN_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_ANALYSIS_MEM_list.append(COMOUT_OCEAN_ANALYSIS_MEM)%} - {% do COMOUT_MED_RESTART_PREV_MEM_list.append(COMOUT_MED_RESTART_PREV_MEM)%} - {% do COMOUT_WAVE_RESTART_PREV_MEM_list.append(COMOUT_WAVE_RESTART_PREV_MEM)%} - -{% endfor %} - ################################################################### # Initial condition to stage - include components based on switches ################################################################### @@ -114,7 +39,7 @@ {% endfilter %} {% endif %} -{% if USE_ATM_ENS_PERTURB_FILES %} +{% if USE_ATM_ENS_PERTURB_FILES and member != 0 %} {% filter indent(width=4) %} {% include "atmosphere_ens_perturbations.yaml.j2" %} {% endfilter %} @@ -135,7 +60,7 @@ {% include "ocean_rerun.yaml.j2" %} {% endfilter %} {% endif %} -{% if USE_OCN_ENS_PERTURB_FILES %} +{% if USE_OCN_ENS_PERTURB_FILES and member != 0 %} {% filter indent(width=4) %} {% include "ocean_ens_perturbations.yaml.j2" %} {% endfilter %} diff --git a/parm/stage/master_gefs_RT.yaml.j2 b/parm/stage/master_gefs_RT.yaml.j2 index 1531422825e..ec6106e2111 100644 --- a/parm/stage/master_gefs_RT.yaml.j2 +++ b/parm/stage/master_gefs_RT.yaml.j2 @@ -25,63 +25,7 @@ # - DO_ATM, DO_OCN, DO_ICE, etc. # For a full list see scripts/exglobal_stage_ic.py ################################################################### -# Set cycle variables -# ------------------------ -{% set half_window = assim_freq // 2 %} -{% set half_window_begin = (-half_window | string + "H") | to_timedelta %} -{% set half_window_end = (half_window | string + "H") | to_timedelta %} -{% set model_start_date_current_cycle = current_cycle %} -{% set current_cycle_YMD = current_cycle | to_YMD %} -{% set current_cycle_HH = current_cycle | strftime("%H") %} -{% set previous_cycle_YMD = previous_cycle | to_YMD %} -{% set previous_cycle_HH = previous_cycle | strftime("%H") %} -{% set p_prefix = previous_cycle | strftime("%Y%m%d.%H0000") %} -{% set m_prefix = model_start_date_current_cycle | strftime("%Y%m%d.%H0000") %} - -################################################################### -# TODO -# this script should run for 30 members (+ control member) -# logic and variables in this script will move to stage_ic.py -# until then this will run only for ENSMEM = 0 (control) -{% set ENSMEM = 0 %} -################################################################### -# Construct member COM directory lists -# ------------------------------------ -{% set current_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':current_cycle_YMD, - '${HH}':current_cycle_HH, - '${MEMDIR}': 'mem%03d' | format(ENSMEM) }) %} -{% set previous_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':previous_cycle_YMD, - '${HH}':previous_cycle_HH, - '${MEMDIR}': 'mem%03d' | format(ENSMEM) }) %} - - -{% set COMOUT_ATMOS_INPUT_MEM = COM_ATMOS_INPUT_TMPL | replace_tmpl(current_cycle_dict) %} -{% set COMOUT_ATMOS_RESTART_PREV_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} -{% set COMOUT_ATMOS_ANALYSIS_MEM = COM_ATMOS_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} -{% set COMOUT_ATMOS_HISTORY_MEM = COM_ATMOS_HISTORY_TMPL | replace_tmpl(previous_cycle_dict) %} -{% set COMOUT_ICE_ANALYSIS_MEM = COM_ICE_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} -{% set COMOUT_ICE_RESTART_PREV_MEM = COM_ICE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} -{% set COMOUT_OCEAN_RESTART_PREV_MEM = COM_OCEAN_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} -{% set COMOUT_OCEAN_ANALYSIS_MEM = COM_OCEAN_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} -{% set COMOUT_MED_RESTART_PREV_MEM = COM_MED_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} -{% set COMOUT_WAVE_RESTART_PREV_MEM = COM_WAVE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} -################################################################### -# Initial condition to stage - include components based on switches -################################################################### -{% set m_index = (current_cycle_HH | int) // 6 %} - -{% if ENSMEM != 0 %} -# GFS members (80) -{% set cyc_ranges = [(range(1, 31) | list), (range(21, 51) | list), (range(41, 71) | list), (range(61, 81) | list) + (range(1, 11) | list)] %} -# select the relevant member for each GEFS member from GFS outputs -{% set gfs_member = cyc_ranges[m_index][(ENSMEM - 1)] %} -{% endif %} - -{% if ENSMEM == 0 %} +{% if member == 0 %} {% include "atmosphere_cold_RT.yaml.j2" %} {% include "ocean_control_RT.yaml.j2" %} {% include "ice_control_RT.yaml.j2" %} diff --git a/parm/stage/master_gfs.yaml.j2 b/parm/stage/master_gfs.yaml.j2 index 35fa21cd8af..c14e6fad4ae 100644 --- a/parm/stage/master_gfs.yaml.j2 +++ b/parm/stage/master_gfs.yaml.j2 @@ -25,105 +25,6 @@ # - COMOUT_ # - DO_ATM, DO_OCN, DO_ICE, etc. # For a full list see scripts/exglobal_stage_ic.py -################################################################### - -# Set cycle date variables -# ------------------------ -{% set half_window = assim_freq // 2 %} -{% set half_window_begin = (-half_window | string + "H") | to_timedelta %} -{% set half_window_end = (half_window | string + "H") | to_timedelta %} -{% if DOIAU and MODE == "cycled" %} - {% set model_start_date_current_cycle = current_cycle | add_to_datetime(half_window_begin) %} -{% else %} - {% set model_start_date_current_cycle = current_cycle %} -{% endif %} - -{% set current_cycle_YMD = current_cycle | to_YMD %} -{% set current_cycle_HH = current_cycle | strftime("%H") %} -{% set previous_cycle_YMD = previous_cycle | to_YMD %} -{% set previous_cycle_HH = previous_cycle | strftime("%H") %} -{% set p_prefix = previous_cycle | strftime("%Y%m%d.%H0000") %} -{% set m_prefix = model_start_date_current_cycle | strftime("%Y%m%d.%H0000") %} - -# Determine restart RUN -# --------------------- -{% set rRUN = RUN %} -{% if RUN == "gfs" %} - {% set rRUN = "gdas" %} -{% endif %} - -# Set first/last mem for loop -# --------------------------- -{% if RUN == "enkfgdas" %} # Ensemble RUN - {% set first_mem = 1 %} - {% set last_mem = NMEM_ENS %} -{% else %} # Deterministic RUN - {% set first_mem = -1 %} - {% set last_mem = -1 %} -{% endif %} - -# Declare to-be-filled lists of member COM directories -# ---------------------------------------------------- -{% set COMOUT_ATMOS_INPUT_MEM_list = [] %} -{% set COMOUT_ATMOS_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_ATMOS_RESTART_MEM_list = [] %} -{% set COMOUT_ATMOS_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_ANALYSIS_MEM_list = [] %} -{% set COMOUT_ICE_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_OCEAN_ANALYSIS_MEM_list = [] %} -{% set COMOUT_MED_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_WAVE_RESTART_PREV_MEM_list = [] %} -{% set COMOUT_CHEM_ANALYSIS_MEM_list = [] %} - -# Construct member COM directory lists -# ------------------------------------ -{% for mem in range(first_mem, last_mem + 1) %} - - {% if mem >= 0 %} - {% set mem_char = 'mem%03d' | format(mem) %} - {% else %} - {% set mem_char = '' %} - {% endif %} - - {% set current_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':RUN, - '${YMD}':current_cycle_YMD, - '${HH}':current_cycle_HH, - '${MEMDIR}': mem_char }) %} - {% set previous_cycle_dict = ({ '${ROTDIR}':ROTDIR, - '${RUN}':rRUN, - '${YMD}':previous_cycle_YMD, - '${HH}':previous_cycle_HH, - '${MEMDIR}': mem_char }) %} - - {% set COMOUT_ATMOS_INPUT_MEM = COM_ATMOS_INPUT_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ATMOS_RESTART_PREV_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_ATMOS_RESTART_MEM = COM_ATMOS_RESTART_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ATMOS_ANALYSIS_MEM = COM_ATMOS_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_ANALYSIS_MEM = COM_ICE_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_ICE_RESTART_PREV_MEM = COM_ICE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_RESTART_PREV_MEM = COM_OCEAN_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COM_OCEAN_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - {% set COMOUT_MED_RESTART_PREV_MEM = COM_MED_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_WAVE_RESTART_PREV_MEM = COM_WAVE_RESTART_TMPL | replace_tmpl(previous_cycle_dict) %} - {% set COMOUT_CHEM_ANALYSIS_MEM = COM_CHEM_ANALYSIS_TMPL | replace_tmpl(current_cycle_dict) %} - - # Append the member COM directories - {% do COMOUT_ATMOS_INPUT_MEM_list.append(COMOUT_ATMOS_INPUT_MEM)%} - {% do COMOUT_ATMOS_RESTART_PREV_MEM_list.append(COMOUT_ATMOS_RESTART_PREV_MEM)%} - {% do COMOUT_ATMOS_RESTART_MEM_list.append(COMOUT_ATMOS_RESTART_MEM)%} - {% do COMOUT_ATMOS_ANALYSIS_MEM_list.append(COMOUT_ATMOS_ANALYSIS_MEM)%} - {% do COMOUT_ICE_ANALYSIS_MEM_list.append(COMOUT_ICE_ANALYSIS_MEM)%} - {% do COMOUT_ICE_RESTART_PREV_MEM_list.append(COMOUT_ICE_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_RESTART_PREV_MEM_list.append(COMOUT_OCEAN_RESTART_PREV_MEM)%} - {% do COMOUT_OCEAN_ANALYSIS_MEM_list.append(COMOUT_OCEAN_ANALYSIS_MEM)%} - {% do COMOUT_MED_RESTART_PREV_MEM_list.append(COMOUT_MED_RESTART_PREV_MEM)%} - {% do COMOUT_WAVE_RESTART_PREV_MEM_list.append(COMOUT_WAVE_RESTART_PREV_MEM)%} - {% do COMOUT_CHEM_ANALYSIS_MEM_list.append(COMOUT_CHEM_ANALYSIS_MEM)%} - -{% endfor %} - ################################################################### # Initial condition to stage - include components based on switches ################################################################### diff --git a/parm/stage/ocean.yaml.j2 b/parm/stage/ocean.yaml.j2 index 135d5056bc4..5916e69aff7 100644 --- a/parm/stage/ocean.yaml.j2 +++ b/parm/stage/ocean.yaml.j2 @@ -1,18 +1,10 @@ ocean: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_RESTART_PREV_MEM = COMOUT_OCEAN_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_OCEAN_RESTART_PREV_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_OCEAN_RESTART_PREV }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_RESTART_PREV_MEM = COMOUT_OCEAN_RESTART_PREV_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.MOM.res.nc", "{{ COMOUT_OCEAN_RESTART_PREV_MEM }}"] + - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.MOM.res.nc", "{{ COMOUT_OCEAN_RESTART_PREV }}"] {% if OCNRES == "025" %} {% for nn in range(1, 4) %} - - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.MOM.res_{{ nn }}.nc", "{{ COMOUT_OCEAN_RESTART_PREV_MEM }}"] + - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.MOM.res_{{ nn }}.nc", "{{ COMOUT_OCEAN_RESTART_PREV }}"] {% endfor %} {% endif %} - {% endfor %} # mem loop diff --git a/parm/stage/ocean_RT.yaml.j2 b/parm/stage/ocean_RT.yaml.j2 index 3957388eba4..810f533d20a 100644 --- a/parm/stage/ocean_RT.yaml.j2 +++ b/parm/stage/ocean_RT.yaml.j2 @@ -1,23 +1,20 @@ ocean_RT: mkdir: - - "{{ COMOUT_OCEAN_RESTART_PREV_MEM }}" - - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}" + - "{{ COMOUT_OCEAN_RESTART_PREV }}" + - "{{ COMOUT_OCEAN_ANALYSIS }}" link_req: # select restart members files (80) specific to the cycle - {% set mid_cyc = ("%02d" | format(previous_cycle_HH | int + half_window)) ~ "0000" %} - {% set restart_mem_path = ICSDIR ~ '/' ~ 'enkfgdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/' ~ 'mem%03d' | format(gfs_member) ~ '/model/ocean/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '.' %} - {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(gfs_member) ~ '/analysis/ocean/enkfgfs.t' ~ current_cycle_HH ~ 'z.ocninc.nc' %} - {% set restart_destination_path = COMOUT_OCEAN_RESTART_PREV_MEM %} - {% set increment_destination_path = COMOUT_OCEAN_ANALYSIS_MEM %} + {% set restart_mem_path = ICSDIR ~ '/' ~ 'enkfgdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/' ~ 'mem%03d' | format(member) ~ '/model/ocean/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '0000.' %} + {% set increment_mem_path = ICSDIR ~ '/' ~ 'enkfgfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/' ~ 'mem%03d' | format(member) ~ '/analysis/ocean/enkfgfs.t' ~ current_cycle_HH ~ 'z.ocninc.nc' %} # Include increment files {% set file = increment_mem_path %} - - ["{{ file }}", "{{ increment_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_OCEAN_ANALYSIS }}"] {% if path_exists(ICSDIR) %} {% for ftype in ["MOM.res.nc", "MOM.res_1.nc", "MOM.res_2.nc", "MOM.res_3.nc"] %} # Include base file for restart files {% set file = restart_mem_path ~ ftype %} - - ["{{ file }}", "{{ restart_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_OCEAN_RESTART_PREV }}"] {% endfor %} {% endif %} diff --git a/parm/stage/ocean_control_RT.yaml.j2 b/parm/stage/ocean_control_RT.yaml.j2 index 249c8940650..6e5f654459d 100644 --- a/parm/stage/ocean_control_RT.yaml.j2 +++ b/parm/stage/ocean_control_RT.yaml.j2 @@ -1,18 +1,15 @@ ocean_control_RT: mkdir: - - "{{ COMOUT_OCEAN_RESTART_PREV_MEM }}" - - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}" + - "{{ COMOUT_OCEAN_RESTART_PREV }}" + - "{{ COMOUT_OCEAN_ANALYSIS }}" link_req: - {% set mid_cyc = ("%02d" | format(previous_cycle_HH | int + half_window)) ~ "0000" %} - {% set restart_path = ICSDIR ~ '/' ~ 'gdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/model/ocean/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '.' %} + {% set restart_path = ICSDIR ~ '/' ~ 'gdas.' ~ previous_cycle_YMD ~ '/' ~ previous_cycle_HH ~ '/model/ocean/restart/' ~ previous_cycle_YMD ~ '.' ~ mid_cyc ~ '0000.' %} {% set increment_file = ICSDIR ~ '/' ~ 'gfs.' ~ current_cycle_YMD ~ '/' ~ current_cycle_HH ~ '/analysis/ocean/gfs.t' ~ current_cycle_HH ~ 'z.ocninc.nc' %} - {% set restart_destination_path = COMOUT_OCEAN_RESTART_PREV_MEM %} - {% set increment_destination_path = COMOUT_OCEAN_ANALYSIS_MEM %} # Restart increment files {% for ftype in ["MOM.res.nc", "MOM.res_1.nc", "MOM.res_2.nc", "MOM.res_3.nc"] %} {% set file = restart_path ~ ftype %} - - ["{{ file }}", "{{ restart_destination_path }}"] + - ["{{ file }}", "{{ COMOUT_OCEAN_RESTART_PREV }}"] {% endfor %} # Include increment files - - ["{{ increment_file }}", "{{ increment_destination_path }}"] + - ["{{ increment_file }}", "{{ COMOUT_OCEAN_ANALYSIS }}"] diff --git a/parm/stage/ocean_ens_perturbations.yaml.j2 b/parm/stage/ocean_ens_perturbations.yaml.j2 index d551d89694f..000dab1aa0c 100644 --- a/parm/stage/ocean_ens_perturbations.yaml.j2 +++ b/parm/stage/ocean_ens_perturbations.yaml.j2 @@ -1,14 +1,6 @@ ocean_ens_perturbation: mkdir: - {% for mem in range(first_mem + 1, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COMOUT_OCEAN_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_OCEAN_ANALYSIS }}" link_req: - {% for mem in range(first_mem + 1, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COMOUT_OCEAN_ANALYSIS_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.mom6_perturbation.nc", - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}/{{ RUN }}.t{{ current_cycle_HH }}z.mom6_increment.i006.nc"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_ANALYSIS | relpath(ROTDIR) }}/{{ m_prefix }}.mom6_perturbation.nc", + "{{ COMOUT_OCEAN_ANALYSIS }}/{{ RUN }}.t{{ current_cycle_HH }}z.mom6_increment.i006.nc"] diff --git a/parm/stage/ocean_mediator.yaml.j2 b/parm/stage/ocean_mediator.yaml.j2 index e72f973ac54..6a60a933df4 100644 --- a/parm/stage/ocean_mediator.yaml.j2 +++ b/parm/stage/ocean_mediator.yaml.j2 @@ -1,15 +1,7 @@ -{% if path_exists(ICSDIR ~ "/" ~ COMOUT_MED_RESTART_PREV_MEM_list[0] | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".ufs.cpld.cpl.r.nc") %} +{% if path_exists(ICSDIR ~ "/" ~ COMOUT_MED_RESTART_PREV | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".ufs.cpld.cpl.r.nc") %} ocean_mediator: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_MED_RESTART_PREV_MEM = COMOUT_MED_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_MED_RESTART_PREV_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_MED_RESTART_PREV }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_MED_RESTART_PREV_MEM = COMOUT_MED_RESTART_PREV_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_MED_RESTART_PREV_MEM | relpath(ROTDIR) }}/{{ m_prefix }}.ufs.cpld.cpl.r.nc", "{{ COMOUT_MED_RESTART_PREV_MEM }}"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_MED_RESTART_PREV | relpath(ROTDIR) }}/{{ m_prefix }}.ufs.cpld.cpl.r.nc", "{{ COMOUT_MED_RESTART_PREV }}"] {% endif %} # path exists diff --git a/parm/stage/ocean_rerun.yaml.j2 b/parm/stage/ocean_rerun.yaml.j2 index c64fe82be4c..9ef484b40f7 100644 --- a/parm/stage/ocean_rerun.yaml.j2 +++ b/parm/stage/ocean_rerun.yaml.j2 @@ -1,14 +1,6 @@ ocean_rerun: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COMOUT_OCEAN_ANALYSIS_MEM_list[imem] %} - - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_OCEAN_ANALYSIS }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_OCEAN_ANALYSIS_MEM = COMOUT_OCEAN_ANALYSIS_MEM_list[imem] %} - - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_ANALYSIS_MEM | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.mom6_increment.i006.nc", - "{{ COMOUT_OCEAN_ANALYSIS_MEM }}/"] - {% endfor %} # mem loop + - ["{{ ICSDIR }}/{{ COMOUT_OCEAN_ANALYSIS | relpath(ROTDIR) }}/{{ RUN }}.t{{ current_cycle_HH }}z.mom6_increment.i006.nc", {{ COMOUT_OCEAN_ANALYSIS }}] + diff --git a/parm/stage/wave.yaml.j2 b/parm/stage/wave.yaml.j2 index f7d42a9a9cf..ecb3ff50781 100644 --- a/parm/stage/wave.yaml.j2 +++ b/parm/stage/wave.yaml.j2 @@ -1,20 +1,12 @@ wave: mkdir: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_WAVE_RESTART_PREV_MEM = COMOUT_WAVE_RESTART_PREV_MEM_list[imem] %} - - "{{ COMOUT_WAVE_RESTART_PREV_MEM }}" - {% endfor %} # mem loop + - "{{ COMOUT_WAVE_RESTART_PREV }}" link_req: - {% for mem in range(first_mem, last_mem + 1) %} - {% set imem = mem - first_mem %} - {% set COMOUT_WAVE_RESTART_PREV_MEM = COMOUT_WAVE_RESTART_PREV_MEM_list[imem] %} - {% set ww3_file = ICSDIR ~ "/" ~ COMOUT_WAVE_RESTART_PREV_MEM | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".restart.ww3" %} - {% if path_exists(ww3_file ~ ".nc") %} - - ["{{ ww3_file }}.nc" , "{{ COMOUT_WAVE_RESTART_PREV_MEM }}/{{ m_prefix }}.restart.ww3.nc"] + {% set ww3_file = ICSDIR ~ "/" ~ COMOUT_WAVE_RESTART_PREV | relpath(ROTDIR) ~ "/" ~ m_prefix ~ ".restart.ww3" %} + {% if path_exists(ww3_file ~ ".nc") %} + - ["{{ ww3_file }}.nc" , "{{ COMOUT_WAVE_RESTART_PREV }}/{{ m_prefix }}.restart.ww3.nc"] {% else %} {% if path_exists(ww3_file) %} - - ["{{ ww3_file }}" , "{{ COMOUT_WAVE_RESTART_PREV_MEM }}/{{ m_prefix }}.restart.ww3"] + - ["{{ ww3_file }}" , "{{ COMOUT_WAVE_RESTART_PREV }}/{{ m_prefix }}.restart.ww3"] {% endif %} {% endif %} - {% endfor %} # mem loop diff --git a/parm/ufs/fv3/diag_table b/parm/ufs/fv3/diag_table index ba4f9c793d5..ffc60816b83 100644 --- a/parm/ufs/fv3/diag_table +++ b/parm/ufs/fv3/diag_table @@ -49,10 +49,10 @@ "ocean_model", "SW", "SW", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 "ocean_model", "LW", "LW", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 "ocean_model", "evap", "evap", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 -"ocean_model", "lprec", "lprec", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 +#"ocean_model", "lprec", "lprec", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 "ocean_model", "lrunoff", "lrunoff", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 #"ocean_model", "frunoff", "frunoff", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 -"ocean_model", "fprec", "fprec", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 +#"ocean_model", "fprec", "fprec", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 "ocean_model", "LwLatSens", "LwLatSens", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 "ocean_model", "Heat_PmE", "Heat_PmE", "@[MOM6_OUTPUT_DIR]/ocn%4yr%2mo%2dy%2hr","all",.true.,"none",2 diff --git a/scripts b/scripts new file mode 120000 index 00000000000..f3685b2bf23 --- /dev/null +++ b/scripts @@ -0,0 +1 @@ +dev/scripts/ \ No newline at end of file diff --git a/scripts/exgdas_atmos_verfozn.sh b/scripts/exgdas_atmos_verfozn.sh deleted file mode 100755 index 30a945ab914..00000000000 --- a/scripts/exgdas_atmos_verfozn.sh +++ /dev/null @@ -1,50 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -# exgdas_atmos_verfozn.sh -# -# This script runs the data extract/validation portion of the Ozone Monitor -# (OznMon) DA package. -# -################################################################################ -export err=0 - -data_available=0 - -if [[ -s ${oznstat} ]]; then - data_available=1 - - #------------------------------------------------------------------ - # Copy data files file to local data directory. - # Untar oznstat file. - #------------------------------------------------------------------ - - cpreq "${oznstat}" "./oznstat.${PDY}${cyc}" - - tar -xvf "oznstat.${PDY}${cyc}" - rm -f "oznstat.${PDY}${cyc}" - - netcdf=0 - count=$(ls diag* | grep ".nc4" | wc -l) - if [ "${count}" -gt 0 ] ; then - netcdf=1 - for filenc4 in $(ls diag*nc4.gz); do - file=$(echo "${filenc4}" | cut -d'.' -f1-2).gz - mv "${filenc4}" "${file}" - done - fi - - export OZNMON_NETCDF=${netcdf} - - "${USHgfs}/ozn_xtrct.sh" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "ozn_xtrct.sh failed!" - fi - -else - # oznstat file not found - export err=1 - err_exit "${oznstat} does not exist!" -fi -exit 0 diff --git a/scripts/exgdas_enkf_earc_vrfy.py b/scripts/exgdas_enkf_earc_vrfy.py deleted file mode 100755 index 973a4257b91..00000000000 --- a/scripts/exgdas_enkf_earc_vrfy.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import os - -from pygfs.task.archive import Archive -from wxflow import AttrDict, Logger, cast_strdict_as_dtypedict, chdir, logit - -# initialize root logger -logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) - - -@logit(logger) -def main(): - - config = cast_strdict_as_dtypedict(os.environ) - - # Instantiate the Archive object - archive = Archive(config) - - # Pull out all the configuration keys needed to run the rest of archive steps - keys = ['current_cycle', 'RUN', 'PSLOT', 'ROTDIR', 'PARMgfs', - 'ARCDIR', 'MODE', 'DO_JEDIATMENS', 'DO_FIT2OBS', 'DO_JEDIATMVAR', - 'DO_JEDISNOWDA', 'DO_AERO_ANL', 'DO_PREP_OBS_AERO', 'NET', 'MODE', 'FHOUT_GFS', - 'FHMAX_HF_GFS', 'FHOUT_GFS', 'FHMAX_FITS', 'FHMAX', 'FHOUT', 'FHMAX_GFS', 'DO_GSISOILDA', 'DO_LAND_IAU'] - - archive_dict = AttrDict() - for key in keys: - archive_dict[key] = archive.task_config.get(key) - if archive_dict[key] is None: - print(f"Warning: key ({key}) not found in task_config!") - - # Also import all COMIN* directory and template variables - for key in archive.task_config.keys(): - if key.startswith("COMIN"): - archive_dict[key] = archive.task_config[key] - - cwd = os.getcwd() - - os.chdir(config.ROTDIR) - - # Determine which archives to create - arcdir_set = archive.configure_vrfy(archive_dict) - - # Populate the product archive (ARCDIR) - archive.execute_store_products(arcdir_set) - - os.chdir(cwd) - - -if __name__ == '__main__': - main() diff --git a/scripts/exgdas_enkf_ecen.sh b/scripts/exgdas_enkf_ecen.sh deleted file mode 100755 index d2a4ff726aa..00000000000 --- a/scripts/exgdas_enkf_ecen.sh +++ /dev/null @@ -1,353 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exgdas_enkf_ecen.sh -# Script description: recenter ensemble around hi-res deterministic analysis -# -# Author: Rahul Mahajan Org: NCEP/EMC Date: 2017-03-02 -# -# Abstract: This script recenters ensemble around hi-res deterministic analysis -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# -################################################################################ - -# Directories. -pwd=$(pwd) - -# Base variables -ntiles=${ntiles:-6} - -# Utilities -NCLEN=${NCLEN:-${USHgfs}/getncdimlen} - -# Scripts - -# Executables. -GETATMENSMEANEXEC=${GETATMENSMEANEXEC:-${EXECgfs}/getsigensmeanp_smooth.x} -GETSFCENSMEANEXEC=${GETSFCENSMEANEXEC:-${EXECgfs}/getsfcensmeanp.x} -RECENATMEXEC=${RECENATMEXEC:-${EXECgfs}/recentersigp.x} -CALCINCNEMSEXEC=${CALCINCNEMSEXEC:-${EXECgfs}/calc_increment_ens.x} -CALCINCNCEXEC=${CALCINCEXEC:-${EXECgfs}/calc_increment_ens_ncio.x} - -# Files. -OPREFIX=${OPREFIX:-""} -OSUFFIX=${OSUFFIX:-""} -APREFIX=${APREFIX:-""} -APREFIX_ENS=${APREFIX_ENS:-${APREFIX}} -GPREFIX=${GPREFIX:-""} -GPREFIX_ENS=${GPREFIX_ENS:-${GPREFIX}} - -# Variables -imp_physics=${imp_physics:-99} -INCREMENTS_TO_ZERO=${INCREMENTS_TO_ZERO:-"'NONE'"} -DOIAU=${DOIAU_ENKF:-"NO"} -FHMIN=${FHMIN_ECEN:-3} -FHMAX=${FHMAX_ECEN:-9} -FHOUT=${FHOUT_ECEN:-3} -FHSFC=${FHSFC_ECEN:-${FHMIN}} -NMEM_ENS_MAX=${NMEM_ENS:-80} -if [[ "${RUN}" = "enkfgfs" ]]; then - DO_CALC_INCREMENT=${DO_CALC_INCREMENT_ENKF_GFS:-"NO"} - NMEM_ENS=${NMEM_ENS_GFS:-30} - ec_offset=${NMEM_ENS_GFS_OFFSET:-20} - mem_offset=$((ec_offset * cyc/6)) -else - DO_CALC_INCREMENT=${DO_CALC_INCREMENT:-"NO"} - NMEM_ENS=${NMEM_ENS:-80} - mem_offset=0 -fi - -# global_chgres stuff -CHGRESNEMS=${CHGRESNEMS:-${EXECgfs}/enkf_chgres_recenter.x} -CHGRESNC=${CHGRESNC:-${EXECgfs}/enkf_chgres_recenter_nc.x} -NTHREADS_CHGRES=${NTHREADS_CHGRES:-24} -APRUN_CHGRES=${APRUN_CHGRES:-""} - -# global_cycle stuff -CYCLESH=${CYCLESH:-${USHgfs}/global_cycle.sh} -export CYCLEXEC=${CYCLEXEC:-${EXECgfs}/global_cycle} -APRUN_CYCLE=${APRUN_CYCLE:-${APRUN:-""}} -NTHREADS_CYCLE=${NTHREADS_CYCLE:-${NTHREADS:-1}} -export CYCLVARS=${CYCLVARS:-"FSNOL=-2.,FSNOS=99999.,"} -export FHOUR=${FHOUR:-0} -export DELTSFC=${DELTSFC:-6} - - -RECENTER_ENKF=${RECENTER_ENKF:-"YES"} -SMOOTH_ENKF=${SMOOTH_ENKF:-"YES"} - -APRUN_ECEN=${APRUN_ECEN:-${APRUN:-""}} -NTHREADS_ECEN=${NTHREADS_ECEN:-${NTHREADS:-1}} -APRUN_CALCINC=${APRUN_CALCINC:-${APRUN:-""}} -NTHREADS_CALCINC=${NTHREADS_CALCINC:-${NTHREADS:-1}} - -################################################################################ -# Preprocessing - -ENKF_SUFFIX="s" -if [[ "${SMOOTH_ENKF}" == "NO" ]]; then - ENKF_SUFFIX="" -fi - -################################################################################ -# Link ensemble member guess, analysis and increment files -for FHR in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - -for imem in $(seq 1 ${NMEM_ENS}); do - smem=$((imem + mem_offset)) - if (( smem > NMEM_ENS_MAX )); then - smem=$((smem - NMEM_ENS_MAX)) - fi - gmemchar="mem"$(printf %03i ${smem}) - memchar="mem"$(printf %03i ${imem}) - - MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ - COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL - - MEMDIR=${gmemchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -x \ - COMIN_ATMOS_HISTORY_MEM_PREV:COM_ATMOS_HISTORY_TMPL - - ${NLN} "${COMIN_ATMOS_HISTORY_MEM_PREV}/${GPREFIX_ENS}atm.f00${FHR}${ENKF_SUFFIX}.nc" "./atmges_${memchar}" - if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}analysis.atm.a00${FHR}.nc" "./atmanl_${memchar}" - fi - mkdir -p "${COMOUT_ATMOS_ANALYSIS_MEM}" - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}increment.atm.i00${FHR}.nc" "./atminc_${memchar}" - if [[ ${RECENTER_ENKF} = "YES" ]]; then - if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}recentered_analysis.atm.a006.nc" "./ratmanl_${memchar}" - else - ${NLN} "${COMOUT_ATMOS_ANALYSIS_MEM}/${APREFIX_ENS}recentered_increment.atm.i00${FHR}.nc" "./ratminc_${memchar}" - fi - fi -done - -if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - # Link ensemble mean analysis - ${NLN} "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX_ENS}ensmean_analysis.atm.a00${FHR}.nc" "./atmanl_ensmean" - - # Compute ensemble mean analysis - DATAPATH="./" - ATMANLNAME="atmanl" - ATMANLMEANNAME="atmanl_ensmean" - - export OMP_NUM_THREADS=${NTHREADS_ECEN} - export pgm=${GETATMENSMEANEXEC} - source prep_step - - cpreq ${GETATMENSMEANEXEC} ${DATA} - ${APRUN_ECEN} ${DATA}/$(basename ${GETATMENSMEANEXEC}) ${DATAPATH} ${ATMANLMEANNAME} ${ATMANLNAME} ${NMEM_ENS} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to recenter the ensemble analyses!" - fi -else - # Link ensemble mean increment - ${NLN} "${COMOUT_ATMOS_ANALYSIS_STAT}/${APREFIX_ENS}ensmean_increment.atm.i00${FHR}.nc" "./atminc_ensmean" - - # Compute ensemble mean increment - DATAPATH="./" - ATMINCNAME="atminc" - ATMINCMEANNAME="atminc_ensmean" - - export OMP_NUM_THREADS=${NTHREADS_ECEN} - export pgm=${GETATMENSMEANEXEC} - source prep_step - - cpreq ${GETATMENSMEANEXEC} ${DATA} - ${APRUN_ECEN} ${DATA}/$(basename ${GETATMENSMEANEXEC}) ${DATAPATH} ${ATMINCMEANNAME} ${ATMINCNAME} ${NMEM_ENS} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to recenter the ensemble increments!" - fi - - # If available, link to ensemble mean guess. Otherwise, compute ensemble mean guess - if [[ -s "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX_ENS}ensmean.atm.f00${FHR}.nc" ]]; then - ${NLN} "${COMIN_ATMOS_HISTORY_STAT_PREV}/${GPREFIX_ENS}ensmean.atm.f00${FHR}.nc" "./atmges_ensmean" - else - DATAPATH="./" - ATMGESNAME="atmges" - ATMGESMEANNAME="atmges_ensmean" - - export OMP_NUM_THREADS=${NTHREADS_ECEN} - export pgm=${GETATMENSMEANEXEC} - source prep_step - - cpreq ${GETATMENSMEANEXEC} ${DATA} - ${APRUN_ECEN} ${DATA}/$(basename ${GETATMENSMEANEXEC}) ${DATAPATH} ${ATMGESMEANNAME} ${ATMGESNAME} ${NMEM_ENS} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to recenter the ensemble mean guess!" - fi - fi -fi - -if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - LONB_ENKF=${LONB_ENKF:-$(${NCLEN} atmanl_ensmean grid_xt)} # get LONB - LATB_ENKF=${LATB_ENKF:-$(${NCLEN} atmanl_ensmean grid_yt)} # get LATB - LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} atmanl_ensmean pfull)} # get LEVS -else - LONB_ENKF=${LONB_ENKF:-$(${NCLEN} atminc_ensmean lon)} # get LONB - LATB_ENKF=${LATB_ENKF:-$(${NCLEN} atminc_ensmean lat)} # get LATB - LEVS_ENKF=${LEVS_ENKF:-$(${NCLEN} atminc_ensmean lev)} # get LEVS -fi -JCAP_ENKF=${JCAP_ENKF:--9999} # there is no jcap in these files -if [[ ${JCAP_ENKF} -eq -9999 && ${LATB_ENKF} -ne -9999 ]]; then - JCAP_ENKF=$((LATB_ENKF-2)) -fi -if [[ ${LONB_ENKF} -eq -9999 || ${LATB_ENKF} -eq -9999 || ${LEVS_ENKF} -eq -9999 || ${JCAP_ENKF} -eq -9999 ]]; then - export err=9 - err_exit "One or more EnKF background parameters are undefined!" -fi - -################################################################################ -# This is to give the user the option to recenter, default is YES -if [[ ${RECENTER_ENKF} = "YES" ]]; then - - # GSI EnVar analysis - ATMANL_GSI="${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}analysis.atm.a00${FHR}.nc" - ATMANL_GSI_ENSRES="${COMIN_ATMOS_ANALYSIS_DET}/${APREFIX}ensres_analysis.atm.a00${FHR}.nc" - - # if we already have a ensemble resolution GSI analysis then just link to it - if [[ -f ${ATMANL_GSI_ENSRES} ]]; then - - ${NLN} ${ATMANL_GSI_ENSRES} atmanl_gsi_ensres - - else - - ${NLN} ${ATMANL_GSI} atmanl_gsi - ${NLN} ${ATMANL_GSI_ENSRES} atmanl_gsi_ensres - SIGLEVEL=${SIGLEVEL:-${FIXgfs}/am/global_hyblev.l${LEVS}.txt} - ${NLN} ${CHGRESNC} chgres.x - chgresnml=chgres_nc_gauss.nml - nmltitle=chgres - - export OMP_NUM_THREADS=${NTHREADS_CHGRES} - - rm -f "${chgresnml}" - cat > "${chgresnml}" << EOF -&${nmltitle}_setup - i_output=${LONB_ENKF} - j_output=${LATB_ENKF} - input_file="atmanl_gsi" - output_file="atmanl_gsi_ensres" - terrain_file="atmanl_ensmean" - vcoord_file="${SIGLEVEL}" -/ -EOF - cat ${chgresnml} - ${APRUN_CHGRES} ./chgres.x - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to change the resolution of the deterministic analysis to the ensemble resolution!" - fi - fi - - if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - ################################################################################ - # Recenter ensemble member atmospheric analyses about hires analysis - - FILENAMEIN="atmanl" - FILENAME_MEANIN="atmanl_ensmean" # EnKF ensemble mean analysis - FILENAME_MEANOUT="atmanl_gsi_ensres" # recenter around GSI analysis at ensemble resolution - FILENAMEOUT="ratmanl" - - export OMP_NUM_THREADS=${NTHREADS_ECEN} - export pgm=${RECENATMEXEC} - source prep_step - - cpreq ${RECENATMEXEC} ${DATA} - ${APRUN_ECEN} ${DATA}/$(basename ${RECENATMEXEC}) ${FILENAMEIN} ${FILENAME_MEANIN} ${FILENAME_MEANOUT} ${FILENAMEOUT} ${NMEM_ENS} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to recenter the ensemble resolution mean analysis" - fi - else - ################################################################################ - # Recenter ensemble member atmospheric increments about hires analysis - - FILENAMEIN="atminc" - FILENAME_INCMEANIN="atminc_ensmean" # EnKF ensemble mean increment - FILENAME_GESMEANIN="atmges_ensmean" # EnKF ensemble mean guess - FILENAME_GSIDET="atmanl_gsi_ensres" # recenter around GSI analysis at ensemble resolution - FILENAMEOUT="ratminc" - - export OMP_NUM_THREADS=${NTHREADS_ECEN} - - # make the small namelist file for incvars_to_zero - - rm -f recenter.nml - cat > recenter.nml << EOF -&recenter - incvars_to_zero = ${INCREMENTS_TO_ZERO} -/ -EOF -cat recenter.nml - - export pgm=${RECENATMEXEC} - source prep_step - - cpreq ${RECENATMEXEC} ${DATA} - ${APRUN_ECEN} ${DATA}/$(basename ${RECENATMEXEC}) ${FILENAMEIN} ${FILENAME_INCMEANIN} ${FILENAME_GSIDET} ${FILENAMEOUT} ${NMEM_ENS} ${FILENAME_GESMEANIN} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to recenter the mean ensemble resolution increments!" - fi - fi -fi - -################################################################################ -# Calculate ensemble analysis increment -if [[ ${DO_CALC_INCREMENT} = "YES" ]]; then - if [[ ${RECENTER_ENKF} = "YES" ]]; then - ATMANLNAME='ratmanl' - else - ATMANLNAME='atmanl' - fi - - export OMP_NUM_THREADS=${NTHREADS_CALCINC} - CALCINCEXEC=${CALCINCNCEXEC} - - export pgm=${CALCINCEXEC} - source prep_step - - cpreq "${CALCINCEXEC}" "${DATA}" - rm -f calc_increment.nml - - cat > calc_increment.nml << EOF -&setup - datapath = './' - analysis_filename = '${ATMANLNAME}' - firstguess_filename = 'atmges' - increment_filename = 'atminc' - debug = .false. - nens = ${NMEM_ENS} - imp_physics = ${imp_physics} -/ -&zeroinc - incvars_to_zero = ${INCREMENTS_TO_ZERO} -/ -EOF -cat calc_increment.nml - - ${APRUN_CALCINC} ${DATA}/$(basename ${CALCINCEXEC}) - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to calculate the increment from the ensemble guess!" - fi -fi -done # loop over analysis times in window - -################################################################################ - -################################################################################ -# Postprocessing -cd "${pwd}" || exit 1 - -exit "${err}" diff --git a/scripts/exgdas_enkf_post.sh b/scripts/exgdas_enkf_post.sh deleted file mode 100755 index 2c75d25619c..00000000000 --- a/scripts/exgdas_enkf_post.sh +++ /dev/null @@ -1,171 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exgdas_enkf_post.sh -# Script description: Global ensemble forecast post processing -# -# Author: Rahul Mahajan Org: NCEP/EMC Date: 2017-03-02 -# -# Abstract: This script post-processes global ensemble forecast output -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# -################################################################################ - -# Directories. -pwd=$(pwd) - -APRUN_EPOS=${APRUN_EPOS:-${APRUN:-""}} -NTHREADS_EPOS=${NTHREADS_EPOS:-1} - -# Fix files -LEVS=${LEVS:-64} -HYBENSMOOTH=${HYBENSMOOTH:-${FIXgfs}/gsi/global_hybens_smoothinfo.l${LEVS}.txt} - -# Executables. -GETATMENSMEANEXEC=${GETATMENSMEANEXEC:-${EXECgfs}/getsigensmeanp_smooth.x} -GETSFCENSMEANEXEC=${GETSFCENSMEANEXEC:-${EXECgfs}/getsfcensmeanp.x} - -# Other variables. -PREFIX=${PREFIX:-""} -FHMIN=${FHMIN_EPOS:-3} -FHMAX=${FHMAX_EPOS:-9} -FHOUT=${FHOUT_EPOS:-3} - -if [[ "${RUN}" == "enkfgfs" ]]; then - NMEM_ENS=${NMEM_ENS_GFS:-${NMEM_ENS:-30}} -else - NMEM_ENS=${NMEM_ENS:-80} -fi -SMOOTH_ENKF=${SMOOTH_ENKF:-"NO"} -ENKF_SPREAD=${ENKF_SPREAD:-"NO"} - -################################################################################ -# Preprocessing -ENKF_SUFFIX="s" -if [[ "${SMOOTH_ENKF}" == "NO" ]]; then - ENKF_SUFFIX="" -fi - -################################################################################ -# Copy executables to working directory -cpreq "${GETSFCENSMEANEXEC}" "${DATA}" -cpreq "${GETATMENSMEANEXEC}" "${DATA}" - -export OMP_NUM_THREADS=${NTHREADS_EPOS} - -################################################################################ -# Forecast ensemble member files -for imem in $(seq 1 ${NMEM_ENS}); do - memchar="mem"$(printf %03i "${imem}") - MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ - COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL - - for fhr in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - fhrchar=$(printf %03i "${fhr}") - ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.f${fhrchar}.nc" "sfcf${fhrchar}_${memchar}" - ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.f${fhrchar}.nc" "atmf${fhrchar}_${memchar}" - done -done - -# Forecast ensemble mean and smoothed files -MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ - COMOUT_ATMOS_HISTORY_STAT:COM_ATMOS_HISTORY_TMPL -if [[ ! -d "${COMOUT_ATMOS_HISTORY_STAT}" ]]; then - mkdir -p "${COMOUT_ATMOS_HISTORY_STAT}" -fi - -for fhr in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - fhrchar=$(printf %03i "${fhr}") - ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.sfc.f${fhrchar}.nc" "sfcf${fhrchar}.ensmean" - ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.atm.f${fhrchar}.nc" "atmf${fhrchar}.ensmean" - if [[ "${SMOOTH_ENKF}" == "YES" ]]; then - for imem in $(seq 1 ${NMEM_ENS}); do - memchar="mem"$(printf %03i "${imem}") - MEMDIR="${memchar}" YMD=${PDY} HH=${cyc} declare_from_tmpl -x \ - COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL - ${NLN} "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.f${fhrchar}${ENKF_SUFFIX}.nc" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" - done - fi - if [[ "${ENKF_SPREAD}" == "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensspread.atm.f${fhrchar}.nc" "atmf${fhrchar}.ensspread" - fi -done - -################################################################################ -# Generate ensemble mean surface and atmospheric files - -if [[ "${SMOOTH_ENKF}" == "YES" ]]; then - cpreq "${HYBENSMOOTH}" ./hybens_smoothinfo -fi - -for fhr in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - fhrchar=$(printf %03i ${fhr}) - - export pgm=${GETSFCENSMEANEXEC} - source prep_step - - ${APRUN_EPOS} "${DATA}/$(basename "${GETSFCENSMEANEXEC}")" ./ "sfcf${fhrchar}.ensmean" "sfcf${fhrchar}" "${NMEM_ENS}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to calculate ensemble surface mean for forecast hour ${fhr}" - fi - - export pgm=${GETATMENSMEANEXEC} - source prep_step - - if [[ "${ENKF_SPREAD}" == "YES" ]]; then - ${APRUN_EPOS} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" ./ "atmf${fhrchar}.ensmean" "atmf${fhrchar}" "${NMEM_ENS}" "atmf${fhrchar}.ensspread" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to calculate ensemble atmospheric mean and spread for forecast hour ${fhr}" - fi - else - ${APRUN_EPOS} "${DATA}/$(basename "${GETATMENSMEANEXEC}")" ./ "atmf${fhrchar}.ensmean" "atmf${fhrchar}" "${NMEM_ENS}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to calculate ensemble atmospheric mean for forecast hour ${fhr}" - fi - fi -done - -################################################################################ -# If smoothing on but no smoothing output, copy smoothed ensemble atmospheric files -if [[ "${SMOOTH_ENKF}" == "YES" ]]; then - for fhr in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - fhrchar=$(printf "%03i" "${fhr}") - if [[ ! -s "atmf${fhrchar}${ENKF_SUFFIX}_mem001" ]]; then - echo "WARNING! no smoothed ensemble member for fhour = ${fhrchar}" >&2 - for imem in $(seq 1 ${NMEM_ENS}); do - memchar="mem"$(printf "%03i" "${imem}") - cpreq "atmf${fhrchar}_${memchar}" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" - done - fi - done -fi - -################################################################################ -# Send DBN alerts -if [[ "${SENDDBN}" == "YES" ]]; then - - for fhr in $(seq ${FHMIN} ${FHOUT} ${FHMAX}); do - fhrchar=$(printf "%03i" "${fhr}") - if [[ $(expr ${fhr} % 3) -eq 0 ]]; then - if [[ -s "./sfcf${fhrchar}.ensmean" ]]; then - "${DBNROOT}/bin/dbn_alert" "MODEL" "GFS_ENKF" "${job}" "${COMOUT_ATMOS_HISTORY_STAT}/${PREFIX}ensmean.sfc.f${fhrchar}.nc" - fi - fi - done - -fi - -################################################################################ -# Postprocessing -cd "${pwd}" || exit 1 - -exit "${err}" diff --git a/scripts/exgfs_atmos_awips_20km_1p0deg.sh b/scripts/exgfs_atmos_awips_20km_1p0deg.sh deleted file mode 100755 index d2bfe23d7eb..00000000000 --- a/scripts/exgfs_atmos_awips_20km_1p0deg.sh +++ /dev/null @@ -1,241 +0,0 @@ -#! /usr/bin/env bash - -############################################################################## -# UTILITY SCRIPT NAME : exgfs_awips_20km_1p0deg.sh -# DATE WRITTEN : 11/01/2017 -# -# Abstract: This utility script produces the GFS AWIPS 20km and 1.0 deg -# grids GRIB2 -# -# Input: 1 arguments are passed to this script. -# 1st argument - Forecast Hour - format of 3I (3 digits) -# -############################################################################### -# echo "------------------------------------------------" -# echo "JGFS_AWIPS_00/06/12/18 GFS postprocessing" -# echo "------------------------------------------------" -# echo "History: NOV 2017 - First implementation of this new script to " -# echo " process GFS AWIPS 20km and 1.0 deg grids products " -# echo " MAR 2025 - Remove job reference from product name strings " -# echo " " -############################################################################### - -fcsthr="$1" -num=$# - -if [[ ${num} -ne 1 ]]; then - echo "" - echo " FATAL ERROR: Incorrect number of arguments " - echo "" - echo "" - echo "Usage: $0 \${fcsthr} (3 digits) " - echo "" - exit 16 -fi - -cd "${DATA}" || exit 2 - -# "Import" functions used in this script -source "${USHgfs}/product_functions.sh" - -############################################### -# Wait for the availability of the pgrb file -############################################### -sleep_interval=10 -max_tries=180 -idxfile="${COMIN_ATMOS_GRIB_0p25}/${RUN}.${cycle}.pres_b.0p25.f${fcsthr}.grib2.idx" -if ! wait_for_file "${idxfile}" "${sleep_interval}" "${max_tries}"; then - msg="FATAL ERROR: No GFS pgrb2 file after waiting" - err_exit "${msg}" -fi - -######################################## - -echo " ------------------------------------------" -echo " BEGIN MAKING GFS AWIPS PRODUCTS" -echo " ------------------------------------------" - -set +x -echo " " -echo "#######################################" -echo " Process GRIB AWIP GRIB2 PRODUCTS " -echo "#######################################" -echo " " -set_trace - -# Set type of Interpolation for WGRIB2 -export opt1=' -set_grib_type same -new_grid_winds earth ' -export opt1uv=' -set_grib_type same -new_grid_winds grid ' -export opt21=' -new_grid_interpolation bilinear -if ' -export opt22=":(CSNOW|CRAIN|CFRZR|CICEP|ICSEV):" -export opt23=' -new_grid_interpolation neighbor -fi ' -export opt24=' -set_bitmap 1 -set_grib_max_bits 16 -if ' -export opt25=":(APCP|ACPCP|PRATE|CPRAT):" -export opt26=' -set_grib_max_bits 25 -fi -if ' -export opt27=":(APCP|ACPCP|PRATE|CPRAT|DZDT):" -export opt28=' -new_grid_interpolation budget -fi ' - -############################################################### -# Process GFS GRIB AWIP PRODUCTS IN GRIB2 # -############################################################### - -cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.t${cyc}z.pres_a.0p25.f${fcsthr}.grib2" "tmpfile2${fcsthr}" -cpreq "${COMIN_ATMOS_GRIB_0p25}/gfs.t${cyc}z.pres_b.0p25.f${fcsthr}.grib2" "tmpfile2b${fcsthr}" -cat "tmpfile2${fcsthr}" "tmpfile2b${fcsthr}" > "tmpfile${fcsthr}" -${WGRIB2} "tmpfile${fcsthr}" | grep -F -f "${PARMgfs}/product/gfs_awips_parmlist_g2" | \ - ${WGRIB2} -i -grib masterfile "tmpfile${fcsthr}" && true -export err=$? -if [[ ${err} -ne 0 ]]; then - err_exit "masterfile does not exist." -fi - -${WGRIB2} masterfile -match ":PWAT:entire atmosphere" -grib gfs_pwat.grb -${WGRIB2} masterfile | grep -v ":PWAT:entire atmosphere" | ${WGRIB2} -i -grib temp_gfs masterfile -################################################################## -# Process to change PWAT from level 200 to 10 (Entire Atmosphere) -# in production defintion template (PDT) 4.0 -################################################################## -${WGRIB2} gfs_pwat.grb -set_byte 4 23 10 -grib gfs_pwat_levels_10.grb && true -export err=$? -if [[ ${err} -ne 0 ]]; then - err_exit "Failed to redefine PWAT for the entire atmosphere!" -fi - -cat temp_gfs gfs_pwat_levels_10.grb > tmp_masterfile - -for GRID in conus ak prico pac 003; do - case ${GRID} in - conus) - gridconus="lambert:265.0:25.0:25.0 226.541:369:20318.0 12.19:257:20318.0" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} tmp_masterfile ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${gridconus} "awps_file_f${fcsthr}_${GRID}" - ;; - ak) - gridak="nps:210.0:60.0 170.0:277:22500 35.0:225:22500" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} tmp_masterfile ${opt1uv} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${gridak} "awps_file_f${fcsthr}_${GRID}" - ;; - prico) - gridprico="latlon 271.75:275:0.25 50.75:205:-0.25" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${gridprico} "awps_file_f${fcsthr}_${GRID}" - ;; - pac) - gridpac="mercator:20.0 110.0:837:20000:270.0 -45.0:725:20000:65.7345" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${gridpac} "awps_file_f${fcsthr}_${GRID}" - ;; - 003) - ###################################################################### - # Process GFS GRIB AWIP 1.0 DEGREE (GRID 003) PRODUCTS IN GRIB2 # - ###################################################################### - grid003="latlon 0:360:1.0 90:181:-1.0" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} tmp_masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${grid003} "awps_file_f${fcsthr}_${GRID}" - ;; - *) - export err=2 - err_exit "Unknown output grid ${GRID}" - ;; - esac - trim_rh "awps_file_f${fcsthr}_${GRID}" - scale_dec "awps_file_f${fcsthr}_${GRID}" - ${GRB2INDEX} "awps_file_f${fcsthr}_${GRID}" "awps_file_fi${fcsthr}_${GRID}" - - ########################################################################### - # Checking fields in awps_file_f${fcsthr}_${GRID} file - # before TOCGRIB2 adding WMO headers for AWIPS products. - # - # NOTE: numparm is the total of fields in grib2_awpgfs_20km_conusf000 file - ########################################################################### - numparm=247 - numrec=$( ${WGRIB2} "awps_file_f${fcsthr}_${GRID}" | wc -l ) - - if [[ ${numrec} -lt ${numparm} ]]; then - export err=1 - msg="awps_file_f${fcsthr}_${GRID} file is missing fields for AWIPS !" - err_exit "${msg}" - fi - - # Processing AWIPS GRIB2 grids with WMO headers - - pgm=tocgrib2 - export pgm; prep_step - startmsg - - if [[ ${GRID} = "003" && $(( 10#${fcsthr} % 6 )) == 0 ]]; then - export FORT11="awps_file_f${fcsthr}_${GRID}" - export FORT31="awps_file_fi${fcsthr}_${GRID}" - export FORT51="grib2.awpgfs${fcsthr}.${GRID}" - - cpreq "${PARMgfs}/wmo/grib2_awpgfs${fcsthr}.${GRID}" "parm_list" - - ${TOCGRIB2} < "parm_list" >> "${pgmout}" 2> errfile && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to generate the awips Grib2 file!" - fi - - ############################## - # Post Files to ${COMOUT_ATMOS_WMO} - ############################## - - cpfs "grib2.awpgfs${fcsthr}.${GRID}" \ - "${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID}" - - ############################## - # Distribute Data - ############################## - - if [[ "${SENDDBN}" == "YES" || "${SENDAWIP}" == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" NTC_LOW "${NET}" "${job}" \ - "${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID}" - else - echo "File ${COMOUT_ATMOS_WMO}/grib2.awpgfs${fcsthr}.${GRID} not posted to db_net." - fi - elif [[ ${GRID} != "003" ]]; then - export FORT11="awps_file_f${fcsthr}_${GRID}" - export FORT31="awps_file_fi${fcsthr}_${GRID}" - export FORT51="grib2.awpgfs_20km_${GRID}_f${fcsthr}" - - cpreq "${PARMgfs}/wmo/grib2_awpgfs_20km_${GRID}f${fcsthr}" "parm_list" - - ${TOCGRIB2} < "parm_list" >> "${pgmout}" 2> errfile && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to write the AWIPS grib2 file" - fi - - ############################## - # Post Files to ${COMOUT_ATMOS_WMO} - ############################## - - cpfs "grib2.awpgfs_20km_${GRID}_f${fcsthr}" \ - "${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr}" - - ############################## - # Distribute Data - ############################## - - if [[ "${SENDDBN}" == "YES" || "${SENDAWIP}" == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" NTC_LOW "${NET}" "${job}" \ - "${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr}" - else - echo "File ${COMOUT_ATMOS_WMO}/grib2.awpgfs_20km_${GRID}_f${fcsthr} not posted to db_net." - fi - fi - echo "Awip Processing ${fcsthr} hour completed normally" - -done - -if [[ -e "${pgmout}" ]]; then - cat "${pgmout}" -fi - - -############## END OF SCRIPT ####################### diff --git a/scripts/exgfs_atmos_gempak_meta.sh b/scripts/exgfs_atmos_gempak_meta.sh deleted file mode 100755 index 0dcabd76a55..00000000000 --- a/scripts/exgfs_atmos_gempak_meta.sh +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env bash - -GEMGRD1="${RUN}_1p00_${PDY}${cyc}f" - -export numproc=23 - -# Find the last hour available -for (( fhr = fhend; fhr >= fhbeg; fhr = fhr - fhinc )) ; do - fhr3=$(printf "%03d" "${fhr}") - if [[ -r "${COMIN_ATMOS_GEMPAK_1p00}/${GEMGRD1}${fhr3}" ]]; then - break - fi -done - -sleep_interval=20 -max_tries=180 -first_time=0 -do_all=0 - -#loop through and process needed forecast hours -while [[ ${fhr} -le ${fhend} ]]; do - # - # First check to see if this is a rerun. If so make all Meta files - if [[ ${fhr} -gt 126 && ${first_time} -eq 0 ]]; then - do_all=1 - fi - first_time=1 - - if [[ ${fhr} -eq 120 ]]; then - fhr=126 - fi - - gempak_file="${COMIN_ATMOS_GEMPAK_1p00}/${GEMGRD1}${fhr3}" - if ! wait_for_file "${gempak_file}" "${sleep_interval}" "${max_tries}"; then - err_exit "FATAL ERROR: gempak grid file ${gempak_file} not available after maximum wait time." - fi - - export fhr - - ######################################################## - # Create a script to be poe'd - # - # Note: The number of scripts to be run MUST match the number - # of total_tasks set in the ecf script, or the job will fail. - # - rm -f poescript - - fhr3=$(printf "%03d" "${fhr}") - - if [[ ${do_all} -eq 1 ]] ; then - do_all=0 - # shellcheck disable=SC2312 - awk '{print $1}' "${HOMEgfs}/gempak/fix/gfs_meta" | envsubst > "poescript" - else - # - # Do not try to grep out 12, it will grab the 12 from 126. - # This will work as long as we don't need 12 fhr metafiles - # - if [[ ${fhr} -ne 12 ]] ; then - # shellcheck disable=SC2312 - grep "${fhr}" "${HOMEgfs}/gempak/fix/gfs_meta" | awk -F" [0-9]" '{print $1}' | envsubst > "poescript" - fi - fi - - # If this is the final fcst hour, alert the - # file to all centers. - # - if [[ ${fhr} -ge ${fhend} ]] ; then - export DBN_ALERT_TYPE=GFS_METAFILE_LAST - fi - - export fend=${fhr} - - cat poescript - - "${HOMEgfs}/ush/run_mpmd.sh" poescript && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to generate one or more gempak meta plots!" - fi - - if [[ ${fhr} -eq 126 ]] ; then - fhr=$((fhr + 6)) - else - fhr=$((fhr + fhinc)) - fi -done - -exit diff --git a/scripts/exgfs_atmos_grib2_special_npoess.sh b/scripts/exgfs_atmos_grib2_special_npoess.sh deleted file mode 100755 index 3c2dae8e8c1..00000000000 --- a/scripts/exgfs_atmos_grib2_special_npoess.sh +++ /dev/null @@ -1,200 +0,0 @@ -#! /usr/bin/env bash - -##################################################################### -# echo "-----------------------------------------------------" -# echo " exglobal_grib2_special_npoess.sh" -# echo " Jan 2008 - Chuang - Produces 1x1 degree special Grib from master." -# echo "-----------------------------------------------------" -##################################################################### - -cd "${DATA}" || exit 2 - -############################################################ -# Define Variables: -# ----------------- -# SHOUR is the starting forecast hour. normally 0 except for restarts. -# FHOUR is the ending forecast hour. -# FHINC is the increment hour for each forecast steps. -# FH is the current forecast hour. -# SLEEP_TIME is the number of seconds to sleep before exiting with error. -# SLEEP_INT is the number of seconds to sleep between restrt file checks. -# restart_file is the name of the file to key off of to kick off pgrb -# generation. -############################################################ - -############################################################ -# NO processing Analysis special Files -############################################################ - -# Set type of Interpolation for WGRIB2 -export opt1=' -set_grib_type same -new_grid_winds earth ' -export opt1uv=' -set_grib_type same -new_grid_winds grid ' -export opt21=' -new_grid_interpolation bilinear -if ' -export opt22=":(CSNOW|CRAIN|CFRZR|CICEP|ICSEV):" -export opt23=' -new_grid_interpolation neighbor -fi ' -export opt24=' -set_bitmap 1 -set_grib_max_bits 16 -if ' -export opt25=":(APCP|ACPCP|PRATE|CPRAT):" -export opt26=' -set_grib_max_bits 25 -fi -if ' -export opt27=":(APCP|ACPCP|PRATE|CPRAT|DZDT):" -export opt28=' -new_grid_interpolation budget -fi ' - -#################################### -# Specify Timeout Behavior of Post -# -# SLEEP_TIME - Amount of time to wait for -# a restart file before exiting -# SLEEP_INT - Amount of time to wait between -# checking for restart files -#################################### -export SLEEP_TIME=${SLEEP_TIME:-900} -export SLEEP_INT=${SLEEP_TIME:-5} - -SLEEP_LOOP_MAX=$(( SLEEP_TIME / SLEEP_INT )) - -# TODO: Does this section do anything? I retained if for clarity of -# changes/updates, but it does not appear to do anything. - -#################################### -# Check if this is a restart -#################################### -if [[ -f "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb2" ]]; then - modelrecvy=$(cat < "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb") - recvy_cyc="${modelrecvy:8:2}" - recvy_shour="${modelrecvy:10:13}" - - if [[ ${RERUN} == "NO" ]]; then - NEW_SHOUR=$(( recvy_shour + FHINC )) - if (( NEW_SHOUR >= SHOUR )); then - export SHOUR="${NEW_SHOUR}" - fi - if (( recvy_shour >= FHOUR )); then - echo "Forecast Pgrb Generation Already Completed to ${FHOUR}" - else - echo "Starting: PDY=${PDY} cycle=t${recvy_cyc}z SHOUR=${SHOUR}" - fi - fi -fi - -############################################################################## -# Specify Forecast Hour Range F000 - F024 for GFS_NPOESS_PGRB2_0P5DEG -############################################################################## -export SHOUR=0 -export FHOUR=24 -export FHINC=3 -if (( FHOUR > FHMAX_GFS )); then - export FHOUR="${FHMAX_GFS}" -fi - -############################################################ -# Loop Through the Post Forecast Files -############################################################ -for (( fhr=SHOUR; fhr <= FHOUR; fhr = fhr + FHINC )); do - - fhr3=$(printf "%03d" "${fhr}") - - ############################### - # Start Looping for the - # existence of the restart files - ############################### - export pgm="postcheck" - grib_file="${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_b.0p50.f${fhr3}.grib2.idx" - if ! wait_for_file "${grib_file}" "${SLEEP_INT}" "${SLEEP_LOOP_MAX}"; then - export err=9 - err_exit "0p50 grib file not available after max sleep time" - fi - - ###################################################################### - # Process Global NPOESS 0.50 GFS GRID PRODUCTS IN GRIB2 F000 - F024 # - ###################################################################### - paramlist="${PARMgfs}/product/global_npoess_paramlist_g2" - cpreq "${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_a.0p50.f${fhr3}.grib2" tmpfile2 - cpreq "${COMIN_ATMOS_GRIB_0p50}/gfs.t${cyc}z.pres_b.0p50.f${fhr3}.grib2" tmpfile2b - cat tmpfile2 tmpfile2b > tmpfile - # shellcheck disable=SC2312 - ${WGRIB2} tmpfile | grep -F -f "${paramlist}" | ${WGRIB2} -i -grib pgb2file tmpfile && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to write pgb2file from the specified parm file \"${paramlist}\"!" - fi - - cpfs pgb2file "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.pgrb2f${fhr3}.npoess" - - if [[ ${SENDDBN} == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL GFS_PGBNPOESS "${job}" \ - "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.pgrb2f${fhr3}.npoess" - else - echo "File ${RUN}.${cycle}.pgrb2f${fhr3}.npoess not posted to db_net." - fi - echo "${PDY}${cyc}${fhr3}" > "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.halfdeg.npoess" - rm -f tmpfile pgb2file - -done - -################################################################ -# Specify Forecast Hour Range F000 - F180 for GOESSIMPGRB files -################################################################ -export SHOUR=${FHMIN_GFS} -export FHOUR=${FHMAX_GOES} -export FHINC=${FHOUT_GOES} - -################################# -# Process GFS PGRB2_SPECIAL_POST -################################# - -for (( fhr=SHOUR; fhr <= FHOUR; fhr = fhr + FHINC )); do - - fhr3=$(printf "%03d" "${fhr}") - - ############################### - # Start Looping for the - # existence of the restart files - ############################### - export pgm="postcheck" - # grib_file="${COMIN_ATMOS_MASTER}/${RUN}.t${cyc}z.goesmasterf${fhr3}.grb2" - grib_file="${COMIN_ATMOS_MASTER}/${RUN}.t${cyc}z.master-goes.f${fhr3}.grib2" - if ! wait_for_file "${grib_file}" "${SLEEP_INT}" "${SLEEP_LOOP_MAX}"; then - export err=9 - err_exit "GOES master grib file ${grib_file} not available after max sleep time" - fi - ############################### - # Put restart files into /nwges - # for backup to start Model Fcst - ############################### - cpreq "${grib_file}" masterfile - export grid0p25="latlon 0:1440:0.25 90:721:-0.25" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${grid0p25} pgb2file - - export gridconus="lambert:253.0:50.0:50.0 214.5:349:32463.0 1.0:277:32463.0" - # shellcheck disable=SC2086,SC2248 - ${WGRIB2} masterfile ${opt1} ${opt21} ${opt22} ${opt23} ${opt24} ${opt25} ${opt26} \ - ${opt27} ${opt28} -new_grid ${gridconus} pgb2file2 - - ${WGRIB2} pgb2file -s > pgb2ifile - - cpfs pgb2file "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr3}" - cpfs pgb2ifile "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr3}.idx" - cpfs pgb2file2 "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2f${fhr3}.grd221" - - if [[ ${SENDDBN} == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMPGB2_0P25 "${job}" \ - "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr}" - "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMPGB2_0P25_WIDX "${job}" \ - "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2.0p25.f${fhr}.idx" - "${DBNROOT}/bin/dbn_alert" MODEL GFS_GOESSIMGRD221_PGB2 "${job}" \ - "${COMOUT_ATMOS_GOES}/${RUN}.${cycle}.goessimpgrb2f${fhr}.grd221" - fi - - echo "${PDY}${cyc}${fhr}" > "${COMOUT_ATMOS_GOES}/${RUN}.t${cyc}z.control.goessimpgrb" - rm -f pgb2file2 pgb2ifile - - if [[ ${SENDECF} == "YES" ]]; then - # TODO Does this even do anything? - export fhour=$(( fhr % 6 )) - fi - -done - - -################## END OF SCRIPT ####################### diff --git a/scripts/exgfs_pmgr.sh b/scripts/exgfs_pmgr.sh deleted file mode 100755 index ddd5257928a..00000000000 --- a/scripts/exgfs_pmgr.sh +++ /dev/null @@ -1,74 +0,0 @@ -#! /usr/bin/env bash - -# -# Script name: exgfs_pmgr.sh.sms -# -# This script monitors the progress of the gfs_fcst job -# - -hour=00 -TEND=384 -TCP=385 - -if [ -e posthours ]; then - rm -f posthours -fi - -while [ $hour -lt $TCP ]; -do - hour=$(printf "%02d" $hour) - echo $hour >>posthours - if [ 10#$hour -lt 240 ] - then - # JY if [ $hour -lt 12 ] - if [ 10#$hour -lt 120 ] - then - let "hour=hour+1" - else - let "hour=hour+3" - fi - else - let "hour=hour+12" - fi -done -postjobs=$(cat posthours) - -# -# Wait for all fcst hours to finish -# -icnt=1 -while [ $icnt -lt 1000 ] -do - for fhr in $postjobs - do - fhr3=$(printf "%03d" $fhr) - if [ -s ${COMIN}/gfs.${cycle}.logf${fhr}.txt -o -s ${COMIN}/gfs.${cycle}.logf${fhr3}.txt ] - then - if [ $fhr -eq 0 ] - then - ecflow_client --event release_postanl - fi - ecflow_client --event release_post${fhr} - # Remove current fhr from list - postjobs=$(echo $postjobs | sed "s/${fhr}//") - fi - done - - result_check=$(echo $postjobs | wc -w) - if [ $result_check -eq 0 ] - then - break - fi - - sleep 10 - icnt=$((icnt + 1)) - if [ $icnt -ge 720 ] - then - msg="ABORTING after 2 hours of waiting for GFS FCST hours $postjobs." - err_exit $msg - fi - -done - - -exit diff --git a/scripts/exgfs_prdgen_manager.sh b/scripts/exgfs_prdgen_manager.sh deleted file mode 100755 index 17913f5d552..00000000000 --- a/scripts/exgfs_prdgen_manager.sh +++ /dev/null @@ -1,72 +0,0 @@ -#! /usr/bin/env bash - -# -# Script name: exgfs_pmgr.sh.sms -# -# This script monitors the progress of the gfs_fcst job -# - -hour=00 -TEND=384 -TCP=385 - -if [ -e pgrb2_hours ]; then - rm -f pgrb2_hours -fi - -while [ $hour -lt $TCP ]; -do - hour=$(printf "%02d" $hour) - echo $hour >>pgrb2_hours - if [ 10#$hour -lt 240 ] - then - if [ 10#$hour -lt 120 ] - then - let "hour=hour+1" - else - let "hour=hour+3" - fi - else - let "hour=hour+12" - fi -done -pgrb2_jobs=$(cat pgrb2_hours) - -# -# Wait for all fcst hours to finish -# -icnt=1 -while [ $icnt -lt 1000 ] -do - for fhr in ${pgrb2_jobs} - do - if [ -s ${COMIN}/gfs.${cycle}.master.grb2if${fhr} ] - then -# if [ $fhr -eq 0 ] -# then -# ecflow_client --event release_pgrb2_anl -# fi - ecflow_client --event release_pgrb2_${fhr} - # Remove current fhr from list - pgrb2_jobs=$(echo ${pgrb2_jobs} | sed "s/${fhr}//") - fi - done - - result_check=$(echo ${pgrb2_jobs} | wc -w) - if [ $result_check -eq 0 ] - then - break - fi - - sleep 10 - icnt=$((icnt + 1)) - if [ $icnt -ge 720 ] - then - msg="ABORTING after 2 hours of waiting for GFS POST hours ${pgrb2_jobs}." - err_exit $msg - fi - -done - - -exit diff --git a/scripts/exgfs_wave_nawips.sh b/scripts/exgfs_wave_nawips.sh deleted file mode 100755 index b703f9399c2..00000000000 --- a/scripts/exgfs_wave_nawips.sh +++ /dev/null @@ -1,132 +0,0 @@ -#! /usr/bin/env bash - -################################################################### -# echo "----------------------------------------------------" -# echo "exnawips - convert NCEP GRIB files into GEMPAK Grids" -# echo "----------------------------------------------------" -# echo "History: Mar 2000 - First implementation of this new script." -# echo "Sept 2011 - First implementation of this new script" -# echo " March 2020- Modified for GEFSv12.0" -# March-2020 Roberto.Padilla@noaa.gov -##################################################################### - -source "${USHgfs}/wave_domain_grid.sh" -source "${USHgfs}/atparse.bash" - -NAGRIB="nagrib2" -fhr3=$(printf "%03d" "${FORECAST_HOUR}") - -cpreq "${HOMEgfs}/gempak/fix/g2varswmo2.tbl" "${DATA}/" - -grids=${GEMPAK_GRIDS:-${waveinterpGRD:-'aoc_9km gnh_10m gsh_15m'}} - -# Create a template for the GEMPAK control file -rm -f "${DATA}/gempak.parm.tmpl" -cat << EOF > "${DATA}/gempak.parm.tmpl" -GBFILE = @[GBFILE] -INDXFL = -GDOUTF = @[GEMGRD] -PROJ = -GRDAREA = -KXKY = -MAXGRD = 4999 -CPYFIL = gds -GAREA = dset -OUTPUT = T -GBTBLS = g2varswmo2.tbl -G2TBLS = -GBDIAG = -PDSEXT = no -l -r -EOF - -# Loop over the grids -for grid in ${grids}; do - case ${grid} in - aoc_9km) - grdIDout='gfswavearc' - ;; - at_10m) - grdIDout='gfswaveat10m' - ;; - ep_10m) - grdIDout='gfswaveep10m' - ;; - wc_10m) - grdIDout='gfswavewc10m' - ;; - glo_30m) - grdIDout='gfswavegl30m' - ;; - gnh_10m) - grdIDout='gfswavenh' - ;; - gsh_15m) - grdIDout='gfswavesh' - ;; - glo_200) - grdIDout='gfswaves200k' - ;; - *) - echo "FATAL ERROR: Unspecified grid '${grid}'" - exit 9 - ;; - esac - process_grdID "${grid}" - - com_varname="COMIN_WAVE_GRID_${GRDREGION}_${GRDRES}" - com_dir=${!com_varname} - GRIBIN="${RUN}.${cycle}.${GRDREGION}.${GRDRES}.f${fhr3}.grib2" - cpreq "${com_dir}/${GRIBIN}" "./${GRIBIN}" - - nagrib_file="${GRIBIN}" - if [[ "${GRDREGION}.${GRDRES}" = "global.0p25" ]]; then - nagrib_file="${RUN}.${cycle}.global.${gridIDout}.${fhr3}.grib2" - ${WGRIB2} -lola 0:720:0.5 -90:361:0.5 "${nagrib_file}" grib "${GRIBIN}" - export err=$? - if [[ ${err} -ne 0 ]]; then - export pgm="${WGRIB2}" - err_exit "wgrib2 failed to interpolate" - fi - fi - - GEMGRD="${grdIDout}_${PDY}${cyc}f${fhr3}" - GBFILE="grib_${grid}" - - cpreq "${nagrib_file}" "${GBFILE}" - - rm -f "gempak.parm.${grid}" - atparse < "${DATA}/gempak.parm.tmpl" >> "${DATA}/gempak.parm.${grid}" - cat "${DATA}/gempak.parm.${grid}" - - startmsg - export pgm="${NAGRIB}" - ${pgm} < "${DATA}/gempak.parm.${grid}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "${pgm} failed during the generation of ${GEMGRD}" - fi - ##################################################### - # GEMPAK DOES NOT ALWAYS HAVE A NON ZERO RETURN CODE - # WHEN IT CAN NOT PRODUCE THE DESIRED GRID. CHECK - # FOR THIS CASE HERE. - ##################################################### - if [[ -f "${GEMGRD}" ]]; then - ls -l "${GEMGRD}" - else - export err=1 - export pgm="GEMPAK CHECK FILE" - err_exit "Gempak failed to generate the desired grid ${GEMGRD}" - fi - - if [[ "${NAGRIB}" == "nagrib2" ]]; then gpend; fi - - # Copy output to COMOUT - cpfs "${GEMGRD}" "${COMOUT_WAVE_GEMPAK}/${GEMGRD}" - - if [[ "${SENDDBN}" == "YES" ]] ; then - "${DBNROOT}/bin/dbn_alert" MODEL "${DBN_ALERT_TYPE}" "${job}" "${COMOUT_WAVE_GEMPAK}/${GEMGRD}" - fi - -done diff --git a/scripts/exgfs_wave_post_pnt.sh b/scripts/exgfs_wave_post_pnt.sh deleted file mode 100755 index 93ba602ff04..00000000000 --- a/scripts/exgfs_wave_post_pnt.sh +++ /dev/null @@ -1,311 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -# -# UNIX Script Documentation Block -# Script name: exgfs_wave_post_pnt.sh -# Script description: Creates point output products from NetCDF WW3 point data -# -# Abstract: This script is the point postprocessor for the wave component in GFS. -# It executes several scripts forpreparing and creating output data -# as follows: -# -# wave_tar.sh : tars the spectral and bulletin multiple files -# -# COM inputs: -# - ${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin -# - ${COMIN_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${FH3}.nc -# -# $Id$ -# -# Attributes: -# Language: Bourne-again (Bash) Shell -# -############################################################################### -# -# --------------------------------------------------------------------------- # -# 0. Preparations - -# 0.a Basic modes of operation - -export WAV_MOD_TAG="${RUN}.t${cyc}z" - -echo "HAS BEGUN on $(hostname)" -echo "Starting WAVE PNT POSTPROCESSOR SCRIPT for ${WAV_MOD_TAG}" - -cat << EOF - - ************************************* - *** WAVE PNT POSTPROCESSOR SCRIPT *** - ************************************* - -Starting at : $(date) -------------- - -EOF - -# Script will run only if pre-defined NTASKS -# The actual work is distributed over these tasks. -if [[ -z "${NTASKS}" ]]; then - export err=1 - err_exit "Requires NTASKS to be set" -fi - -# 0.c Defining model grids - -waveuoutpGRD=${waveuoutpGRD:?buoyNotSet} - -# 0.c.1 Define a temporary directory for storing ascii point output files -# and flush it - -export STA_DIR="${DATA}/station_ascii_files" -rm -rf "${STA_DIR}" -mkdir -p "${STA_DIR}" -mkdir -p "${STA_DIR}/spec" -mkdir -p "${STA_DIR}/bull" -mkdir -p "${STA_DIR}/cbull" - -printf "\n Grid information :\n ------------------\n Output points : %s\n" "${waveuoutpGRD}" - -# --------------------------------------------------------------------------- # -# 1. Get files that are used by most child scripts - -printf "\nPreparing input files :\n-------------------------\n" - -# 1.a Model definition files and output files (set up using poe) - -# Copy model definition files -iloop=0 -for grdID in ${waveuoutpGRD}; do - if [[ -f "${COMIN_WAVE_PREP}/${WAV_MOD_TAG}.mod_def.${grdID}.bin" ]]; then - echo " Mod def file for ${grdID} found in ${COMIN_WAVE_PREP}. copying ...." - cpreq -f "${COMIN_WAVE_PREP}/${WAV_MOD_TAG}.mod_def.${grdID}.bin" "mod_def.${grdID}" - iloop=$((iloop + 1)) - fi -done - -for grdID in ${waveuoutpGRD}; do - if [[ -f "mod_def.${grdID}" ]]; then - echo "File mod_def.${grdID} found. Syncing to all nodes ..." - else - export err=2 - err_exit "NO MOD_DEF FILE mod_def.${grdID}" - fi -done - -# 1.b Output locations file - -rm -f buoy.loc -if [[ -f "${PARMgfs}/wave/wave_${NET}.buoys" ]]; then - cpreq -f "${PARMgfs}/wave/wave_${NET}.buoys" buoy.loc.temp - if [[ "${DOBNDPNT_WAV}" == "YES" ]]; then - #only do boundary points - sed -n '/^\$.*/!p' buoy.loc.temp | grep IBP > buoy.loc || { - echo "WARNING: No boundary points found in buoy file ${PARMgfs}/wave/wave_${NET}.buoys" - echo " Ending job without doing anything." - exit 0 - } - else - #exclude boundary points - sed -n '/^\$.*/!p' buoy.loc.temp | grep -v IBP > buoy.loc - fi -fi - -if [[ -s buoy.loc ]]; then - echo " buoy.loc and buoy.ibp copied and processed (${PARMgfs}/wave/wave_${NET}.buoys)." -else - export err=3 - err_exit 'NO BUOY LOCATION FILE' -fi - -# 1.c Input template files - -if [[ -f "${PARMgfs}/wave/ww3_outp_spec.inp.tmpl" ]]; then - cpreq -f "${PARMgfs}/wave/ww3_outp_spec.inp.tmpl" ww3_outp_spec.inp.tmpl -fi - -if [[ -f ww3_outp_spec.inp.tmpl ]]; then - echo " ww3_outp_spec.inp.tmpl copied. Syncing to all grids ..." -else - export err=3 - err_exit "NO TEMPLATE FOR SPEC INPUT FILE" -fi - -if [[ -f "${PARMgfs}/wave/ww3_outp_bull.inp.tmpl" ]]; then - cpreq "${PARMgfs}/wave/ww3_outp_bull.inp.tmpl" ww3_outp_bull.inp.tmpl -fi - -if [[ -f ww3_outp_bull.inp.tmpl ]]; then - echo " ww3_outp_bull.inp.tmpl copied. Syncing to all nodes ..." -else - export err=4 - err_exit "NO TEMPLATE FOR BULLETIN INPUT FILE" -fi - -# 1.d Linking the output files - -# Loop through forecast hours to link output file -fhr=${FHMIN_WAV} -while [[ ${fhr} -le ${FHMAX_WAV_PNT} ]]; do - ymdhms=$(date --utc +%Y%m%d.%H0000 -d "${PDY} ${cyc} + ${fhr} hours") - FH3=$(printf %03i ${fhr}) - pfile="${COMIN_WAVE_HISTORY}/${WAV_MOD_TAG}.points.f${FH3}.nc" - if [[ -f "${pfile}" ]]; then - ${NLN} "${pfile}" "./${ymdhms}.out_pnt.ww3.nc" - else - export err=7 - err_exit "NO RAW POINT OUTPUT FILE ${ymdhms}.out_pnt.ww3.nc" - fi - - FHINCP=$(( DTPNT_WAV / 3600 )) - fhr=$(( fhr + FHINCP )) # no gridded output, loop with out_pnt stride -done - -# 1.e Getting buoy information for points - -ymdh=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${WAVHINDH} hours") -tstart="${ymdh:0:8} ${ymdh:8:2}0000" -truntime="${PDY} ${cyc}0000" -N=$(( (FHMAX_WAV_PNT - FHMIN_WAV) * 3600 / DTPNT_WAV + 1 )) - -if [[ "${DOSPC_WAV}" == "YES" || "${DOBLL_WAV}" == "YES" ]]; then - sed -e "s/TIME/${tstart}/g" \ - -e "s/DT/${DTPNT_WAV}/g" \ - -e "s/999/${N}/g" \ - -e "s/PREFIX/${RUN}/g" \ - -e "s/^.*POINT.*/\$ &/g" \ - -e "s/ITYPE/0/g" \ - -e "s/FORMAT/F/g" \ - ww3_outp_spec.inp.tmpl > ww3_outp.inp -fi - -rm -f buoy_tmp.loc buoy_log.ww3 ww3_oup.inp -${NLN} ./mod_def.${waveuoutpGRD} ./mod_def.ww3 - -export pgm="${NET,,}_ww3_outp.x" -source prep_step - -"${EXECgfs}/${pgm}" > buoy_lst.loc 2>&1 -export err=$? -if [[ ${err} -ne 0 && ! -f buoy_log.ww3 ]]; then - cat buoy_tmp.loc || true - export err=5 - err_exit "${WAV_MOD_TAG} post ${date} ${cycle} : buoy log file failed to be created." -fi - -# Create new buoy_log.ww3 -awk '{print $3}' buoy.loc | sed 's/'\''//g' > ibp_tags -grep -F -f ibp_tags buoy_log.ww3 > buoy_log.tmp -rm -f buoy_log.dat -mv buoy_log.tmp buoy_log.dat - -Nb=$(wc buoy_log.dat | awk '{ print $1 }') - -if [[ -s buoy_log.dat ]]; then - echo 'Buoy log file created. Syncing to all nodes ...' -else - export err=6 - err_exit "NO BUOY LOG FILE CREATED" -fi - -# 1.f Data summary - -cat << EOF - -Input files read and processed at : $(date) - -Data summary : ---------------------------------------------- - Sufficient data for spectral files : ${DOSPC_WAV} (${Nb} points) - Sufficient data for bulletins : ${DOBLL_WAV} (${Nb} points) - Boundary points : ${DOBNDPNT_WAV} - -EOF - -# --------------------------------------------------------------------------- # -# 2. Make files for processing boundary points -# -# 2.a Creating ww3_outp.inp for each job and execute ww3_outp - -echo ' Making command file for wave post points ' - -grep -F -f ibp_tags buoy_log.dat | awk '{ print $2 }' > buoys -grep -F -f buoys buoy_log.ww3 | awk '{ print $1 }' > points -points=$(awk '{print $0 "\\n"}' points | tr -d '\n') -rm -f buoys - -# Generate the ww3_outp.inp file from the template -if [[ "${DOSPC_WAV}" == "YES" ]]; then - sed -e "s/TIME/${tstart}/g" \ - -e "s/DT/${DTPNT_WAV}/g" \ - -e "s/999/${N}/g" \ - -e "s/PREFIX/${RUN}/g" \ - -e "s|POINT|${points}|g" \ - -e "s/ITYPE/1/g" \ - -e "s/FORMAT/F/g" \ - ww3_outp_spec.inp.tmpl > ww3_outp.inp - - export pgm="${NET,,}_ww3_outp.x" - "${EXECgfs}/${pgm}" -fi - -if [[ "${DOBLL_WAV}" == "YES" ]]; then - sed -e "s/TIME/${tstart}/g" \ - -e "s/DT/${DTPNT_WAV}/g" \ - -e "s/999/${N}/g" \ - -e "s/PREFIX/${RUN}/g" \ - -e "s|POINT|${points}|g" \ - -e "s/REFT/${truntime}/g" \ - ww3_outp_bull.inp.tmpl > ww3_outp.inp - export pgm="${NET,,}_ww3_outp.x" - "${EXECgfs}/${pgm}" -fi - -# --------------------------------------------------------------------------- # -# 3. Compress point output data into tar files - -# 3.a Set up cmdfile - -rm -f cmdtarfile -touch cmdtarfile -chmod 744 cmdtarfile - -printf "\n Making command file for taring all point output files." - -# 3.b Execute the taring - -if [[ "${DOBNDPNT_WAV}" == "YES" ]]; then - if [[ "${DOSPC_WAV}" == "YES" ]]; then - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibp ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibp_tar.out" >> cmdtarfile - fi - if [[ "${DOBLL_WAV}" == "YES" ]]; then - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibpbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibpbull_tar.out" >> cmdtarfile - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} ibpcbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_ibpcbull_tar.out" >> cmdtarfile - fi -else - if [[ "${DOSPC_WAV}" == "YES" ]]; then - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} spec ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_spec_tar.out" >> cmdtarfile - fi - if [[ "${DOBLL_WAV}" == "YES" ]]; then - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} bull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_bull_tar.out" >> cmdtarfile - echo "${USHgfs}/wave_tar.sh ${WAV_MOD_TAG} cbull ${Nb} 2>&1 | tee ${WAV_MOD_TAG}_cbull_tar.out" >> cmdtarfile - fi -fi - -# Ensure there are enough processors for MPMD else use serial -ncmds=$(wc -l < cmdtarfile) -if [[ ${NTASKS} -lt ${ncmds} ]]; then - if [[ "${USE_CFP:-}" == "YES" ]]; then - echo "WARNING: Not enough processors for MPMD, '${NTASKS} < ${ncmd}', running in serial mode" - export USE_CFP="NO" - fi -fi - -"${USHgfs}/run_mpmd.sh" "${DATA}/cmdtarfile" && true -export err=$? -if [[ ${err} -ne 0 ]]; then - export pgm="run_mpmd.sh" - err_exit "run_mpmd failed while tarring point outputs." -fi - -# End of WW3 point postprocessor script ---------------------------------------- # diff --git a/scripts/exgfs_wave_prdgen_gridded.sh b/scripts/exgfs_wave_prdgen_gridded.sh deleted file mode 100755 index 0c0a7829b19..00000000000 --- a/scripts/exgfs_wave_prdgen_gridded.sh +++ /dev/null @@ -1,194 +0,0 @@ -#! /usr/bin/env bash - -############################################################################### -# # -# This script is the product generator ("graphics job") for the # -# GFSv16-wave output for gridded wave fields # -# # -# COM inputs: # -# - ${COMIN_WAVE_GRID}/${RUN}.${cycle}.${grdOut}.f${fhr}.grib2 # -# # -# COM outputs: # -# - ${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut} # -# # -# Origination : 05/02/2007 # -# Last update : 10/08/2020 # -# # -# Oct, 2020 Roberto.Padilla@noaa.gov, Henrique.HAlves@noaa.gov # -# - Merging wave scripts to GFSv16 global workflow # -# # -############################################################################### -# --------------------------------------------------------------------------- # -# 0. Preparations - -source "${USHgfs}/wave_domain_grid.sh" - -# 0.a Basic modes of operation - -fstart=${fstart:-0} -FHMAX_WAV=${FHMAX_WAV_WMO:-180} #180 Total of hours to process -FHMAX_HF_WAV=${FHMAX_HF_WAV_WMO:-72} #from 00 to 72 inc=3 -FHOUT_WAV=${FHOUT_WAV_WMO:-6} #from 72 to 180 inc=6 -FHOUT_HF_WAV=${FHOUT_HF_WAV_WMO:-3} - -echo "Starting MWW3 GRIDDED PRODUCTS SCRIPT" -# Output grids -grids=${GEMPAK_GRIDS:-'aoc_9km at_10m ep_10m wc_10m glo_30m'} -# 0.b Date and time stuff -cat << EOF - - **************************** - *** MWW3 PRODUCTS SCRIPT *** - **************************** - ${PDY} ${cycle} - - AWIPS grib fields - Wave Grids : ${grids} -EOF - -# --------------------------------------------------------------------------- # -# 1. Get necessary files -printf "\nPreparing input files\n-----------------------" - -#======================================================================= - -ASWELL=(SWELL1 SWELL2) # Indices of HS from partitions -ASWPER=(SWPER1 SWPER2) # Indices of PERIODS from partitions -ASWDIR=(SWDIR1 SWDIR2) # Indices of DIRECTIONS from partitions - # (should be same as ASWELL) -#declare -a arrpar=(WIND UGRD VGRD HTSGW PERPW DIRPW WVHGT WVPER WVDIR WDIR ${ASWELL[@]} ${ASWDIR[@]} ${ASWPER[@]}) -declare -a arrpar=(WIND WDIR UGRD VGRD HTSGW PERPW DIRPW WVHGT "${ASWELL[@]}" WVPER "${ASWPER[@]}" WVDIR "${ASWDIR[@]}" ) -nparam=$(echo "${arrpar[@]}" | wc -w) - -# 1.a Grib file (AWIPS and FAX charts) -# Get input grid - -sleep_interval=5 -max_tries=1000 - -fhcnt="${fstart}" -while [[ "${fhcnt}" -le "${FHMAX_WAV}" ]]; do - fhr=$(printf "%03d" "${fhcnt}") - for grdOut in ${grids}; do - process_grdID "${grdOut}" - - com_varname="COMIN_WAVE_GRID_${GRDREGION}_${GRDRES}" - com_dir=${!com_varname} - - GRIBIN="${com_dir}/${RUN}.${cycle}.${GRDREGION}.${GRDRES}.f${fhr}.grib2" - GRIBIN_chk="${GRIBIN}.idx" - if ! wait_for_file "${GRIBIN_chk}" "${sleep_interval}" "${max_tries}"; then - export err=1 - err_exit "${GRIBIN_chk} not found after waiting $((sleep_interval * ( max_tries - 1))) secs" - fi - GRIBOUT="${RUN}.${cycle}.${grdID}.f${fhr}.clipped.grib2" - - iparam=1 - while [[ ${iparam} -le ${nparam} ]]; do - nip=${arrpar[${iparam}-1]} - prepar=${nip::-1} # Part prefix (assumes 1 digit index) - paridx="${nip:0-1}" - npart=0 - case ${prepar} in - SWELL) npart=1 ;; - SWDIR) npart=1 ;; - SWPER) npart=1 ;; - *) npart=0 ;; - esac - echo "${nip} ${prepar} ${paridx} ${npart}" - rm -f temp.grib2 - if [[ ${npart} -eq 0 ]]; then - #shellcheck disable=SC2312 - ${WGRIB2} "${GRIBIN}" -s | grep ":${nip}" | "${WGRIB2}" -i "${GRIBIN}" -grib temp.grib2 > wgrib.out 2>&1 - #shellcheck disable=SC2312 - ${WGRIB2} temp.grib2 -append -grib "${GRIBOUT}" - else - #shellcheck disable=SC2312 - ${WGRIB2} "${GRIBIN}" -s | grep ":${prepar}" | grep "${paridx} in sequence" | \ - ${WGRIB2} -i "${GRIBIN}" -grib temp.grib2 > wgrib.out 2>&1 - ${WGRIB2} temp.grib2 -append -grib "${GRIBOUT}" - fi - iparam=$(( iparam + 1 )) - done #end wave param loop -#====================================================================== - GRIBIN="${RUN}.${cycle}.${grdID}.f${fhr}.clipped.grib2" - - ${NLN} "${GRIBIN}" "gribfile.${grdID}.f${fhr}" - -# 1.d Input template files - parmfile="${PARMgfs}/wave/grib2_${RUN}wave.${grdOut}.f${fhr}" - if [[ -f "${parmfile}" ]]; then - ${NLN} "${parmfile}" "awipsgrb.${grdID}.f${fhr}" - else - export err=3 - err_exit "NO template grib2_${RUN}wave.${grdID}.f${fhr}" - fi - -# 2. AWIPS product generation -# 2.a AWIPS GRIB file with headers - echo ' ' - echo 'AWIPS headers to GRIB file ...' - echo '------------------------------' - -# 2.a.1 Set up for tocgrib2 - echo " Do set up for tocgrib2." -# 2.a.2 Make GRIB index - echo " Make GRIB index for tocgrib2." - export pgm="${GRB2INDEX}" - ${GRB2INDEX} "gribfile.${grdID}.f${fhr}" "gribindex.${grdID}.f${fhr}" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "ERROR IN grb2index MWW3 for grid ${grdID}" - fi - -# 2.a.3 Run AWIPS GRIB packing program tocgrib2 - - echo " Run tocgrib2" - export pgm="${TOCGRIB2}" - export pgmout=tocgrib2.out - source prep_step - - AWIPSGRB="awipsgrib" - export FORT11="gribfile.${grdID}.f${fhr}" - export FORT31="gribindex.${grdID}.f${fhr}" - export FORT51="${AWIPSGRB}.${grdID}.f${fhr}" - - ${TOCGRIB2} < "awipsgrb.${grdID}.f${fhr}" > "${pgmout}" 2>&1 - export err=$? - if [[ ${err} -ne 0 ]]; then - cat "${pgmout}" - err_exit "ERROR IN tocgrib2" - else - echo '*** tocgrib2 ran succesfully *** ' - fi - -# 2.a.7 Get the AWIPS grib bulletin out ... - echo " Get awips GRIB bulletins out ..." - echo " Saving ${AWIPSGRB}.${grdOut}.f${fhr} as grib2.${cycle}.awipsww3_${grdID}.f${fhr}" - echo " in ${COMOUT_WAVE_WMO}" - cpfs "${AWIPSGRB}.${grdID}.f${fhr}" "${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut}" - - if [[ "${SENDDBN}" == "YES" ]]; then - echo " Sending ${AWIPSGRB}.${grdID}.f${fhr} to DBRUN." - "${DBNROOT}/bin/dbn_alert" GRIB_LOW "${RUN}" "${job}" "${COMOUT_WAVE_WMO}/grib2.${cycle}.f${fhr}.awipsww3_${grdOut}" - fi - rm -f "${AWIPSGRB}.${grdID}.f${fhr}" "${pgmout}" - done # For grids - - if [[ ${fhcnt} -ge ${FHMAX_HF_WAV} ]]; then - inc="${FHOUT_WAV}" - else - inc="${FHOUT_HF_WAV}" - fi - ((fhcnt = fhcnt+inc)) -done #For fcst time - -# --------------------------------------------------------------------------- # -# 5. Clean up - -rm -f gribfile gribindex.* awipsgrb.* awipsbull.data - -# --------------------------------------------------------------------------- # -# 6. Ending output - -# End of GFSWAVE product generation script -------------------------------------- # diff --git a/scripts/exgfs_wave_prep.sh b/scripts/exgfs_wave_prep.sh deleted file mode 100755 index 3508555bff7..00000000000 --- a/scripts/exgfs_wave_prep.sh +++ /dev/null @@ -1,433 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -# -# UNIX Script Documentation Block -# Script name: exwave_prep.sh -# Script description: Creates output products from binary WW3 data -# -# Abstract: This is the preprocessor for the wave component in GFS. -# It executes several scripts for preparing and creating input data -# as follows: -# # -# wave_prnc_ice.sh : preprocess ice fields. # -# wave_prnc_cur.sh : preprocess current fields. # -# # -# COM inputs: # -# - ${COMIN_WAVE_PREP}/${RUN}.wave.mod_def.${grdID} # -# - ${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f#HHH_prog.nc # -# # -# COM outputs: # -# - ${COMOUT_WAVE_PREP}/${RUN}.wave.${WAVECUR_FID}.${cycle}.cur # -# # -# Update record : # -# # -# - Origination: 01-Mar-2007 # -# # -# WAV_MOD_ID and WAV_MOD_TAG replace modID. WAV_MOD_TAG # -# is used for ensemble-specific I/O. For deterministic # -# WAV_MOD_ID=WAV_MOD_TAG # -# # -############################################################################### -# --------------------------------------------------------------------------- # -# 0. Preparations - -# 0.a Basic modes of operation - - # Set wave model ID tag to include member number - # if ensemble; waveMEMB var empty in deterministic - export WAV_MOD_TAG="${RUN}wave${waveMEMB}" - - mkdir outtmp - -cat << EOF -HAS BEGUN on $(hostname) -Starting MWW3 PREPROCESSOR SCRIPT for ${WAV_MOD_TAG} - - ******************************** - *** WW3 PREPROCESSOR SCRIPT *** - ******************************** - PREP for wave component of NCEP coupled system - Wave component identifier : ${WAV_MOD_TAG} - - -EOF - - # 0.b Date and time stuff - - # Beginning time for outpupt may differ from SDATE if DOIAU=YES - # Roll back ${IAU_FHROT} hours of DOIAU=YES - IAU_FHROT=3 - if [[ "${DOIAU}" == "YES" ]] - then - WAVHINDH=$(( WAVHINDH + IAU_FHROT )) - fi - # Set time stamps for model start and output - # For special case when IAU is on but this is an initial half cycle - if [[ ${IAU_OFFSET} -eq 0 ]]; then - ymdh_beg=${PDY}${cyc} - else - ymdh_beg=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${WAVHINDH} hours") - fi - time_beg=$(date --utc -d "${ymdh_beg:0:8} ${ymdh_beg:8:2}" +"%Y%m%d %H0000") - ymdh_end=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${FHMAX_WAV} hours") - time_end=$(date --utc -d "${ymdh_end:0:8} ${ymdh_end:8:2}" +"%Y%m%d %H0000") - ymdh_beg_out=${PDY}${cyc} - time_beg_out="$(echo ${ymdh_beg_out} | cut -c1-8) $(echo ${ymdh_beg_out} | cut -c9-10)0000" - - # Restart file times (already has IAU_FHROT in WAVHINDH) - RSTOFFSET=$(( ${WAVHCYC} - ${WAVHINDH} )) - # Update restart time is added offset relative to model start - RSTOFFSET=$(( ${RSTOFFSET} + ${RSTIOFF_WAV} )) - ymdh_rst_ini=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${RSTOFFSET} hours") - RST2OFFSET=$(( DT_2_RST_WAV / 3600 )) - # DT2 relative to first-first-cycle restart file - ymdh_rst2_ini=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${RST2OFFSET} hours") - # First restart file for cycling - time_rst_ini="$(echo ${ymdh_rst_ini} | cut -c1-8) $(echo ${ymdh_rst_ini} | cut -c9-10)0000" - if [[ ${DT_1_RST_WAV} -eq 1 ]]; then - time_rst1_end=${time_rst_ini} - else - RST1OFFSET=$(( DT_1_RST_WAV / 3600 )) - ymdh_rst1_end=$(date --utc +%Y%m%d%H -d "${ymdh_rst_ini} + ${RST1OFFSET} hours") - time_rst1_end="$(echo ${ymdh_rst1_end} | cut -c1-8) $(echo ${ymdh_rst1_end} | cut -c9-10)0000" - fi - # Second restart file for checkpointing - if [[ "${RSTTYPE_WAV}" == "T" ]]; then - time_rst2_ini="$(echo ${ymdh_rst2_ini} | cut -c1-8) $(echo ${ymdh_rst2_ini} | cut -c9-10)0000" - time_rst2_end=${time_end} - # Condition for gdas run or any other run when checkpoint stamp is > ymdh_end - if [[ ${ymdh_rst2_ini} -ge ${ymdh_end} ]]; then - ymdh_rst2_ini=$(date --utc +%Y%m%d%H -d "${ymdh_end} + 3 hours") - time_rst2_ini="$(echo ${ymdh_rst2_ini} | cut -c1-8) $(echo ${ymdh_rst2_ini} | cut -c9-10)0000" - time_rst2_end=${time_rst2_ini} - fi - else - time_rst2_ini="$" - time_rst2_end= - DT_2_RST_WAV= - fi - cat << EOF - -Times in wave model format : ----------------------------- - date / cycle : ${PDY} ${cycle} - starting time : ${time_beg} - ending time : ${time_end} - -EOF - - # Script will run only if pre-defined NTASKS - # The actual work is distributed over these tasks. - if [[ -z ${NTASKS} ]] - then - export err=1 - err_exit "Requires NTASKS to be set" - fi - - # --------------------------------------------------------------------------- # - # 1. Get files that are used by most child scripts - - printf "Preparing input files :\n-----------------------\n" - - # 1.a Model definition files - - rm -f cmdfile - touch cmdfile - - grdINP='' - if [[ "${WW3ATMINP}" == 'YES' ]]; then - grdINP="${grdINP} ${WAVEWND_FID}" - fi - if [[ "${WW3ICEINP}" == 'YES' ]]; then - grdINP="${grdINP} ${WAVEICE_FID}" - fi - if [[ "${WW3CURINP}" == 'YES' ]]; then - grdINP="${grdINP} ${WAVECUR_FID}" - fi - - ifile=1 - - for grdID in ${grdINP} ${waveGRD} - do - if [[ -f "${COMIN_WAVE_PREP}/${RUN}.wave.mod_def.${grdID}" ]] - then - echo " Mod def file for ${grdID} found in ${COMIN_WAVE_PREP}. copying ...." - cpreq ${COMIN_WAVE_PREP}/${RUN}.wave.mod_def.${grdID} mod_def.${grdID} - - else - export err=2 - err_exit "NO MODEL DEFINITION FILE" - fi - done - - # 1.b Netcdf Preprocessor template files - if [[ "${WW3ATMINP}" == 'YES' ]]; then - itype="${itype:-} wind" - fi - if [[ "${WW3ICEINP}" == 'YES' ]]; then - itype="${itype:-} ice" - fi - if [[ "${WW3CURINP}" == 'YES' ]]; then - itype="${itype:-} cur" - fi - - for type in ${itype} - do - - case ${type} in - wind ) - grdID=${WAVEWND_FID} - ;; - ice ) - grdID=${WAVEICE_FID} - ;; - cur ) - grdID=${WAVECUR_FID} - ;; - * ) - export err=3 - err_exit 'Input type not yet implemented' - ;; - esac - - if [[ -f ${PARMgfs}/wave/ww3_prnc.${type}.${grdID}.inp.tmpl ]] - then - cpreq ${PARMgfs}/wave/ww3_prnc.${type}.${grdID}.inp.tmpl . - fi - - if [[ -f ww3_prnc.${type}.${grdID}.inp.tmpl ]] - then - printf"\n ww3_prnc.${type}.${grdID}.inp.tmpl copied (${PARMgfs}/wave).\n" - else - export err=4 - err_exit "NO TEMPLATE FILE ww3_prnc.${type}.${grdID}.inp.tmpl" - fi - done - -# --------------------------------------------------------------------------- # -# ICEC processing - - if [[ "${WW3ICEINP}" == 'YES' ]]; then - -# --------------------------------------------------------------------------- # -# 2. Ice pre - processing - -# 2.a Check if ice input is perturbed (number of inputs equal to number of wave -# ensemble members - if [[ "${RUNMEM}" == "-1" || "${WW3ICEIENS}" == "T" || "${waveMEMB}" == "00" ]] - then - - ${USHgfs}/wave_prnc_ice.sh > wave_prnc_ice.out && true - ERR=$? - - if [[ -d ice || ${ERR} -ne 0 ]] - then - sed "s/^/wave_prnc_ice.out : /g" wave_prnc_ice.out - echo ' ' - if [[ ${ERR} -ne 0 ]]; then - export err=${ERR} - else - export err=5 - fi - err_exit "ice field not generated" - else - mv -f wave_prnc_ice.out ${DATA}/outtmp - printf "\n Ice field unpacking successful.\n" - fi - - else - echo ' ' - echo "WARNING: Ice input is not perturbed, single ice file generated, skipping ${WAV_MOD_TAG}" - echo ' ' - fi - else - echo ' ' - echo "WARNING: No input ice file generated, this run did not request pre-processed ice data" - echo ' ' - fi - -# --------------------------------------------------------------------------- # -# WIND processing - if [[ "${WW3ATMINP}" == 'YES' ]]; then - - export err=6 - err_exit "Not set-up to preprocess wind" - fi - -#------------------------------------------------------------------- -# 3. Process current fields - - if [[ "${WW3CURINP}" == 'YES' ]]; then - -# Get into single file - if [[ "${RUNMEM}" == "-1" || "${WW3CURIENS}" == "T" || "${waveMEMB}" == "00" ]] - then - - printf "\n Concatenate binary current fields ...\n" - -# Prepare files for cfp process - rm -f cmdfile - touch cmdfile - chmod 744 cmdfile - - BDATE=$(date --utc +%Y%m%d%H -d "${RPDY}00 - 24 hours") - bPDY=${BDATE:0:8} - - ymdh_rtofs=${RPDY}00 # RTOFS runs once daily use ${PDY}00 - if [[ ${ymdh_beg} -lt ${ymdh_rtofs} ]]; then - #If the start time is before the first hour of RTOFS, use the previous cycle - export RPDY=${bPDY} - fi - #Set the first time for RTOFS files to be the beginning time of simulation - ymdh_rtofs=${ymdh_beg} - - if [[ "${FHMAX_WAV_CUR}" -le 72 ]]; then - rtofsfile1="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f024_prog.nc" - rtofsfile2="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f048_prog.nc" - rtofsfile3="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f072_prog.nc" - if [[ ! -f ${rtofsfile1} ]] || [[ ! -f ${rtofsfile2} ]] || [[ ! -f ${rtofsfile3} ]]; then - #Needed current files are not available, so use RTOFS from previous day - export RPDY=${bPDY} - fi - else - rtofsfile1="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f096_prog.nc" - rtofsfile2="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f120_prog.nc" - rtofsfile3="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f144_prog.nc" - rtofsfile4="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f168_prog.nc" - rtofsfile5="${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_f192_prog.nc" - if [[ ! -f ${rtofsfile1} ]] || [[ ! -f ${rtofsfile2} ]] || [[ ! -f ${rtofsfile3} ]] || - [[ ! -f ${rtofsfile4} ]] || [[ ! -f ${rtofsfile5} ]]; then - #Needed current files are not available, so use RTOFS from previous day - export RPDY=${bPDY} - fi - fi - - ymdh_end_rtofs=$(date --utc +%Y%m%d%H -d "${RPDY}00 + ${FHMAX_WAV_CUR} hours") - if [[ ${ymdh_end} -lt ${ymdh_end_rtofs} ]]; then - ymdh_end_rtofs=${ymdh_end} - fi - - DATE_DT=${WAV_CUR_HF_DT} - FLGHF='T' - FLGFIRST='T' - fext='f' - - if [[ ${CFP_MP:-"NO"} == "YES" ]]; then - # Counter for MP CFP - nm=0 - fi - while [[ ${ymdh_rtofs} -le ${ymdh_end_rtofs} ]] - do - # Timing has to be made relative to the single 00z RTOFS cycle for RTOFS PDY (RPDY) - # Start at first fhr for - fhr_rtofs=$(${NHOUR} ${ymdh_rtofs} ${RPDY}00) - fh3_rtofs=$(printf "%03d" "${fhr_rtofs#0}") - - curfile1h=${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_${fext}${fh3_rtofs}_prog.nc - curfile3h=${COMINrtofs}/rtofs.${RPDY}/rtofs_glo_2ds_${fext}${fh3_rtofs}_prog.nc - - if [[ -s ${curfile1h} && "${FLGHF}" == "T" ]] ; then - curfile=${curfile1h} - elif [[ -s ${curfile3h} ]]; then - curfile=${curfile3h} - FLGHF='F' - else - echo ' ' - if [[ "${FLGHF}" == "T" ]] ; then - curfile=${curfile1h} - else - curfile=${curfile3h} - fi - export err=11 - err_exit "NO CURRENT FILE (RTOFS): ${curfile}" - fi - - if [[ ${CFP_MP:-"NO"} == "YES" ]]; then - echo "${nm} ${USHgfs}/wave_prnc_cur.sh ${ymdh_rtofs} ${curfile} ${fhr_rtofs} ${FLGFIRST} > cur_${ymdh_rtofs}.out 2>&1" >> cmdfile - nm=$(expr ${nm} + 1) - else - echo "${USHgfs}/wave_prnc_cur.sh ${ymdh_rtofs} ${curfile} ${fhr_rtofs} ${FLGFIRST} > cur_${ymdh_rtofs}.out 2>&1" >> cmdfile - fi - - if [[ "${FLGFIRST}" == "T" ]] ; then - FLGFIRST='F' - fi - - if [[ ${fhr_rtofs} -ge ${WAV_CUR_HF_FH} ]] ; then - DATE_DT=${WAV_CUR_DT} - fi - ymdh_rtofs=$(date --utc +%Y%m%d%H -d "${ymdh_rtofs} + ${DATE_DT} hours") - done - -# Set number of processes for mpmd - wavenproc=$(wc -l < cmdfile) - wavenproc=$(echo $((${wavenproc}<${NTASKS}?${wavenproc}:${NTASKS}))) - - printf "\n Executing the curr prnc cmdfile at : %s\n ------------------------------------\n" "$(date)" - - if [[ ${wavenproc} -gt 1 ]] - then - if [[ ${CFP_MP:-"NO"} == "YES" ]]; then - ${wavempexec} -n "${wavenproc}" "${wave_mpmd}" cmdfile && true - else - ${wavempexec} "${wavenproc}" "${wave_mpmd}" cmdfile && true - fi - export stat=$? - else - chmod 744 ./cmdfile - ./cmdfile - export stat=$? - fi - - if [[ ${stat} -ne 0 ]] - then - set +x - echo ' ' - echo '********************************************' - echo '*** CMDFILE FAILED IN CUR GENERATION ***' - echo '********************************************' - echo ' See Details Below ' - # TODO: What details should be expected? - echo ' ' - # TODO: Should this raise a fatal error whether or not rtofs files are found? - set_trace - fi - - files=$(ls rtofs.* 2> /dev/null) - - if [[ -z "${files}" ]] - then - export err=11 - err_exit "NO ${WAVECUR_FID}.* FILES FOUND" - fi - - rm -f cur.${WAVECUR_FID} - - for file in ${files} - do - echo ${file} - cat ${file} >> cur.${WAVECUR_FID} - done - - cpfs cur.${WAVECUR_FID} ${COMOUT_WAVE_PREP}/${RUN}.wave.${WAVECUR_FID}.${cycle}.cur - - else - echo ' ' - echo " Current input is not perturbed, single cur file generated, skipping ${WAV_MOD_TAG}" - echo ' ' - fi - - else - - echo ' ' - echo ' Current inputs not generated, this run did not request pre-processed currents ' - echo ' ' - - fi - -# --------------------------------------------------------------------------- # -# 4. Ending output - - -# End of MWW3 preprocessor script ------------------------------------------- # diff --git a/scripts/exglobal_archive_vrfy.py b/scripts/exglobal_archive_vrfy.py deleted file mode 100755 index 5054908fc4d..00000000000 --- a/scripts/exglobal_archive_vrfy.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 - -import os - -from pygfs.task.archive import Archive -from wxflow import AttrDict, Logger, cast_strdict_as_dtypedict, logit, chdir - -# initialize root logger -logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) - - -@logit(logger) -def main(): - - config = cast_strdict_as_dtypedict(os.environ) - - # Instantiate the Archive object - archive = Archive(config) - - # update these keys to be 3 digits if they are part of archive.task_config.keys - for key in ['OCNRES', 'ICERES']: - try: - archive.task_config[key] = f"{archive.task_config[key]:03d}" - except KeyError as ee: - logger.info(f"key ({key}) not found in archive.task_config!") - - # Pull out all the configuration keys needed to run the rest of archive steps - keys = ['current_cycle', 'RUN', 'PSLOT', 'ROTDIR', 'PARMgfs', - 'ARCDIR', 'MODE', 'DO_JEDIATMENS', 'DO_FIT2OBS', 'DO_JEDIATMVAR', 'FHMIN_GFS', - 'DO_JEDISNOWDA', 'DO_AERO_ANL', 'DO_PREP_OBS_AERO', 'NET', 'MODE', 'FHOUT_GFS', - 'FHMAX_HF_GFS', 'FHOUT_GFS', 'FHMAX_FITS', 'FHMAX', 'FHOUT', 'FHMAX_GFS', 'DO_GSISOILDA', 'DO_LAND_IAU'] - - archive_dict = AttrDict() - for key in keys: - try: - archive_dict[key] = archive.task_config[key] - except KeyError as ee: - logger.warning(f"WARNING: key ({key}) not found in archive.task_config!") - - # Also import all COMIN* and COMOUT* directory and template variables - for key in archive.task_config.keys(): - if key.startswith(("COM_", "COMIN_", "COMOUT_")): - archive_dict[key] = archive.task_config.get(key) - - with chdir(config.ROTDIR): - - # Determine which archives to create - arcdir_set = archive.configure_vrfy(archive_dict) - - # Populate the product archive (ARCDIR) - archive.execute_store_products(arcdir_set) - - # Clean up any temporary files - archive.clean() - - -if __name__ == '__main__': - main() diff --git a/scripts/exglobal_atmos_analysis_calc.sh b/scripts/exglobal_atmos_analysis_calc.sh deleted file mode 100755 index 46371403efb..00000000000 --- a/scripts/exglobal_atmos_analysis_calc.sh +++ /dev/null @@ -1,186 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exglobal_atmos_analysis_calc.sh -# Script description: Runs non-diagnostic file tasks after GSI analysis is performed -# -# Author: Cory Martin Org: NCEP/EMC Date: 2020-03-03 -# -# Abstract: This script wraps up analysis-related tasks after GSI exits successfully -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# -################################################################################ - -# Set environment. - -# Directories. -pwd=$(pwd) - -# Base variables -rCDUMP=${rCDUMP:-"gdas"} -GDUMP=${GDUMP:-"gdas"} - -# Utilities -export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} -export NCLEN=${NCLEN:-${USHgfs}/getncdimlen} -COMPRESS=${COMPRESS:-gzip} -UNCOMPRESS=${UNCOMPRESS:-gunzip} -APRUNCFP=${APRUNCFP:-""} - -# Diagnostic files options -netcdf_diag=${netcdf_diag:-".true."} -binary_diag=${binary_diag:-".false."} - -# IAU -DOIAU=${DOIAU:-"NO"} -export IAUFHRS=${IAUFHRS:-"6,"} - -# Dependent Scripts and Executables -export NTHREADS_CALCINC=${NTHREADS_CALCINC:-1} -export APRUN_CALCINC=${APRUN_CALCINC:-${APRUN:-""}} -export APRUN_CALCANL=${APRUN_CALCANL:-${APRUN:-""}} -export APRUN_CHGRES=${APRUN_CALCANL:-${APRUN:-""}} - -export CALCANLEXEC=${CALCANLEXEC:-${EXECgfs}/calc_analysis.x} -export CHGRESNCEXEC=${CHGRESNCEXEC:-${EXECgfs}/enkf_chgres_recenter_nc.x} -export CHGRESINCEXEC=${CHGRESINCEXEC:-${EXECgfs}/interp_inc.x} -export NTHREADS_CHGRES=${NTHREADS_CHGRES:-1} -CALCINCPY=${CALCINCPY:-${USHgfs}/calcinc_gfs.py} -CALCANLPY=${CALCANLPY:-${USHgfs}/calcanl_gfs.py} - -DOGAUSFCANL=${DOGAUSFCANL-"NO"} -GAUSFCANLSH=${GAUSFCANLSH:-${USHgfs}/gaussian_sfcanl.sh} -export GAUSFCANLEXE=${GAUSFCANLEXE:-${EXECgfs}/gaussian_sfcanl.x} -NTHREADS_GAUSFCANL=${NTHREADS_GAUSFCANL:-1} -APRUN_GAUSFCANL=${APRUN_GAUSFCANL:-${APRUN:-""}} - -# Guess files -GPREFIX=${GPREFIX:-""} -ATMG03=${ATMG03:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f003.nc} -ATMG04=${ATMG04:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f004.nc} -ATMG05=${ATMG05:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f005.nc} -ATMGES=${ATMGES:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f006.nc} -ATMG07=${ATMG07:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f007.nc} -ATMG08=${ATMG08:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f008.nc} -ATMG09=${ATMG09:-${COMIN_ATMOS_HISTORY_PREV}/${GPREFIX}atm.f009.nc} - -# Analysis files -export APREFIX=${APREFIX:-""} -SFCANL=${SFCANL:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.sfc.a006.nc} -DTFANL=${DTFANL:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.dtf.a006.nc} -ATMANL=${ATMANL:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a006.nc} - -# Increment files -ATMINC=${ATMINC:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i006.nc} - -# Set script / GSI control parameters -DOHYBVAR=${DOHYBVAR:-"NO"} -lrun_subdirs=${lrun_subdirs:-".true."} -if [[ "${DOHYBVAR}" == "YES" ]]; then - l_hyb_ens=.true. - export l4densvar=${l4densvar:-".false."} - export lwrite4danl=${lwrite4danl:-".false."} -else - l_hyb_ens=.false. - export l4densvar=.false. - export lwrite4danl=.false. -fi - -# Set 4D-EnVar specific variables -if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then - ATMA03=${ATMA03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a003.nc} - ATMI03=${ATMI03:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i003.nc} - ATMA04=${ATMA04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a004.nc} - ATMI04=${ATMI04:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i004.nc} - ATMA05=${ATMA05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a005.nc} - ATMI05=${ATMI05:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i005.nc} - ATMA07=${ATMA07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a007.nc} - ATMI07=${ATMI07:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i007.nc} - ATMA08=${ATMA08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a008.nc} - ATMI08=${ATMI08:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i008.nc} - ATMA09=${ATMA09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a009.nc} - ATMI09=${ATMI09:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i009.nc} -fi - -################################################################################ -# Clean the run-directory -rm -rf dir.* - -############################################################## -# If analysis increment is written by GSI, produce an analysis file here -if [[ "${DO_CALC_ANALYSIS}" == "YES" ]]; then - # link analysis and increment files - ${NLN} "${ATMANL}" siganl - ${NLN} "${ATMINC}" siginc.nc - if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then - ${NLN} "${ATMA03}" siga03 - ${NLN} "${ATMI03}" sigi03.nc - ${NLN} "${ATMA04}" siga04 - ${NLN} "${ATMI04}" sigi04.nc - ${NLN} "${ATMA05}" siga05 - ${NLN} "${ATMI05}" sigi05.nc - ${NLN} "${ATMA07}" siga07 - ${NLN} "${ATMI07}" sigi07.nc - ${NLN} "${ATMA08}" siga08 - ${NLN} "${ATMI08}" sigi08.nc - ${NLN} "${ATMA09}" siga09 - ${NLN} "${ATMI09}" sigi09.nc - fi - # link guess files - ${NLN} "${ATMG03}" sigf03 - ${NLN} "${ATMGES}" sigf06 - ${NLN} "${ATMG09}" sigf09 - - if [[ -f "${ATMG04}" ]]; then - ${NLN} "${ATMG04}" sigf04 - fi - if [[ -f "${ATMG05}" ]]; then - ${NLN} "${ATMG05}" sigf05 - fi - if [[ -f "${ATMG07}" ]]; then - ${NLN} "${ATMG07}" sigf07 - fi - if [[ -f "${ATMG08}" ]]; then - ${NLN} "${ATMG08}" sigf08 - fi - - # Link hourly backgrounds (if present) - if [[ -f "${ATMG04}" && -f "${ATMG05}" && -f "${ATMG07}" && -f "${ATMG08}" ]]; then - nhr_obsbin=1 - fi - - ${CALCANLPY} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to run ${CALCANLPY}" - fi -else - echo "WARNING Neither increment nor analysis are generated by external utils" -fi - -############################################################## -# Create gaussian grid surface analysis file at middle of window -if [[ "${DOGAUSFCANL}" == "YES" ]]; then - export APRUNSFC=${APRUN_GAUSFCANL} - export OMP_NUM_THREADS_SFC=${NTHREADS_GAUSFCANL} - - ${GAUSFCANLSH} - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Gaussian grid surface file was not generated!" - fi -fi - -echo "${rCDUMP} ${PDY}${cyc} atmanl and sfcanl done at $(date)" > "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.done.txt" - -################################################################################ -# Postprocessing -cd "${pwd}" || exit 1 - -exit 0 diff --git a/scripts/exglobal_atmos_pmgr.sh b/scripts/exglobal_atmos_pmgr.sh deleted file mode 100755 index 390ab1cb71f..00000000000 --- a/scripts/exglobal_atmos_pmgr.sh +++ /dev/null @@ -1,70 +0,0 @@ -#! /usr/bin/env bash - -# -# Script name: exgfs_pmgr.sh.sms -# -# This script monitors the progress of the gfs_fcst job -# - -hour=00 - -case $RUN in - gfs) - TEND=384 - TCP=385 - ;; - gdas) - TEND=9 - TCP=10 - ;; -esac - -if [ -e posthours ]; then - rm -f posthours -fi - -while [ $hour -lt $TCP ]; do - hour=$(printf "%02d" $hour) - echo $hour >>posthours - if [ 10#$hour -lt 120 ]; then - let "hour=hour+1" - else - let "hour=hour+3" - fi -done -postjobs=$(cat posthours) - -# -# Wait for all fcst hours to finish -# -icnt=1 -while [ $icnt -lt 1000 ]; do - for fhr in $postjobs; do - fhr3=$(printf "%03d" $fhr) - if [ -s ${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.logf${fhr3}.txt ]; then - if [ $fhr -eq 0 ]; then - #### ecflow_client --event release_${RUN}_postanl - ecflow_client --event release_postanl - fi - #### ecflow_client --event release_${RUN}_post${fhr} - ecflow_client --event release_post${fhr3} - # Remove current fhr from list - postjobs=$(echo $postjobs | sed "s/${fhr}//") - fi - done - - result_check=$(echo $postjobs | wc -w) - if [ $result_check -eq 0 ]; then - break - fi - - sleep 10 - icnt=$((icnt + 1)) - if [[ ${icnt} -ge 1080 ]]; then - msg="ABORTING after 3 hours of waiting for ${RUN} FCST hours $postjobs." - err_exit $msg - fi -done - - -exit diff --git a/scripts/exglobal_atmos_products.sh b/scripts/exglobal_atmos_products.sh deleted file mode 100755 index 6c0ee4fc122..00000000000 --- a/scripts/exglobal_atmos_products.sh +++ /dev/null @@ -1,282 +0,0 @@ -#! /usr/bin/env bash - -cd "${DATA}" || exit 1 - -# Set paramlist files based on FORECAST_HOUR (-1, 0, 3, 6, etc.) -# Determine if supplemental products (PGBS) (1-degree and 1/2-degree) should be generated -if [[ ${FORECAST_HOUR} -le 0 ]]; then - if [[ ${FORECAST_HOUR} -lt 0 ]]; then - fhr3="analysis" - # shellcheck disable=SC2034 # paramlista is used later indirectly - paramlista="${paramlista_anl}" - FLXGF="NO" - elif [[ ${FORECAST_HOUR} == 0 ]]; then - fhr3=$(printf "f%03d" "${FORECAST_HOUR}") - # shellcheck disable=SC2034 # paramlista is used later indirectly - paramlista="${paramlista_f000}" - fi - PGBS="YES" -else - fhr3=$(printf "f%03d" "${FORECAST_HOUR}") - if (( FORECAST_HOUR%FHOUT_PGBS == 0 )); then - PGBS="YES" - fi -fi - -#----------------------------------------------------- -# Section creating pressure grib2 interpolated products - -# Determine grids once and save them as a string and an array for processing -grid_string="0p25" -if [[ "${PGBS:-}" == "YES" ]]; then - grid_string="${grid_string}:0p50:1p00" -else - echo "INFO: Supplemental product generation is disabled for fhr = ${fhr3}" - PGBS="NO" # Can't generate supplemental products if PGBS is not YES -fi -# Also transform the ${grid_string} into an array for processing -IFS=':' read -ra grids <<< "${grid_string}" - -# Files needed by ${USHgfs}/interp_atmos_master.sh -MASTER_FILE="${COMIN_ATMOS_MASTER}/${PREFIX}master.${fhr3}.grib2" - -nset=1 -while [[ ${nset} -le ${downset:-1} ]]; do - - echo "INFO: Begin processing nset = ${nset}" - - # Each set represents a group of files - if [[ ${nset} == 1 ]]; then - grp="a" - elif [[ ${nset} == 2 ]]; then - grp="b" - fi - - # Get inventory from ${MASTER_FILE} that matches patterns from ${paramlist} - # Extract this inventory from ${MASTER_FILE} into a smaller tmpfile based on paramlist - - tmpfile="tmpfile${grp}_${fhr3}" - paramlist="paramlist${grp}" - parmfile="${!paramlist}" - - # shellcheck disable=SC2312 - ${WGRIB2} "${MASTER_FILE}" | grep -F -f "${parmfile}" | ${WGRIB2} -i -grib "${tmpfile}" "${MASTER_FILE}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "wgrib2 failed to create intermediate grib2 file from '${MASTER_FILE}' using '${parmfile}'" - fi - - # Number of processors available to process $nset - nproc=${ntasks} - - # shellcheck disable=SC2312 - ncount=$(${WGRIB2} "${tmpfile}" | wc -l) - if [[ ${nproc} -gt ${ncount} ]]; then - echo "WARNING: Total no. of available processors '${nproc}' exceeds no. of records '${ncount}' in ${tmpfile}" - echo "WARNING: Reduce nproc to ${ncount} (or less) to not waste resources" - fi - inv=$(( ncount / nproc )) - rm -f "${DATA}/cmdfile" - - last=0 - iproc=1 - while [[ ${iproc} -le ${nproc} ]]; do - first=$((last + 1)) - last=$((last + inv)) - if [[ ${last} -gt ${ncount} ]]; then - last=${ncount} - fi - - # if final record of is u-component, add next record v-component - # if final record is land, add next record icec - # grep returns 1 if no match is found, so temporarily turn off exit on non-zero rc - set +e - # shellcheck disable=SC2312 - ${WGRIB2} -d "${last}" "${tmpfile}" | grep -E -i "ugrd|ustm|uflx|u-gwd|land|maxuw" - rc=$? - set_strict - if [[ ${rc} == 0 ]]; then # Matched the grep - last=$(( last + 1 )) - fi - if [[ ${iproc} -eq ${nproc} ]]; then - last=${ncount} - fi - - # Break tmpfile into processor specific chunks in preparation for MPMD - ${WGRIB2} "${tmpfile}" -for "${first}":"${last}" -grib "${tmpfile}_${iproc}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "wgrib2 failed to geneate an intermediate grib2 file from ${tmpfile} records ${first} to ${last}" - fi - input_file="${tmpfile}_${iproc}" - output_file_prefix="pgb2${grp}file_${fhr3}_${iproc}" - echo "${USHgfs}/interp_atmos_master.sh ${input_file} ${output_file_prefix} ${grid_string}" >> "${DATA}/cmdfile" - - # if at final record and have not reached the final processor then write echo's to - # cmdfile for remaining processors - if [[ ${last} -eq ${ncount} ]]; then - for (( pproc = iproc+1 ; pproc < nproc ; pproc++ )); do - echo "/bin/echo ${pproc}" >> "${DATA}/cmdfile" - done - break - fi - iproc=$(( iproc + 1 )) - done # while [[ iproc -le nproc ]]; do - - # Run with MPMD or serial - "${USHgfs}/run_mpmd.sh" "${DATA}/cmdfile" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Some or all interpolations of the master grib file failed during MPMD execution!" - fi - - # We are in a loop over downset, save output from mpmd into nset specific output - mv mpmd.out "mpmd_${nset}.out" - - # Concatenate grib files from each processor into a single one - # and clean-up as you go - echo "INFO: Concatenating processor-specific grib2 files into a single product file" - iproc=1 - while [[ ${iproc} -le ${nproc} ]]; do - for grid in "${grids[@]}"; do - if [[ -s "pgb2${grp}file_${fhr3}_${iproc}_${grid}" ]]; then - cat "pgb2${grp}file_${fhr3}_${iproc}_${grid}" >> "pgb2${grp}file_${fhr3}_${grid}" - rm -f "pgb2${grp}file_${fhr3}_${iproc}_${grid}" - fi - done - # There is no further use of the processor specific tmpfile; delete it - rm -f "${tmpfile}_${iproc}" - iproc=$(( iproc + 1 )) - done - - # Move to COM and index the product grib files - for grid in "${grids[@]}"; do - ${WGRIB2} -s "pgb2${grp}file_${fhr3}_${grid}" > "pgb2${grp}file_${fhr3}_${grid}.idx" - prod_dir="COMOUT_ATMOS_GRIB_${grid}" - cpfs "pgb2${grp}file_${fhr3}_${grid}" "${!prod_dir}/${PREFIX}pres_${grp}.${grid}.${fhr3}.grib2" - cpfs "pgb2${grp}file_${fhr3}_${grid}.idx" "${!prod_dir}/${PREFIX}pres_${grp}.${grid}.${fhr3}.grib2.idx" - done - - echo "INFO: Finished processing nset = ${nset}" - - nset=$(( nset + 1 )) -done # while [[ ${nset} -le ${downset} ]]; do - -#--------------------------------------------------------------- - -# Create the index file for the sflux master, if it exists. -FLUX_FILE="${COMIN_ATMOS_MASTER}/${PREFIX}sflux.${fhr3}.grib2" -if [[ -s "${FLUX_FILE}" ]]; then - ${WGRIB2} -s "${FLUX_FILE}" > "${FLUX_FILE}.idx" -fi - -# Section creating sflux grib2 interpolated products -# Create 1-degree sflux grib2 output -# move to COM and index it -if [[ "${FLXGF:-}" == "YES" ]]; then - - # Files needed by ${USHgfs}/interp_atmos_sflux.sh - input_file="${FLUX_FILE}" - output_file_prefix="sflux_${fhr3}" - grid_string="1p00" - "${USHgfs}/interp_atmos_sflux.sh" "${input_file}" "${output_file_prefix}" "${grid_string}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Unable to interpolate the surface flux grib2 files!" - fi - - # Move to COM and index the product sflux file - IFS=':' read -ra grids <<< "${grid_string}" - for grid in "${grids[@]}"; do - ${WGRIB2} -s "sflux_${fhr3}_${grid}" > "sflux_${fhr3}_${grid}.idx" - prod_dir="COMOUT_ATMOS_GRIB_${grid}" - cpfs "sflux_${fhr3}_${grid}" "${!prod_dir}/${PREFIX}flux.${grid}.${fhr3}.grib2" - cpfs "sflux_${fhr3}_${grid}.idx" "${!prod_dir}/${PREFIX}flux.${grid}.${fhr3}.grib2.idx" - done -fi - -# Section creating 0.25 degree WGNE products for nset=1, and fhr <= FHMAX_WGNE -if [[ "${WGNE:-}" == "YES" ]]; then - grp="a" - if [[ ${FORECAST_HOUR} -gt 0 && ${FORECAST_HOUR} -le ${FHMAX_WGNE:-0} ]]; then - # 598 is the message number for APCP in GFSv17 (it was 597 in GFSv16) - ${WGRIB2} "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_${grp}.0p25.${fhr3}.grib2" \ - -d "${APCP_MSG:-598}" \ - -grib "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" - fi -fi - -#--------------------------------------------------------------- - -# Start sending DBN alerts -# Everything below this line is for sending files to DBN (SENDDBN=YES) -if [[ "${SENDDBN:-}" == "YES" ]]; then - - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P25" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_a.0p25.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P25_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_a.0p25.${fhr3}.grib2.idx" - if [[ "${RUN}" == "gfs" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P25" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_b.0p25.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P25_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}pres_b.0p25.${fhr3}.grib2.idx" - if [[ -s "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P5" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_0P5_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_a.0p50.${fhr3}.grib2.idx" - fi - if [[ -s "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P5" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_0P5_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_0p50}/${PREFIX}pres_b.0p50.${fhr3}.grib2.idx" - fi - if [[ -s "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_1P0" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2_1P0_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" - fi - if [[ -s "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_1P0" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB2B_1P0_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_b.1p00.${fhr3}.grib2.idx" - fi - if [[ "${WGNE:-}" == "YES" ]] && [[ -s "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" ]] ; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WGNE" "${job}" "${COMOUT_ATMOS_GRIB_0p25}/${PREFIX}wgne.${fhr3}.grib2" - fi - fi - - if [[ "${fhr3}" == "analysis" ]]; then - - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_MSC_sfcanl" "${job}" "${COMIN_ATMOS_ANALYSIS}/${PREFIX}analysis.sfc.a006.nc" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SA" "${job}" "${COMIN_ATMOS_ANALYSIS}/${PREFIX}analysis.atm.a006.nc" - - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGA_GB2" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGA_GB2_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" - - else # forecast hours f000, f003, f006, etc. - - case "${RUN}" in - gdas) - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB_GB2" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_PGB_GB2_WIDX" "${job}" "${COMOUT_ATMOS_GRIB_1p00}/${PREFIX}pres_a.1p00.${fhr3}.grib2.idx" - if (( FORECAST_HOUR % 3 == 0 )); then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.${fhr3}.nc" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_BF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.${fhr3}.nc" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2_WIDX" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2.idx" - fi - ;; - gfs) - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}atm.${fhr3}.nc" - if [[ ${fhr} -gt 0 && ${fhr} -le 84 || ${fhr} -eq 120 ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_BF" "${job}" "${COMIN_ATMOS_HISTORY}/${PREFIX}sfc.${fhr3}.nc" - fi - - if [[ -s "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_SGB_GB2_WIDX" "${job}" "${COMIN_ATMOS_MASTER}/${PREFIX}sflux.f${fhr3}.grib2.idx" - fi - ;; - *) - err_exit "Unsupported RUN value '${RUN}' for SENDDBN section" - ;; - esac - - fi # end if fhr3=anl - -fi # end if SENDDBN=YES - -exit 0 diff --git a/scripts/exglobal_atmos_sfcanl.sh b/scripts/exglobal_atmos_sfcanl.sh deleted file mode 100755 index 903f28fd967..00000000000 --- a/scripts/exglobal_atmos_sfcanl.sh +++ /dev/null @@ -1,192 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exglobal_atmos_sfcanl.sh -# Script description: Makes global model surface analysis files -# -# Author: Russ Treadon Org: NCEP/EMC Date: 2021-12-13 -# -# Abstract: This script makes global model surface analysis files -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# -################################################################################ - -# Set environment. - -# Derived base variables - -# Dependent Scripts and Executables -CYCLESH=${CYCLESH:-${USHgfs}/global_cycle.sh} -REGRIDSH=${REGRIDSH:-"${USHgfs}/regrid_gsiSfcIncr_to_tile.sh"} -export CYCLEXEC=${CYCLEXEC:-${EXECgfs}/global_cycle} -NTHREADS_CYCLE=${NTHREADS_CYCLE:-24} -APRUN_CYCLE=${APRUN_CYCLE:-${APRUN:-""}} - -# Surface cycle related parameters -export SNOW_NUDGE_COEFF=${SNOW_NUDGE_COEFF:-'-2.'} -export CYCLVARS=${CYCLVARS:-""} -export FHOUR=${FHOUR:-0} -export DELTSFC=${DELTSFC:-6} -export COUPLED=${COUPLED:-".false."} - -# Other info used in this script -# Ignore possible spelling error (nothing is misspelled) -# shellcheck disable=SC2153 -GPREFIX="gdas.t${GDATE:8:2}z." -OPREFIX="${RUN/enkf}.t${cyc}z." -APREFIX="${RUN/enkf}.t${cyc}z." - -ntiles=6 - - -############################################################## -# Get dimension information based on CASE -res="${CASE:1}" -JCAP_CASE=$((res*2-2)) -LATB_CASE=$((res*2)) -LONB_CASE=$((res*4)) - -# Global cycle requires these files -export FNTSFA=${FNTSFA:-${COMIN_OBS}/${OPREFIX}rtgssthr.grb} -export FNACNA=${FNACNA:-${COMIN_OBS}/${OPREFIX}seaice.5min.blend.grb} -export FNSNOA=${FNSNOA:-${COMIN_OBS}/${OPREFIX}snogrb_t${JCAP_CASE}.${LONB_CASE}.${LATB_CASE}} -# Check if resolution specific FNSNOA exists, if not use t1534 version -if [[ ! -f ${FNSNOA} ]]; then - export FNSNOA="${COMIN_OBS}/${OPREFIX}snogrb_t1534.3072.1536" -fi -if [[ ! -f ${FNSNOA} ]]; then - echo "WARNING: Current cycle snow file ${FNSNOA} is missing. Snow coverage will not be updated." -else - echo "INFO: Current cycle snow file is ${FNSNOA}" -fi -export FNSNOG=${FNSNOG:-${COMIN_OBS_PREV}/${GPREFIX}snogrb_t${JCAP_CASE}.${LONB_CASE}.${LATB_CASE}} -# Check if resolution specific FNSNOG exists, if not use t1534 version -if [[ ! -f ${FNSNOG} ]]; then - export FNSNOG="${COMIN_OBS_PREV}/${GPREFIX}snogrb_t1534.3072.1536" -fi -if [[ ! -f ${FNSNOG} ]]; then - echo "WARNING: Previous cycle snow file ${FNSNOG} is missing. Snow coverage will not be updated." -else - echo "INFO: Previous cycle snow file is ${FNSNOG}" -fi - -# If any snow files are missing, don't apply snow in the global_cycle step. -if [[ ! -f ${FNSNOA} ]] || [[ ! -f ${FNSNOG} ]]; then - export FNSNOA=" " - export CYCLVARS="FSNOL=99999.,FSNOS=99999.," -# Set CYCLVARS by checking grib date of current snogrb vs that of prev cycle -elif [[ $(${WGRIB} -4yr "${FNSNOA}" 2>/dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') -le \ - $(${WGRIB} -4yr "${FNSNOG}" 2>/dev/null | grep -i snowc | awk -F: '{print $3}' | awk -F= '{print $2}') ]] ; then - export FNSNOA=" " - export CYCLVARS="FSNOL=99999.,FSNOS=99999.," -else - export CYCLVARS="FSNOL=${SNOW_NUDGE_COEFF},${CYCLVARS}" -fi - -# determine where the input snow restart files come from -snow_prefix="" -if [[ "${DO_JEDISNOWDA:-}" == "YES" ]]; then - sfcdata_dir="${COMIN_SNOW_ANALYSIS}" - snow_prefix="snow_analysis." -else - sfcdata_dir="${COMIN_ATMOS_RESTART_PREV}" -fi - -# global_cycle executable specific variables -export APRUNCY=${APRUN_CYCLE} -export OMP_NUM_THREADS_CY=${NTHREADS_CYCLE} -export MAX_TASKS_CY=${ntiles} - -# Copy fix files required by global_cycle to DATA just once -for (( nn=1; nn <= ntiles; nn++ )); do - cpreq "${FIXgfs}/orog/${CASE}/${CASE}_grid.tile${nn}.nc" "${DATA}/fngrid.00${nn}" - cpreq "${FIXgfs}/orog/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${nn}.nc" "${DATA}/fnorog.00${nn}" -done - -# Copy the NSST analysis file for global_cycle -# There is only a single NSST analysis at the middle of the window -# For now use/assume it is the same at the beginning of the window if doing IAU -if [[ "${DONST}" == "YES" ]]; then - cpreq "${COMIN_ATMOS_ANALYSIS}/${APREFIX}analysis.dtf.a006.nc" "${DATA}/dtfanl" - export NST_FILE="dtfanl" -else - export NST_FILE="NULL" -fi - -# Collect the dates in the window to update surface restarts -gcycle_dates=("${PDY}${cyc}") # Always update surface restarts at middle of window -soilinc_fhrs=("${assim_freq}") # increment file at middle of window -LFHR=${assim_freq} -if [[ "${DOIAU:-}" == "YES" ]]; then # Update surface restarts at beginning of window - half_window=$(( assim_freq / 2 )) - soilinc_fhrs+=("${half_window}") - LFHR=-1 - BDATE=$(date --utc -d "${PDY} ${cyc} - ${half_window} hours" +%Y%m%d%H) - gcycle_dates+=("${BDATE}") -fi - -# if doing GSI soil anaysis, copy increment file and re-grid it to native model resolution -if [[ "${DO_GSISOILDA}" = "YES" ]]; then - - export COMIN_SOIL_ANALYSIS_MEM="${COMIN_ATMOS_ENKF_ANALYSIS_STAT}" - export COMOUT_ATMOS_ANALYSIS_MEM="${COMIN_ATMOS_ANALYSIS}" - export CASE_IN="${CASE_ENS}" - export CASE_OUT="${CASE}" - export OCNRES_OUT="${OCNRES}" - export LFHR - - "${REGRIDSH}" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Soil increment file was not regridded correctly!" - fi - -fi - -# Loop over the dates in the window to update the surface restarts -for hr in "${!gcycle_dates[@]}"; do - - gcycle_date=${gcycle_dates[hr]} - FHR=${soilinc_fhrs[hr]} - echo "Updating surface restarts for ${gcycle_date} ..." - - datestr="${gcycle_date:0:8}.${gcycle_date:8:2}0000" - - if [[ "${DO_GSISOILDA}" == "YES" && "${GCYCLE_DO_SOILINCR}" == ".true." ]]; then - for (( nn=1; nn <= ntiles; nn++ )); do - cpreq "${COMIN_ATMOS_ANALYSIS}/increment.sfc.i00${FHR}.tile${nn}.nc" \ - "${DATA}/soil_xainc.00${nn}" - done - fi - - # Copy inputs from COMIN to DATA - for (( nn=1; nn <= ntiles; nn++ )); do - cpreq "${sfcdata_dir}/${datestr}.${snow_prefix}sfc_data.tile${nn}.nc" "${DATA}/fnbgsi.00${nn}" - cpreq "${DATA}/fnbgsi.00${nn}" "${DATA}/fnbgso.00${nn}" - done - - "${CYCLESH}" && true - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Unable to update surface data from guess and analysis!" - fi - - # Copy outputs from DATA to COMOUT - for (( nn=1; nn <= ntiles; nn++ )); do - cpfs "${DATA}/fnbgso.00${nn}" "${COMOUT_ATMOS_RESTART}/${datestr}.sfcanl_data.tile${nn}.nc" - done - -done - - -################################################################################ - -exit "${err}" - -################################################################################ diff --git a/scripts/exglobal_atmos_tropcy_qc_reloc.sh b/scripts/exglobal_atmos_tropcy_qc_reloc.sh deleted file mode 100755 index bd99bf69547..00000000000 --- a/scripts/exglobal_atmos_tropcy_qc_reloc.sh +++ /dev/null @@ -1,167 +0,0 @@ -#! /usr/bin/env bash - -############################################################################ -# echo "---------------------------------------------------------------------" -# echo "exglobal_atmos_tropcy_qc_reloc.sh - Tropical Cyclone QC/Relocation Prcocessing" -# echo "---------------------------------------------------------------------" -# echo "History: Jun 13 2006 - Original script." -# echo " March 2013 - No changes needed for WCOSS transition" -# echo " MP_LABELIO default added" -# echo " Oct 2013 - Use main USH vars as part of minor pkg cleanup" -############################################################################ - -# Make sure we are in the $DATA directory -cd "${DATA}" - -tmhr=${tmmark:2:2} -cdate10=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${tmhr} hours") - -NET_uc=${RUN^^} -tmmark_uc=${tmmark^^} - -iflag=0 -if [[ "${RUN}" = ndas ]]; then - if [[ "${DO_RELOCATE}" = NO ]]; then - echo "CENTER PROCESSING TIME FOR NDAS TROPICAL CYCLONE QC IS ${cdate10}" - echo "Output tcvitals files will be copied forward in time to proper \ -output file directory path locations" - iflag=1 - else - echo "CENTER PROCESSING TIME FOR ${tmmark_uc} NDAS TROPICAL CYCLONE \ -RELOCATION IS ${cdate10}" - fi -else - echo "CENTER PROCESSING TIME FOR ${tmmark_uc} ${NET_uc} TROPICAL CYCLONE QC/\ -RELOCATION IS ${cdate10}" -fi - - -if [[ "${PROCESS_TROPCY}" = 'YES' ]]; then - -#################################### -#################################### -# QC tcvitals for tropical cyclones -#################################### -#################################### - -#echo $PDY - - "${USHgfs}/syndat_qctropcy.sh" "${cdate10}" - errsc=$? - if [[ ${errsc} -ne 0 ]]; then - echo "syndat_qctropcy.sh failed. exit" - exit ${errsc} - fi - - - cd "${COMOUT_OBS}" || exit 1 - pwd - ls -ltr *syndata* - cd "${ARCHSYND}" - pwd;ls -ltr - cat syndat_dateck - cd "${HOMENHC}" - pwd;ls -ltr - cd "${DATA}" - -else - -# Copy null files into "syndata.tcvitals" and "jtwc-fnoc.tcvitals" -# (Note: Only do so if files don't already exist - need because in NDAS this -# script is run twice, first time with DO_RELOCATE=NO, copying these -# files, and second time with PROCESS_TROPCY=NO and thus coming here - -# don't want to wipe out these files) -# - - if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.syndata.tcvitals.${tmmark}" ]]; then - cpfs "/dev/null" "${COMOUT_OBS}/${RUN}.t${cyc}z.syndata.tcvitals.${tmmark}" - fi - if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.jtwc-fnoc.tcvitals.${tmmark}" ]]; then - cpfs "/dev/null" "${COMOUT_OBS}/${RUN}.t${cyc}z.jtwc-fnoc.tcvitals.${tmmark}" - fi - -# endif loop $PROCESS_TROPCY -fi - - -if [[ "${DO_RELOCATE}" = 'YES' ]]; then - -################################################### -################################################### -# Relocate tropical cyclones in global sigma guess -################################################### -################################################### - - export MP_LABELIO=${MP_LABELIO:-yes} - "${USHgfs}/tropcy_relocate.sh" "${cdate10}" - export err=$? - - if [[ ${err} -ne 0 ]]; then - err_exit "Failed while updating tropical cyclone data!" - fi - - -# save global sigma guess file(s) possibly updated by tropical cyclone -# relocation processing in COMSP path - qual_last=".${tmmark}" # need this because gfs and gdas don't add $tmmark - # qualifer to end of output sigma guess files - if [[ "${RUN}" == gfs || "${RUN}" == gdas || "${NET}" == cfs ]]; then - qual_last="" - fi - - if [[ ${BKGFREQ} -eq 1 ]]; then - if [[ -s sgm3prep ]]; then - cpfs "sgm3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm3prep${qual_last}" - fi - if [[ -s sgm2prep ]]; then - cpfs "sgm2prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm2prep${qual_last}" - fi - if [[ -s sgm1prep ]]; then - cpfs "sgm1prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm1prep${qual_last}" - fi - if [[ -s sgesprep ]]; then - cpfs "sgesprep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgesprep${qual_last}" - fi - if [[ -s sgp1prep ]]; then - cpfs "sgp1prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp1prep${qual_last}" - fi - if [[ -s sgp2prep ]]; then - cpfs "sgp2prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp2prep${qual_last}" - fi - if [[ -s sgp3prep ]]; then - cpfs "sgp3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp3prep${qual_last}" - fi - elif [[ ${BKGFREQ} -eq 3 ]]; then - if [[ -s sgm3prep ]]; then - cpfs "sgm3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgm3prep${qual_last}" - fi - if [[ -s sgesprep ]]; then - cpfs "sgesprep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgesprep${qual_last}" - fi - if [[ -s sgp3prep ]]; then - cpfs "sgp3prep" "${COMOUT_OBS}/${RUN}.t${cyc}z.sgp3prep${qual_last}" - fi - fi - -# The existence of ${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.$tmmark file will tell the -# subsequent PREP processing that RELOCATION processing occurred, if this file -# does not already exist at this point, echo "RECORDS PROCESSED" into it to -# further tell PREP processing that records were processed by relocation and -# the global sigma guess was modified by tropical cyclone relocation -# Note: If ${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.$tmmark already exists at this -# point it means that it contains the string "NO RECORDS to process" -# and was created by the child script tropcy_relocate.sh because records -# were not processed by relocation and the global sigma guess was NOT -# modified by tropical cyclone relocation (because no tcvitals records -# were found in the relocation step) -# ---------------------------------------------------------------------------- - - if [[ ! -s "${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.${tmmark}" ]]; then - echo "RECORDS PROCESSED" > "${COMOUT_OBS}/${RUN}.t${cyc}z.tropcy_relocation_status.${tmmark}" - fi - -# endif loop $DO_RELOCATE -fi - - -################## END OF SCRIPT ####################### diff --git a/scripts/exglobal_cleanup.sh b/scripts/exglobal_cleanup.sh deleted file mode 100755 index c460cc8282c..00000000000 --- a/scripts/exglobal_cleanup.sh +++ /dev/null @@ -1,120 +0,0 @@ -#! /usr/bin/env bash - -############################################################### -echo "Begin Cleanup ${DATAROOT}!" - -# Remove DATAoutput from the forecast model run -# TODO: Handle this better -DATAfcst="${DATAROOT}/${RUN}fcst.${PDY:-}${cyc}" -if [[ -d "${DATAfcst}" ]]; then rm -rf "${DATAfcst}"; fi -#DATAefcs="${DATAROOT}/${RUN}efcs???${PDY:-}${cyc}" -rm -rf "${DATAROOT}/${RUN}efcs"*"${PDY:-}${cyc}" -############################################################### - -if [[ "${CLEANUP_COM:-YES}" == NO ]] ; then - exit 0 -fi - -############################################################### -# Clean up previous cycles; various depths - -# Step back every assim_freq hours and remove old rotating directories -# for successful cycles (defaults from 24h to 120h). -# Retain files needed by Fit2Obs -last_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${RMOLDEND:-24} hours") -first_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${RMOLDSTD:-120} hours") -last_rtofs=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${RMOLDRTOFS:-48} hours") -function remove_files() { - local directory=$1 - shift - if [[ ! -d ${directory} ]]; then - echo "No directory ${directory} to remove files from, skiping" - return - fi - local find_exclude_string="" - for exclude in "$@"; do - find_exclude_string+="${find_exclude_string} -name ${exclude} -or" - done - # Chop off any trailing or - find_exclude_string="${find_exclude_string[*]/%-or}" - # Remove all regular files that do not match - # shellcheck disable=SC2086 - if [[ -n "${find_exclude_string}" ]]; then - # String is non-empty → use exclusion - find "${directory}" -type f -not \( ${find_exclude_string} \) -ignore_readdir_race -delete - else - # String is empty → no exclusion - find "${directory}" -type f -ignore_readdir_race -delete - fi - - # Remove all symlinks that do not match - # shellcheck disable=SC2086 - if [[ -n "${find_exclude_string}" ]]; then - # String is non-empty → use exclusion - find "${directory}" -type l -not \( ${find_exclude_string} \) -ignore_readdir_race -delete - else - # String is empty → no exclusion - find "${directory}" -type l -ignore_readdir_race -delete - fi - - # Remove any empty directories - find "${directory}" -type d -empty -delete -} - -for (( current_date=first_date; current_date <= last_date; \ - current_date=$(date --utc +%Y%m%d%H -d "${current_date:0:8} ${current_date:8:2} +${assim_freq} hours") )); do - current_PDY="${current_date:0:8}" - current_cyc="${current_date:8:2}" - rtofs_dir="${ROTDIR}/rtofs.${current_PDY}" - rocotolog="${EXPDIR}/logs/${current_date}.log" - if [[ -f "${rocotolog}" ]]; then - # TODO: This needs to be revamped to not look at the rocoto log. - # shellcheck disable=SC2312 - if [[ $(tail -n 1 "${rocotolog}") =~ "This cycle is complete: Success" ]]; then - YMD="${current_PDY}" HH="${current_cyc}" declare_from_tmpl \ - COMOUT_TOP:COM_TOP_TMPL - if [[ -d "${COMOUT_TOP}" ]]; then - IFS=", " read -r -a exclude_list <<< "${exclude_string:-}" - remove_files "${COMOUT_TOP}" "${exclude_list[@]:-}" - fi - if [[ -d "${rtofs_dir}" ]] && (( current_date < last_rtofs )); then rm -rf "${rtofs_dir}" ; fi - fi - fi -done - -# Remove archived gaussian files used for Fit2Obs in $VFYARC that are -# $FHMAX_FITS plus a delta before ${PDY}${cyc}. Touch existing archived -# gaussian files to prevent the files from being removed by automatic -# scrubber present on some machines. - -if [[ "${RUN}" == "gfs" ]]; then - fhmax=$((FHMAX_FITS + 36)) - RDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${fhmax} hours") - verify_dir="${ROTDIR}/vrfyarch/${RUN}.${RDATE:0:8}" - if [[ -d "${verify_dir}" ]]; then - rm -rf "${verify_dir}" - fi - - touch_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${FHMAX_FITS} hours") - while (( touch_date < "${PDY}${cyc}" )); do - touch_PDY="${touch_date:0:8}" - touch_cyc="${touch_date:8:2}" - touch_dir="${ROTDIR}/vrfyarch/${RUN}.${touch_PDY}/${touch_cyc}" - if [[ -d "${touch_dir}" ]]; then - touch "${touch_dir}"/* - fi - touch_date=$(date --utc +%Y%m%d%H -d "${touch_PDY} ${touch_cyc} +6 hours") - done -fi - -# Remove $RUN.$rPDY for the older of GDATE or RDATE -GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${RMOLDSTD:-120} hours") -RDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} -${FHMAX_GFS} hours") -if (( GDATE < RDATE )); then - RDATE=${GDATE} -fi -deletion_target="${ROTDIR}/${RUN}.${RDATE:0:8}" -if [[ -d ${deletion_target} ]]; then rm -rf "${deletion_target}"; fi - -# sync and wait to avoid filesystem synchronization issues -sync && sleep 1 diff --git a/scripts/exglobal_diag.sh b/scripts/exglobal_diag.sh deleted file mode 100755 index 8957e6201ca..00000000000 --- a/scripts/exglobal_diag.sh +++ /dev/null @@ -1,284 +0,0 @@ -#! /usr/bin/env bash - -################################################################################ -#### UNIX Script Documentation Block -# . . -# Script name: exglobal_diag.sh -# Script description: Creates diagnostic files after GSI analysis is performed -# -# Author: Cory Martin Org: NCEP/EMC Date: 2020-03-03 -# -# Abstract: This script creates GSI diagnostic files after GSI exits successfully -# -# $Id$ -# -# Attributes: -# Language: POSIX shell -# -################################################################################ - -# Set environment. - -# Base variables -GDUMP=${GDUMP:-"gdas"} - -# Utilities -export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} -export NCLEN=${NCLEN:-${USHgfs}/getncdimlen} -export CATEXEC=${CATEXEC:-${ncdiag_ROOT:-${gsi_ncdiag_ROOT}}/bin/ncdiag_cat_serial.x} -COMPRESS=${COMPRESS:-gzip} -UNCOMPRESS=${UNCOMPRESS:-gunzip} -APRUNCFP=${APRUNCFP:-""} - -# Diagnostic files options -netcdf_diag=${netcdf_diag:-".true."} -binary_diag=${binary_diag:-".false."} - -# Analysis files -export APREFIX=${APREFIX:-""} -RADSTAT=${RADSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}radstat.tar} -PCPSTAT=${PCPSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}pcpstat} -CNVSTAT=${CNVSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}cnvstat.tar} -OZNSTAT=${OZNSTAT:-${COMOUT_ATMOS_ANALYSIS}/${APREFIX}oznstat.tar} - -# Remove stat file if file already exists -rm -f "${RADSTAT}" "${PCPSTAT}" "${CNVSTAT}" "${OZNSTAT}" - -# Obs diag -GENDIAG=${GENDIAG:-"YES"} -DIAG_SUFFIX=${DIAG_SUFFIX:-""} -if [[ "${netcdf_diag}" == ".true." ]] ; then - DIAG_SUFFIX="${DIAG_SUFFIX}.nc4" -fi -DIAG_COMPRESS=${DIAG_COMPRESS:-"YES"} -DIAG_TARBALL=${DIAG_TARBALL:-"YES"} -USE_CFP=${USE_CFP:-"NO"} -CFP_MP=${CFP_MP:-"NO"} -nm="" -if [[ "${CFP_MP}" == "YES" ]]; then - nm=0 -fi -DIAG_DIR=${DIAG_DIR:-${COMOUT_ATMOS_ANALYSIS}/gsidiags} -REMOVE_DIAG_DIR=${REMOVE_DIAG_DIR:-"NO"} - -# Set script / GSI control parameters -lrun_subdirs=${lrun_subdirs:-".true."} - - -################################################################################ -# If requested, generate diagnostic files -if [[ "${GENDIAG}" == "YES" ]] ; then - if [[ "${lrun_subdirs}" == ".true." ]] ; then - for pe in ${DIAG_DIR}/dir.*; do - pedir="$(basename -- "${pe}")" - ${NLN} "${pe}" "${DATA}/${pedir}" - done - else - err_exit "lrun_subdirs must be true. Abort job" - fi - - # Set up lists and variables for various types of diagnostic files. - ntype=3 - - diagtype[0]="conv conv_gps conv_ps conv_pw conv_q conv_sst conv_t conv_tcp conv_uv conv_spd" - diagtype[1]="pcp_ssmi_dmsp pcp_tmi_trmm" - if [[ ${USE_BUILD_GSINFO} == "YES" ]]; then - diagtype[2]=$(cat ${BUILD_GSINFO_DIR}/ozinfo/satellites) - diagtype[3]=$(cat ${BUILD_GSINFO_DIR}/satinfo/satellites) - else - diagtype[2]="sbuv2_n16 sbuv2_n17 sbuv2_n18 sbuv2_n19 gome_metop-a gome_metop-b omi_aura mls30_aura ompsnp_npp ompstc8_npp ompstc8_n20 ompsnp_n20 ompstc8_n21 ompsnp_n21 ompslp_npp gome_metop-c" - diagtype[3]="msu_n14 sndr_g08 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g12 sndrd2_g12 sndrd3_g12 sndrd4_g12 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 sndrd1_g14 sndrd2_g14 sndrd3_g14 sndrd4_g14 sndrd1_g15 sndrd2_g15 sndrd3_g15 sndrd4_g15 amsua_n15 amsua_n16 amsua_n17 amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 imgr_g14 imgr_g15 ssmi_f13 ssmi_f15 amsua_n18 amsua_metop-a mhs_n18 mhs_metop-a amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_f16 ssmis_f17 ssmis_f18 ssmis_f19 ssmis_f20 iasi_metop-a amsua_n19 mhs_n19 seviri_m08 seviri_m09 seviri_m10 seviri_m11 cris_npp cris-fsr_npp cris-fsr_n20 atms_npp atms_n20 amsua_metop-b mhs_metop-b iasi_metop-b avhrr_metop-b avhrr_n18 avhrr_n19 avhrr_metop-a amsr2_gcom-w1 gmi_gpm saphir_meghat ahi_himawari8 abi_g16 abi_g17 amsua_metop-c mhs_metop-c iasi_metop-c avhrr_metop-c viirs-m_npp viirs-m_j1 abi_g18 ahi_himawari9 viirs-m_j2 cris-fsr_n21 atms_n21 abi_g19" - fi - - - diaglist[0]=listcnv - diaglist[1]=listpcp - diaglist[2]=listozn - diaglist[3]=listrad - - diagfile[0]=${CNVSTAT} - diagfile[1]=${PCPSTAT} - diagfile[2]=${OZNSTAT} - diagfile[3]=${RADSTAT} - - numfile[0]=0 - numfile[1]=0 - numfile[2]=0 - numfile[3]=0 - - # Set diagnostic file prefix based on lrun_subdirs variable - if [[ "${lrun_subdirs}" == ".true." ]]; then - prefix=" dir.*/" - else - prefix="pe*" - fi - - if [[ "${USE_CFP}" == "YES" ]]; then - rm -f "${DATA}/diag.sh" "${DATA}/mp_diag.sh" - cat > "${DATA}/diag.sh" << EOFdiag -#!/bin/sh -lrun_subdirs=\$1 -binary_diag=\$2 -type=\$3 -loop=\$4 -string=\$5 -PDY=\$6 -cyc=\$7 -DIAG_COMPRESS=\$8 -DIAG_SUFFIX=\$9 -if [[ "\${lrun_subdirs}" == ".true." ]]; then - prefix=" dir.*/" -else - prefix="pe*" -fi -file=diag_\${type}_\${string}.\${PDY}\${cyc}\${DIAG_SUFFIX} -if [[ "\${binary_diag}" == ".true." ]]; then - cat \${prefix}\${type}_\${loop}* > \$file -else - ${CATEXEC} -o \$file \${prefix}\${type}_\${loop}* -fi -if [[ "\${DIAG_COMPRESS}" == "YES" ]]; then - ${COMPRESS} "\${file}" -fi -EOFdiag - chmod 755 "${DATA}/diag.sh" - fi - - # Collect diagnostic files as a function of loop and type. - # Loop over first and last outer loops to generate innovation - # diagnostic files for indicated observation types (groups) - # - # NOTE: Since we set miter=2 in GSI namelist SETUP, outer - # loop 03 will contain innovations with respect to - # the analysis. Creation of o-a innovation files - # is triggered by write_diag(3)=.true. The setting - # write_diag(1)=.true. turns on creation of o-g - # innovation files. - - loops="01 03" - for loop in ${loops}; do - case ${loop} in - 01) string=ges;; - 03) string=anl;; - *) string=${loop};; - esac - echo "$(date) START loop ${string}" >&2 - n=-1 - while [[ ${n} -lt ${ntype} ]] ;do - n=$(( n + 1 )) - for type in $(echo "${diagtype[n]}"); do - count=$(ls ${prefix}${type}_${loop}* 2>/dev/null | wc -l) - if [[ ${count} -gt 1 ]]; then - if [[ "${USE_CFP}" == "YES" ]]; then - echo "${nm} ${DATA}/diag.sh ${lrun_subdirs} ${binary_diag} ${type} ${loop} ${string} ${PDY} ${cyc} ${DIAG_COMPRESS} ${DIAG_SUFFIX}" | tee -a "${DATA}/mp_diag.sh" - if [[ "${CFP_MP:-"NO"}" == "YES" ]]; then - nm=$((nm+1)) - fi - else - if [[ "${binary_diag}" == ".true." ]]; then - cat ${prefix}${type}_${loop}* > "diag_${type}_${string}.${PDY}${cyc}${DIAG_SUFFIX}" - else - ${CATEXEC} -o "diag_${type}_${string}.${PDY}${cyc}${DIAG_SUFFIX}" "${prefix}${type}_${loop}"* - fi - fi - echo "diag_${type}_${string}.${PDY}${cyc}*" >> "${diaglist[n]}" - numfile[n]=$(expr ${numfile[n]} + 1) - elif [[ ${count} -eq 1 ]]; then - cat ${prefix}${type}_${loop}* > "diag_${type}_${string}.${PDY}${cyc}${DIAG_SUFFIX}" - if [[ "${DIAG_COMPRESS}" == "YES" ]]; then - ${COMPRESS} "diag_${type}_${string}.${PDY}${cyc}${DIAG_SUFFIX}" - fi - echo "diag_${type}_${string}.${PDY}${cyc}*" >> "${diaglist[n]}" - numfile[n]=$(expr "${numfile[n]}" + 1) - fi - done - done - echo $(date) END loop "${string}" >&2 - done - - # We should already be in $DATA, but extra cd to be sure. - cd "${DATA}" || exit - - # If requested, compress diagnostic files - if [[ "${DIAG_COMPRESS}" == "YES" && "${USE_CFP}" == "NO" ]]; then - echo $(date) START "${COMPRESS}" diagnostic files >&2 - # shellcheck disable=SC2086 - for file in "diag_"*"${PDY}${cyc}${DIAG_SUFFIX}"; do - ${COMPRESS} "${file}" - done - echo "$(date) END ${COMPRESS} diagnostic files" >&2 - fi - - if [[ "${USE_CFP}" == "YES" ]] ; then - chmod 755 "${DATA}/mp_diag.sh" - ncmd=$(wc -l < "${DATA}/mp_diag.sh") - if [[ ${ncmd} -gt 0 ]]; then - if [[ ${ncmd} -lt ${max_tasks_per_node} ]]; then - ncmd_max=${ncmd} - else - ncmd_max=${max_tasks_per_node} - fi - APRUNCFP_DIAG=$(eval echo "${APRUNCFP}") - ${APRUNCFP_DIAG} "${DATA}/mp_diag.sh" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Failed to compress one or more observation diagnostic files!" - fi - fi - fi - - # Restrict diagnostic files containing rstprod data - if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then - rlist="conv_gps conv_ps conv_pw conv_q conv_sst conv_t conv_uv saphir" - for rtype in ${rlist}; do - for rfile in *"${rtype}"*; do - if [[ -s "${rfile}" ]]; then - ${CHGRP_CMD} "${rfile}" - fi - done - done - fi - - # If requested, create diagnostic file tarballs - if [[ ${DIAG_TARBALL} == "YES" ]]; then - echo $(date) START tar diagnostic files >&2 - n=-1 - while [[ ${n} -lt ${ntype} ]] ;do - n=$((n+1)) - TAROPTS="-uvf" - if [[ ! -s "${diagfile[n]}" ]]; then - TAROPTS="-cvf" - fi - if [[ ${numfile[n]} -gt 0 ]]; then - tar ${TAROPTS} "${diagfile[n]}" $(cat "${diaglist[n]}") - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "Unable to create ${diagfile[n]}!" - fi - fi - done - - # Restrict CNVSTAT - chmod 750 "${CNVSTAT}" - if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then - ${CHGRP_CMD} "${CNVSTAT}" - fi - - # Restrict RADSTAT - chmod 750 "${RADSTAT}" - if [[ "${CHGRP_RSTPROD}" == "YES" ]]; then - ${CHGRP_CMD} "${RADSTAT}" - fi - - echo "$(date) END tar diagnostic files" >&2 - fi -fi # End diagnostic file generation block - if [[ "${GENDIAG}" == "YES" ]] - -################################################################################ -# Postprocessing -# Remove $DIAG_DIR -if [[ "${REMOVE_DIAG_DIR}" == "YES" ]]; then - rm -rf "${DIAG_DIR}" -fi - -exit 0 diff --git a/scripts/exglobal_prep_obs_aero.py b/scripts/exglobal_prep_obs_aero.py deleted file mode 100755 index c9e209471e8..00000000000 --- a/scripts/exglobal_prep_obs_aero.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# exglobal_prep_obs_aero.py -# This script collect available viirs -# obs files, combine and preprocess -# them. -import os - -from wxflow import Logger, cast_strdict_as_dtypedict -from pygfs.task.aero_prepobs import AerosolObsPrep - -# Initialize root logger -logger = Logger(level='DEBUG', colored_log=True) - - -if __name__ == '__main__': - - # Take configuration from environment and cast it as python dictionary - config = cast_strdict_as_dtypedict(os.environ) - - AeroObs = AerosolObsPrep(config) - if config.DO_PREP_OBS_AERO: - AeroObs.initialize() - AeroObs.runConverter() - AeroObs.finalize() - else: - # just sync files from DMPDIR - AeroObs.syncObs() diff --git a/scripts/exglobal_stage_ic.py b/scripts/exglobal_stage_ic.py deleted file mode 100755 index b442cf1b12a..00000000000 --- a/scripts/exglobal_stage_ic.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 - -import os - -from pygfs.task.stage_ic import Stage -from wxflow import AttrDict, Logger, cast_strdict_as_dtypedict, logit - -# Initialize root logger -logger = Logger(level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=True) - - -@logit(logger) -def main(): - - config = cast_strdict_as_dtypedict(os.environ) - - # Instantiate the Stage object - stage = Stage(config) - - # Pull out all the configuration keys needed to run stage job - keys = ['RUN', 'MODE', 'EXP_WARM_START', 'NMEM_ENS', - 'assim_freq', 'current_cycle', 'previous_cycle', - 'ROTDIR', 'ICSDIR', 'STAGE_IC_YAML_TMPL', 'DO_JEDIATMVAR', - 'OCNRES', 'waveGRD', 'ntiles', 'DOIAU', - 'DO_JEDIOCNVAR', 'DO_STARTMEM_FROM_JEDIICE', - 'DO_WAVE', 'DO_OCN', 'DO_ICE', 'DO_NEST', 'DO_CA', 'DO_AERO_ANL', - 'USE_ATM_ENS_PERTURB_FILES', 'USE_OCN_ENS_PERTURB_FILES', 'DO_GSISOILDA', 'DO_LAND_IAU'] - - # Only pull the DOIAU_ENKF key if this is a gfs staging job - if stage.task_config['NET'] == 'gfs': - keys.append('DOIAU_ENKF') - - stage_dict = AttrDict() - for key in keys: - # Make sure OCNRES is three digits - if key == "OCNRES": - stage.task_config.OCNRES = f"{stage.task_config.OCNRES :03d}" - stage_dict[key] = stage.task_config[key] - - # Also import all COM* directory and template variables - for key in stage.task_config.keys(): - if key.startswith("COM"): - stage_dict[key] = stage.task_config[key] - if "ENSMEM" in stage.task_config: - stage_dict["ENSMEM"] = stage.task_config["ENSMEM"] - - # Stage ICs - stage.execute_stage(stage_dict) - - -if __name__ == '__main__': - main() diff --git a/sorc/build_compute.sh b/sorc/build_compute.sh index 0db25f86119..08c80c960bd 100755 --- a/sorc/build_compute.sh +++ b/sorc/build_compute.sh @@ -87,33 +87,6 @@ echo "Generating build.xml for building global-workflow programs on compute node # Catch errors manually from here out set +e -# Temporarily build the GDASApp on the head node -# Cleanup function to kill the GDASApp build on ctrl-c or non-clean exit -build_ids=() -function cleanup() { - echo "Exiting build script. Terminating subprocesses..." - for pid in "${build_ids[@]}"; do - if kill -0 "${pid}" 2>/dev/null; then # Check if process still exists - kill "${pid}" - fi - done - exit 1 -} - -trap cleanup TERM -trap cleanup INT -trap cleanup ERR - -# TODO remove this when all builds move to the head nodes and/or the GDASApp is able to build on all compute nodes again -# See GW issue 3933 -if [[ ${systems} == "all" || ${systems} =~ "gdas" ]]; then - echo "Building the GDASApp locally (on this node)" - gdas_build_log="${HOMEgfs}/sorc/logs/build_gdas.log" - "${HOMEgfs}/sorc/build_gdas.sh" -j 12 >& "${gdas_build_log}" & - build_gdas_id=$! - build_ids+=("${build_gdas_id}") -fi - "${HOMEgfs}/dev/workflow/build_compute.py" --account "${HPC_ACCOUNT}" --yaml "${yaml}" --systems "${systems}" rc=$? if [[ "${rc}" -ne 0 ]]; then @@ -167,23 +140,9 @@ while [[ "${finished}" == "false" ]]; do fi done < rocotostat.out - # Kill the GDASApp build if it is still running - cleanup fi done -# Wait for the GDASApp to finish building -if [[ -n "${build_gdas_id+0}" ]]; then - echo "Compute builds have completed successfully, but the GDASApp is still building locally. Waiting for it to complete." - wait "${build_gdas_id}" - gdas_stat=$? - if [[ ${gdas_stat} -ne 0 ]]; then - echo "FATAL ERROR The GDASApp failed to build! Check log in ${gdas_build_log}" - # Capture the error log in logs/error.logs - echo "${gdas_build_log}" >> "${err_file}" - exit 3 - fi -fi echo "All builds completed successfully!" exit 0 diff --git a/sorc/build_gdas.sh b/sorc/build_gdas.sh index 32213153423..e49cc00429c 100755 --- a/sorc/build_gdas.sh +++ b/sorc/build_gdas.sh @@ -13,11 +13,9 @@ while getopts ":j:dv" option; do v) _opts+="-v ";; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" - usage ;; *) echo "[${BASH_SOURCE[0]}]: Unrecognized option: ${option}" - usage ;; esac done diff --git a/sorc/build_gsi_enkf.sh b/sorc/build_gsi_enkf.sh index 09cf250acf2..badba6c332d 100755 --- a/sorc/build_gsi_enkf.sh +++ b/sorc/build_gsi_enkf.sh @@ -9,11 +9,9 @@ while getopts ":j:dv" option; do v) BUILD_VERBOSE="YES";; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" - usage ;; *) echo "[${BASH_SOURCE[0]}]: Unrecognized option: ${option}" - usage ;; esac done @@ -33,4 +31,3 @@ REGRESSION_TESTS=NO \ "${HOMEgfs_}/sorc/gsi_enkf.fd/ush/build.sh" exit - diff --git a/sorc/build_gsi_monitor.sh b/sorc/build_gsi_monitor.sh index d355067f127..e982f14f703 100755 --- a/sorc/build_gsi_monitor.sh +++ b/sorc/build_gsi_monitor.sh @@ -12,11 +12,9 @@ while getopts ":j:dv" option; do v) BUILD_VERBOSE="YES";; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" - usage ;; *) echo "[${BASH_SOURCE[0]}]: Unrecognized option: ${option}" - usage ;; esac done diff --git a/sorc/build_ufs_utils.sh b/sorc/build_ufs_utils.sh index 2284b151343..e6698bb5008 100755 --- a/sorc/build_ufs_utils.sh +++ b/sorc/build_ufs_utils.sh @@ -12,11 +12,9 @@ while getopts ":j:dv" option; do v) BUILD_VERBOSE="YES";; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" - usage ;; *) echo "[${BASH_SOURCE[0]}]: Unrecognized option: ${option}" - usage ;; esac done @@ -31,4 +29,3 @@ BUILD_VERBOSE=${BUILD_VERBOSE:-} \ "${HOMEgfs_}/sorc/ufs_utils.fd/build_all.sh" exit - diff --git a/sorc/build_ww3prepost.sh b/sorc/build_ww3prepost.sh index 19133b12972..5408a5c390c 100755 --- a/sorc/build_ww3prepost.sh +++ b/sorc/build_ww3prepost.sh @@ -16,11 +16,9 @@ while getopts ":j:a:dvw" option; do w) PDLIB="OFF" ;; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" - usage ;; *) echo "[${BASH_SOURCE[0]}]: Unrecognized option: ${option}" - usage ;; esac done diff --git a/sorc/gdas.cd b/sorc/gdas.cd index 3e774e7b507..740245c65a2 160000 --- a/sorc/gdas.cd +++ b/sorc/gdas.cd @@ -1 +1 @@ -Subproject commit 3e774e7b50752c5bc40e57f8719058aa8602b2d9 +Subproject commit 740245c65a2ac036ea1778bb8c1870493b2d3204 diff --git a/sorc/gsi_enkf.fd b/sorc/gsi_enkf.fd index 7da30e79df0..6f500cd5802 160000 --- a/sorc/gsi_enkf.fd +++ b/sorc/gsi_enkf.fd @@ -1 +1 @@ -Subproject commit 7da30e79df0c986712c92b30de8136d7caa00adc +Subproject commit 6f500cd580239fb173377c12f1f4628db1ec9666 diff --git a/sorc/link_workflow.sh b/sorc/link_workflow.sh index 84eb45134a4..207b23188fc 100755 --- a/sorc/link_workflow.sh +++ b/sorc/link_workflow.sh @@ -76,7 +76,7 @@ case "${machine}" in "hercules") FIX_DIR="/work2/noaa/global/role-global/fix" ;; "gaeac5") FIX_DIR="/gpfs/f5/ufs-ard/world-shared/global/glopara/data/fix" ;; "gaeac6") FIX_DIR="/gpfs/f6/drsa-precip3/world-shared/role.glopara/fix" ;; -"noaacloud") FIX_DIR="/contrib/global-workflow-shared-data/fix" ;; +"noaacloud") FIX_DIR="/lustre/fix" ;; *) echo "FATAL: Unknown target machine ${machine}, couldn't set FIX_DIR" exit 1 @@ -260,19 +260,13 @@ if [[ -d "${HOMEgfs}/sorc/gdas.cd/build" ]]; then ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ufsda" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/gen_bufr2ioda_json.py" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/gen_bufr2ioda_yaml.py" . + ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/run_bufr2ioda.py" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/sorc/da-utils/ush/gsincdiag_to_ioda" . + ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/sorc/da-utils/ush/pyiodaconv" . cd "${HOMEgfs}/ush" || exit 1 - ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/run_bufr2ioda.py" . + ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/gsi_satbias2ioda_all.sh" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/snow/bufr_snocvr_snomad.py" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/build/bin/imsfv3_scf2ioda.py" . - declare -a gdasapp_ocn_insitu_profile_platforms=("argo" "bathy" "glider" "marinemammal" "tesac" "xbtctd") - for platform in "${gdasapp_ocn_insitu_profile_platforms[@]}"; do - ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/marine/bufr2ioda_insitu_profile_${platform}.py" . - done - declare -a gdasapp_ocn_insitu_sfc_platforms=("altkob" "trkob") - for platform in "${gdasapp_ocn_insitu_sfc_platforms[@]}"; do - ${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/ush/ioda/bufr2ioda/marine/bufr2ioda_insitu_surface_${platform}.py" . - done fi #------------------------------ @@ -420,7 +414,6 @@ fi # GDASApp executables if [[ -d "${HOMEgfs}/sorc/gdas.cd/install" ]]; then cp -f "${HOMEgfs}/sorc/gdas.cd/install/bin"/gdas* ./ - cp -f "${HOMEgfs}/sorc/gdas.cd/install/bin/bufr2ioda.x" ./gdas_bufr2ioda.x cp -f "${HOMEgfs}/sorc/gdas.cd/install/bin/calcfIMS.exe" ./gdas_calcfIMS.x cp -f "${HOMEgfs}/sorc/gdas.cd/install/bin/apply_incr.exe" ./gdas_apply_incr.x fi diff --git a/sorc/ufs_model.fd b/sorc/ufs_model.fd index 2a33f2c8ee2..6f22f57403d 160000 --- a/sorc/ufs_model.fd +++ b/sorc/ufs_model.fd @@ -1 +1 @@ -Subproject commit 2a33f2c8ee265e75d5df18b652a23bf674528899 +Subproject commit 6f22f57403db693dee3b6979a4e6f58ade633e86 diff --git a/ush/atmos_ensstat.sh b/ush/atmos_ensstat.sh index 36218731627..4be0a96d56b 100755 --- a/ush/atmos_ensstat.sh +++ b/ush/atmos_ensstat.sh @@ -24,8 +24,8 @@ for ((mem_num = 0; mem_num <= "${NMEM_ENS:-0}"; mem_num++)); do done num_found=${#input_files[@]} -if (( num_found != NMEM_ENS + 1 )); then - echo "FATAL ERROR: Only ${num_found} grib files found out of $(( NMEM_ENS + 1 )) expected members." +if ((num_found != NMEM_ENS + 1)); then + echo "FATAL ERROR: Only ${num_found} grib files found out of $((NMEM_ENS + 1)) expected members." exit 10 fi @@ -47,8 +47,8 @@ cat << EOF > input.nml cfopg2="${spr_out}" $( - for (( filenum = 1; filenum <= num_found; filenum++ )); do - echo " cfipg(${filenum})=\"${input_files[$((filenum-1))]}\"," + for ((filenum = 1; filenum <= num_found; filenum++)); do + echo " cfipg(${filenum})=\"${input_files[$((filenum - 1))]}\"," echo " iskip(${filenum})=0," done ) @@ -61,7 +61,7 @@ cat input.nml "${EXECgfs}/ensstat.x" < input.nml export err=$? -if (( err != 0 )) ; then +if [[ "${err}" -ne 0 ]]; then echo "FATAL ERROR: ensstat returned error code ${err}" exit "${err}" fi @@ -78,7 +78,7 @@ for outfile in ${mean_out} ${spr_out}; do ${WGRIB2} -s "${outfile}" > "${outfile}.idx" err=$? - if (( err != 0 )); then + if [[ "${err}" -ne 0 ]]; then echo "FATAL ERROR: Failed to create inventory file, wgrib2 returned ${err}" exit "${err}" fi @@ -94,4 +94,3 @@ for outfile in ${mean_out} ${spr_out}; do fi done - diff --git a/ush/atmos_extractvars.sh b/ush/atmos_extractvars.sh index 2033fd8c849..31cd61087bd 100755 --- a/ush/atmos_extractvars.sh +++ b/ush/atmos_extractvars.sh @@ -14,101 +14,101 @@ dcnt=1 # lead day subdata=${1} if [[ ! -d "${subdata}" ]]; then - mkdir -p "${subdata}" + mkdir -p "${subdata}" fi for outtype in "f2d" "f3d"; do - if [[ "${outtype}" == "f2d" ]]; then - varlist=${varlist_2d} - ARC_RFCST_PROD_ATMOS="${ARC_RFCST_PROD_ATMOS_F2D}" - elif [[ "${outtype}" == "f3d" ]]; then - varlist=${varlist_3d} - varlist_d=${varlist_3d_d} - ARC_RFCST_PROD_ATMOS="${ARC_RFCST_PROD_ATMOS_F3D}" - fi - - outdirpre="${subdata}/${outtype}" - if [[ ! -d "${outdirpre}" ]]; then - mkdir -p "${outdirpre}" - fi - - nh=${FHMIN} - - while (( nh <= FHMAX_GFS )); do - fnh=$(printf "%3.3d" "${nh}") - if [[ "${outtype}" == "f2d" ]]; then - if (( nh < FHMAX_HF_GFS )); then - outres="0p25" - else - outres="0p50" - fi + varlist=${varlist_2d} + ARC_RFCST_PROD_ATMOS="${ARC_RFCST_PROD_ATMOS_F2D}" elif [[ "${outtype}" == "f3d" ]]; then - outres="1p00" + varlist=${varlist_3d} + varlist_d=${varlist_3d_d} + ARC_RFCST_PROD_ATMOS="${ARC_RFCST_PROD_ATMOS_F3D}" fi - if [[ "${outtype}" == "f2d" ]]; then - if (( nh < FHMAX_HF_GFS )); then - outfreq=${FHOUT_HF_GFS} - else - outfreq=${FHOUT_GFS} - fi - elif [[ "${outtype}" == "f3d" ]]; then - outfreq=${FHOUT_GFS} + outdirpre="${subdata}/${outtype}" + if [[ ! -d "${outdirpre}" ]]; then + mkdir -p "${outdirpre}" fi - com_var="COMIN_ATMOS_GRIB_${outres}" - infile1="${!com_var}/${RUN}.t${cyc}z.pres_a.${outres}.f${fnh}.grib2" - infile2="${!com_var}/${RUN}.t${cyc}z.pres_b.${outres}.f${fnh}.grib2" - outfile="${outdirpre}/${RUN}.t${cyc}z.pres_a.${outres}.f${fnh}.grib2" - rm -f "${outfile}" #remove outfile if it already exists before extraction - - for infile in "${infile1}" "${infile2}"; do - if [[ -f "${infile}" ]]; then # check if input file exists before extraction - new_infile="${outdirpre}/$(basename "${infile}")_ext" - if ! cpfs "${infile}" "${new_infile}"; then - echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." - exit 1 + nh=${FHMIN} + + while ((nh <= FHMAX_GFS)); do + fnh=$(printf "%3.3d" "${nh}") + + if [[ "${outtype}" == "f2d" ]]; then + if ((nh < FHMAX_HF_GFS)); then + outres="0p25" + else + outres="0p50" + fi + elif [[ "${outtype}" == "f3d" ]]; then + outres="1p00" fi - # shellcheck disable=SC2312 - ${WGRIB2} "${new_infile}" | grep -F -f "${varlist}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" - else - echo "WARNING: ${infile} does not exist in ${com_dir}." - fi - done - - check_atmos "${infile1}" "${infile2}" "${varlist}" "${fnh}" - copy_to_comout "${outfile}" "${ARC_RFCST_PROD_ATMOS}" - - # Compute daily average for a subset of variables - if (( nh % 6 == 0 )) && (( nh != 0 )) && [[ "${outtype}" == "f3d" ]]; then - outfile=${subdata}/vartmp_raw_vari_ldy${dcnt}.grib2 - for infile in "${infile1}" "${infile2}"; do - if [[ -f "${infile}" ]]; then # check if input file exists before extraction - new_infile="${outdirpre}/$(basename "${infile}")_ext" - if ! cpfs "${infile}" "${new_infile}"; then - echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." - exit 1 - fi - # shellcheck disable=SC2312 - ${WGRIB2} "${new_infile}" | grep -F -f "${varlist_d}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" - else - echo "WARNING: ${infile} does not exist in ${com_dir}." + + if [[ "${outtype}" == "f2d" ]]; then + if ((nh < FHMAX_HF_GFS)); then + outfreq=${FHOUT_HF_GFS} + else + outfreq=${FHOUT_GFS} + fi + elif [[ "${outtype}" == "f3d" ]]; then + outfreq=${FHOUT_GFS} fi - done - if [[ ${fcnt} -eq 4 ]]; then - daily_avg_atmos "${outfile}" "${dcnt}" "${outres}" - copy_to_comout "${davg_file}" "${ARC_RFCST_PROD_ATMOS}" - fcnt=1 - dcnt=$(( dcnt + 1 )) - else - fcnt=$(( fcnt + 1 )) - fi # If at final lead hour of a given day - fi # if lead hour is divisible by 6 and outtype is f3d - - nh=$(( nh + outfreq )) - done # nh + + com_var="COMIN_ATMOS_GRIB_${outres}" + infile1="${!com_var}/${RUN}.t${cyc}z.pres_a.${outres}.f${fnh}.grib2" + infile2="${!com_var}/${RUN}.t${cyc}z.pres_b.${outres}.f${fnh}.grib2" + outfile="${outdirpre}/${RUN}.t${cyc}z.pres_a.${outres}.f${fnh}.grib2" + rm -f "${outfile}" #remove outfile if it already exists before extraction + + for infile in "${infile1}" "${infile2}"; do + if [[ -f "${infile}" ]]; then # check if input file exists before extraction + new_infile="${outdirpre}/$(basename "${infile}")_ext" + if ! cpfs "${infile}" "${new_infile}"; then + echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." + exit 1 + fi + # shellcheck disable=SC2312 + ${WGRIB2} "${new_infile}" | grep -F -f "${varlist}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" + else + echo "WARNING: ${infile} does not exist in ${com_dir}." + fi + done + + check_atmos "${infile1}" "${infile2}" "${varlist}" "${fnh}" + copy_to_comout "${outfile}" "${ARC_RFCST_PROD_ATMOS}" + + # Compute daily average for a subset of variables + if ((nh % 6 == 0)) && ((nh != 0)) && [[ "${outtype}" == "f3d" ]]; then + outfile=${subdata}/vartmp_raw_vari_ldy${dcnt}.grib2 + for infile in "${infile1}" "${infile2}"; do + if [[ -f "${infile}" ]]; then # check if input file exists before extraction + new_infile="${outdirpre}/$(basename "${infile}")_ext" + if ! cpfs "${infile}" "${new_infile}"; then + echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." + exit 1 + fi + # shellcheck disable=SC2312 + ${WGRIB2} "${new_infile}" | grep -F -f "${varlist_d}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" + else + echo "WARNING: ${infile} does not exist in ${com_dir}." + fi + done + if [[ ${fcnt} -eq 4 ]]; then + daily_avg_atmos "${outfile}" "${dcnt}" "${outres}" + copy_to_comout "${davg_file}" "${ARC_RFCST_PROD_ATMOS}" + fcnt=1 + dcnt=$((dcnt + 1)) + else + fcnt=$((fcnt + 1)) + fi # If at final lead hour of a given day + fi # if lead hour is divisible by 6 and outtype is f3d + + nh=$((nh + outfreq)) + done # nh done # f2d,f3d diff --git a/ush/bash_utils.sh b/ush/bash_utils.sh index fc69a79131a..48007623351 100755 --- a/ush/bash_utils.sh +++ b/ush/bash_utils.sh @@ -42,14 +42,14 @@ function declare_from_tmpl() { while getopts "rx" option; do opts="${opts}${option}" done - shift $((OPTIND-1)) + shift $((OPTIND - 1)) for input in "$@"; do IFS=':' read -ra args <<< "${input}" local com_var="${args[0]}" local template local value - if (( ${#args[@]} > 1 )); then + if ((${#args[@]} > 1)); then template="${args[1]}" else template="${com_var}_TMPL" @@ -99,7 +99,7 @@ function wait_for_file() { local sleep_interval=${2:-60} local max_tries=${3:-100} - for (( iter=0; iter [use2mobs]" - echo " : conv, oz, or sat" - echo " : date string to match" - echo " : where to write the new GSI info files into" - echo " [use2mobs]: (optional, only for conv, whether to use 2m observations) YES or NO" - exit 1 + echo "Usage: ${0} [use2mobs]" + echo " : conv, oz, or sat" + echo " : date string to match" + echo " : where to write the new GSI info files into" + echo " [use2mobs]: (optional, only for conv, whether to use 2m observations) YES or NO" + exit 1 fi # Function to get the most recent data available for the target obs. # If an empty string is returned, this represents an error. # Assumes the variable date_in is set. get_usedate() { - usedate="" - # Loop over files matching date pattern. - for datex in [1-2][0-9][0-9][0-9]*; do - # Skip for loop if there are no matches. - if [[ ! -e "${datex}" ]]; then - continue - fi - - if [[ ${date_in} -ge ${datex} ]]; then - usedate=${datex} - fi - done - - echo "${usedate}" + usedate="" + # Loop over files matching date pattern. + for datex in [1-2][0-9][0-9][0-9]*; do + # Skip for loop if there are no matches. + if [[ ! -e "${datex}" ]]; then + continue + fi + + if [[ ${date_in} -ge ${datex} ]]; then + usedate=${datex} + fi + done + + echo "${usedate}" } # Get the starting directory @@ -52,88 +52,87 @@ cd "${build_dir}" || exit 1 # Get the list of satellites available if [[ "${type_in}" != "conv" ]]; then - if [[ ! -f satellites ]]; then - echo "FATAL ERROR: Satellite list file 'satellites' not found in ${build_dir}!" - exit 1 - fi + if [[ ! -f satellites ]]; then + echo "FATAL ERROR: Satellite list file 'satellites' not found in ${build_dir}!" + exit 1 + fi - satellite_list=$(grep -Ev '^ *#|readme' satellites) + satellite_list=$(grep -Ev '^ *#|readme' satellites) - if [[ -z "${satellite_list}" ]]; then - echo "FATAL ERROR: No satellites found in the satellite file list!" - exit 1 - fi + if [[ -z "${satellite_list}" ]]; then + echo "FATAL ERROR: No satellites found in the satellite file list!" + exit 1 + fi fi # Filename to write the info to info_file="${write_dir}/${type_in}info" if [[ -f "${info_file}" ]]; then - rm -f "${info_file}" + rm -f "${info_file}" fi # Function to cycle through the list of satellites (oz or sat) and build the info file. build_info_file() { - while IFS= read -r sat - do - usedate="" - # Check that the satellite directory exists - if [[ ! -d "${sat}" ]]; then - echo "FATAL ERROR: Directory ${sat} does not exist!" - exit 1 - fi - - cd "${sat}" || exit 1 - - usedate=$(get_usedate) - - cd "${build_dir}" || exit 1 - - if [[ ${usedate} != "" ]]; then - cat "${sat}/${usedate}" >> "${info_file}" - else - echo "FATAL ERROR: No valid satellite info was found for satellite target '${sat}'!" - exit 1 - fi - done <<< "${satellite_list}" + while IFS= read -r sat; do + usedate="" + # Check that the satellite directory exists + if [[ ! -d "${sat}" ]]; then + echo "FATAL ERROR: Directory ${sat} does not exist!" + exit 1 + fi + + cd "${sat}" || exit 1 + + usedate=$(get_usedate) + + cd "${build_dir}" || exit 1 + + if [[ ${usedate} != "" ]]; then + cat "${sat}/${usedate}" >> "${info_file}" + else + echo "FATAL ERROR: No valid satellite info was found for satellite target '${sat}'!" + exit 1 + fi + done <<< "${satellite_list}" } case "${type_in}" in - conv) - usedate=$(get_usedate) - if [[ ${usedate} != "" ]]; then - if [[ ${use2mobs} == "YES" ]]; then - # Turn on 2m t,q obs over land - sed -e "s/t 181 0 -1/t 181 0 1/g" \ - -e "s/t 187 0 -1/t 187 0 1/g" \ - -e "s/q 181 0 -1/q 181 0 1/g" \ - -e "s/q 187 0 -1/q 187 0 1/g" "${usedate}" >> "${info_file}" - else - cat "${usedate}" >> "${info_file}" - fi - else - echo "FATAL ERROR: No valid conventional info was found!" - exit 1 - fi - ;; - oz) - # Header lines - { - echo '! For mls data, pressure and obs errors are pulled from bufr, so not listed here' - echo '! sens/instr/sat lev use pressure gross obs b_oz pg_oz' - echo '! error error variational qc' - } >> "${info_file}" - build_info_file - ;; - - sat) - # Header line - echo '!sensor/instr/sat chan iuse error error_cld ermax var_b var_pg icld_det icloud iaerosol' >> "${info_file}" - build_info_file - ;; - *) - echo "FATAL ERROR: Unknown info file type: '${type_in}'. Must be one of: conv, oz, sat" - exit 2 - ;; + conv) + usedate=$(get_usedate) + if [[ ${usedate} != "" ]]; then + if [[ ${use2mobs} == "YES" ]]; then + # Turn on 2m t,q obs over land + sed -e "s/t 181 0 -1/t 181 0 1/g" \ + -e "s/t 187 0 -1/t 187 0 1/g" \ + -e "s/q 181 0 -1/q 181 0 1/g" \ + -e "s/q 187 0 -1/q 187 0 1/g" "${usedate}" >> "${info_file}" + else + cat "${usedate}" >> "${info_file}" + fi + else + echo "FATAL ERROR: No valid conventional info was found!" + exit 1 + fi + ;; + oz) + # Header lines + { + echo '! For mls data, pressure and obs errors are pulled from bufr, so not listed here' + echo '! sens/instr/sat lev use pressure gross obs b_oz pg_oz' + echo '! error error variational qc' + } >> "${info_file}" + build_info_file + ;; + + sat) + # Header line + echo '!sensor/instr/sat chan iuse error error_cld ermax var_b var_pg icld_det icloud iaerosol' >> "${info_file}" + build_info_file + ;; + *) + echo "FATAL ERROR: Unknown info file type: '${type_in}'. Must be one of: conv, oz, sat" + exit 2 + ;; esac # Return to starting directory diff --git a/ush/detect_machine.sh b/ush/detect_machine.sh index ee6c2c2c79b..070904eb683 100755 --- a/ush/detect_machine.sh +++ b/ush/detect_machine.sh @@ -16,49 +16,49 @@ fi # First detect w/ hostname case $(hostname -f) in - adecflow0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn - alogin0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn - clogin0[1-9].cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus01-9 - clogin10.cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus10 - dlogin0[1-9].dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood01-9 - dlogin10.dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood10 + adecflow0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn + alogin0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn + clogin0[1-9].cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus01-9 + clogin10.cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus10 + dlogin0[1-9].dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood01-9 + dlogin10.dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood10 - gaea5[1-8]) MACHINE_ID=gaeac5 ;; ### gaea51-58 - gaea5[1-8].ncrc.gov) MACHINE_ID=gaeac5 ;; ### gaea51-58 + gaea5[1-8]) MACHINE_ID=gaeac5 ;; ### gaea51-58 + gaea5[1-8].ncrc.gov) MACHINE_ID=gaeac5 ;; ### gaea51-58 - gaea6[1-8]) MACHINE_ID=gaeac6 ;; ### gaea61-68 - gaea6[1-8].ncrc.gov) MACHINE_ID=gaeac6 ;; ### gaea61-68 + gaea6[1-8]) MACHINE_ID=gaeac6 ;; ### gaea61-68 + gaea6[1-8].ncrc.gov) MACHINE_ID=gaeac6 ;; ### gaea61-68 - hfe0[1-9]) MACHINE_ID=hera ;; ### hera01-09 - hfe1[0-2]) MACHINE_ID=hera ;; ### hera10-12 - hecflow01) MACHINE_ID=hera ;; ### heraecflow01 + hfe0[1-9]) MACHINE_ID=hera ;; ### hera01-09 + hfe1[0-2]) MACHINE_ID=hera ;; ### hera10-12 + hecflow01) MACHINE_ID=hera ;; ### heraecflow01 - ufe0[1-9]) MACHINE_ID=ursa ;; ### ursa01-09 - ufe1[0-6]) MACHINE_ID=ursa ;; ### ursa10-16 - uecflow01) MACHINE_ID=ursa ;; ### ursaecflow01 + ufe0[1-9]) MACHINE_ID=ursa ;; ### ursa01-09 + ufe1[0-6]) MACHINE_ID=ursa ;; ### ursa10-16 + uecflow01) MACHINE_ID=ursa ;; ### ursaecflow01 - s4-submit.ssec.wisc.edu) MACHINE_ID=s4 ;; ### s4 + s4-submit.ssec.wisc.edu) MACHINE_ID=s4 ;; ### s4 - fe[1-8]) MACHINE_ID=jet ;; ### jet01-8 - tfe[12]) MACHINE_ID=jet ;; ### tjet1-2 + fe[1-8]) MACHINE_ID=jet ;; ### jet01-8 + tfe[12]) MACHINE_ID=jet ;; ### tjet1-2 - Orion-login-[1-4].HPC.MsState.Edu) MACHINE_ID=orion ;; ### orion1-4 + Orion-login-[1-4].HPC.MsState.Edu) MACHINE_ID=orion ;; ### orion1-4 - [Hh]ercules-login-[1-4].[Hh][Pp][Cc].[Mm]s[Ss]tate.[Ee]du) MACHINE_ID=hercules ;; ### hercules1-4 + [Hh]ercules-login-[1-4].[Hh][Pp][Cc].[Mm]s[Ss]tate.[Ee]du) MACHINE_ID=hercules ;; ### hercules1-4 - login[1-4].stampede2.tacc.utexas.edu) MACHINE_ID=stampede ;; ### stampede1-4 + login[1-4].stampede2.tacc.utexas.edu) MACHINE_ID=stampede ;; ### stampede1-4 - login0[1-2].expanse.sdsc.edu) MACHINE_ID=expanse ;; ### expanse1-2 + login0[1-2].expanse.sdsc.edu) MACHINE_ID=expanse ;; ### expanse1-2 - discover3[1-5].prv.cube) MACHINE_ID=discover ;; ### discover31-35 - *) MACHINE_ID=UNKNOWN ;; # Unknown platform + discover3[1-5].prv.cube) MACHINE_ID=discover ;; ### discover31-35 + *) MACHINE_ID=UNKNOWN ;; # Unknown platform esac if [[ ${MACHINE_ID} == "UNKNOWN" ]]; then - case ${PW_CSP:-} in - "aws" | "google" | "azure") MACHINE_ID=noaacloud ;; - *) PW_CSP="UNKNOWN" - esac + case ${PW_CSP:-} in + "aws" | "google" | "azure") MACHINE_ID=noaacloud ;; + *) PW_CSP="UNKNOWN" ;; + esac fi # Overwrite auto-detect with MACHINE if set @@ -66,50 +66,50 @@ MACHINE_ID=${MACHINE:-${MACHINE_ID}} # If MACHINE_ID is no longer UNKNNOWN, return it if [[ "${MACHINE_ID}" != "UNKNOWN" ]]; then - # TODO: make this read-only when UPP#1308 is addressed. - declare -x MACHINE_ID # Should be -rx, but the UPP system needs Gaea C6 to be ID'd as "gaea" - return + # TODO: make this read-only when UPP#1308 is addressed. + declare -x MACHINE_ID # Should be -rx, but the UPP system needs Gaea C6 to be ID'd as "gaea" + return fi # Try searching based on paths since hostname may not match on compute nodes if [[ -d /lfs/h3 ]]; then - # We are on NOAA Cactus or Dogwood - MACHINE_ID=wcoss2 + # We are on NOAA Cactus or Dogwood + MACHINE_ID=wcoss2 elif [[ -d /lfs/h1 && ! -d /lfs/h3 ]]; then - # We are on NOAA TDS Acorn - MACHINE_ID=acorn + # We are on NOAA TDS Acorn + MACHINE_ID=acorn elif [[ -d /mnt/lfs5 ]]; then - # We are on NOAA Jet - MACHINE_ID=jet + # We are on NOAA Jet + MACHINE_ID=jet elif [[ -d /scratch3 ]]; then - # We are on NOAA Hera or Ursa - mount=$(findmnt -n -o SOURCE /apps) || true # /home doesn't exist on the GitHub runners - if [[ ${mount} =~ "ursa" ]]; then - MACHINE_ID=ursa - elif [[ ${mount} =~ "hera" ]]; then - MACHINE_ID=hera - else # Assume we are on the GitHub runners, which mock Hera - MACHINE_ID=hera - fi + # We are on NOAA Hera or Ursa + mount=$(findmnt -n -o SOURCE /apps) || true # /home doesn't exist on the GitHub runners + if [[ ${mount} =~ "ursa" ]]; then + MACHINE_ID=ursa + elif [[ ${mount} =~ "hera" ]]; then + MACHINE_ID=hera + else # Assume we are on the GitHub runners, which mock Hera + MACHINE_ID=hera + fi elif [[ -d /work ]]; then - # We are on MSU Orion or Hercules - mount=$(findmnt -n -o SOURCE /home) - if [[ -n "${mount+0}" && ${mount} =~ "hercules" ]]; then - MACHINE_ID=hercules - else - MACHINE_ID=orion - fi + # We are on MSU Orion or Hercules + mount=$(findmnt -n -o SOURCE /home) + if [[ -n "${mount+0}" && ${mount} =~ "hercules" ]]; then + MACHINE_ID=hercules + else + MACHINE_ID=orion + fi elif [[ -d /gpfs/f5 ]]; then - # We are on GAEAC5. - MACHINE_ID=gaeac5 + # We are on GAEAC5. + MACHINE_ID=gaeac5 elif [[ -d /gpfs/f6 ]]; then - # We are on GAEAC6. - MACHINE_ID=gaeac6 + # We are on GAEAC6. + MACHINE_ID=gaeac6 elif [[ -d /data/prod ]]; then - # We are on SSEC's S4 - MACHINE_ID=s4 + # We are on SSEC's S4 + MACHINE_ID=s4 else - echo WARNING: UNKNOWN PLATFORM 1>&2 + echo WARNING: UNKNOWN PLATFORM 1>&2 fi # TODO: Make this read-only when UPP#1308 is addressed. -declare -x MACHINE_ID # Should be -rx, but the UPP system needs Gaea C6 to be ID'd as "gaea" +declare -x MACHINE_ID # Should be -rx, but the UPP system needs Gaea C6 to be ID'd as "gaea" diff --git a/ush/extractvars_tools.sh b/ush/extractvars_tools.sh index f351441fa53..fe7a4d34a43 100644 --- a/ush/extractvars_tools.sh +++ b/ush/extractvars_tools.sh @@ -1,59 +1,59 @@ #! /usr/bin/env bash check_atmos() { - # Function to check if there are any missing parm variables in any of the input product grib2 files - # A warning will be displayed if there is a parm variable that cannot be found in any of the given input product grib2 files - infile1p=$1 - infile2p=$2 - varlistl=$3 - fnhl=$4 - requestedvar_in_allgrb2file="${subdata}/parmvarsingribfil.txt" - rm -f "${requestedvar_in_allgrb2file}" - touch "${requestedvar_in_allgrb2file}" - for infilep in "${infile1p}" "${infile2p}"; do - # It is permitted for an empty string to return if no parmlist vars are in infilep, therefore do not return exit 1 error - # shellcheck disable=SC2312 - ${WGRIB2} "${infilep}" | grep -F -f "${varlist}" >> "${requestedvar_in_allgrb2file}" || true - done - mapfile -t requestedvar_in_allgrb2file_arr < "${requestedvar_in_allgrb2file}" - while read -r vari; do - # shellcheck disable=SC2076 - if [[ ! ${requestedvar_in_allgrb2file_arr[*]} =~ "${vari}" ]] ;then - echo "WARNING: PARM VARIABLE (${vari}) is not available in pgrb and pgrb2b for f${fnhl}." - fi - done <"${varlistl}" + # Function to check if there are any missing parm variables in any of the input product grib2 files + # A warning will be displayed if there is a parm variable that cannot be found in any of the given input product grib2 files + infile1p=$1 + infile2p=$2 + varlistl=$3 + fnhl=$4 + requestedvar_in_allgrb2file="${subdata}/parmvarsingribfil.txt" + rm -f "${requestedvar_in_allgrb2file}" + touch "${requestedvar_in_allgrb2file}" + for infilep in "${infile1p}" "${infile2p}"; do + # It is permitted for an empty string to return if no parmlist vars are in infilep, therefore do not return exit 1 error + # shellcheck disable=SC2312 + ${WGRIB2} "${infilep}" | grep -F -f "${varlist}" >> "${requestedvar_in_allgrb2file}" || true + done + mapfile -t requestedvar_in_allgrb2file_arr < "${requestedvar_in_allgrb2file}" + while read -r vari; do + # shellcheck disable=SC2076 + if [[ ! ${requestedvar_in_allgrb2file_arr[*]} =~ "${vari}" ]]; then + echo "WARNING: PARM VARIABLE (${vari}) is not available in pgrb and pgrb2b for f${fnhl}." + fi + done < "${varlistl}" } daily_avg_atmos() { - # Function to calculate the 24-hr average of a grib2 file with atmospheric fields - # The input grib2 file must contain all the time records to be averaged (e.g. 6hr, 12hr, 18hr and 24hr record in one grib2 file) - outfile_p=$1 - dcnt_p=$2 - outres_p=$3 - fnd=$(printf "%2.2d" "${dcnt_p}") - davg_file=${outdirpre}/${RUN}.t${cyc}z.pgrb2.${outres_p}.24hr_avg.ldy${fnd} - vcnt=1 #count variables in varlist_d - while read -r vari; do - davgtmp=${subdata}/atmos_tmp.ldy${fnd}.${vcnt} - # shellcheck disable=SC2312 - ${WGRIB2} "${outfile_p}" | grep "${vari}" | ${WGRIB2} -i "${outfile_p}" -fcst_ave 6hr "${davgtmp}" - # shellcheck disable=SC2312 - ${WGRIB2} "${davgtmp}" | ${WGRIB2} -i "${davgtmp}" -append -grib "${davg_file}" - rm -f "${davgtmp}" - vcnt=$(( vcnt + 1 )) - done <"${varlist_d}" # variable + # Function to calculate the 24-hr average of a grib2 file with atmospheric fields + # The input grib2 file must contain all the time records to be averaged (e.g. 6hr, 12hr, 18hr and 24hr record in one grib2 file) + outfile_p=$1 + dcnt_p=$2 + outres_p=$3 + fnd=$(printf "%2.2d" "${dcnt_p}") + davg_file=${outdirpre}/${RUN}.t${cyc}z.pgrb2.${outres_p}.24hr_avg.ldy${fnd} + vcnt=1 #count variables in varlist_d + while read -r vari; do + davgtmp=${subdata}/atmos_tmp.ldy${fnd}.${vcnt} + # shellcheck disable=SC2312 + ${WGRIB2} "${outfile_p}" | grep "${vari}" | ${WGRIB2} -i "${outfile_p}" -fcst_ave 6hr "${davgtmp}" + # shellcheck disable=SC2312 + ${WGRIB2} "${davgtmp}" | ${WGRIB2} -i "${davgtmp}" -append -grib "${davg_file}" + rm -f "${davgtmp}" + vcnt=$((vcnt + 1)) + done < "${varlist_d}" # variable } copy_to_comout() { - # Function to copy the output file with the extracted product variables to a user-defined destination directory - rundir_outfile=$1 # output data file generated in RUNDIR - comout_dir=$2 # destination directory to which to copy the data file - if [[ -f "${rundir_outfile}" ]]; then - cpfs "${rundir_outfile}" "${comout_dir}" - else - export err=1 - err_exit "Output file (${rundir_outfile}) does not exist." - fi + # Function to copy the output file with the extracted product variables to a user-defined destination directory + rundir_outfile=$1 # output data file generated in RUNDIR + comout_dir=$2 # destination directory to which to copy the data file + if [[ -f "${rundir_outfile}" ]]; then + cpfs "${rundir_outfile}" "${comout_dir}" + else + export err=1 + err_exit "Output file (${rundir_outfile}) does not exist." + fi } declare -xf check_atmos diff --git a/ush/forecast_det.sh b/ush/forecast_det.sh index cb7a3eac601..602e7d473fb 100755 --- a/ush/forecast_det.sh +++ b/ush/forecast_det.sh @@ -2,149 +2,149 @@ # Disable variable not used warnings # shellcheck disable=SC2034 -UFS_det(){ - echo "SUB ${FUNCNAME[0]}: Run type determination for UFS" - - # Determine if the current cycle is a warm start (based on the availability of restarts) - if [[ -f "${COMIN_ATMOS_RESTART_PREV}/${model_start_date_current_cycle:0:8}.${model_start_date_current_cycle:8:2}0000.coupler.res" ]]; then - warm_start=".true." - fi - - # If restarts were not available, this is likely a cold start - if [[ "${warm_start}" == ".false." ]]; then - - # Since restarts are not available from the previous cycle, this is likely a cold start - # Ensure cold start ICs are present when warm start is not set - # TODO: add checks for other cold start ICs as well - if [[ ! -f "${COMIN_ATMOS_INPUT}/gfs_ctrl.nc" ]]; then - echo "FATAL ERROR: Cold start ICs are missing from '${COMIN_ATMOS_INPUT}'" - exit 1 - fi +UFS_det() { + echo "SUB ${FUNCNAME[0]}: Run type determination for UFS" - # Since warm start is false, we cannot do IAU - DOIAU="NO" - IAU_OFFSET=0 - model_start_date_current_cycle=${current_cycle} - - DO_LAND_IAU=".false." - - # It is still possible that a restart is available from a previous forecast attempt - # So we have to continue checking for restarts - fi - - # Lets assume this is was not run before and hence this is not a RERUN - RERUN="NO" - - # RERUN is only available for RUN=gfs|gefs. It is not available for RUN=gdas|enkfgdas|enkfgfs - if [[ "${RUN}" =~ "gdas" ]] || [[ "${RUN}" == "enkfgfs" ]]; then - echo "RERUN is not available for RUN='${RUN}'" - return 0 - fi - - # However, if this was run before, a DATArestart/FV3_RESTART must exist with data in it. - local file_array nrestarts - # shellcheck disable=SC2312 - mapfile -t file_array < <(find "${DATArestart}/FV3_RESTART" -name "????????.??0000.coupler.res" | sort) - nrestarts=${#file_array[@]} - if [[ ${nrestarts} -eq 0 ]]; then - echo "No restarts found in '${DATArestart}/FV3_RESTART', RERUN='${RERUN}'" - return 0 - else - echo "Found ${nrestarts} restarts in '${DATArestart}/FV3_RESTART' to check for RERUN" - ls -1 "${DATArestart}/FV3_RESTART/"????????.??0000.coupler.res - fi - - # Look in reverse order of file_array to determine available restart times - local ii filepath filename - local rdate seconds - local fv3_rst_ok cmeps_rst_ok mom6_rst_ok cice6_rst_ok ww3_rst_ok - local hdate hdatep1 fhout_ocn_by_2 - for (( ii=nrestarts-1; ii>=0; ii-- )); do - - filepath="${file_array[ii]}" - filename=$(basename "${filepath}") # Strip path from YYYYMMDD.HH0000.coupler.res - rdate="${filename:0:8}${filename:9:2}" # match YYYYMMDD and HH of YYYYMMDD.HH0000.coupler.res - - # Assume all is well; all restarts are available - fv3_rst_ok="YES" - cmeps_rst_ok="YES" - mom6_rst_ok="YES" - cice6_rst_ok="YES" - ww3_rst_ok="YES" - - # Check for FV3 restart availability - if [[ ! -f "${DATArestart}/FV3_RESTART/${rdate:0:8}.${rdate:8:2}0000.coupler.res" ]]; then - # TODO: add checks for other FV3 restarts as well - fv3_rst_ok="NO" + # Determine if the current cycle is a warm start (based on the availability of restarts) + if [[ -f "${COMIN_ATMOS_RESTART_PREV}/${model_start_date_current_cycle:0:8}.${model_start_date_current_cycle:8:2}0000.coupler.res" ]]; then + warm_start=".true." fi - # Check for CMEPS and MOM6 restart availability - if [[ "${cplflx}" == ".true." ]]; then - seconds=$(to_seconds "${rdate:8:2}0000") - if [[ ! -f "${DATArestart}/CMEPS_RESTART/ufs.cpld.cpl.r.${rdate:0:4}-${rdate:4:2}-${rdate:6:2}-${seconds}.nc" ]]; then - cmeps_rst_ok="NO" - fi - # TODO: add checks for other MOM6 restarts as well - if [[ ! -f "${DATArestart}/MOM6_RESTART/${rdate:0:8}.${rdate:8:2}0000.MOM.res.nc" ]]; then - mom6_rst_ok="NO" - else - # Also check for MOM6 history file availability - # TODO: SFS runs with 24-hr averaging of ocean output, which causes issues with restart checks, - # TODO: so we will skip them for now, and revisit this logic later - if [[ ${FHOUT_OCN} -le 6 ]]; then - fhout_ocn_by_2=$((FHOUT_OCN / 2)) - hdate=$(date -u -d "${rdate:0:8} ${rdate:8:2} + ${fhout_ocn_by_2} hours" +"%Y%m%d%H") - if [[ ! -f "${DATAoutput}/MOM6_OUTPUT/ocn_${hdate:0:4}_${hdate:4:2}_${hdate:6:2}_${hdate:8:2}.nc" ]]; then - mom6_rst_ok="NO" - else - # Also check for the next MOM6 history file (hdate + FHOUT_OCN hours) - hdatep1=$(date -u -d "${hdate:0:8} ${hdate:8:2} + ${FHOUT_OCN} hours" +"%Y%m%d%H") - if [[ ! -f "${DATAoutput}/MOM6_OUTPUT/ocn_${hdatep1:0:4}_${hdatep1:4:2}_${hdatep1:6:2}_${hdatep1:8:2}.nc" ]]; then - mom6_rst_ok="NO" - fi - fi + # If restarts were not available, this is likely a cold start + if [[ "${warm_start}" == ".false." ]]; then + + # Since restarts are not available from the previous cycle, this is likely a cold start + # Ensure cold start ICs are present when warm start is not set + # TODO: add checks for other cold start ICs as well + if [[ ! -f "${COMIN_ATMOS_INPUT}/gfs_ctrl.nc" ]]; then + echo "FATAL ERROR: Cold start ICs are missing from '${COMIN_ATMOS_INPUT}'" + exit 1 fi - fi - MOM6_RESTART_SETTING='r' - MOM6_INIT_FROM_Z=True - MOM6_WARMSTART_FILE="none" - MOM6_INIT_UV="zero" - ODA_INCUPD="False" - fi - # Check for CICE6 restart availability - if [[ "${cplice}" == ".true." ]]; then - if [[ ! -f "${DATArestart}/CICE_RESTART/cice_model.res.${rdate:0:4}-${rdate:4:2}-${rdate:6:2}-${seconds}.nc" ]]; then - cice6_rst_ok="NO" - fi + # Since warm start is false, we cannot do IAU + DOIAU="NO" + IAU_OFFSET=0 + model_start_date_current_cycle=${current_cycle} + + DO_LAND_IAU=".false." + + # It is still possible that a restart is available from a previous forecast attempt + # So we have to continue checking for restarts fi - # Check for WW3 restart availability - if [[ "${cplwav}" == ".true." ]]; then - if [[ ! -f "${DATArestart}/WW3_RESTART/${rdate:0:8}.${rdate:8:2}0000.restart.ww3.nc" ]]; then - ww3_rst_ok="NO" - fi + # Lets assume this is was not run before and hence this is not a RERUN + RERUN="NO" + + # RERUN is only available for RUN=gfs|gefs. It is not available for RUN=gdas|enkfgdas|enkfgfs + if [[ "${RUN}" =~ "gdas" ]] || [[ "${RUN}" == "enkfgfs" ]]; then + echo "RERUN is not available for RUN='${RUN}'" + return 0 fi - # Collective check - if [[ "${fv3_rst_ok}" == "YES" ]] \ - && [[ "${cmeps_rst_ok}" == "YES" ]] \ - && [[ "${mom6_rst_ok}" == "YES" ]] \ - && [[ "${cice6_rst_ok}" == "YES" ]] \ - && [[ "${ww3_rst_ok}" == "YES" ]]; then - RERUN="YES" - RERUN_DATE="${rdate}" - - # Check if RERUN_DATE is at/after model end time; if so, this will cause the model to crash - if [[ ${RERUN_DATE} -ge ${forecast_end_cycle} ]]; then - echo "FATAL ERROR Warm start detected, but restart date (${RERUN_DATE}) is at/after model end date (${forecast_end_cycle})" - exit 1 - fi - - warm_start=".true." - echo "All restarts found for '${RERUN_DATE}', RERUN='${RERUN}', warm_start='${warm_start}'" - break + # However, if this was run before, a DATArestart/FV3_RESTART must exist with data in it. + local file_array nrestarts + # shellcheck disable=SC2312 + mapfile -t file_array < <(find "${DATArestart}/FV3_RESTART" -name "????????.??0000.coupler.res" | sort) + nrestarts=${#file_array[@]} + if [[ ${nrestarts} -eq 0 ]]; then + echo "No restarts found in '${DATArestart}/FV3_RESTART', RERUN='${RERUN}'" + return 0 + else + echo "Found ${nrestarts} restarts in '${DATArestart}/FV3_RESTART' to check for RERUN" + ls -1 "${DATArestart}/FV3_RESTART/"????????.??0000.coupler.res fi - done # loop over nrestarts + # Look in reverse order of file_array to determine available restart times + local ii filepath filename + local rdate seconds + local fv3_rst_ok cmeps_rst_ok mom6_rst_ok cice6_rst_ok ww3_rst_ok + local hdate hdatep1 fhout_ocn_by_2 + for ((ii = nrestarts - 1; ii >= 0; ii--)); do + + filepath="${file_array[ii]}" + filename=$(basename "${filepath}") # Strip path from YYYYMMDD.HH0000.coupler.res + rdate="${filename:0:8}${filename:9:2}" # match YYYYMMDD and HH of YYYYMMDD.HH0000.coupler.res + + # Assume all is well; all restarts are available + fv3_rst_ok="YES" + cmeps_rst_ok="YES" + mom6_rst_ok="YES" + cice6_rst_ok="YES" + ww3_rst_ok="YES" + + # Check for FV3 restart availability + if [[ ! -f "${DATArestart}/FV3_RESTART/${rdate:0:8}.${rdate:8:2}0000.coupler.res" ]]; then + # TODO: add checks for other FV3 restarts as well + fv3_rst_ok="NO" + fi + + # Check for CMEPS and MOM6 restart availability + if [[ "${cplflx}" == ".true." ]]; then + seconds=$(to_seconds "${rdate:8:2}0000") + if [[ ! -f "${DATArestart}/CMEPS_RESTART/ufs.cpld.cpl.r.${rdate:0:4}-${rdate:4:2}-${rdate:6:2}-${seconds}.nc" ]]; then + cmeps_rst_ok="NO" + fi + # TODO: add checks for other MOM6 restarts as well + if [[ ! -f "${DATArestart}/MOM6_RESTART/${rdate:0:8}.${rdate:8:2}0000.MOM.res.nc" ]]; then + mom6_rst_ok="NO" + else + # Also check for MOM6 history file availability + # TODO: SFS runs with 24-hr averaging of ocean output, which causes issues with restart checks, + # TODO: so we will skip them for now, and revisit this logic later + if [[ "${FHOUT_OCN}" -le 6 ]]; then + fhout_ocn_by_2=$((FHOUT_OCN / 2)) + hdate=$(date -u -d "${rdate:0:8} ${rdate:8:2} + ${fhout_ocn_by_2} hours" +"%Y%m%d%H") + if [[ ! -f "${DATAoutput}/MOM6_OUTPUT/ocn_${hdate:0:4}_${hdate:4:2}_${hdate:6:2}_${hdate:8:2}.nc" ]]; then + mom6_rst_ok="NO" + else + # Also check for the next MOM6 history file (hdate + FHOUT_OCN hours) + hdatep1=$(date -u -d "${hdate:0:8} ${hdate:8:2} + ${FHOUT_OCN} hours" +"%Y%m%d%H") + if [[ ! -f "${DATAoutput}/MOM6_OUTPUT/ocn_${hdatep1:0:4}_${hdatep1:4:2}_${hdatep1:6:2}_${hdatep1:8:2}.nc" ]]; then + mom6_rst_ok="NO" + fi + fi + fi + fi + MOM6_RESTART_SETTING='r' + MOM6_INIT_FROM_Z=True + MOM6_WARMSTART_FILE="none" + MOM6_INIT_UV="zero" + ODA_INCUPD="False" + fi + + # Check for CICE6 restart availability + if [[ "${cplice}" == ".true." ]]; then + if [[ ! -f "${DATArestart}/CICE_RESTART/cice_model.res.${rdate:0:4}-${rdate:4:2}-${rdate:6:2}-${seconds}.nc" ]]; then + cice6_rst_ok="NO" + fi + fi + + # Check for WW3 restart availability + if [[ "${cplwav}" == ".true." ]]; then + if [[ ! -f "${DATArestart}/WW3_RESTART/${rdate:0:8}.${rdate:8:2}0000.restart.ww3.nc" ]]; then + ww3_rst_ok="NO" + fi + fi + + # Collective check + if [[ "${fv3_rst_ok}" == "YES" ]] && + [[ "${cmeps_rst_ok}" == "YES" ]] && + [[ "${mom6_rst_ok}" == "YES" ]] && + [[ "${cice6_rst_ok}" == "YES" ]] && + [[ "${ww3_rst_ok}" == "YES" ]]; then + RERUN="YES" + RERUN_DATE="${rdate}" + + # Check if RERUN_DATE is at/after model end time; if so, this will cause the model to crash + if [[ "${RERUN_DATE}" -ge "${forecast_end_cycle}" ]]; then + echo "FATAL ERROR Warm start detected, but restart date (${RERUN_DATE}) is at/after model end date (${forecast_end_cycle})" + exit 1 + fi + + warm_start=".true." + echo "All restarts found for '${RERUN_DATE}', RERUN='${RERUN}', warm_start='${warm_start}'" + break + fi + + done # loop over nrestarts } diff --git a/ush/forecast_postdet.sh b/ush/forecast_postdet.sh index 39a12b3c61c..aee9fe9bced 100755 --- a/ush/forecast_postdet.sh +++ b/ush/forecast_postdet.sh @@ -4,1017 +4,1021 @@ # shellcheck disable=SC2034 # shellcheck disable=SC2178 FV3_postdet() { - echo "SUB ${FUNCNAME[0]}: Entering for RUN = ${RUN}" - - echo "warm_start = ${warm_start}" - echo "RERUN = ${RERUN}" - - - #============================================================================ - # First copy initial conditions - # cold start case - if [[ "${warm_start}" == ".false." ]]; then - - # Get list of FV3 cold start files - local file_list - file_list=$(FV3_coldstarts) - echo "Copying FV3 cold start files for 'RUN=${RUN}' at '${current_cycle}' from '${COMIN_ATMOS_INPUT}'" - local fv3_file - for fv3_file in ${file_list}; do - cpreq "${COMIN_ATMOS_INPUT}/${fv3_file}" "${DATA}/INPUT/${fv3_file}" - done - - # warm start case - elif [[ "${warm_start}" == ".true." ]]; then - - # Determine restart date and directory containing restarts - local restart_date restart_dir - if [[ "${RERUN}" == "YES" ]]; then - restart_date="${RERUN_DATE}" - restart_dir="${DATArestart}/FV3_RESTART" - else # "${RERUN}" == "NO" - restart_date="${model_start_date_current_cycle}" - restart_dir="${COMIN_ATMOS_RESTART_PREV}" - fi + echo "SUB ${FUNCNAME[0]}: Entering for RUN = ${RUN}" + + echo "warm_start = ${warm_start}" + echo "RERUN = ${RERUN}" + + #============================================================================ + # First copy initial conditions + # cold start case + if [[ "${warm_start}" == ".false." ]]; then + + # Get list of FV3 cold start files + local file_list + file_list=$(FV3_coldstarts) + echo "Copying FV3 cold start files for 'RUN=${RUN}' at '${current_cycle}' from '${COMIN_ATMOS_INPUT}'" + local fv3_file + for fv3_file in ${file_list}; do + cpreq "${COMIN_ATMOS_INPUT}/${fv3_file}" "${DATA}/INPUT/${fv3_file}" + done - # Get list of FV3 restart files - local file_list - file_list=$(FV3_restarts) - echo "Copying FV3 restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" - local fv3_file restart_file - for fv3_file in ${file_list}; do - restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${fv3_file}" - cpreq "${restart_dir}/${restart_file}" "${DATA}/INPUT/${fv3_file}" - done + # warm start case + elif [[ "${warm_start}" == ".true." ]]; then + + # Determine restart date and directory containing restarts + local restart_date restart_dir + if [[ "${RERUN}" == "YES" ]]; then + restart_date="${RERUN_DATE}" + restart_dir="${DATArestart}/FV3_RESTART" + else # "${RERUN}" == "NO" + restart_date="${model_start_date_current_cycle}" + restart_dir="${COMIN_ATMOS_RESTART_PREV}" + fi - if [[ "${RERUN}" == "YES" ]]; then - if [[ "${DO_SPPT:-}" == "YES" || "${DO_SKEB:-}" == "YES" || \ - "${DO_SHUM:-}" == "YES" || "${DO_LAND_PERT:-}" == "YES" ]]; then - stochini=".true." - file_list=$(stoch_restarts) - echo "Copying stochastic restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" - for stoch_file in $(stoch_restarts); do - restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${stoch_file}" - cpreq "${restart_dir}/${restart_file}" "${DATA}/INPUT/${stoch_file}" + # Get list of FV3 restart files + local file_list + file_list=$(FV3_restarts) + echo "Copying FV3 restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" + local fv3_file restart_file + for fv3_file in ${file_list}; do + restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${fv3_file}" + cpreq "${restart_dir}/${restart_file}" "${DATA}/INPUT/${fv3_file}" done - fi - else - # Replace sfc_data with sfcanl_data restart files from current cycle (if found) - local nn - for (( nn = 1; nn <= ntiles; nn++ )); do - if [[ -f "${COMIN_ATMOS_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" ]]; then - rm -f "${DATA}/INPUT/sfc_data.tile${nn}.nc" - cpreq "${COMIN_ATMOS_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" \ - "${DATA}/INPUT/sfc_data.tile${nn}.nc" - # GCAFS does not run the sfcanl, only GCDAS - elif [[ ${DO_AERO_FCST} == "YES" && -f "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" ]]; then - rm -f "${DATA}/INPUT/sfc_data.tile${nn}.nc" - cpreq "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" \ - "${DATA}/INPUT/sfc_data.tile${nn}.nc" + + if [[ "${RERUN}" == "YES" ]]; then + if [[ "${DO_SPPT:-}" == "YES" || "${DO_SKEB:-}" == "YES" || + "${DO_SHUM:-}" == "YES" || "${DO_LAND_PERT:-}" == "YES" ]]; then + stochini=".true." + file_list=$(stoch_restarts) + echo "Copying stochastic restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" + for stoch_file in $(stoch_restarts); do + restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${stoch_file}" + cpreq "${restart_dir}/${restart_file}" "${DATA}/INPUT/${stoch_file}" + done + fi else - echo "'sfcanl_data.tile1.nc' not found in '${COMIN_ATMOS_RESTART}', using 'sfc_data.tile1.nc'" - break + # Replace sfc_data with sfcanl_data restart files from current cycle (if found) + local nn + for ((nn = 1; nn <= ntiles; nn++)); do + if [[ -f "${COMIN_ATMOS_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" ]]; then + rm -f "${DATA}/INPUT/sfc_data.tile${nn}.nc" + cpreq "${COMIN_ATMOS_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" \ + "${DATA}/INPUT/sfc_data.tile${nn}.nc" + # GCAFS does not run the sfcanl, only GCDAS + elif [[ ${DO_AERO_FCST} == "YES" && -f "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" ]]; then + rm -f "${DATA}/INPUT/sfc_data.tile${nn}.nc" + cpreq "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.sfcanl_data.tile${nn}.nc" \ + "${DATA}/INPUT/sfc_data.tile${nn}.nc" + else + echo "'sfcanl_data.tile1.nc' not found in '${COMIN_ATMOS_RESTART}', using 'sfc_data.tile1.nc'" + break + fi + done + + # If aerosol analysis is to be done, replace fv_tracer with aeroanl_fv_tracer + # restart files from current cycle (if found) + if [[ "${DO_AERO_FCST}" == "YES" ]]; then + local nn + local use_anl_aero="YES" + for ((nn = 1; nn <= ntiles; nn++)); do + test_tracer_file="${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.aeroanl_fv_tracer.res.tile${nn}.nc" + if [[ ! -f "${test_tracer_file}" ]]; then + use_anl_aero="NO" + echo "WARNING: File ${test_tracer_file} does not exist, will not replace any files from the aerosol analysis" + break + fi + done + if [[ "${use_anl_aero}" == "YES" ]]; then + for ((nn = 1; nn <= ntiles; nn++)); do + rm -f "${DATA}/INPUT/fv_tracer.res.tile${nn}.nc" + cpreq "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.aeroanl_fv_tracer.res.tile${nn}.nc" \ + "${DATA}/INPUT/fv_tracer.res.tile${nn}.nc" + done + fi # if [[ ${use_anl_aero} == "YES" ]]; then + + fi # [[ ${DO_AERO_FCST} == "YES" ]]; then + + fi # if [[ "${RERUN}" == "YES" ]]; then + + fi # if [[ "${warm_start}" == ".true." ]]; then + + # Regardless of warm_start or not, the sfc_data and orography files should be consistent + # Check for consistency + # TODO: the checker has a --fatal option, which is not used here. This needs to be decided how to handle. + if [[ "${CHECK_LAND_RESTART_OROG:-NO}" == "YES" ]]; then + "${USHgfs}/check_land_input_orography.py" \ + --input_dir "${DATA}/INPUT" --orog_dir "${DATA}/INPUT" + err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: check_land_input_orography.py returned error code ${err}, ABORT!" + exit "${err}" fi - done - - # If aerosol analysis is to be done, replace fv_tracer with aeroanl_fv_tracer - # restart files from current cycle (if found) - if [[ "${DO_AERO_FCST}" == "YES" ]]; then - local nn - local use_anl_aero="YES" - for (( nn = 1; nn <= ntiles; nn++ )); do - test_tracer_file="${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.aeroanl_fv_tracer.res.tile${nn}.nc" - if [[ ! -f "${test_tracer_file}" ]]; then - use_anl_aero="NO" - echo "WARNING: File ${test_tracer_file} does not exist, will not replace any files from the aerosol analysis" - break - fi - done - if [[ "${use_anl_aero}" == "YES" ]]; then - for (( nn = 1; nn <= ntiles; nn++ )); do - rm -f "${DATA}/INPUT/fv_tracer.res.tile${nn}.nc" - cpreq "${COMIN_TRACER_RESTART}/${restart_date:0:8}.${restart_date:8:2}0000.aeroanl_fv_tracer.res.tile${nn}.nc" \ - "${DATA}/INPUT/fv_tracer.res.tile${nn}.nc" - done - fi # if [[ ${use_anl_aero} == "YES" ]]; then - - fi # [[ ${DO_AERO_FCST} == "YES" ]]; then - - fi # if [[ "${RERUN}" == "YES" ]]; then - - fi # if [[ "${warm_start}" == ".true." ]]; then - - # Regardless of warm_start or not, the sfc_data and orography files should be consistent - # Check for consistency - # TODO: the checker has a --fatal option, which is not used here. This needs to be decided how to handle. - if [[ "${CHECK_LAND_RESTART_OROG:-NO}" == "YES" ]]; then - "${USHgfs}/check_land_input_orography.py" \ - --input_dir "${DATA}/INPUT" --orog_dir "${DATA}/INPUT" - err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: check_land_input_orography.py returned error code ${err}, ABORT!" - exit "${err}" - fi - fi - - #============================================================================ - # Determine increment files when doing cold start - if [[ "${warm_start}" == ".false." ]]; then - - if [[ "${USE_ATM_ENS_PERTURB_FILES:-NO}" == "YES" ]]; then - if (( MEMBER == 0 )); then - inc_files=() - else - inc_files=("increment.atm.i006.nc") - read_increment=".true." - res_latlon_dynamics="increment.atm.i006.nc" - fi - increment_file_on_native_grid=".false." - local increment_file - for inc_file in "${inc_files[@]}"; do - increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${inc_file}" - cpreq "${increment_file}" "${DATA}/INPUT/${inc_file}" - done fi - # Determine IAU and increment files when doing warm start - elif [[ "${warm_start}" == ".true." ]]; then + #============================================================================ + # Determine increment files when doing cold start + if [[ "${warm_start}" == ".false." ]]; then - #-------------------------------------------------------------------------- - if [[ "${RERUN}" == "YES" ]]; then + if [[ "${USE_ATM_ENS_PERTURB_FILES:-NO}" == "YES" ]]; then + if ((MEMBER == 0)); then + inc_files=() + else + inc_files=("increment.atm.i006.nc") + read_increment=".true." + res_latlon_dynamics="increment.atm.i006.nc" + fi + increment_file_on_native_grid=".false." + local increment_file + for inc_file in "${inc_files[@]}"; do + increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${inc_file}" + cpreq "${increment_file}" "${DATA}/INPUT/${inc_file}" + done + fi - local restart_fhr - restart_fhr=$(nhour "${RERUN_DATE}" "${current_cycle}") - IAU_FHROT=$((IAU_OFFSET + restart_fhr)) - if [[ "${DOIAU}" == "YES" ]]; then - IAUFHRS=-1 - IAU_DELTHRS=0 - IAU_INC_FILES="''" - fi - DO_LAND_IAU=".false." - #-------------------------------------------------------------------------- - else # "${RERUN}" == "NO" - - # Need a coupler.res that is consistent with the model start time - if [[ "${DOIAU:-NO}" == "YES" ]]; then - local model_start_time="${previous_cycle}" - else - local model_start_time="${current_cycle}" - fi - local model_current_time="${model_start_date_current_cycle}" - rm -f "${DATA}/INPUT/coupler.res" - cat >> "${DATA}/INPUT/coupler.res" << EOF + # Determine IAU and increment files when doing warm start + elif [[ "${warm_start}" == ".true." ]]; then + + #-------------------------------------------------------------------------- + if [[ "${RERUN}" == "YES" ]]; then + + local restart_fhr + restart_fhr=$(nhour "${RERUN_DATE}" "${current_cycle}") + IAU_FHROT=$((IAU_OFFSET + restart_fhr)) + if [[ "${DOIAU}" == "YES" ]]; then + IAUFHRS=-1 + IAU_DELTHRS=0 + IAU_INC_FILES="''" + fi + DO_LAND_IAU=".false." + #-------------------------------------------------------------------------- + else # "${RERUN}" == "NO" + + # Need a coupler.res that is consistent with the model start time + if [[ "${DOIAU:-NO}" == "YES" ]]; then + local model_start_time="${previous_cycle}" + else + local model_start_time="${current_cycle}" + fi + local model_current_time="${model_start_date_current_cycle}" + rm -f "${DATA}/INPUT/coupler.res" + cat >> "${DATA}/INPUT/coupler.res" << EOF 3 (Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4) ${model_start_time:0:4} ${model_start_time:4:2} ${model_start_time:6:2} ${model_start_time:8:2} 0 0 Model start time: year, month, day, hour, minute, second ${model_current_time:0:4} ${model_current_time:4:2} ${model_current_time:6:2} ${model_current_time:8:2} 0 0 Current model time: year, month, day, hour, minute, second EOF - # Create a array of increment files - local inc_files inc_file iaufhrs iaufhr - if [[ "${DOIAU}" == "YES" ]]; then - # create an array of inc_files for each IAU hour - IFS=',' read -ra iaufhrs <<< "${IAUFHRS}" - inc_files=() - delimiter="" - IAU_INC_FILES="" - for iaufhr in "${iaufhrs[@]}"; do - if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then - for tile in {1..6}; do - inc_file="jedi_increment.atm.i$(printf %03i "${iaufhr}").tile${tile}.nc" - inc_files+=("${inc_file}") - IAU_INC_FILES="${IAU_INC_FILES}${delimiter}'${inc_file}'" + # Create a array of increment files + local inc_files inc_file iaufhrs iaufhr + if [[ "${DOIAU}" == "YES" ]]; then + # create an array of inc_files for each IAU hour + IFS=',' read -ra iaufhrs <<< "${IAUFHRS}" + inc_files=() + delimiter="" + IAU_INC_FILES="" + for iaufhr in "${iaufhrs[@]}"; do + if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then + for tile in {1..6}; do + inc_file="jedi_increment.atm.i$(printf %03i "${iaufhr}").tile${tile}.nc" + inc_files+=("${inc_file}") + IAU_INC_FILES="${IAU_INC_FILES}${delimiter}'${inc_file}'" + done + else + inc_file="increment.atm.i$(printf %03i "${iaufhr}").nc" + inc_files+=("${inc_file}") + IAU_INC_FILES="${IAU_INC_FILES}${delimiter}'${inc_file}'" + fi + + delimiter="," + done + else # "${DOIAU}" == "NO" + read_increment=".true." + + if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then + inc_files=("jedi_increment.atm.i006.tile1.nc" "jedi_increment.atm.i006.tile2.nc" "jedi_increment.atm.i006.tile3.nc" "jedi_increment.atm.i006.tile4.nc" "jedi_increment.atm.i006.tile5.nc" "jedi_increment.atm.i006.tile6.nc") + increment_file_on_native_grid=".true." + res_latlon_dynamics="jedi_increment.atm.i006" + if [[ "${DO_JEDIATMENS:-NO}" == "NO" ]]; then + inc_files=("increment.atm.i006.nc") + res_latlon_dynamics="increment.atm.i006.nc" + increment_file_on_native_grid=".false." + fi + else + inc_files=("increment.atm.i006.nc") + res_latlon_dynamics="increment.atm.i006.nc" + increment_file_on_native_grid=".false." + fi + if [[ "${USE_ATM_ENS_PERTURB_FILES:-NO}" == "YES" ]]; then + # Control member has no perturbation + if ((MEMBER == 0)); then + inc_files=() + read_increment=".false." + res_latlon_dynamics='""' + fi + fi + fi + + if [[ "${RUN}" == "enkfgfs" ]] || [[ "${RUN}" == "enkfgdas" ]]; then + prefix_atminc="recentered_" + else + prefix_atminc="" + fi + + local increment_file + for inc_file in "${inc_files[@]}"; do + if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then + increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${prefix_atminc}${inc_file}" + if [[ "${DO_JEDIATMENS:-NO}" == "NO" ]]; then + increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${prefix_atminc}${inc_file}" + fi + else + if [[ "${RUN}" == "gcafs" ]]; then + increment_file="${COMIN_ATMOS_ANALYSIS}/gcdas.t${cyc}z.${prefix_atminc}${inc_file}" + else + increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${prefix_atminc}${inc_file}" + fi + fi + cpreq "${increment_file}" "${DATA}/INPUT/${inc_file}" done - else - inc_file="increment.atm.i$(printf %03i "${iaufhr}").nc" - inc_files+=("${inc_file}") - IAU_INC_FILES="${IAU_INC_FILES}${delimiter}'${inc_file}'" - fi - - delimiter="," - done - else # "${DOIAU}" == "NO" - read_increment=".true." - if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then - inc_files=("jedi_increment.atm.i006.tile1.nc" "jedi_increment.atm.i006.tile2.nc" "jedi_increment.atm.i006.tile3.nc" "jedi_increment.atm.i006.tile4.nc" "jedi_increment.atm.i006.tile5.nc" "jedi_increment.atm.i006.tile6.nc") - increment_file_on_native_grid=".true." - res_latlon_dynamics="jedi_increment.atm.i006" - else - inc_files=("increment.atm.i006.nc") - res_latlon_dynamics="increment.atm.i006.nc" - increment_file_on_native_grid=".false." - fi - if [[ "${USE_ATM_ENS_PERTURB_FILES:-NO}" == "YES" ]]; then - # Control member has no perturbation - if (( MEMBER == 0 )); then - inc_files=() - read_increment=".false." - res_latlon_dynamics='""' - fi - fi - fi - - if [[ "${RUN}" = "enkfgfs" ]] || [[ "${RUN}" = "enkfgdas" ]]; then - prefix_atminc="recentered_" - else - prefix_atminc="" - fi - - local increment_file - for inc_file in "${inc_files[@]}"; do - if [[ "${DO_JEDIATMVAR:-NO}" == "YES" ]]; then - increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${prefix_atminc}${inc_file}" - else - if [[ "${RUN}" == "gcafs" ]]; then - increment_file="${COMIN_ATMOS_ANALYSIS}/gcdas.t${cyc}z.${prefix_atminc}${inc_file}" - else - increment_file="${COMIN_ATMOS_ANALYSIS}/${RUN}.t${cyc}z.${prefix_atminc}${inc_file}" - fi + # Land IAU increments: sfc_inc in FV3 grid, all timesteps in one file per tile + if [[ ${DO_LAND_IAU} == ".true." ]]; then + local TN sfc_increment_file + for TN in $(seq 1 "${ntiles}"); do + sfc_increment_file="${COMIN_ATMOS_ANALYSIS}/increment.sfc.tile${TN}.nc" + if [[ ! -f "${sfc_increment_file}" ]]; then + export err=1 + err_exit "FATAL ERROR: DO_LAND_IAU=${DO_LAND_IAU}, but missing increment file ${sfc_increment_file}, ABORT!" + else + cpreq "${sfc_increment_file}" "${DATA}/INPUT/sfc_inc.tile${TN}.nc" + fi + done + fi + fi # if [[ "${RERUN}" == "YES" ]]; then + #-------------------------------------------------------------------------- + fi # if [[ "${warm_start}" == ".true." ]]; then + #============================================================================ + + #============================================================================ + # If doing IAU, change forecast hours + if [[ "${DOIAU:-NO}" == "YES" ]]; then + FHMAX=$((FHMAX + 6)) + if [[ ${FHMAX_HF} -gt 0 ]]; then + FHMAX_HF=$((FHMAX_HF + 6)) fi - cpreq "${increment_file}" "${DATA}/INPUT/${inc_file}" - done - - # Land IAU increments: sfc_inc in FV3 grid, all timesteps in one file per tile - if [[ ${DO_LAND_IAU} = ".true." ]]; then - local TN sfc_increment_file - for TN in $(seq 1 "${ntiles}"); do - sfc_increment_file="${COMIN_ATMOS_ANALYSIS}/increment.sfc.tile${TN}.nc" - if [[ ! -f "${sfc_increment_file}" ]]; then - echo "FATAL ERROR: DO_LAND_IAU=${DO_LAND_IAU}, but missing increment file ${sfc_increment_file}, ABORT!" - exit 1 - else - cpreq "${sfc_increment_file}" "${DATA}/INPUT/sfc_inc.tile${TN}.nc" - fi - done + fi + #============================================================================ - fi + #============================================================================ + # If warm starting from restart files, set the following flags + if [[ "${warm_start}" == ".true." ]]; then - fi # if [[ "${RERUN}" == "YES" ]]; then - #-------------------------------------------------------------------------- + # start from restart file + nggps_ic=".false." + ncep_ic=".false." + external_ic=".false." + mountain=".true." - fi # if [[ "${warm_start}" == ".true." ]]; then - #============================================================================ + # restarts contain non-hydrostatic state + if [[ "${TYPE}" == "nh" ]]; then + make_nh=".false." + fi - #============================================================================ - # If doing IAU, change forecast hours - if [[ "${DOIAU:-NO}" == "YES" ]]; then - FHMAX=$((FHMAX + 6)) - if (( FHMAX_HF > 0 )); then - FHMAX_HF=$((FHMAX_HF + 6)) - fi - fi - #============================================================================ - - #============================================================================ - # If warm starting from restart files, set the following flags - if [[ "${warm_start}" == ".true." ]]; then - - # start from restart file - nggps_ic=".false." - ncep_ic=".false." - external_ic=".false." - mountain=".true." - - # restarts contain non-hydrostatic state - if [[ "${TYPE}" == "nh" ]]; then - make_nh=".false." + # do not pre-condition the solution + na_init=0 + + fi # warm_start == .true. + #============================================================================ + + #============================================================================ + if [[ "${QUILTING}" == ".true." ]] && [[ "${OUTPUT_GRID}" == "gaussian_grid" ]]; then + local FH2 FH3 + for fhr in ${FV3_OUTPUT_FH}; do + FH3=$(printf %03i "${fhr}") + FH2=$(printf %02i "${fhr}") + ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.atm.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/atmf${FH3}.nc" + ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.sfc.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/sfcf${FH3}.nc" + ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.log.f${FH3}.txt" "${DATAoutput}/FV3ATM_OUTPUT/log.atm.f${FH3}" + if [[ "${DO_JEDIATMVAR:-}" == "YES" || "${DO_HISTORY_FILE_ON_NATIVE_GRID:-"NO"}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.csg_atm.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/cubed_sphere_grid_atmf${FH3}.nc" + ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.csg_sfc.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/cubed_sphere_grid_sfcf${FH3}.nc" + fi + if [[ "${WRITE_DOPOST}" == ".true." ]]; then + ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.master.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSPRS.GrbF${FH2}" + ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.sflux.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSFLX.GrbF${FH2}" + if [[ "${DO_NEST:-NO}" == "YES" ]]; then + ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.master.nest.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSPRS.GrbF${FH2}.nest02" + ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.sflux.nest.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSFLX.GrbF${FH2}.nest02" + fi + fi + done fi - - # do not pre-condition the solution - na_init=0 - - fi # warm_start == .true. - #============================================================================ - - #============================================================================ - if [[ "${QUILTING}" = ".true." ]] && [[ "${OUTPUT_GRID}" = "gaussian_grid" ]]; then - local FH2 FH3 - for fhr in ${FV3_OUTPUT_FH}; do - FH3=$(printf %03i "${fhr}") - FH2=$(printf %02i "${fhr}") - ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.atm.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/atmf${FH3}.nc" - ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.sfc.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/sfcf${FH3}.nc" - ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.log.f${FH3}.txt" "${DATAoutput}/FV3ATM_OUTPUT/log.atm.f${FH3}" - if [[ "${DO_JEDIATMVAR:-}" == "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.csg_atm.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/cubed_sphere_grid_atmf${FH3}.nc" - ${NLN} "${COMOUT_ATMOS_HISTORY}/${RUN}.t${cyc}z.csg_sfc.f${FH3}.nc" "${DATAoutput}/FV3ATM_OUTPUT/cubed_sphere_grid_sfcf${FH3}.nc" - fi - if [[ "${WRITE_DOPOST}" == ".true." ]]; then - ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.master.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSPRS.GrbF${FH2}" - ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.sflux.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSFLX.GrbF${FH2}" - if [[ "${DO_NEST:-NO}" == "YES" ]]; then - ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.master.nest.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSPRS.GrbF${FH2}.nest02" - ${NLN} "${COMOUT_ATMOS_MASTER}/${RUN}.t${cyc}z.sflux.nest.f${FH3}.grib2" "${DATAoutput}/FV3ATM_OUTPUT/GFSFLX.GrbF${FH2}.nest02" + #============================================================================ + restart_interval=${restart_interval:-${FHMAX}} + # restart_interval = 0 implies write restart at the END of the forecast i.e. at FHMAX + # Convert restart interval into an explicit list for CMEPS/CICE/MOM6/WW3 + # Note, this must be computed after determination IAU in forecast_det and fhrot. + if [[ ${restart_interval} -eq 0 ]]; then + if [[ "${DOIAU:-NO}" == "YES" ]]; then + FV3_RESTART_FH=$((FHMAX + assim_freq)) + else + FV3_RESTART_FH=("${FHMAX}") fi - fi - done - fi - #============================================================================ - restart_interval=${restart_interval:-${FHMAX}} - # restart_interval = 0 implies write restart at the END of the forecast i.e. at FHMAX - # Convert restart interval into an explicit list for CMEPS/CICE/MOM6/WW3 - # Note, this must be computed after determination IAU in forecast_det and fhrot. - if (( restart_interval == 0 )); then - if [[ "${DOIAU:-NO}" == "YES" ]]; then - FV3_RESTART_FH=$(( FHMAX + assim_freq )) - else - FV3_RESTART_FH=("${FHMAX}") - fi - else - if [[ "${DOIAU:-NO}" == "YES" ]]; then - if [[ "${MODE}" = "cycled" && "${SDATE}" = "${PDY}${cyc}" && ${EXP_WARM_START} = ".false." ]]; then - local restart_interval_start=${restart_interval} - local restart_interval_end=${FHMAX} - else - local restart_interval_start=$(( restart_interval + assim_freq )) - local restart_interval_end=$(( FHMAX + assim_freq )) - fi else - local restart_interval_start=${restart_interval} - local restart_interval_end=${FHMAX} + if [[ "${DOIAU:-NO}" == "YES" ]]; then + if [[ "${MODE}" = "cycled" && "${SDATE}" = "${PDY}${cyc}" && ${EXP_WARM_START} = ".false." ]]; then + local restart_interval_start=${restart_interval} + local restart_interval_end=${FHMAX} + else + local restart_interval_start=$((restart_interval + assim_freq)) + local restart_interval_end=$((FHMAX + assim_freq)) + fi + else + local restart_interval_start=${restart_interval} + local restart_interval_end=${FHMAX} + fi + FV3_RESTART_FH="$(seq -s ' ' "${restart_interval_start}" "${restart_interval}" "${restart_interval_end}")" fi - FV3_RESTART_FH="$(seq -s ' ' "${restart_interval_start}" "${restart_interval}" "${restart_interval_end}")" - fi - export FV3_RESTART_FH - #============================================================================ + export FV3_RESTART_FH + #============================================================================ } FV3_nml() { - # namelist output for a certain component - echo "SUB ${FUNCNAME[0]}: Creating name lists and model configure file for FV3" - - source "${USHgfs}/parsing_namelists_FV3.sh" - source "${USHgfs}/parsing_model_configure_FV3.sh" - - # Call the appropriate namelist functions - if [[ "${DO_NEST:-NO}" == "YES" ]] ; then - source "${USHgfs}/parsing_namelists_FV3_nest.sh" - FV3_namelists_nest global - FV3_namelists_nest nest - else - FV3_namelists - fi - FV3_model_configure - - echo "SUB ${FUNCNAME[0]}: FV3 name lists and model configure file created" + # namelist output for a certain component + echo "SUB ${FUNCNAME[0]}: Creating name lists and model configure file for FV3" + + source "${USHgfs}/parsing_namelists_FV3.sh" + source "${USHgfs}/parsing_model_configure_FV3.sh" + + # Call the appropriate namelist functions + if [[ "${DO_NEST:-NO}" == "YES" ]]; then + source "${USHgfs}/parsing_namelists_FV3_nest.sh" + FV3_namelists_nest global + FV3_namelists_nest nest + else + FV3_namelists + fi + FV3_model_configure + + echo "SUB ${FUNCNAME[0]}: FV3 name lists and model configure file created" } FV3_out() { - echo "SUB ${FUNCNAME[0]}: copying output data for FV3" - - # Copy configuration files - cpfs "${DATA}/input.nml" "${COMOUT_CONF}/ufs.input.nml" - cpfs "${DATA}/model_configure" "${COMOUT_CONF}/ufs.model_configure" - cpfs "${DATA}/ufs.configure" "${COMOUT_CONF}/ufs.ufs.configure" - cpfs "${DATA}/diag_table" "${COMOUT_CONF}/ufs.diag_table" - - - # Determine the dates for restart files to be copied to COM - local restart_date restart_dates - restart_dates=() - - case ${RUN} in - gdas|enkfgdas|enkfgfs|enkfgcafs|gcdas) # Copy restarts in the assimilation window for RUN=gdas|enkfgdas|enkfgfs - restart_date="${model_start_date_next_cycle}" - while (( restart_date <= forecast_end_cycle )); do - restart_dates+=("${restart_date:0:8}.${restart_date:8:2}0000") - restart_date=$(date --utc -d "${restart_date:0:8} ${restart_date:8:2} + ${restart_interval} hours" +%Y%m%d%H) - done - ;; - gfs|gefs|sfs|gcafs) # Copy restarts at the end of the forecast segment for RUN=gfs|gefs|sfs|gcafs - if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then - restart_dates+=("${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000") - fi - ;; - *) - echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" - exit 25 - ;; - esac - - ### Check that there are restart files to copy - if [[ ${#restart_dates[@]} -gt 0 ]]; then - # Get list of FV3 restart files - local file_list fv3_file - file_list=$(FV3_restarts) - - # Copy restarts for the dates collected above to COM - for restart_date in "${restart_dates[@]}"; do - echo "Copying FV3 restarts for 'RUN=${RUN}' at ${restart_date}" - for fv3_file in ${file_list}; do - cpfs "${DATArestart}/FV3_RESTART/${restart_date}.${fv3_file}" \ - "${COMOUT_ATMOS_RESTART}/${restart_date}.${fv3_file}" - done - done + echo "SUB ${FUNCNAME[0]}: copying output data for FV3" + + # Copy configuration files + cpfs "${DATA}/input.nml" "${COMOUT_CONF}/ufs.input.nml" + cpfs "${DATA}/model_configure" "${COMOUT_CONF}/ufs.model_configure" + cpfs "${DATA}/ufs.configure" "${COMOUT_CONF}/ufs.ufs.configure" + cpfs "${DATA}/diag_table" "${COMOUT_CONF}/ufs.diag_table" + + # Determine the dates for restart files to be copied to COM + local restart_date restart_dates + restart_dates=() + + case ${RUN} in + gdas | enkfgdas | enkfgfs | enkfgcafs | gcdas) # Copy restarts in the assimilation window for RUN=gdas|enkfgdas|enkfgfs + restart_date="${model_start_date_next_cycle}" + while ((restart_date <= forecast_end_cycle)); do + restart_dates+=("${restart_date:0:8}.${restart_date:8:2}0000") + restart_date=$(date --utc -d "${restart_date:0:8} ${restart_date:8:2} + ${restart_interval} hours" +%Y%m%d%H) + done + ;; + gfs | gefs | sfs | gcafs) # Copy restarts at the end of the forecast segment for RUN=gfs|gefs|sfs|gcafs + if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then + restart_dates+=("${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000") + fi + ;; + *) + echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" + exit 25 + ;; + esac + + ### Check that there are restart files to copy + if [[ ${#restart_dates[@]} -gt 0 ]]; then + # Get list of FV3 restart files + local file_list fv3_file + file_list=$(FV3_restarts) + + # Copy restarts for the dates collected above to COM + for restart_date in "${restart_dates[@]}"; do + echo "Copying FV3 restarts for 'RUN=${RUN}' at ${restart_date}" + for fv3_file in ${file_list}; do + cpfs "${DATArestart}/FV3_RESTART/${restart_date}.${fv3_file}" \ + "${COMOUT_ATMOS_RESTART}/${restart_date}.${fv3_file}" + done + done - echo "SUB ${FUNCNAME[0]}: Output data for FV3 copied" - fi + echo "SUB ${FUNCNAME[0]}: Output data for FV3 copied" + fi } # Disable variable not used warnings # shellcheck disable=SC2034 WW3_postdet() { - echo "SUB ${FUNCNAME[0]}: Linking input data for WW3" - # Copy initial condition files: - local restart_date restart_dir - if [[ "${RERUN}" == "YES" ]]; then - restart_date="${RERUN_DATE}" - restart_dir="${DATArestart}/WW3_RESTART" - else - restart_date="${model_start_date_current_cycle}" - restart_dir="${COMIN_WAVE_RESTART_PREV}" - fi - - echo "Copying WW3 restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" - - local ww3_restart_file ww3_restart_dest_file seconds - seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds - ww3_restart_file="${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3" - ww3_restart_dest_file="ufs.cpld.ww3.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}" - if [[ -s "${ww3_restart_file}.nc" ]]; then # First check to see if netcdf restart exists: - export WW3_restart_from_binary=false - cpreq "${ww3_restart_file}.nc" "${DATA}/${ww3_restart_dest_file}.nc" - elif [[ -s "${ww3_restart_file}" ]]; then # If not, check to see if binary restart exists: - export WW3_restart_from_binary=true - cpreq "${ww3_restart_file}" "${DATA}/${ww3_restart_dest_file}" - else - if [[ "${RERUN}" == "YES" ]] || [[ -f "${DATA}/ufs.cpld.cpl.r.nc" ]]; then # The || part requires CMEPS_postdet to be called before WW3_postdet - # In the case of a RERUN, the WW3 restart file is required - # In the case of runtype=continue, if no wave restart when using PIO, the model will fail - echo "FATAL ERROR: WW3 binary | netcdf restart file '${ww3_restart_file}' | '${ww3_restart_file}.nc' not found for RERUN='${RERUN}' or runtype=continue, ABORT!" - exit 1 + echo "SUB ${FUNCNAME[0]}: Linking input data for WW3" + # Copy initial condition files: + local restart_date restart_dir + if [[ "${RERUN}" == "YES" ]]; then + restart_date="${RERUN_DATE}" + restart_dir="${DATArestart}/WW3_RESTART" else - export WW3_restart_from_binary=false - echo "WARNING: WW3 binary | netcdf restart file '${ww3_restart_file}' | '${ww3_restart_file}.nc' not found for warm_start='${warm_start}', will start from rest!" + restart_date="${model_start_date_current_cycle}" + restart_dir="${COMIN_WAVE_RESTART_PREV}" fi - fi - - local first_ww3_restart_out - first_ww3_restart_out=$(date --utc -d "${restart_date:0:8} ${restart_date:8:2} + ${restart_interval} hours" +%Y%m%d%H) - if [[ "${DOIAU:-NO}" == "YES" ]]; then - first_ww3_restart_out=$(date --utc -d "${first_ww3_restart_out:0:8} ${first_ww3_restart_out:8:2} + ${half_window} hours" +%Y%m%d%H) - fi - - # Link restart files to their expected names in DATArestart/WW3_RESTART - # TODO: Have the UFSWM write out the WW3 restart files in the expected format of 'YYYYMMDD.HHmmSS.restart.ww3.nc' - local cwd vdate ww3_ufs_restart_file ww3_netcdf_restart_file - cwd="${PWD}" - cd "${DATArestart}/WW3_RESTART" || exit 1 - for (( vdate = first_ww3_restart_out; vdate <= forecast_end_cycle; - vdate = $(date --utc -d "${vdate:0:8} ${vdate:8:2} + ${restart_interval} hours" +%Y%m%d%H) )); do - seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds - ww3_ufs_restart_file="ufs.cpld.ww3.r.${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}.nc" # UFS restart file name - ww3_netcdf_restart_file="${vdate:0:8}.${vdate:8:2}0000.restart.ww3.nc" # WW3 restart file name in COM - ${NLN} "${ww3_netcdf_restart_file}" "${ww3_ufs_restart_file}" - done - - # TODO: link GEFS restart for next cycle IC - #if [[ "${RUN}" == "gefs" ]]; then - # vdate=${model_start_date_next_cycle} - # seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds - # ww3_ufs_restart_file="ufs.cpld.ww3.r.${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}.nc" - # ww3_netcdf_restart_file="${vdate:0:8}.${vdate:8:2}0000.restart.ww3.nc" - # ${NLN} "${ww3_netcdf_restart_file}" "${ww3_ufs_restart_file}" - #fi - cd "${cwd}" || exit 1 - - # Link output files - ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.${PDY}${cyc}.log" "log.ww3" - - # Loop for gridded output (uses FHINC) - local fhr fhr3 FHINC - fhr=${FHMIN_WAV} - if [[ ${FHMAX_HF_WAV} -gt 0 && ${FHOUT_HF_WAV} -gt 0 && ${fhr} -lt ${FHMAX_HF_WAV} ]]; then - fhinc=${FHOUT_HF_WAV} - else - fhinc=${FHOUT_WAV} - fi - while [[ ${fhr} -le ${FHMAX_WAV} ]]; do - fhr3=$(printf '%03d' "${fhr}") - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d.%H0000) - ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.f${fhr3}.bin" "${DATAoutput}/WW3_OUTPUT/${vdate}.out_grd.ww3" - ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.f${fhr3}.log" "${DATAoutput}/WW3_OUTPUT/log.${vdate}.out_grd.ww3.txt" - - if [[ ${fhr} -ge ${FHMAX_HF_WAV} ]]; then - fhinc=${FHOUT_WAV} + + echo "Copying WW3 restarts for 'RUN=${RUN}' at '${restart_date}' from '${restart_dir}'" + + local ww3_restart_file ww3_restart_dest_file seconds + seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds + ww3_restart_file="${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3" + ww3_restart_dest_file="ufs.cpld.ww3.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}" + if [[ -s "${ww3_restart_file}.nc" ]]; then # First check to see if netcdf restart exists: + export WW3_restart_from_binary=false + cpreq "${ww3_restart_file}.nc" "${DATA}/${ww3_restart_dest_file}.nc" + elif [[ -s "${ww3_restart_file}" ]]; then # If not, check to see if binary restart exists: + export WW3_restart_from_binary=true + cpreq "${ww3_restart_file}" "${DATA}/${ww3_restart_dest_file}" + else + if [[ "${RERUN}" == "YES" ]] || [[ -f "${DATA}/ufs.cpld.cpl.r.nc" ]]; then # The || part requires CMEPS_postdet to be called before WW3_postdet + # In the case of a RERUN, the WW3 restart file is required + # In the case of runtype=continue, if no wave restart when using PIO, the model will fail + echo "FATAL ERROR: WW3 binary | netcdf restart file '${ww3_restart_file}' | '${ww3_restart_file}.nc' not found for RERUN='${RERUN}' or runtype=continue, ABORT!" + exit 1 + else + export WW3_restart_from_binary=false + echo "WARNING: WW3 binary | netcdf restart file '${ww3_restart_file}' | '${ww3_restart_file}.nc' not found for warm_start='${warm_start}', will start from rest!" + fi + fi + + local first_ww3_restart_out + first_ww3_restart_out=$(date --utc -d "${restart_date:0:8} ${restart_date:8:2} + ${restart_interval} hours" +%Y%m%d%H) + if [[ "${DOIAU:-NO}" == "YES" ]]; then + first_ww3_restart_out=$(date --utc -d "${first_ww3_restart_out:0:8} ${first_ww3_restart_out:8:2} + ${half_window} hours" +%Y%m%d%H) + fi + + # Link restart files to their expected names in DATArestart/WW3_RESTART + # TODO: Have the UFSWM write out the WW3 restart files in the expected format of 'YYYYMMDD.HHmmSS.restart.ww3.nc' + local cwd vdate ww3_ufs_restart_file ww3_netcdf_restart_file + cwd="${PWD}" + cd "${DATArestart}/WW3_RESTART" || exit 1 + for ((vdate = first_ww3_restart_out; vdate <= forecast_end_cycle; \ + vdate = $(date --utc -d "${vdate:0:8} ${vdate:8:2} + ${restart_interval} hours" +%Y%m%d%H))); do + seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds + ww3_ufs_restart_file="ufs.cpld.ww3.r.${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}.nc" # UFS restart file name + ww3_netcdf_restart_file="${vdate:0:8}.${vdate:8:2}0000.restart.ww3.nc" # WW3 restart file name in COM + ${NLN} "${ww3_netcdf_restart_file}" "${ww3_ufs_restart_file}" + done + + # TODO: link GEFS restart for next cycle IC + #if [[ "${RUN}" == "gefs" ]]; then + # vdate=${model_start_date_next_cycle} + # seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds + # ww3_ufs_restart_file="ufs.cpld.ww3.r.${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}.nc" + # ww3_netcdf_restart_file="${vdate:0:8}.${vdate:8:2}0000.restart.ww3.nc" + # ${NLN} "${ww3_netcdf_restart_file}" "${ww3_ufs_restart_file}" + #fi + cd "${cwd}" || exit 1 + + # Link output files + ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.${PDY}${cyc}.log" "log.ww3" + + # Loop for gridded output (uses FHINC) + local fhr fhr3 FHINC + # shellcheck disable=SC2153 + fhr="${FHMIN_WAV}" + if [[ ${FHMAX_HF_WAV} -gt 0 && ${FHOUT_HF_WAV} -gt 0 && ${fhr} -lt ${FHMAX_HF_WAV} ]]; then + fhinc=${FHOUT_HF_WAV} + else + fhinc=${FHOUT_WAV} fi - fhr=$((fhr + fhinc)) - done - - # Loop for point output (uses DTPNT) - fhr=${FHMIN_WAV} - fhinc=${FHINCP_WAV} - while [[ ${fhr} -le ${FHMAX_WAV} ]]; do - fhr3=$(printf '%03d' "${fhr}") - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d.%H0000) - ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${fhr3}.nc" "${DATAoutput}/WW3_OUTPUT/${vdate}.out_pnt.ww3.nc" - ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${fhr3}.log" "${DATAoutput}/WW3_OUTPUT/log.${vdate}.out_pnt.ww3.txt" - - fhr=$((fhr + fhinc)) - done + while [[ ${fhr} -le ${FHMAX_WAV} ]]; do + fhr3=$(printf '%03d' "${fhr}") + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d.%H0000) + ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.f${fhr3}.bin" "${DATAoutput}/WW3_OUTPUT/${vdate}.out_grd.ww3" + ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.${waveGRD}.f${fhr3}.log" "${DATAoutput}/WW3_OUTPUT/log.${vdate}.out_grd.ww3.txt" + + if [[ ${fhr} -ge ${FHMAX_HF_WAV} ]]; then + fhinc=${FHOUT_WAV} + fi + fhr=$((fhr + fhinc)) + done + + # Loop for point output (uses DTPNT) + fhr=${FHMIN_WAV} + fhinc=${FHINCP_WAV} + while [[ ${fhr} -le ${FHMAX_WAV} ]]; do + fhr3=$(printf '%03d' "${fhr}") + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d.%H0000) + ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${fhr3}.nc" "${DATAoutput}/WW3_OUTPUT/${vdate}.out_pnt.ww3.nc" + ${NLN} "${COMOUT_WAVE_HISTORY}/${RUN}.t${cyc}z.points.f${fhr3}.log" "${DATAoutput}/WW3_OUTPUT/log.${vdate}.out_pnt.ww3.txt" + + fhr=$((fhr + fhinc)) + done } WW3_nml() { - echo "SUB ${FUNCNAME[0]}: Copying input files for WW3" - source "${USHgfs}/parsing_namelists_WW3.sh" - WW3_namelists + echo "SUB ${FUNCNAME[0]}: Copying input files for WW3" + source "${USHgfs}/parsing_namelists_WW3.sh" + WW3_namelists } WW3_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for WW3" - - # Copy wave namelist from DATA to COMOUT_CONF after the forecast is run (and successfull) - cpfs "${DATA}/ww3_shel.nml" "${COMOUT_CONF}/ufs.ww3_shel.nml" - - # Copy WW3 restarts at the end of the forecast segment to COM for RUN=gfs|gefs - if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then - local restart_file - if [[ "${RUN}" == "gfs" || "${RUN}" == "gefs" || "${RUN}" == "gcafs" ]]; then - echo "Copying WW3 restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" - restart_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.restart.ww3.nc" - cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ - "${COMOUT_WAVE_RESTART}/${restart_file}" + echo "SUB ${FUNCNAME[0]}: Copying output data for WW3" + + # Copy wave namelist from DATA to COMOUT_CONF after the forecast is run (and successfull) + cpfs "${DATA}/ww3_shel.nml" "${COMOUT_CONF}/ufs.ww3_shel.nml" + + # Copy WW3 restarts at the end of the forecast segment to COM for RUN=gfs|gefs + if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then + local restart_file + if [[ "${RUN}" == "gfs" || "${RUN}" == "gefs" || "${RUN}" == "gcafs" ]]; then + echo "Copying WW3 restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" + restart_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.restart.ww3.nc" + cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ + "${COMOUT_WAVE_RESTART}/${restart_file}" + fi fi - fi - - # Copy restarts for next cycle for RUN=gdas|gefs - # TODO: GEFS needs to be added here - if [[ "${RUN}" == "gdas" ]]; then - local restart_date restart_file - restart_date="${model_start_date_next_cycle}" - echo "Copying WW3 restarts for 'RUN=${RUN}' at ${restart_date}" - restart_file="${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3.nc" - cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ - "${COMOUT_WAVE_RESTART}/${restart_file}" - fi - - # Copy restarts for downstream usage in HAFS - if [[ "${RUN}" == "gdas" ]]; then - local restart_date restart_file - restart_date="${next_cycle}" - echo "Copying WW3 restarts for 'RUN=${RUN}' at ${restart_date}" - restart_file="${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3.nc" - cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ - "${COMOUT_WAVE_RESTART}/${restart_file}" - fi -} + # Copy restarts for next cycle for RUN=gdas|gefs + # TODO: GEFS needs to be added here + if [[ "${RUN}" == "gdas" ]]; then + local restart_date restart_file + restart_date="${model_start_date_next_cycle}" + echo "Copying WW3 restarts for 'RUN=${RUN}' at ${restart_date}" + restart_file="${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3.nc" + cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ + "${COMOUT_WAVE_RESTART}/${restart_file}" + fi + # Copy restarts for downstream usage in HAFS + if [[ "${RUN}" == "gdas" ]]; then + local restart_date restart_file + restart_date="${next_cycle}" + echo "Copying WW3 restarts for 'RUN=${RUN}' at ${restart_date}" + restart_file="${restart_date:0:8}.${restart_date:8:2}0000.restart.ww3.nc" + cpfs "${DATArestart}/WW3_RESTART/${restart_file}" \ + "${COMOUT_WAVE_RESTART}/${restart_file}" + fi -CPL_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for general cpl fields" - if [[ "${esmf_profile:-.false.}" == ".true." ]]; then - cpfs "${DATA}/ESMF_Profile.summary" "${COMOUT_ATMOS_HISTORY}/ESMF_Profile.summary" - fi } -MOM6_postdet() { - echo "SUB ${FUNCNAME[0]}: MOM6 after run type determination" - - local restart_dir restart_date - if [[ "${RERUN}" == "YES" ]]; then - restart_dir="${DATArestart}/MOM6_RESTART" - restart_date="${RERUN_DATE}" - else # "${RERUN}" == "NO" - restart_dir="${COMIN_OCEAN_RESTART_PREV}" - restart_date="${model_start_date_current_cycle}" - fi - - # Copy MOM6 ICs - cpreq "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res.nc" "${DATA}/INPUT/MOM.res.nc" - case ${OCNRES} in - "025") - local nn - for (( nn = 1; nn <= 4; nn++ )); do - if [[ -f "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res_${nn}.nc" ]]; then - cpreq "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res_${nn}.nc" "${DATA}/INPUT/MOM.res_${nn}.nc" - fi - done - ;; - *) ;; - esac - - # Copy increment (only when RERUN=NO) - if [[ "${RERUN}" == "NO" ]]; then - if [[ "${DO_JEDIOCNVAR:-NO}" == "YES" ]] || [[ ${MEMBER} -gt 0 && "${ODA_INCUPD:-False}" == "True" ]]; then - cpreq "${COMIN_OCEAN_ANALYSIS}/${RUN}.t${cyc}z.mom6_increment.i006.nc" "${DATA}/INPUT/mom6_increment.nc" +CPL_out() { + echo "SUB ${FUNCNAME[0]}: Copying output data for general cpl fields" + if [[ "${esmf_profile:-.false.}" == ".true." ]]; then + cpfs "${DATA}/ESMF_Profile.summary" "${COMOUT_ATMOS_HISTORY}/ESMF_Profile.summary" fi - fi # if [[ "${RERUN}" == "NO" ]]; then - - # Link output files - case ${RUN} in - gfs|enkfgfs|gefs|sfs|gcafs) # Link output files for RUN=gfs|enkfgfs|gefs|sfs - # Looping over MOM6 output hours - local fhr fhr3 last_fhr interval midpoint vdate vdate_mid source_file dest_file - for fhr in ${MOM6_OUTPUT_FH}; do - fhr3=$(printf %03i "${fhr}") +} - if [[ -z ${last_fhr:-} ]]; then - last_fhr=${fhr} - continue - fi +MOM6_postdet() { + echo "SUB ${FUNCNAME[0]}: MOM6 after run type determination" - (( interval = fhr - last_fhr )) - (( midpoint = last_fhr + interval/2 )) + local restart_dir restart_date + if [[ "${RERUN}" == "YES" ]]; then + restart_dir="${DATArestart}/MOM6_RESTART" + restart_date="${RERUN_DATE}" + else # "${RERUN}" == "NO" + restart_dir="${COMIN_OCEAN_RESTART_PREV}" + restart_date="${model_start_date_current_cycle}" + fi - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) - #If OFFSET_START_HOUR is greater than 0, OFFSET_START_HOUR should be added to the midpoint for first lead time - if (( OFFSET_START_HOUR > 0 )) && (( fhr == FHOUT_OCN ));then - vdate_mid=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + $(( midpoint + OFFSET_START_HOUR )) hours" +%Y%m%d%H) - else - vdate_mid=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${midpoint} hours" +%Y%m%d%H) - fi + # Copy MOM6 ICs + cpreq "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res.nc" "${DATA}/INPUT/MOM.res.nc" + case ${OCNRES} in + "025") + local nn + for ((nn = 1; nn <= 4; nn++)); do + if [[ -f "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res_${nn}.nc" ]]; then + cpreq "${restart_dir}/${restart_date:0:8}.${restart_date:8:2}0000.MOM.res_${nn}.nc" "${DATA}/INPUT/MOM.res_${nn}.nc" + fi + done + ;; + *) ;; + esac - # Native model output uses window midpoint in the filename, but we are mapping that to the end of the period for COM - if (( OFFSET_START_HOUR > 0 )) && (( fhr == FHOUT_OCN ));then - source_file="ocn_lead1_${vdate_mid:0:4}_${vdate_mid:4:2}_${vdate_mid:6:2}_${vdate_mid:8:2}.nc" - else - source_file="ocn_${vdate_mid:0:4}_${vdate_mid:4:2}_${vdate_mid:6:2}_${vdate_mid:8:2}.nc" + # Copy increment (only when RERUN=NO) + if [[ "${RERUN}" == "NO" ]]; then + if [[ "${DO_JEDIOCNVAR:-NO}" == "YES" ]] || [[ ${MEMBER} -gt 0 && "${ODA_INCUPD:-False}" == "True" ]]; then + cpreq "${COMIN_OCEAN_ANALYSIS}/${RUN}.t${cyc}z.mom6_increment.i006.nc" "${DATA}/INPUT/mom6_increment.nc" fi - dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" - ${NLN} "${COMOUT_OCEAN_HISTORY}/${dest_file}" "${DATAoutput}/MOM6_OUTPUT/${source_file}" + fi # if [[ "${RERUN}" == "NO" ]]; then + + # Link output files + case ${RUN} in + gfs | enkfgfs | gefs | sfs | gcafs) # Link output files for RUN=gfs|enkfgfs|gefs|sfs + # Looping over MOM6 output hours + local fhr fhr3 last_fhr interval midpoint vdate vdate_mid source_file dest_file + for fhr in ${MOM6_OUTPUT_FH}; do + fhr3=$(printf %03i "${fhr}") + + if [[ -z ${last_fhr:-} ]]; then + last_fhr=${fhr} + continue + fi + + ((interval = fhr - last_fhr)) + ((midpoint = last_fhr + interval / 2)) + + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) + #If OFFSET_START_HOUR is greater than 0, OFFSET_START_HOUR should be added to the midpoint for first lead time + if ((OFFSET_START_HOUR > 0)) && ((fhr == FHOUT_OCN)); then + vdate_mid=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + $((midpoint + OFFSET_START_HOUR)) hours" +%Y%m%d%H) + else + vdate_mid=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${midpoint} hours" +%Y%m%d%H) + fi + + # Native model output uses window midpoint in the filename, but we are mapping that to the end of the period for COM + if ((OFFSET_START_HOUR > 0)) && ((fhr == FHOUT_OCN)); then + source_file="ocn_lead1_${vdate_mid:0:4}_${vdate_mid:4:2}_${vdate_mid:6:2}_${vdate_mid:8:2}.nc" + else + source_file="ocn_${vdate_mid:0:4}_${vdate_mid:4:2}_${vdate_mid:6:2}_${vdate_mid:8:2}.nc" + fi + dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" + ${NLN} "${COMOUT_OCEAN_HISTORY}/${dest_file}" "${DATAoutput}/MOM6_OUTPUT/${source_file}" + + last_fhr=${fhr} - last_fhr=${fhr} - - done - ;; + done + ;; + + gdas | enkfgdas) # Link output files for RUN=gdas|enkfgdas + # Save (instantaneous) MOM6 backgrounds + local fhr3 vdatestr + for fhr in ${MOM6_OUTPUT_FH}; do + fhr3=$(printf %03i "${fhr}") + vdatestr=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y_%m_%d_%H) + ${NLN} "${COMOUT_OCEAN_HISTORY}/${RUN}.t${cyc}z.inst.f${fhr3}.nc" "${DATAoutput}/MOM6_OUTPUT/ocn_da_${vdatestr}.nc" + done + ;; + *) + echo "FATAL ERROR: Don't know how to copy MOM output files for RUN ${RUN}" + exit 25 + ;; + esac - gdas|enkfgdas) # Link output files for RUN=gdas|enkfgdas - # Save (instantaneous) MOM6 backgrounds - local fhr3 vdatestr - for fhr in ${MOM6_OUTPUT_FH}; do - fhr3=$(printf %03i "${fhr}") - vdatestr=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y_%m_%d_%H) - ${NLN} "${COMOUT_OCEAN_HISTORY}/${RUN}.t${cyc}z.inst.f${fhr3}.nc" "${DATAoutput}/MOM6_OUTPUT/ocn_da_${vdatestr}.nc" - done - ;; - *) - echo "FATAL ERROR: Don't know how to copy MOM output files for RUN ${RUN}" - exit 25 - ;; - esac - - echo "SUB ${FUNCNAME[0]}: MOM6 input data linked/copied" + echo "SUB ${FUNCNAME[0]}: MOM6 input data linked/copied" } MOM6_nml() { - echo "SUB ${FUNCNAME[0]}: Creating name list for MOM6" - source "${USHgfs}/parsing_namelists_MOM6.sh" - MOM6_namelists + echo "SUB ${FUNCNAME[0]}: Creating name list for MOM6" + source "${USHgfs}/parsing_namelists_MOM6.sh" + MOM6_namelists } MOM6_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for MOM6" - - # Copy MOM_input from DATA to COMOUT_CONF after the forecast is run (and successfull) - cpfs "${DATA}/INPUT/MOM_input" "${COMOUT_CONF}/ufs.MOM_input" - # Copy runtime configuration of MOM: MOM_parameter_doc.all that was used in the forecast - if [[ -f "${DATA}/MOM6_OUTPUT/MOM_parameter_doc.all" ]]; then - cpfs "${DATA}/MOM6_OUTPUT/MOM_parameter_doc.all" "${COMOUT_CONF}/MOM_parameter_doc.all" - fi - - # Create a list of MOM6 restart files - # Coarser than 1/2 degree has a single MOM restart - local mom6_restart_files mom6_restart_file restart_file - mom6_restart_files=(MOM.res.nc) - # 1/4 degree resolution has 3 additional restarts - case "${OCNRES}" in - "025") - local nn - for (( nn = 1; nn <= 3; nn++ )); do - mom6_restart_files+=("MOM.res_${nn}.nc") - done - ;; - *) ;; - esac - - case ${RUN} in - gdas|enkfgdas|enkfgfs) # Copy restarts for the next cycle for RUN=gdas|enkfgdas|enkfgfs - local restart_date - restart_date="${model_start_date_next_cycle}" - echo "Copying MOM6 restarts for 'RUN=${RUN}' at ${restart_date}" - for mom6_restart_file in "${mom6_restart_files[@]}"; do - restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${mom6_restart_file}" - cpfs "${DATArestart}/MOM6_RESTART/${restart_file}" \ - "${COMOUT_OCEAN_RESTART}/${restart_file}" - done - ;; - gfs|gefs|sfs|gcafs) # Copy MOM6 restarts at the end of the forecast segment to COM for RUN=gfs|gefs|sfs - if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then - local restart_file - echo "Copying MOM6 restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" - for mom6_restart_file in "${mom6_restart_files[@]}"; do - restart_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.${mom6_restart_file}" - cpfs "${DATArestart}/MOM6_RESTART/${restart_file}" \ - "${COMOUT_OCEAN_RESTART}/${restart_file}" - done - fi - ;; - *) - echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" - exit 25 - ;; - esac + echo "SUB ${FUNCNAME[0]}: Copying output data for MOM6" + + # Copy MOM_input from DATA to COMOUT_CONF after the forecast is run (and successfull) + cpfs "${DATA}/INPUT/MOM_input" "${COMOUT_CONF}/ufs.MOM_input" + # Copy runtime configuration of MOM: MOM_parameter_doc.all that was used in the forecast + if [[ -f "${DATA}/MOM6_OUTPUT/MOM_parameter_doc.all" ]]; then + cpfs "${DATA}/MOM6_OUTPUT/MOM_parameter_doc.all" "${COMOUT_CONF}/MOM_parameter_doc.all" + fi + + # Create a list of MOM6 restart files + # Coarser than 1/2 degree has a single MOM restart + local mom6_restart_files mom6_restart_file restart_file + mom6_restart_files=(MOM.res.nc) + # 1/4 degree resolution has 3 additional restarts + case "${OCNRES}" in + "025") + local nn + for ((nn = 1; nn <= 3; nn++)); do + mom6_restart_files+=("MOM.res_${nn}.nc") + done + ;; + *) ;; + esac + + case ${RUN} in + gdas | enkfgdas | enkfgfs) # Copy restarts for the next cycle for RUN=gdas|enkfgdas|enkfgfs + local restart_date + restart_date="${model_start_date_next_cycle}" + echo "Copying MOM6 restarts for 'RUN=${RUN}' at ${restart_date}" + for mom6_restart_file in "${mom6_restart_files[@]}"; do + restart_file="${restart_date:0:8}.${restart_date:8:2}0000.${mom6_restart_file}" + cpfs "${DATArestart}/MOM6_RESTART/${restart_file}" \ + "${COMOUT_OCEAN_RESTART}/${restart_file}" + done + ;; + gfs | gefs | sfs | gcafs) # Copy MOM6 restarts at the end of the forecast segment to COM for RUN=gfs|gefs|sfs + if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then + local restart_file + echo "Copying MOM6 restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" + for mom6_restart_file in "${mom6_restart_files[@]}"; do + restart_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.${mom6_restart_file}" + cpfs "${DATArestart}/MOM6_RESTART/${restart_file}" \ + "${COMOUT_OCEAN_RESTART}/${restart_file}" + done + fi + ;; + *) + echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" + exit 25 + ;; + esac } CICE_postdet() { - echo "SUB ${FUNCNAME[0]}: CICE after run type determination" - - local restart_date cice_restart_file - if [[ "${RERUN}" == "YES" ]]; then - restart_date="${RERUN_DATE}" - local seconds - seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds - cice_restart_file="${DATArestart}/CICE_RESTART/cice_model.res.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" - else # "${RERUN}" == "NO" - restart_date="${model_start_date_current_cycle}" - cice_restart_file="${COMIN_ICE_RESTART_PREV}/${restart_date:0:8}.${restart_date:8:2}0000.cice_model.res.nc" - if [[ "${DO_JEDIOCNVAR:-NO}" == "YES" ]]; then - if [[ ${MEMBER} -eq 0 ]]; then - # Start the deterministic from the JEDI/SOCA analysis if the Marine DA in ON - cice_restart_file="${COMIN_ICE_ANALYSIS}/${restart_date:0:8}.${restart_date:8:2}0000.analysis.cice_model.res.nc" - elif [[ ${MEMBER} -gt 0 && "${DO_STARTMEM_FROM_JEDIICE:-NO}" == "YES" ]]; then - # Ignore the JEDI/SOCA ensemble analysis for the ensemble members if DO_START_FROM_JEDIICE is OFF - cice_restart_file="${COMIN_ICE_ANALYSIS}/${restart_date:0:8}.${restart_date:8:2}0000.analysis.cice_model.res.nc" - fi + echo "SUB ${FUNCNAME[0]}: CICE after run type determination" + + local restart_date cice_restart_file + if [[ "${RERUN}" == "YES" ]]; then + restart_date="${RERUN_DATE}" + local seconds + seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds + cice_restart_file="${DATArestart}/CICE_RESTART/cice_model.res.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" + else # "${RERUN}" == "NO" + restart_date="${model_start_date_current_cycle}" + cice_restart_file="${COMIN_ICE_RESTART_PREV}/${restart_date:0:8}.${restart_date:8:2}0000.cice_model.res.nc" + if [[ "${DO_JEDIOCNVAR:-NO}" == "YES" ]]; then + if [[ "${MEMBER}" -eq 0 ]]; then + # Start the deterministic from the JEDI/SOCA analysis if the Marine DA in ON + cice_restart_file="${COMIN_ICE_ANALYSIS}/${restart_date:0:8}.${restart_date:8:2}0000.analysis.cice_model.res.nc" + elif [[ "${MEMBER}" -gt 0 ]] && [[ "${DO_STARTMEM_FROM_JEDIICE:-NO}" == "YES" ]]; then + # Ignore the JEDI/SOCA ensemble analysis for the ensemble members if DO_START_FROM_JEDIICE is OFF + cice_restart_file="${COMIN_ICE_ANALYSIS}/${restart_date:0:8}.${restart_date:8:2}0000.analysis.cice_model.res.nc" + fi + fi fi - fi - # Copy CICE ICs - cpreq "${cice_restart_file}" "${DATA}/cice_model.res.nc" + # Copy CICE ICs + cpreq "${cice_restart_file}" "${DATA}/cice_model.res.nc" - # Link iceh_ic file to COM. This is the initial condition file from CICE (f000) - # TODO: Is this file needed in COM? Is this going to be used for generating any products? - local vdate seconds vdatestr fhr fhr3 interval last_fhr - seconds=$(to_seconds "${model_start_date_current_cycle:8:2}0000") # convert HHMMSS to seconds - vdatestr="${model_start_date_current_cycle:0:4}-${model_start_date_current_cycle:4:2}-${model_start_date_current_cycle:6:2}-${seconds}" - ${NLN} "${COMOUT_ICE_HISTORY}/${RUN}.t${cyc}z.ic.nc" "${DATAoutput}/CICE_OUTPUT/iceh_ic.${vdatestr}.nc" + # Link iceh_ic file to COM. This is the initial condition file from CICE (f000) + # TODO: Is this file needed in COM? Is this going to be used for generating any products? + local vdate seconds vdatestr fhr fhr3 interval last_fhr + seconds=$(to_seconds "${model_start_date_current_cycle:8:2}0000") # convert HHMMSS to seconds + vdatestr="${model_start_date_current_cycle:0:4}-${model_start_date_current_cycle:4:2}-${model_start_date_current_cycle:6:2}-${seconds}" + ${NLN} "${COMOUT_ICE_HISTORY}/${RUN}.t${cyc}z.ic.nc" "${DATAoutput}/CICE_OUTPUT/iceh_ic.${vdatestr}.nc" - # Link CICE forecast output files from DATAoutput/CICE_OUTPUT to COM - local source_file dest_file - for fhr in "${CICE_OUTPUT_FH[@]}"; do + # Link CICE forecast output files from DATAoutput/CICE_OUTPUT to COM + local source_file dest_file + for fhr in "${CICE_OUTPUT_FH[@]}"; do - if [[ -z ${last_fhr:-} ]]; then - last_fhr=${fhr} - continue - fi + if [[ -z ${last_fhr:-} ]]; then + last_fhr=${fhr} + continue + fi - fhr3=$(printf %03i "${fhr}") - (( interval = fhr - last_fhr )) - - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) - seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds - vdatestr="${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}" - - case "${RUN}" in - gdas|enkfgdas) - source_file="iceh_inst.${vdatestr}.nc" - dest_file="${RUN}.t${cyc}z.inst.f${fhr3}.nc" - ;; - gfs|enkfgfs|sfs|gcafs) - source_file="iceh_$(printf "%0.2d" "${FHOUT_ICE}")h.${vdatestr}.nc" - dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" - ;; - gefs) - source_file="iceh.${vdatestr}.nc" - dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" - ;; - *) - echo "FATAL ERROR: Unsupported RUN ${RUN} in CICE postdet" - exit 10 - esac + fhr3=$(printf %03i "${fhr}") + ((interval = fhr - last_fhr)) - ${NLN} "${COMOUT_ICE_HISTORY}/${dest_file}" "${DATAoutput}/CICE_OUTPUT/${source_file}" + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) + seconds=$(to_seconds "${vdate:8:2}0000") # convert HHMMSS to seconds + vdatestr="${vdate:0:4}-${vdate:4:2}-${vdate:6:2}-${seconds}" + + case "${RUN}" in + gdas | enkfgdas) + source_file="iceh_inst.${vdatestr}.nc" + dest_file="${RUN}.t${cyc}z.inst.f${fhr3}.nc" + ;; + gfs | enkfgfs | sfs | gcafs) + source_file="iceh_$(printf "%0.2d" "${FHOUT_ICE}")h.${vdatestr}.nc" + dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" + ;; + gefs) + source_file="iceh.${vdatestr}.nc" + dest_file="${RUN}.t${cyc}z.${interval}hr_avg.f${fhr3}.nc" + ;; + *) + echo "FATAL ERROR: Unsupported RUN ${RUN} in CICE postdet" + exit 10 + ;; + esac + + ${NLN} "${COMOUT_ICE_HISTORY}/${dest_file}" "${DATAoutput}/CICE_OUTPUT/${source_file}" - last_fhr=${fhr} - done + last_fhr=${fhr} + done } CICE_nml() { - echo "SUB ${FUNCNAME[0]}: Creating name list for CICE" - source "${USHgfs}/parsing_namelists_CICE.sh" - CICE_namelists + echo "SUB ${FUNCNAME[0]}: Creating name list for CICE" + source "${USHgfs}/parsing_namelists_CICE.sh" + CICE_namelists } CICE_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for CICE" - - # Copy ice_in namelist from DATA to COMOUT_CONF after the forecast is run (and successfull) - cpfs "${DATA}/ice_in" "${COMOUT_CONF}/ufs.ice_in" - - case ${RUN} in - gdas|enkfgdas|enkfgfs) # Copy restarts for next cycle for RUN=gdas|enkfgdas|enkfgfs - local restart_date - restart_date="${model_start_date_next_cycle}" - echo "Copying CICE restarts for 'RUN=${RUN}' at ${restart_date}" - seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds - source_file="cice_model.res.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" - target_file="${restart_date:0:8}.${restart_date:8:2}0000.cice_model.res.nc" - cpfs "${DATArestart}/CICE_RESTART/${source_file}" \ - "${COMOUT_ICE_RESTART}/${target_file}" - ;; - gfs|gefs|sfs|gcafs) # Copy CICE restarts at the end of the forecast segment to COM for RUN=gfs|gefs|sfs|gcafs - if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then - local seconds source_file target_file - echo "Copying CICE restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" - seconds=$(to_seconds "${forecast_end_cycle:8:2}0000") # convert HHMMSS to seconds - source_file="cice_model.res.${forecast_end_cycle:0:4}-${forecast_end_cycle:4:2}-${forecast_end_cycle:6:2}-${seconds}.nc" - target_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.cice_model.res.nc" - cpfs "${DATArestart}/CICE_RESTART/${source_file}" \ - "${COMOUT_ICE_RESTART}/${target_file}" - fi - ;; - *) - echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" - exit 25 - ;; - esac + echo "SUB ${FUNCNAME[0]}: Copying output data for CICE" + + # Copy ice_in namelist from DATA to COMOUT_CONF after the forecast is run (and successfull) + cpfs "${DATA}/ice_in" "${COMOUT_CONF}/ufs.ice_in" + + case ${RUN} in + gdas | enkfgdas | enkfgfs) # Copy restarts for next cycle for RUN=gdas|enkfgdas|enkfgfs + local restart_date + restart_date="${model_start_date_next_cycle}" + echo "Copying CICE restarts for 'RUN=${RUN}' at ${restart_date}" + seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds + source_file="cice_model.res.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" + target_file="${restart_date:0:8}.${restart_date:8:2}0000.cice_model.res.nc" + cpfs "${DATArestart}/CICE_RESTART/${source_file}" \ + "${COMOUT_ICE_RESTART}/${target_file}" + ;; + gfs | gefs | sfs | gcafs) # Copy CICE restarts at the end of the forecast segment to COM for RUN=gfs|gefs|sfs|gcafs + if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then + local seconds source_file target_file + echo "Copying CICE restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" + seconds=$(to_seconds "${forecast_end_cycle:8:2}0000") # convert HHMMSS to seconds + source_file="cice_model.res.${forecast_end_cycle:0:4}-${forecast_end_cycle:4:2}-${forecast_end_cycle:6:2}-${seconds}.nc" + target_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.cice_model.res.nc" + cpfs "${DATArestart}/CICE_RESTART/${source_file}" \ + "${COMOUT_ICE_RESTART}/${target_file}" + fi + ;; + *) + echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" + exit 25 + ;; + esac } GOCART_rc() { - echo "SUB ${FUNCNAME[0]}: Linking input data and copying config files for GOCART" - # set input directory containing GOCART input data and configuration files - # this variable is platform-dependent and should be set via a YAML file - - # link directory containing GOCART input dataset, if provided - if [[ -n "${AERO_INPUTS_DIR}" ]]; then - ${NLN} "${AERO_INPUTS_DIR}" "${DATA}/ExtData" - status=$? - if [[ ${status} -ne 0 ]]; then - exit "${status}" + echo "SUB ${FUNCNAME[0]}: Linking input data and copying config files for GOCART" + # set input directory containing GOCART input data and configuration files + # this variable is platform-dependent and should be set via a YAML file + + # link directory containing GOCART input dataset, if provided + if [[ -n "${AERO_INPUTS_DIR}" ]]; then + ${NLN} "${AERO_INPUTS_DIR}" "${DATA}/ExtData" + status=$? + if [[ ${status} -ne 0 ]]; then + exit "${status}" + fi fi - fi - source "${USHgfs}/parsing_namelists_GOCART.sh" - GOCART_namelists + source "${USHgfs}/parsing_namelists_GOCART.sh" + GOCART_namelists } GOCART_postdet() { - echo "SUB ${FUNCNAME[0]}: Linking output data for GOCART" - - local vdate - for fhr in $(GOCART_output_fh); do - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) - - # Temporarily delete existing files due to noclobber in GOCART - local file_types=("inst_aod" "inst_du_ss" "inst_ca" "inst_ni" "inst_su" \ - "inst_du_bin" "inst_ss_bin" "inst_ca_bin" "inst_ni_bin" "inst_su_bin" \ - "inst_2d" "inst_3d" "tavg_du_ss" "tavg_du_bin" "tavg_2d_rad" "tavg_3d_rad") - for file_type in "${file_types[@]}"; do - if [[ -e "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" ]]; then - rm -f "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" - fi - done + echo "SUB ${FUNCNAME[0]}: Linking output data for GOCART" - #TODO: Temporarily removing this as this will crash gocart, adding copy statement at the end - #${NLN} "${COMOUT_CHEM_HISTORY}/gocart.inst_aod.${vdate:0:8}_${vdate:8:2}00z.nc4" \ - # "${DATA}/gocart.inst_aod.${vdate:0:8}_${vdate:8:2}00z.nc4" - done + local vdate + for fhr in $(GOCART_output_fh); do + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) + + # Temporarily delete existing files due to noclobber in GOCART + local file_types=("inst_aod" "inst_du_ss" "inst_ca" "inst_ni" "inst_su" + "inst_du_bin" "inst_ss_bin" "inst_ca_bin" "inst_ni_bin" "inst_su_bin" + "inst_2d" "inst_3d" "tavg_du_ss" "tavg_du_bin" "tavg_2d_rad" "tavg_3d_rad") + for file_type in "${file_types[@]}"; do + if [[ -e "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" ]]; then + rm -f "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" + fi + done + + #TODO: Temporarily removing this as this will crash gocart, adding copy statement at the end + #${NLN} "${COMOUT_CHEM_HISTORY}/gocart.inst_aod.${vdate:0:8}_${vdate:8:2}00z.nc4" \ + # "${DATA}/gocart.inst_aod.${vdate:0:8}_${vdate:8:2}00z.nc4" + done } GOCART_output_fh() { - # This has to be called during postdet after FHROT has been set - local aero_min - local gocart_output_fh - # GOCART produces no AOD files at the initial forecast time, so start the time - # after the forecast start (accounting for FHROT) - aero_min=$(( ${IAU_FHROT:-0} > FHMIN ? IAU_FHROT + FHOUT_AERO : FHMIN + FHOUT_AERO )) - gocart_output_fh=$(seq -s ' ' "$(( aero_min ))" "${FHOUT_AERO}" "${GOCART_MAX}") - - echo "${gocart_output_fh}" + # This has to be called during postdet after FHROT has been set + local aero_min + local gocart_output_fh + # GOCART produces no AOD files at the initial forecast time, so start the time + # after the forecast start (accounting for FHROT) + aero_min=$((${IAU_FHROT:-0} > FHMIN ? IAU_FHROT + FHOUT_AERO : FHMIN + FHOUT_AERO)) + gocart_output_fh=$(seq -s ' ' "$((aero_min))" "${FHOUT_AERO}" "${GOCART_MAX}") + + echo "${gocart_output_fh}" } GOCART_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for GOCART" - - # Copy gocart.inst_aod after the forecast is run (and successfull) - # TODO: this should be linked but there are issues where gocart crashing if it is linked - local fhr - local vdate - - local file_types=("inst_aod" "inst_du_ss" "inst_ca" "inst_ni" "inst_su" \ - "inst_du_bin" "inst_ss_bin" "inst_ca_bin" "inst_ni_bin" "inst_su_bin" \ - "inst_2d" "inst_3d" "tavg_du_ss" "tavg_du_bin" "tavg_2d_rad" "tavg_3d_rad") - - for fhr in $(GOCART_output_fh); do - vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) - for file_type in "${file_types[@]}"; do - if [[ -e "${DATA}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" ]]; then - cpfs "${DATA}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" \ - "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" - fi + echo "SUB ${FUNCNAME[0]}: Copying output data for GOCART" + + # Copy gocart.inst_aod after the forecast is run (and successfull) + # TODO: this should be linked but there are issues where gocart crashing if it is linked + local fhr + local vdate + + local file_types=("inst_aod" "inst_du_ss" "inst_ca" "inst_ni" "inst_su" + "inst_du_bin" "inst_ss_bin" "inst_ca_bin" "inst_ni_bin" "inst_su_bin" + "inst_2d" "inst_3d" "tavg_du_ss" "tavg_du_bin" "tavg_2d_rad" "tavg_3d_rad") + + for fhr in $(GOCART_output_fh); do + vdate=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${fhr} hours" +%Y%m%d%H) + for file_type in "${file_types[@]}"; do + if [[ -e "${DATA}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" ]]; then + cpfs "${DATA}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" \ + "${COMOUT_CHEM_HISTORY}/gocart.${file_type}.${vdate:0:8}_${vdate:8:2}00z.nc4" + fi + done done - done } # shellcheck disable=SC2178 CMEPS_postdet() { - echo "SUB ${FUNCNAME[0]}: Linking output data for CMEPS mediator" - - if [[ "${warm_start}" == ".true." ]]; then - - # Determine the appropriate restart file - local restart_date cmeps_restart_file - if [[ "${RERUN}" == "YES" ]]; then - restart_date="${RERUN_DATE}" - local seconds - seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds - cmeps_restart_file="${DATArestart}/CMEPS_RESTART/ufs.cpld.cpl.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" - else # "${RERUN}" == "NO" - restart_date="${model_start_date_current_cycle}" - cmeps_restart_file="${COMIN_MED_RESTART_PREV}/${restart_date:0:8}.${restart_date:8:2}0000.ufs.cpld.cpl.r.nc" - fi - - # Copy CMEPS restarts - if [[ -f "${cmeps_restart_file}" ]]; then - cpreq "${cmeps_restart_file}" "${DATA}/ufs.cpld.cpl.r.nc" - rm -f "${DATA}/rpointer.cpl" - touch "${DATA}/rpointer.cpl" - echo "ufs.cpld.cpl.r.nc" >> "${DATA}/rpointer.cpl" - else - # We have a choice to make here. - # Either we can FATAL ERROR out, or we can let the coupling fields initialize from zero - # cmeps_run_type is determined based on the availability of the CMEPS restart file - echo "WARNING: CMEPS restart file '${cmeps_restart_file}' not found for warm_start='${warm_start}', will initialize!" - if [[ "${RERUN}" == "YES" ]]; then - # In the case of a RERUN, the CMEPS restart file is required - echo "FATAL ERROR: CMEPS restart file '${cmeps_restart_file}' not found for RERUN='${RERUN}', ABORT!" - exit 1 - fi - fi + echo "SUB ${FUNCNAME[0]}: Linking output data for CMEPS mediator" + + if [[ "${warm_start}" == ".true." ]]; then + + # Determine the appropriate restart file + local restart_date cmeps_restart_file + if [[ "${RERUN}" == "YES" ]]; then + restart_date="${RERUN_DATE}" + local seconds + seconds=$(to_seconds "${restart_date:8:2}0000") # convert HHMMSS to seconds + cmeps_restart_file="${DATArestart}/CMEPS_RESTART/ufs.cpld.cpl.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" + else # "${RERUN}" == "NO" + restart_date="${model_start_date_current_cycle}" + cmeps_restart_file="${COMIN_MED_RESTART_PREV}/${restart_date:0:8}.${restart_date:8:2}0000.ufs.cpld.cpl.r.nc" + fi - fi # [[ "${warm_start}" == ".true." ]]; + # Copy CMEPS restarts + if [[ -f "${cmeps_restart_file}" ]]; then + cpreq "${cmeps_restart_file}" "${DATA}/ufs.cpld.cpl.r.nc" + rm -f "${DATA}/rpointer.cpl" + touch "${DATA}/rpointer.cpl" + echo "ufs.cpld.cpl.r.nc" >> "${DATA}/rpointer.cpl" + else + # We have a choice to make here. + # Either we can FATAL ERROR out, or we can let the coupling fields initialize from zero + # cmeps_run_type is determined based on the availability of the CMEPS restart file + echo "WARNING: CMEPS restart file '${cmeps_restart_file}' not found for warm_start='${warm_start}', will initialize!" + if [[ "${RERUN}" == "YES" ]]; then + # In the case of a RERUN, the CMEPS restart file is required + echo "FATAL ERROR: CMEPS restart file '${cmeps_restart_file}' not found for RERUN='${RERUN}', ABORT!" + exit 1 + fi + fi - # For CMEPS, CICE, MOM6 and WW3 determine restart writes - # Note FV3 has its own restart intervals - cmeps_restart_interval=${restart_interval:-${FHMAX}} - # restart_interval = 0 implies write restart at the END of the forecast i.e. at FHMAX - # Convert restart interval into an explicit list for CMEPS/CICE/MOM6/WW3 - # Note, this must be computed after determination IAU in forecast_det and fhrot. - if (( cmeps_restart_interval == 0 )); then - if [[ "${DOIAU:-NO}" == "YES" ]]; then - CMEPS_RESTART_FH=$(( FHMAX + half_window )) - else - CMEPS_RESTART_FH=("${FHMAX}") - fi - else - if [[ "${DOIAU:-NO}" == "YES" ]]; then - if [[ "${MODE}" = "cycled" && "${SDATE}" = "${PDY}${cyc}" && ${EXP_WARM_START} = ".false." ]]; then - local restart_interval_start=${cmeps_restart_interval} - local restart_interval_end=${FHMAX} - else - local restart_interval_start=$(( cmeps_restart_interval + half_window )) - local restart_interval_end=$(( FHMAX + half_window )) - fi + fi # [[ "${warm_start}" == ".true." ]]; + + # For CMEPS, CICE, MOM6 and WW3 determine restart writes + # Note FV3 has its own restart intervals + cmeps_restart_interval=${restart_interval:-${FHMAX}} + # restart_interval = 0 implies write restart at the END of the forecast i.e. at FHMAX + # Convert restart interval into an explicit list for CMEPS/CICE/MOM6/WW3 + # Note, this must be computed after determination IAU in forecast_det and fhrot. + if ((cmeps_restart_interval == 0)); then + if [[ "${DOIAU:-NO}" == "YES" ]]; then + CMEPS_RESTART_FH=$((FHMAX + half_window)) + else + CMEPS_RESTART_FH=("${FHMAX}") + fi else - local restart_interval_start=${cmeps_restart_interval} - local restart_interval_end=${FHMAX} + if [[ "${DOIAU:-NO}" == "YES" ]]; then + if [[ "${MODE}" = "cycled" && "${SDATE}" = "${PDY}${cyc}" && ${EXP_WARM_START} = ".false." ]]; then + local restart_interval_start=${cmeps_restart_interval} + local restart_interval_end=${FHMAX} + else + local restart_interval_start=$((cmeps_restart_interval + half_window)) + local restart_interval_end=$((FHMAX + half_window)) + fi + else + local restart_interval_start=${cmeps_restart_interval} + local restart_interval_end=${FHMAX} + fi + CMEPS_RESTART_FH="$(seq -s ' ' "${restart_interval_start}" "${cmeps_restart_interval}" "${restart_interval_end}")" fi - CMEPS_RESTART_FH="$(seq -s ' ' "${restart_interval_start}" "${cmeps_restart_interval}" "${restart_interval_end}")" - fi - export CMEPS_RESTART_FH - # TODO: For GEFS, once cycling waves "self-cycles" and therefore needs to have a restart at 6 hour + export CMEPS_RESTART_FH + # TODO: For GEFS, once cycling waves "self-cycles" and therefore needs to have a restart at 6 hour } CMEPS_out() { - echo "SUB ${FUNCNAME[0]}: Copying output data for CMEPS mediator" - - case ${RUN} in - gdas|enkfgdas|enkfgfs) # Copy restarts for the next cycle to COM - local restart_date - restart_date="${model_start_date_next_cycle}" - echo "Copying mediator restarts for 'RUN=${RUN}' at ${restart_date}" - seconds=$(to_seconds "${restart_date:8:2}"0000) - source_file="ufs.cpld.cpl.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" - target_file="${restart_date:0:8}.${restart_date:8:2}0000.ufs.cpld.cpl.r.nc" - if [[ -f "${DATArestart}/CMEPS_RESTART/${source_file}" ]]; then - cpfs "${DATArestart}/CMEPS_RESTART/${source_file}" \ - "${COMOUT_MED_RESTART}/${target_file}" - else - echo "Mediator restart '${DATArestart}/CMEPS_RESTART/${source_file}' not found." - fi - ;; - gfs|gefs|sfs|gcafs) # Copy mediator restarts at the end of the forecast segment - if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then - echo "Copying mediator restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" - local seconds source_file target_file - seconds=$(to_seconds "${forecast_end_cycle:8:2}"0000) - source_file="ufs.cpld.cpl.r.${forecast_end_cycle:0:4}-${forecast_end_cycle:4:2}-${forecast_end_cycle:6:2}-${seconds}.nc" - target_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.ufs.cpld.cpl.r.nc" - if [[ -f "${DATArestart}/CMEPS_RESTART/${source_file}" ]]; then - cpfs "${DATArestart}/CMEPS_RESTART/${source_file}" \ - "${COMOUT_MED_RESTART}/${target_file}" - else - echo "Mediator restart '${DATArestart}/CMEPS_RESTART/${source_file}' not found." - fi - fi - ;; - *) - echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" - exit 25 - ;; - esac + echo "SUB ${FUNCNAME[0]}: Copying output data for CMEPS mediator" + + case ${RUN} in + gdas | enkfgdas | enkfgfs) # Copy restarts for the next cycle to COM + local restart_date + restart_date="${model_start_date_next_cycle}" + echo "Copying mediator restarts for 'RUN=${RUN}' at ${restart_date}" + seconds=$(to_seconds "${restart_date:8:2}"0000) + source_file="ufs.cpld.cpl.r.${restart_date:0:4}-${restart_date:4:2}-${restart_date:6:2}-${seconds}.nc" + target_file="${restart_date:0:8}.${restart_date:8:2}0000.ufs.cpld.cpl.r.nc" + if [[ -f "${DATArestart}/CMEPS_RESTART/${source_file}" ]]; then + cpfs "${DATArestart}/CMEPS_RESTART/${source_file}" \ + "${COMOUT_MED_RESTART}/${target_file}" + else + echo "Mediator restart '${DATArestart}/CMEPS_RESTART/${source_file}' not found." + fi + ;; + gfs | gefs | sfs | gcafs) # Copy mediator restarts at the end of the forecast segment + if [[ "${COPY_FINAL_RESTARTS}" == "YES" ]]; then + echo "Copying mediator restarts for 'RUN=${RUN}' at ${forecast_end_cycle}" + local seconds source_file target_file + seconds=$(to_seconds "${forecast_end_cycle:8:2}"0000) + source_file="ufs.cpld.cpl.r.${forecast_end_cycle:0:4}-${forecast_end_cycle:4:2}-${forecast_end_cycle:6:2}-${seconds}.nc" + target_file="${forecast_end_cycle:0:8}.${forecast_end_cycle:8:2}0000.ufs.cpld.cpl.r.nc" + if [[ -f "${DATArestart}/CMEPS_RESTART/${source_file}" ]]; then + cpfs "${DATArestart}/CMEPS_RESTART/${source_file}" \ + "${COMOUT_MED_RESTART}/${target_file}" + else + echo "Mediator restart '${DATArestart}/CMEPS_RESTART/${source_file}' not found." + fi + fi + ;; + *) + echo "FATAL ERROR: Not sure how to copy restart files for RUN ${RUN}" + exit 25 + ;; + esac } diff --git a/ush/forecast_predet.sh b/ush/forecast_predet.sh index 905ae85b351..3a59f8b7889 100755 --- a/ush/forecast_predet.sh +++ b/ush/forecast_predet.sh @@ -1,757 +1,755 @@ #! /usr/bin/env bash to_seconds() { - # Function to convert HHMMSS to seconds since 00Z - local hhmmss hh mm ss seconds padded_seconds - hhmmss=${1:?} - hh=${hhmmss:0:2} - mm=${hhmmss:2:2} - ss=${hhmmss:4:2} - seconds=$((10#${hh}*3600+10#${mm}*60+10#${ss})) - padded_seconds=$(printf "%05d" "${seconds}") - echo "${padded_seconds}" + # Function to convert HHMMSS to seconds since 00Z + local hhmmss hh mm ss seconds padded_seconds + hhmmss=${1:?} + hh=${hhmmss:0:2} + mm=${hhmmss:2:2} + ss=${hhmmss:4:2} + seconds=$((10#${hh} * 3600 + 10#${mm} * 60 + 10#${ss})) + padded_seconds=$(printf "%05d" "${seconds}") + echo "${padded_seconds}" } -middle_date(){ - # Function to calculate mid-point date in YYYYMMDDHH between two dates also in YYYYMMDDHH - local date1 date2 date1s date2s dtsecsby2 mid_date - date1=${1:?} - date2=${2:?} - date1s=$(date --utc -d "${date1:0:8} ${date1:8:2}:00:00" +%s) - date2s=$(date --utc -d "${date2:0:8} ${date2:8:2}:00:00" +%s) - dtsecsby2=$(( $((date2s - date1s)) / 2 )) - mid_date=$(date --utc -d "${date1:0:8} ${date1:8:2} + ${dtsecsby2} seconds" +%Y%m%d%H%M%S) - echo "${mid_date:0:10}" +middle_date() { + # Function to calculate mid-point date in YYYYMMDDHH between two dates also in YYYYMMDDHH + local date1 date2 date1s date2s dtsecsby2 mid_date + date1=${1:?} + date2=${2:?} + date1s=$(date --utc -d "${date1:0:8} ${date1:8:2}:00:00" +%s) + date2s=$(date --utc -d "${date2:0:8} ${date2:8:2}:00:00" +%s) + dtsecsby2=$(($((date2s - date1s)) / 2)) + mid_date=$(date --utc -d "${date1:0:8} ${date1:8:2} + ${dtsecsby2} seconds" +%Y%m%d%H%M%S) + echo "${mid_date:0:10}" } -nhour(){ - # Function to calculate hours between two dates (This replicates prod-util NHOUR) - local date1 date2 seconds1 seconds2 hours - date1=${1:?} - date2=${2:?} - # Convert dates to UNIX timestamps - seconds1=$(date --utc -d "${date1:0:8} ${date1:8:2}:00:00" +%s) - seconds2=$(date --utc -d "${date2:0:8} ${date2:8:2}:00:00" +%s) - hours=$(( $((seconds1 - seconds2)) / 3600 )) # Calculate the difference in seconds and convert to hours - echo "${hours}" +nhour() { + # Function to calculate hours between two dates (This replicates prod-util NHOUR) + local date1 date2 seconds1 seconds2 hours + date1=${1:?} + date2=${2:?} + # Convert dates to UNIX timestamps + seconds1=$(date --utc -d "${date1:0:8} ${date1:8:2}:00:00" +%s) + seconds2=$(date --utc -d "${date2:0:8} ${date2:8:2}:00:00" +%s) + hours=$(($((seconds1 - seconds2)) / 3600)) # Calculate the difference in seconds and convert to hours + echo "${hours}" } -FV3_coldstarts(){ - # Function to return an comma-separated string of cold-start input files for FV3 - # Create an array of chgres-ed FV3 files - local fv3_input_files tile_files - fv3_input_files=(gfs_ctrl.nc) - tile_files=(gfs_data sfc_data) - local nn tt - for (( nn = 1; nn <= ntiles; nn++ )); do - for tt in "${tile_files[@]}"; do - fv3_input_files+=("${tt}.tile${nn}.nc") +FV3_coldstarts() { + # Function to return an comma-separated string of cold-start input files for FV3 + # Create an array of chgres-ed FV3 files + local fv3_input_files tile_files + fv3_input_files=(gfs_ctrl.nc) + tile_files=(gfs_data sfc_data) + local nn tt + for ((nn = 1; nn <= ntiles; nn++)); do + for tt in "${tile_files[@]}"; do + fv3_input_files+=("${tt}.tile${nn}.nc") + done done - done - # Create a comma separated string from array using IFS - IFS=, echo "${fv3_input_files[*]}" + # Create a comma separated string from array using IFS + IFS=, echo "${fv3_input_files[*]}" } -FV3_restarts(){ - # Function to return an comma-separated string of warm-start input files for FV3 - # Create an array of FV3 restart files - local fv3_restart_files tile_files - fv3_restart_files=(coupler.res fv_core.res.nc) - tile_files=(fv_core.res fv_srf_wnd.res fv_tracer.res phy_data sfc_data) - if [[ ${DO_CA:-"NO"} == "YES" ]]; then - tile_files+=(ca_data) - fi - local nn tt - for (( nn = 1; nn <= ntiles; nn++ )); do - for tt in "${tile_files[@]}"; do - fv3_restart_files+=("${tt}.tile${nn}.nc") +FV3_restarts() { + # Function to return an comma-separated string of warm-start input files for FV3 + # Create an array of FV3 restart files + local fv3_restart_files tile_files + fv3_restart_files=(coupler.res fv_core.res.nc) + tile_files=(fv_core.res fv_srf_wnd.res fv_tracer.res phy_data sfc_data) + if [[ ${DO_CA:-"NO"} == "YES" ]]; then + tile_files+=(ca_data) + fi + local nn tt + for ((nn = 1; nn <= ntiles; nn++)); do + for tt in "${tile_files[@]}"; do + fv3_restart_files+=("${tt}.tile${nn}.nc") + done done - done - # Create a comma separated string from array using IFS - IFS=, echo "${fv3_restart_files[*]}" + # Create a comma separated string from array using IFS + IFS=, echo "${fv3_restart_files[*]}" } -stoch_restarts(){ - # These only get copied for reruns - local stoch_restart_files - stoch_restart_files=( ) +stoch_restarts() { + # These only get copied for reruns + local stoch_restart_files + stoch_restart_files=() - if [[ "${DO_SPPT:-}" == "YES" || "${DO_SKEB:-}" == "YES" || \ + if [[ "${DO_SPPT:-}" == "YES" || "${DO_SKEB:-}" == "YES" || "${DO_SHUM:-}" == "YES" || "${DO_LAND_PERT:-}" == "YES" ]]; then - stoch_restart_files+=(atm_stoch.res.nc) - fi - if [[ "${DO_OCN:-}" == "YES" && ( "${DO_OCN_SPPT:-}" == "YES" || "${DO_OCN_PERT_EPBL}" == "YES" ) ]]; then - stoch_restart_files+=(ocn_stoch.res.nc) - fi - # Create a comma separated string from array using IFS - IFS=, echo "${stoch_restart_files[*]}" + stoch_restart_files+=(atm_stoch.res.nc) + fi + if [[ "${DO_OCN:-}" == "YES" && ("${DO_OCN_SPPT:-}" == "YES" || "${DO_OCN_PERT_EPBL}" == "YES") ]]; then + stoch_restart_files+=(ocn_stoch.res.nc) + fi + # Create a comma separated string from array using IFS + IFS=, echo "${stoch_restart_files[*]}" } # shellcheck disable=SC2034 -common_predet(){ - echo "SUB ${FUNCNAME[0]}: Defining variables for shared through model components" - - RUN=${RUN:-gdas} - rCDUMP=${rCDUMP:-${RUN}} - - ENSMEM=${ENSMEM:-000} - MEMBER=$(( 10#${ENSMEM:-"-1"} )) # -1: control, 0: ensemble mean, >0: ensemble member $MEMBER - - # Define significant cycles - half_window=$(( assim_freq / 2 )) - current_cycle="${PDY}${cyc}" - previous_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} - ${assim_freq} hours" +%Y%m%d%H) - next_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${assim_freq} hours" +%Y%m%d%H) - current_cycle_begin=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} - ${half_window} hours" +%Y%m%d%H) - current_cycle_end=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${half_window} hours" +%Y%m%d%H) - next_cycle_begin=$(date --utc -d "${next_cycle:0:8} ${next_cycle:8:2} - ${half_window} hours" +%Y%m%d%H) - forecast_end_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${FHMAX} hours" +%Y%m%d%H) - - # Define model start date for current_cycle and next_cycle as the time the forecast will start - if [[ "${DOIAU:-NO}" == "YES" ]]; then - model_start_date_current_cycle="${current_cycle_begin}" - model_start_date_next_cycle="${next_cycle_begin}" - else - model_start_date_current_cycle=${current_cycle} - if [[ "${DO_AERO_ANL:-NO}" == "YES" ]]; then - # even without IAU we want 3-hourly restarts for FGAT - model_start_date_next_cycle="${next_cycle_begin}" +common_predet() { + echo "SUB ${FUNCNAME[0]}: Defining variables for shared through model components" + + RUN=${RUN:-gdas} + rCDUMP=${rCDUMP:-${RUN}} + + ENSMEM=${ENSMEM:-000} + MEMBER=$((10#${ENSMEM:-"-1"})) # -1: control, 0: ensemble mean, >0: ensemble member $MEMBER + + # Define significant cycles + half_window=$((assim_freq / 2)) + current_cycle="${PDY}${cyc}" + previous_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} - ${assim_freq} hours" +%Y%m%d%H) + next_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${assim_freq} hours" +%Y%m%d%H) + current_cycle_begin=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} - ${half_window} hours" +%Y%m%d%H) + current_cycle_end=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${half_window} hours" +%Y%m%d%H) + next_cycle_begin=$(date --utc -d "${next_cycle:0:8} ${next_cycle:8:2} - ${half_window} hours" +%Y%m%d%H) + forecast_end_cycle=$(date --utc -d "${current_cycle:0:8} ${current_cycle:8:2} + ${FHMAX} hours" +%Y%m%d%H) + + # Define model start date for current_cycle and next_cycle as the time the forecast will start + if [[ "${DOIAU:-NO}" == "YES" ]]; then + model_start_date_current_cycle="${current_cycle_begin}" + model_start_date_next_cycle="${next_cycle_begin}" else - model_start_date_next_cycle=${next_cycle} + model_start_date_current_cycle=${current_cycle} + if [[ "${DO_AERO_ANL:-NO}" == "YES" ]]; then + # even without IAU we want 3-hourly restarts for FGAT + model_start_date_next_cycle="${next_cycle_begin}" + else + model_start_date_next_cycle=${next_cycle} + fi fi - fi - FHMIN=${FHMIN:-0} - FHMAX=${FHMAX:-9} - FHOUT=${FHOUT:-3} - FHMAX_HF=${FHMAX_HF:-0} - FHOUT_HF=${FHOUT_HF:-1} + FHMIN=${FHMIN:-0} + FHMAX=${FHMAX:-9} + FHOUT=${FHOUT:-3} + FHMAX_HF=${FHMAX_HF:-0} + FHOUT_HF=${FHOUT_HF:-1} - if [[ ! -d "${COMOUT_CONF}" ]]; then mkdir -p "${COMOUT_CONF}"; fi + mkdir -p "${COMOUT_CONF}" - cd "${DATA}" && true - err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Unable to 'cd ${DATA}', ABORT!" - exit 1 - fi + cd "${DATA}" && true + err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: Unable to 'cd ${DATA}', ABORT!" + exit 1 + fi - # Several model components share DATA/INPUT for input data - if [[ ! -d "${DATA}/INPUT" ]]; then mkdir -p "${DATA}/INPUT"; fi + # Several model components share DATA/INPUT for input data + mkdir -p "${DATA}/INPUT" } # shellcheck disable=SC2034 -FV3_predet(){ - echo "SUB ${FUNCNAME[0]}: Defining variables for FV3" - - if [[ ! -d "${COMOUT_ATMOS_HISTORY}" ]]; then mkdir -p "${COMOUT_ATMOS_HISTORY}"; fi - if [[ ! -d "${COMOUT_ATMOS_MASTER}" ]]; then mkdir -p "${COMOUT_ATMOS_MASTER}"; fi - if [[ ! -d "${COMOUT_ATMOS_RESTART}" ]]; then mkdir -p "${COMOUT_ATMOS_RESTART}"; fi - if [[ ! -d "${DATAoutput}/FV3ATM_OUTPUT" ]]; then mkdir -p "${DATAoutput}/FV3ATM_OUTPUT"; fi - if [[ ! -d "${DATArestart}/FV3_RESTART" ]]; then mkdir -p "${DATArestart}/FV3_RESTART"; fi - - # The $DATA/RESTART directory is used for writing FV3 restart files (it is hard-wired in the model) - # Link the output and restart directories to the DATA directory - ${NLN} "${DATAoutput}/FV3ATM_OUTPUT" "${DATA}/FV3ATM_OUTPUT" - ${NLN} "${DATArestart}/FV3_RESTART" "${DATA}/RESTART" - - FHZERO=${FHZERO:-6} - FHCYC=${FHCYC:-24} - - # Convert output settings into an explicit list for FV3 - # Create an FV3 fhr list to be used in the filenames - FV3_OUTPUT_FH="" - local fhr=${FHMIN} - if (( FHOUT_HF > 0 && FHMAX_HF > 0 )); then - FV3_OUTPUT_FH="${FV3_OUTPUT_FH} $(seq -s ' ' "${FHMIN}" "${FHOUT_HF}" "${FHMAX_HF}")" - fhr=${FHMAX_HF} - fi - FV3_OUTPUT_FH="${FV3_OUTPUT_FH} $(seq -s ' ' "${fhr}" "${FHOUT}" "${FHMAX}")" - - # If, FHOUT_HF == FHOUT, the FV3_OUTPUT_FH_NML can be cast as: - if [[ ${FHOUT_HF} -eq ${FHOUT} ]]; then - FV3_OUTPUT_FH_NML="${FHOUT} -1" - else - FV3_OUTPUT_FH_NML="${FV3_OUTPUT_FH}" - fi - - # IAU options - IAUFHRS=${IAUFHRS:-0} - IAU_DELTHRS=${IAU_DELTHRS:-0} - - #------------------------------------------------------------------ - # changeable parameters - # dycore definitions - res="${CASE:1}" - resh="${CASE_HIST:1}" - resp=$((res+1)) - npx=${resp} - npy=${resp} - npz=$((LEVS-1)) - io_layout="1,1" - #ncols=$(( (${npx}-1)*(${npy}-1)*3/2 )) - - # spectral truncation and regular grid resolution based on FV3 resolution - JCAP_CASE=$((2*res-2)) - LONB_CASE=$((4*res)) - LATB_CASE=$((2*res)) - - JCAP_CASE_HIST=$((2*resh-2)) - LONB_CASE_HIST=$((4*resh)) - LATB_CASE_HIST=$((2*resh)) - - JCAP=${JCAP:-${JCAP_CASE}} - LONB=${LONB:-${LONB_CASE}} - LATB=${LATB:-${LATB_CASE}} - - LONB_IMO=${LONB_IMO:-${LONB_CASE_HIST}} - LATB_JMO=${LATB_JMO:-${LATB_CASE_HIST}} - - # NSST Options - # nstf_name contains the NSST related parameters - # nstf_name(1) : NST_MODEL (NSST Model) : 0 = OFF, 1 = ON but uncoupled, 2 = ON and coupled - # nstf_name(2) : NST_SPINUP : 0 = OFF, 1 = ON, - # nstf_name(3) : NST_RESV (Reserved, NSST Analysis) : 0 = OFF, 1 = ON - # nstf_name(4) : ZSEA1 (in mm) : 0 - # nstf_name(5) : ZSEA2 (in mm) : 0 - # nst_anl : .true. or .false., NSST analysis over lake - NST_MODEL=${NST_MODEL:-0} - NST_SPINUP=${NST_SPINUP:-0} - NST_RESV=${NST_RESV-0} - ZSEA1=${ZSEA1:-0} - ZSEA2=${ZSEA2:-0} - nstf_name=${nstf_name:-"${NST_MODEL},${NST_SPINUP},${NST_RESV},${ZSEA1},${ZSEA2}"} - nst_anl=${nst_anl:-".false."} - - # blocking factor used for threading and general physics performance - #nyblocks=$(expr \( $npy - 1 \) \/ $layout_y ) - #nxblocks=$(expr \( $npx - 1 \) \/ $layout_x \/ 32) - #if [ $nxblocks -le 0 ]; then nxblocks=1 ; fi - blocksize=${blocksize:-32} - - # variables for controlling initialization of NCEP/NGGPS ICs - filtered_terrain=${filtered_terrain:-".true."} - gfs_dwinds=${gfs_dwinds:-".true."} - - # various debug options - no_dycore=${no_dycore:-".false."} - dycore_only=${adiabatic:-".false."} - chksum_debug=${chksum_debug:-".false."} - print_freq=${print_freq:-6} - - # the pre-conditioning of the solution - # =0 implies no pre-conditioning - # >0 means new adiabatic pre-conditioning - # <0 means older adiabatic pre-conditioning - na_init=${na_init:-1} - - local suite_file="${HOMEgfs}/sorc/ufs_model.fd/UFSATM/ccpp/suites/suite_${CCPP_SUITE}.xml" - if [[ ! -f "${suite_file}" ]]; then - echo "FATAL ERROR: CCPP Suite file ${suite_file} does not exist, ABORT!" - exit 2 - fi - - # Scan suite file to determine whether it uses Noah-MP - local num_noahmpdrv - num_noahmpdrv=$(grep -c noahmpdrv "${suite_file}") - if (( num_noahmpdrv > 0 )); then - lsm="2" - lheatstrg=".false." - landice=".false." - iopt_dveg=${iopt_dveg:-"4"} - iopt_crs=${iopt_crs:-"2"} - iopt_btr=${iopt_btr:-"1"} - iopt_run=${iopt_run:-"1"} - iopt_sfc=${iopt_sfc:-"1"} - iopt_frz=${iopt_frz:-"1"} - iopt_inf=${iopt_inf:-"1"} - iopt_rad=${iopt_rad:-"3"} - iopt_alb=${iopt_alb:-"1"} - iopt_snf=${iopt_snf:-"4"} - iopt_tbot=${iopt_tbot:-"2"} - iopt_stc=${iopt_stc:-"3"} - IALB=${IALB:-2} - IEMS=${IEMS:-2} - else - lsm="1" - lheatstrg=".true." - landice=".true." - iopt_dveg=${iopt_dveg:-"1"} - iopt_crs=${iopt_crs:-"1"} - iopt_btr=${iopt_btr:-"1"} - iopt_run=${iopt_run:-"1"} - iopt_sfc=${iopt_sfc:-"1"} - iopt_frz=${iopt_frz:-"1"} - iopt_inf=${iopt_inf:-"1"} - iopt_rad=${iopt_rad:-"1"} - iopt_alb=${iopt_alb:-"2"} - iopt_snf=${iopt_snf:-"4"} - iopt_tbot=${iopt_tbot:-"2"} - iopt_stc=${iopt_stc:-"1"} - IALB=${IALB:-1} - IEMS=${IEMS:-1} - fi - - if [[ "${TYPE}" == "nh" ]]; then # non-hydrostatic options - hydrostatic=".false." - phys_hydrostatic=".false." # enable heating in hydrostatic balance in non-hydrostatic simulation - use_hydro_pressure=".false." # use hydrostatic pressure for physics - make_nh=".true." # running in non-hydrostatic mode - pass_full_omega_to_physics_in_non_hydrostatic_mode=".true." - else # hydrostatic options - hydrostatic=".true." - phys_hydrostatic=".false." # ignored when hydrostatic = T - use_hydro_pressure=".false." # ignored when hydrostatic = T - make_nh=".false." # running in hydrostatic mode - fi - - # Conserve total energy as heat globally - consv_te=${consv_te:-1.} # range 0.-1., 1. will restore energy to orig. val. before physics - if [[ "${DO_NEST:-NO}" == "YES" ]] ; then - consv_te=0 - k_split=${k_split:-1} - k_split_nest=${k_split_nest:-4} - else +FV3_predet() { + echo "SUB ${FUNCNAME[0]}: Defining variables for FV3" + + if [[ ! -d "${COMOUT_ATMOS_HISTORY}" ]]; then mkdir -p "${COMOUT_ATMOS_HISTORY}"; fi + if [[ ! -d "${COMOUT_ATMOS_MASTER}" ]]; then mkdir -p "${COMOUT_ATMOS_MASTER}"; fi + if [[ ! -d "${COMOUT_ATMOS_RESTART}" ]]; then mkdir -p "${COMOUT_ATMOS_RESTART}"; fi + if [[ ! -d "${DATAoutput}/FV3ATM_OUTPUT" ]]; then mkdir -p "${DATAoutput}/FV3ATM_OUTPUT"; fi + if [[ ! -d "${DATArestart}/FV3_RESTART" ]]; then mkdir -p "${DATArestart}/FV3_RESTART"; fi + + # The $DATA/RESTART directory is used for writing FV3 restart files (it is hard-wired in the model) + # Link the output and restart directories to the DATA directory + ${NLN} "${DATAoutput}/FV3ATM_OUTPUT" "${DATA}/FV3ATM_OUTPUT" + ${NLN} "${DATArestart}/FV3_RESTART" "${DATA}/RESTART" + + FHZERO=${FHZERO:-6} + FHCYC=${FHCYC:-24} + + # Convert output settings into an explicit list for FV3 + # Create an FV3 fhr list to be used in the filenames + FV3_OUTPUT_FH="" + local fhr=${FHMIN} + if [[ "${FHOUT_HF}" -gt 0 && "${FHMAX_HF}" -gt 0 ]]; then + FV3_OUTPUT_FH="${FV3_OUTPUT_FH} $(seq -s ' ' "${FHMIN}" "${FHOUT_HF}" "${FHMAX_HF}")" + fhr=${FHMAX_HF} + fi + FV3_OUTPUT_FH="${FV3_OUTPUT_FH} $(seq -s ' ' "${fhr}" "${FHOUT}" "${FHMAX}")" + + if [[ "${FHOUT_HF}" -eq "${FHOUT}" ]]; then + FV3_OUTPUT_FH_NML="${FHOUT} -1" + else + FV3_OUTPUT_FH_NML="${FV3_OUTPUT_FH}" + fi + + # IAU options + IAUFHRS=${IAUFHRS:-0} + IAU_DELTHRS=${IAU_DELTHRS:-0} + + #------------------------------------------------------------------ + # changeable parameters + # dycore definitions + res="${CASE:1}" + resh="${CASE_HIST:1}" + resp=$((res + 1)) + npx=${resp} + npy=${resp} + npz=$((LEVS - 1)) + io_layout="1,1" + #ncols=$(( (${npx}-1)*(${npy}-1)*3/2 )) + + # spectral truncation and regular grid resolution based on FV3 resolution + JCAP_CASE=$((2 * res - 2)) + LONB_CASE=$((4 * res)) + LATB_CASE=$((2 * res)) + + JCAP_CASE_HIST=$((2 * resh - 2)) + LONB_CASE_HIST=$((4 * resh)) + LATB_CASE_HIST=$((2 * resh)) + + JCAP=${JCAP:-${JCAP_CASE}} + LONB=${LONB:-${LONB_CASE}} + LATB=${LATB:-${LATB_CASE}} + + LONB_IMO=${LONB_IMO:-${LONB_CASE_HIST}} + LATB_JMO=${LATB_JMO:-${LATB_CASE_HIST}} + + # NSST Options + # nstf_name contains the NSST related parameters + # nstf_name(1) : NST_MODEL (NSST Model) : 0 = OFF, 1 = ON but uncoupled, 2 = ON and coupled + # nstf_name(2) : NST_SPINUP : 0 = OFF, 1 = ON, + # nstf_name(3) : NST_RESV (Reserved, NSST Analysis) : 0 = OFF, 1 = ON + # nstf_name(4) : ZSEA1 (in mm) : 0 + # nstf_name(5) : ZSEA2 (in mm) : 0 + # nst_anl : .true. or .false., NSST analysis over lake + NST_MODEL=${NST_MODEL:-0} + NST_SPINUP=${NST_SPINUP:-0} + NST_RESV=${NST_RESV-0} + ZSEA1=${ZSEA1:-0} + ZSEA2=${ZSEA2:-0} + nstf_name=${nstf_name:-"${NST_MODEL},${NST_SPINUP},${NST_RESV},${ZSEA1},${ZSEA2}"} + nst_anl=${nst_anl:-".false."} + + # blocking factor used for threading and general physics performance + #nyblocks=$(expr \( $npy - 1 \) \/ $layout_y ) + #nxblocks=$(expr \( $npx - 1 \) \/ $layout_x \/ 32) + #if [[ $nxblocks -le 0 ]]; then nxblocks=1 ; fi + blocksize=${blocksize:-32} + + # variables for controlling initialization of NCEP/NGGPS ICs + filtered_terrain=${filtered_terrain:-".true."} + gfs_dwinds=${gfs_dwinds:-".true."} + + # various debug options + no_dycore=${no_dycore:-".false."} + dycore_only=${adiabatic:-".false."} + chksum_debug=${chksum_debug:-".false."} + print_freq=${print_freq:-6} + + # the pre-conditioning of the solution + # =0 implies no pre-conditioning + # >0 means new adiabatic pre-conditioning + # <0 means older adiabatic pre-conditioning + na_init=${na_init:-1} + + local suite_file="${HOMEgfs}/sorc/ufs_model.fd/UFSATM/ccpp/suites/suite_${CCPP_SUITE}.xml" + if [[ ! -f "${suite_file}" ]]; then + echo "FATAL ERROR: CCPP Suite file ${suite_file} does not exist, ABORT!" + exit 2 + fi + + # Scan suite file to determine whether it uses Noah-MP + local num_noahmpdrv + num_noahmpdrv=$(grep -c noahmpdrv "${suite_file}") + if [[ "${num_noahmpdrv}" -gt 0 ]]; then + lsm="2" + lheatstrg=".false." + landice=".false." + iopt_dveg=${iopt_dveg:-"4"} + iopt_crs=${iopt_crs:-"2"} + iopt_btr=${iopt_btr:-"1"} + iopt_run=${iopt_run:-"1"} + iopt_sfc=${iopt_sfc:-"1"} + iopt_frz=${iopt_frz:-"1"} + iopt_inf=${iopt_inf:-"1"} + iopt_rad=${iopt_rad:-"3"} + iopt_alb=${iopt_alb:-"1"} + iopt_snf=${iopt_snf:-"4"} + iopt_tbot=${iopt_tbot:-"2"} + iopt_stc=${iopt_stc:-"3"} + IALB=${IALB:-2} + IEMS=${IEMS:-2} + else + lsm="1" + lheatstrg=".true." + landice=".true." + iopt_dveg=${iopt_dveg:-"1"} + iopt_crs=${iopt_crs:-"1"} + iopt_btr=${iopt_btr:-"1"} + iopt_run=${iopt_run:-"1"} + iopt_sfc=${iopt_sfc:-"1"} + iopt_frz=${iopt_frz:-"1"} + iopt_inf=${iopt_inf:-"1"} + iopt_rad=${iopt_rad:-"1"} + iopt_alb=${iopt_alb:-"2"} + iopt_snf=${iopt_snf:-"4"} + iopt_tbot=${iopt_tbot:-"2"} + iopt_stc=${iopt_stc:-"1"} + IALB=${IALB:-1} + IEMS=${IEMS:-1} + fi + + if [[ "${TYPE}" == "nh" ]]; then # non-hydrostatic options + hydrostatic=".false." + phys_hydrostatic=".false." # enable heating in hydrostatic balance in non-hydrostatic simulation + use_hydro_pressure=".false." # use hydrostatic pressure for physics + make_nh=".true." # running in non-hydrostatic mode + pass_full_omega_to_physics_in_non_hydrostatic_mode=".true." + else # hydrostatic options + hydrostatic=".true." + phys_hydrostatic=".false." # ignored when hydrostatic = T + use_hydro_pressure=".false." # ignored when hydrostatic = T + make_nh=".false." # running in hydrostatic mode + fi + + # Conserve total energy as heat globally consv_te=${consv_te:-1.} # range 0.-1., 1. will restore energy to orig. val. before physics - k_split=${k_split:-2} - fi - - # time step parameters in FV3 - n_split=${n_split:-5} - - if [[ "${MONO:0:4}" == "mono" ]]; then # monotonic options - d_con=${d_con_mono:-"0."} - do_vort_damp=".false." - if [[ "${TYPE}" == "nh" ]]; then # monotonic and non-hydrostatic - hord_mt=${hord_mt_nh_mono:-"10"} - hord_xx=${hord_xx_nh_mono:-"10"} - hord_dp=${hord_xx_nh_mono:-"10"} - else # monotonic and hydrostatic - hord_mt=${hord_mt_hydro_mono:-"10"} - hord_xx=${hord_xx_hydro_mono:-"10"} - hord_dp=${hord_xx_hydro_mono:-"10"} - kord_tm=${kord_tm_hydro_mono:-"-12"} - kord_mt=${kord_mt_hydro_mono:-"12"} - kord_wz=${kord_wz_hydro_mono:-"12"} - kord_tr=${kord_tr_hydro_mono:-"12"} - fi - else # non-monotonic options - d_con=${d_con_nonmono:-"1."} - do_vort_damp=".true." - if [[ "${TYPE}" == "nh" ]]; then # non-monotonic and non-hydrostatic - hord_mt=${hord_mt_nh_nonmono:-"5"} - hord_xx=${hord_xx_nh_nonmono:-"5"} - hord_dp=${hord_dp_nh_nonmono:-"-5"} - else # non-monotonic and hydrostatic - hord_mt=${hord_mt_hydro_nonmono:-"10"} - hord_xx=${hord_xx_hydro_nonmono:-"10"} - hord_dp=${hord_xx_hydro_nonmono:-"10"} - fi - fi - - if [[ "${MONO:0:4}" != "mono" && "${TYPE}" == "nh" ]]; then - vtdm4=${vtdm4_nh_nonmono:-"0.06"} - else - vtdm4=${vtdm4:-"0.05"} - fi - - # Initial conditions are chgres-ed from GFS analysis file - nggps_ic=${nggps_ic:-".true."} - ncep_ic=${ncep_ic:-".false."} - external_ic=".true." - mountain=".false." - warm_start=".false." - read_increment=".false." - res_latlon_dynamics='""' - increment_file_on_native_grid=".false." - - # Stochastic Physics Options - do_skeb=".false." - do_shum=".false." - do_sppt=".false." - do_ca=".false." - ISEED=0 - local imem=${MEMBER#0} - local base_seed=$((current_cycle*10000 + imem*100)) - - if [[ "${DO_SKEB:-}" == "YES" ]]; then - do_skeb=".true." - ISEED_SKEB=$((base_seed + 1)) - fi - - if [[ "${DO_SHUM:-}" == "YES" ]]; then - do_shum=".true." - ISEED_SHUM=$((base_seed + 2)) - fi - - if [[ "${DO_SPPT:-}" == "YES" ]]; then - do_sppt=".true." - ISEED_SPPT=$((base_seed + 3)),$((base_seed + 4)),$((base_seed + 5)),$((base_seed + 6)),$((base_seed + 7)) - fi - - if [[ "${DO_CA:-}" == "YES" ]]; then - do_ca=".true." - ISEED_CA=$(( (base_seed + 18) % 2147483647 )) - fi - - if [[ "${DO_LAND_PERT:-}" == "YES" ]]; then - lndp_type=${lndp_type:-2} - ISEED_LNDP=$(( (base_seed + 5) % 2147483647 )) - LNDP_TAU=${LNDP_TAU:-21600} - LNDP_SCALE=${LNDP_SCALE:-500000} - lndp_var_list=${lndp_var_list:-"'smc', 'vgf',"} - lndp_prt_list=${lndp_prt_list:-"0.2,0.1"} - n_var_lndp=$(echo "${lndp_var_list}" | wc -w) - fi - - #-------------------------------------------------------------------------- - - # Fix files - FNGLAC=${FNGLAC:-"${FIXgfs}/am/global_glacier.2x2.grb"} - FNMXIC=${FNMXIC:-"${FIXgfs}/am/global_maxice.2x2.grb"} - FNTSFC=${FNTSFC:-"${FIXgfs}/am/RTGSST.1982.2012.monthly.clim.grb"} - FNSNOC=${FNSNOC:-"${FIXgfs}/am/global_snoclim.1.875.grb"} - FNZORC=${FNZORC:-"igbp"} - FNAISC=${FNAISC:-"${FIXgfs}/am/IMS-NIC.blended.ice.monthly.clim.grb"} - FNALBC2=${FNALBC2:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.facsf.tileX.nc"} - FNTG3C=${FNTG3C:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.substrate_temperature.tileX.nc"} - FNVEGC=${FNVEGC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} - FNMSKH=${FNMSKH:-"${FIXgfs}/am/global_slmask.t1534.3072.1536.grb"} - FNVMNC=${FNVMNC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} - FNVMXC=${FNVMXC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} - FNSLPC=${FNSLPC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.slope_type.tileX.nc"} - FNALBC=${FNALBC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.snowfree_albedo.tileX.nc"} - FNVETC=${FNVETC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_type.tileX.nc"} - FNSOTC=${FNSOTC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_type.tileX.nc"} - FNSOCC=${FNSOCC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_color.tileX.nc"} - FNABSC=${FNABSC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.maximum_snow_albedo.tileX.nc"} - FNSMCC=${FNSMCC:-"${FIXgfs}/am/global_soilmgldas.statsgo.t${JCAP}.${LONB}.${LATB}.grb"} - - # If the appropriate resolution fix file is not present, use the highest resolution available (T1534) - if [[ ! -f "${FNSMCC}" ]]; then - FNSMCC="${FIXgfs}/am/global_soilmgldas.statsgo.t1534.3072.1536.grb" - fi - - # Grid and orography data - if [[ "${cplflx}" == ".false." ]] ; then - cpreq "${FIXorog}/${CASE}/${CASE}_mosaic.nc" "${DATA}/INPUT/grid_spec.nc" - else - cpreq "${FIXorog}/${CASE}/${CASE}_mosaic.nc" "${DATA}/INPUT/${CASE}_mosaic.nc" - fi - - # Files for GWD - cpreq "${FIXugwd}/ugwp_limb_tau.nc" "${DATA}/ugwp_limb_tau.nc" - - # Files for orography, GWD tiles - local tt - for (( tt = 1; tt <= ntiles; tt++ )); do - cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${tt}.nc" "${DATA}/INPUT/oro_data.tile${tt}.nc" - cpreq "${FIXorog}/${CASE}/${CASE}_grid.tile${tt}.nc" "${DATA}/INPUT/${CASE}_grid.tile${tt}.nc" - cpreq "${FIXugwd}/${CASE}/${CASE}_oro_data_ls.tile${tt}.nc" "${DATA}/INPUT/oro_data_ls.tile${tt}.nc" - cpreq "${FIXugwd}/${CASE}/${CASE}_oro_data_ss.tile${tt}.nc" "${DATA}/INPUT/oro_data_ss.tile${tt}.nc" - done - if [[ "${DO_NEST:-NO}" == "YES" ]] ; then - ${NLN} "${DATA}/INPUT/oro_data.tile7.nc" "${DATA}/INPUT/oro_data.nest02.tile7.nc" - ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/${CASE}_grid.nest02.tile7.nc" - ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/grid.nest02.tile7.nc" - ${NLN} "${DATA}/INPUT/oro_data_ls.tile7.nc" "${DATA}/INPUT/oro_data_ls.nest02.tile7.nc" - ${NLN} "${DATA}/INPUT/oro_data_ss.tile7.nc" "${DATA}/INPUT/oro_data_ss.nest02.tile7.nc" - fi - - # NoahMP table - local noahmptablefile="${PARMgfs}/ufs/noahmptable.tbl" - cpreq "${noahmptablefile}" "${DATA}/noahmptable.tbl" - - # Thompson microphysics fix files - if (( imp_physics == 8 )); then - cpreq "${FIXgfs}/am/CCN_ACTIVATE.BIN" "${DATA}/CCN_ACTIVATE.BIN" - cpreq "${FIXgfs}/am/freezeH2O.dat" "${DATA}/freezeH2O.dat" - cpreq "${FIXgfs}/am/qr_acr_qgV2.dat" "${DATA}/qr_acr_qgV2.dat" - cpreq "${FIXgfs}/am/qr_acr_qsV2.dat" "${DATA}/qr_acr_qsV2.dat" - fi - - if [[ "${new_o3forc:-YES}" == "YES" ]]; then - if [[ "${o3forc_params:-McCormack}" == "McCormack-empirical-sh-ozh" ]]; then - O3FORC="ozprdlos_2015_new_sbuvO3_tclm15_nuchem_shozhvlogp.f77" + if [[ "${DO_NEST:-NO}" == "YES" ]]; then + consv_te=0 + k_split=${k_split:-1} + k_split_nest=${k_split_nest:-4} else - O3FORC="ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77" - fi - else - O3FORC="global_o3prdlos.f77" - fi - H2OFORC=${H2OFORC:-"global_h2o_pltc.f77"} - cpreq "${FIXgfs}/am/${O3FORC}" "${DATA}/global_o3prdlos.f77" - cpreq "${FIXgfs}/am/${H2OFORC}" "${DATA}/global_h2oprdlos.f77" - - # GFS standard input data - - ISOL=${ISOL:-2} - - cpreq "${FIXgfs}/am/global_solarconstant_noaa_an.txt" "${DATA}/solarconstant_noaa_an.txt" - cpreq "${FIXgfs}/am/global_sfc_emissivity_idx.txt" "${DATA}/sfc_emissivity_idx.txt" - - # Aerosol options - IAER=${IAER:-1011} - MERRA2_6ym=${MERRA2_6ym:-".false."} - ## merra2 aerosol climo - if (( IAER == 1011 )); then - if [[ "${MERRA2_6ym}" == ".false." ]]; then -# local month mm - for (( month = 1; month <=12; month++ )); do - mm=$(printf %02d "${month}") - cpreq "${FIXgfs}/aer/merra2.aerclim.2014-2023.m${mm}.nc" "aeroclim.m${mm}.nc" - done - elif [[ "${MERRA2_6ym}" == ".true." ]]; then - year=${current_cycle:0:4} - for i in {1980..2300..5} - do - if [[ ${year} -le ${i} ]] - then - Eyear=$(printf %04d "${i}") - Syear=$(( i - 5 )) - break + consv_te=${consv_te:-1.} # range 0.-1., 1. will restore energy to orig. val. before physics + k_split=${k_split:-2} + fi + + # time step parameters in FV3 + n_split=${n_split:-5} + + if [[ "${MONO:0:4}" == "mono" ]]; then # monotonic options + d_con=${d_con_mono:-"0."} + do_vort_damp=".false." + if [[ "${TYPE}" == "nh" ]]; then # monotonic and non-hydrostatic + hord_mt=${hord_mt_nh_mono:-"10"} + hord_xx=${hord_xx_nh_mono:-"10"} + hord_dp=${hord_xx_nh_mono:-"10"} + else # monotonic and hydrostatic + hord_mt=${hord_mt_hydro_mono:-"10"} + hord_xx=${hord_xx_hydro_mono:-"10"} + hord_dp=${hord_xx_hydro_mono:-"10"} + kord_tm=${kord_tm_hydro_mono:-"-12"} + kord_mt=${kord_mt_hydro_mono:-"12"} + kord_wz=${kord_wz_hydro_mono:-"12"} + kord_tr=${kord_tr_hydro_mono:-"12"} fi - done - for (( month = 1; month <=12; month++ )); do - mm=$(printf %02d "${month}") - cpreq "${FIXgfs}/aer/y${Syear}-${Eyear}/merra2_${Syear}-${Eyear}_${mm}.nc" "aeroclim.m${mm}.nc" - done - fi # if [[ "${MERRA2_6ym}" == ".true." ]]; - fi # if (( IAER == 1011 )) - - cpreq "${FIXgfs}/am/global_climaeropac_global.txt" "${DATA}/aerosol.dat" - if (( IAER > 0 )) ; then - local file - for file in "${FIXgfs}/am/global_volcanic_aerosols"* ; do - cpreq "${file}" "${DATA}/$(basename "${file//global_}")" - done - fi - - cpreq "${FIXgfs}/lut/optics_BC.v1_3.dat" "${DATA}/optics_BC.dat" - cpreq "${FIXgfs}/lut/optics_OC.v1_3.dat" "${DATA}/optics_OC.dat" - cpreq "${FIXgfs}/lut/optics_DU.v15_3.dat" "${DATA}/optics_DU.dat" - cpreq "${FIXgfs}/lut/optics_SS.v3_3.dat" "${DATA}/optics_SS.dat" - cpreq "${FIXgfs}/lut/optics_SU.v1_3.dat" "${DATA}/optics_SU.dat" - - # CO2 options - ICO2=${ICO2:-2} - - cpreq "${FIXgfs}/am/global_co2historicaldata_glob.txt" "${DATA}/co2historicaldata_glob.txt" - cpreq "${FIXgfs}/am/co2monthlycyc.txt" "${DATA}/co2monthlycyc.txt" - # Set historical CO2 values based on whether this is a reforecast run or not - # Ref. issue 2403 - local co2dir - co2dir="fix_co2_proj" - if [[ "${reforecast:-}" == "YES" ]]; then - co2dir="co2dat_4a" - fi - if (( ICO2 > 0 )); then - local file - for file in "${FIXgfs}/am/${co2dir}/global_co2historicaldata"* ; do - cpreq "${file}" "${DATA}/$(basename "${file//global_}")" - done - fi - - # Inline UPP fix files - if [[ "${WRITE_DOPOST:-}" == ".true." ]]; then - cpreq "${POSTGRB2TBL:-${PARMgfs}/post/params_grib2_tbl_new}" "${DATA}/params_grib2_tbl_new" - cpreq "${PARMgfs}/ufs/post_itag_gfs" "${DATA}/itag" # TODO: Need a GEFS version when available in the UFS-weather-model - # TODO: These should be replaced with ones from the ufs-weather-model when available there - case ${NET} in - gfs|gcafs) - cpreq "${PARMgfs}/post/gfs/postxconfig-NT-gfs-two.txt" "${DATA}/postxconfig-NT.txt" - cpreq "${PARMgfs}/post/gfs/postxconfig-NT-gfs-f00-two.txt" "${DATA}/postxconfig-NT_FH00.txt" - ;; - gefs) - cpreq "${PARMgfs}/post/gefs/postxconfig-NT-gefs.txt" "${DATA}/postxconfig-NT.txt" - cpreq "${PARMgfs}/post/gefs/postxconfig-NT-gefs-f00.txt" "${DATA}/postxconfig-NT_FH00.txt" - # Provide ensemble header information for GEFS - if [[ "${ENSMEM}" == "000" ]]; then - export e1=1 - else - export e1=3 + else # non-monotonic options + d_con=${d_con_nonmono:-"1."} + do_vort_damp=".true." + if [[ "${TYPE}" == "nh" ]]; then # non-monotonic and non-hydrostatic + hord_mt=${hord_mt_nh_nonmono:-"5"} + hord_xx=${hord_xx_nh_nonmono:-"5"} + hord_dp=${hord_dp_nh_nonmono:-"-5"} + else # non-monotonic and hydrostatic + hord_mt=${hord_mt_hydro_nonmono:-"10"} + hord_xx=${hord_xx_hydro_nonmono:-"10"} + hord_dp=${hord_xx_hydro_nonmono:-"10"} fi - export e2="${ENSMEM:1:2}" - export e3="${NMEM_ENS}" - ;; - sfs) - cpreq "${PARMgfs}/post/sfs/postxconfig-NT-sfs.txt" "${DATA}/postxconfig-NT.txt" - cpreq "${PARMgfs}/post/sfs/postxconfig-NT-sfs.txt" "${DATA}/postxconfig-NT_FH00.txt" - # Provide ensemble header information for SFS - if [[ "${ENSMEM}" == "000" ]]; then - export e1=1 + fi + + if [[ "${MONO:0:4}" != "mono" && "${TYPE}" == "nh" ]]; then + vtdm4=${vtdm4_nh_nonmono:-"0.06"} + else + vtdm4=${vtdm4:-"0.05"} + fi + + # Initial conditions are chgres-ed from GFS analysis file + nggps_ic=${nggps_ic:-".true."} + ncep_ic=${ncep_ic:-".false."} + external_ic=".true." + mountain=".false." + warm_start=".false." + read_increment=".false." + res_latlon_dynamics='""' + increment_file_on_native_grid=".false." + + # Stochastic Physics Options + do_skeb=".false." + do_shum=".false." + do_sppt=".false." + do_ca=".false." + ISEED=0 + local imem=${MEMBER#0} + local base_seed=$((current_cycle * 10000 + imem * 100)) + + if [[ "${DO_SKEB:-}" == "YES" ]]; then + do_skeb=".true." + ISEED_SKEB=$((base_seed + 1)) + fi + + if [[ "${DO_SHUM:-}" == "YES" ]]; then + do_shum=".true." + ISEED_SHUM=$((base_seed + 2)) + fi + + if [[ "${DO_SPPT:-}" == "YES" ]]; then + do_sppt=".true." + ISEED_SPPT=$((base_seed + 3)),$((base_seed + 4)),$((base_seed + 5)),$((base_seed + 6)),$((base_seed + 7)) + fi + + if [[ "${DO_CA:-}" == "YES" ]]; then + do_ca=".true." + ISEED_CA=$(((base_seed + 18) % 2147483647)) + fi + + if [[ "${DO_LAND_PERT:-}" == "YES" ]]; then + lndp_type=${lndp_type:-2} + ISEED_LNDP=$(((base_seed + 5) % 2147483647)) + LNDP_TAU=${LNDP_TAU:-21600} + LNDP_SCALE=${LNDP_SCALE:-500000} + lndp_var_list=${lndp_var_list:-"'smc', 'vgf',"} + lndp_prt_list=${lndp_prt_list:-"0.2,0.1"} + n_var_lndp=$(echo "${lndp_var_list}" | wc -w) + fi + + #-------------------------------------------------------------------------- + + # Fix files + FNGLAC=${FNGLAC:-"${FIXgfs}/am/global_glacier.2x2.grb"} + FNMXIC=${FNMXIC:-"${FIXgfs}/am/global_maxice.2x2.grb"} + FNTSFC=${FNTSFC:-"${FIXgfs}/am/RTGSST.1982.2012.monthly.clim.grb"} + FNSNOC=${FNSNOC:-"${FIXgfs}/am/global_snoclim.1.875.grb"} + FNZORC=${FNZORC:-"igbp"} + FNAISC=${FNAISC:-"${FIXgfs}/am/IMS-NIC.blended.ice.monthly.clim.grb"} + FNALBC2=${FNALBC2:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.facsf.tileX.nc"} + FNTG3C=${FNTG3C:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.substrate_temperature.tileX.nc"} + FNVEGC=${FNVEGC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} + FNMSKH=${FNMSKH:-"${FIXgfs}/am/global_slmask.t1534.3072.1536.grb"} + FNVMNC=${FNVMNC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} + FNVMXC=${FNVMXC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_greenness.tileX.nc"} + FNSLPC=${FNSLPC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.slope_type.tileX.nc"} + FNALBC=${FNALBC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.snowfree_albedo.tileX.nc"} + FNVETC=${FNVETC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.vegetation_type.tileX.nc"} + FNSOTC=${FNSOTC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_type.tileX.nc"} + FNSOCC=${FNSOCC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.soil_color.tileX.nc"} + FNABSC=${FNABSC:-"${FIXorog}/${CASE}/sfc/${CASE}.mx${OCNRES}.maximum_snow_albedo.tileX.nc"} + FNSMCC=${FNSMCC:-"${FIXgfs}/am/global_soilmgldas.statsgo.t${JCAP}.${LONB}.${LATB}.grb"} + + # If the appropriate resolution fix file is not present, use the highest resolution available (T1534) + if [[ ! -f "${FNSMCC}" ]]; then + FNSMCC="${FIXgfs}/am/global_soilmgldas.statsgo.t1534.3072.1536.grb" + fi + + # Grid and orography data + if [[ "${cplflx}" == ".false." ]]; then + cpreq "${FIXorog}/${CASE}/${CASE}_mosaic.nc" "${DATA}/INPUT/grid_spec.nc" + else + cpreq "${FIXorog}/${CASE}/${CASE}_mosaic.nc" "${DATA}/INPUT/${CASE}_mosaic.nc" + fi + + # Files for GWD + cpreq "${FIXugwd}/ugwp_limb_tau.nc" "${DATA}/ugwp_limb_tau.nc" + + # Files for orography, GWD tiles + local tt + for ((tt = 1; tt <= ntiles; tt++)); do + cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile${tt}.nc" "${DATA}/INPUT/oro_data.tile${tt}.nc" + cpreq "${FIXorog}/${CASE}/${CASE}_grid.tile${tt}.nc" "${DATA}/INPUT/${CASE}_grid.tile${tt}.nc" + cpreq "${FIXugwd}/${CASE}/${CASE}_oro_data_ls.tile${tt}.nc" "${DATA}/INPUT/oro_data_ls.tile${tt}.nc" + cpreq "${FIXugwd}/${CASE}/${CASE}_oro_data_ss.tile${tt}.nc" "${DATA}/INPUT/oro_data_ss.tile${tt}.nc" + done + if [[ "${DO_NEST:-NO}" == "YES" ]]; then + ${NLN} "${DATA}/INPUT/oro_data.tile7.nc" "${DATA}/INPUT/oro_data.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/${CASE}_grid.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/grid.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/oro_data_ls.tile7.nc" "${DATA}/INPUT/oro_data_ls.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/oro_data_ss.tile7.nc" "${DATA}/INPUT/oro_data_ss.nest02.tile7.nc" + fi + + # NoahMP table + local noahmptablefile="${PARMgfs}/ufs/noahmptable.tbl" + cpreq "${noahmptablefile}" "${DATA}/noahmptable.tbl" + + # Thompson microphysics fix files + if ((imp_physics == 8)); then + cpreq "${FIXgfs}/am/CCN_ACTIVATE.BIN" "${DATA}/CCN_ACTIVATE.BIN" + cpreq "${FIXgfs}/am/freezeH2O.dat" "${DATA}/freezeH2O.dat" + cpreq "${FIXgfs}/am/qr_acr_qgV2.dat" "${DATA}/qr_acr_qgV2.dat" + cpreq "${FIXgfs}/am/qr_acr_qsV2.dat" "${DATA}/qr_acr_qsV2.dat" + fi + + if [[ "${new_o3forc:-YES}" == "YES" ]]; then + if [[ "${o3forc_params:-McCormack}" == "McCormack-empirical-sh-ozh" ]]; then + O3FORC="ozprdlos_2015_new_sbuvO3_tclm15_nuchem_shozhvlogp.f77" else - export e1=3 + O3FORC="ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77" fi - export e2="${ENSMEM:1:2}" - export e3="${NMEM_ENS}" - ;; - *) - echo "FATAL ERROR: Unknown NET ${NET}, unable to determine appropriate post files" - exit 20 - esac - fi + else + O3FORC="global_o3prdlos.f77" + fi + H2OFORC=${H2OFORC:-"global_h2o_pltc.f77"} + cpreq "${FIXgfs}/am/${O3FORC}" "${DATA}/global_o3prdlos.f77" + cpreq "${FIXgfs}/am/${H2OFORC}" "${DATA}/global_h2oprdlos.f77" + + # GFS standard input data + + ISOL=${ISOL:-2} + + cpreq "${FIXgfs}/am/global_solarconstant_noaa_an.txt" "${DATA}/solarconstant_noaa_an.txt" + cpreq "${FIXgfs}/am/global_sfc_emissivity_idx.txt" "${DATA}/sfc_emissivity_idx.txt" + + # Aerosol options + IAER=${IAER:-1011} + MERRA2_6ym=${MERRA2_6ym:-".false."} + ## merra2 aerosol climo + if ((IAER == 1011)); then + if [[ "${MERRA2_6ym}" == ".false." ]]; then + # local month mm + for ((month = 1; month <= 12; month++)); do + mm=$(printf %02d "${month}") + cpreq "${FIXgfs}/aer/merra2.aerclim.2014-2023.m${mm}.nc" "aeroclim.m${mm}.nc" + done + elif [[ "${MERRA2_6ym}" == ".true." ]]; then + year=${current_cycle:0:4} + for i in {1980..2300..5}; do + if [[ ${year} -le ${i} ]]; then + Eyear=$(printf %04d "${i}") + Syear=$((i - 5)) + break + fi + done + for ((month = 1; month <= 12; month++)); do + mm=$(printf %02d "${month}") + cpreq "${FIXgfs}/aer/y${Syear}-${Eyear}/merra2_${Syear}-${Eyear}_${mm}.nc" "aeroclim.m${mm}.nc" + done + fi # if [[ "${MERRA2_6ym}" == ".true." ]]; + fi # if (( IAER == 1011 )) + + cpreq "${FIXgfs}/am/global_climaeropac_global.txt" "${DATA}/aerosol.dat" + if ((IAER > 0)); then + local file + for file in "${FIXgfs}/am/global_volcanic_aerosols"*; do + cpreq "${file}" "${DATA}/$(basename "${file//global_/}")" + done + fi + + cpreq "${FIXgfs}/lut/optics_BC.v1_3.dat" "${DATA}/optics_BC.dat" + cpreq "${FIXgfs}/lut/optics_OC.v1_3.dat" "${DATA}/optics_OC.dat" + cpreq "${FIXgfs}/lut/optics_DU.v15_3.dat" "${DATA}/optics_DU.dat" + cpreq "${FIXgfs}/lut/optics_SS.v3_3.dat" "${DATA}/optics_SS.dat" + cpreq "${FIXgfs}/lut/optics_SU.v1_3.dat" "${DATA}/optics_SU.dat" + + # CO2 options + ICO2=${ICO2:-2} + + cpreq "${FIXgfs}/am/global_co2historicaldata_glob.txt" "${DATA}/co2historicaldata_glob.txt" + cpreq "${FIXgfs}/am/co2monthlycyc.txt" "${DATA}/co2monthlycyc.txt" + # Set historical CO2 values based on whether this is a reforecast run or not + # Ref. issue 2403 + local co2dir + co2dir="fix_co2_proj" + if [[ "${reforecast:-}" == "YES" ]]; then + co2dir="co2dat_4a" + fi + if ((ICO2 > 0)); then + local file + for file in "${FIXgfs}/am/${co2dir}/global_co2historicaldata"*; do + cpreq "${file}" "${DATA}/$(basename "${file//global_/}")" + done + fi + + # Inline UPP fix files + if [[ "${WRITE_DOPOST:-}" == ".true." ]]; then + cpreq "${POSTGRB2TBL:-${PARMgfs}/post/params_grib2_tbl_new}" "${DATA}/params_grib2_tbl_new" + cpreq "${PARMgfs}/ufs/post_itag_gfs" "${DATA}/itag" # TODO: Need a GEFS version when available in the UFS-weather-model + # TODO: These should be replaced with ones from the ufs-weather-model when available there + case ${NET} in + gfs | gcafs) + cpreq "${PARMgfs}/post/gfs/postxconfig-NT-gfs-two.txt" "${DATA}/postxconfig-NT.txt" + cpreq "${PARMgfs}/post/gfs/postxconfig-NT-gfs-f00-two.txt" "${DATA}/postxconfig-NT_FH00.txt" + ;; + gefs) + cpreq "${PARMgfs}/post/gefs/postxconfig-NT-gefs.txt" "${DATA}/postxconfig-NT.txt" + cpreq "${PARMgfs}/post/gefs/postxconfig-NT-gefs-f00.txt" "${DATA}/postxconfig-NT_FH00.txt" + # Provide ensemble header information for GEFS + if [[ "${ENSMEM}" == "000" ]]; then + export e1=1 + else + export e1=3 + fi + export e2="${ENSMEM:1:2}" + export e3="${NMEM_ENS}" + ;; + sfs) + cpreq "${PARMgfs}/post/sfs/postxconfig-NT-sfs.txt" "${DATA}/postxconfig-NT.txt" + cpreq "${PARMgfs}/post/sfs/postxconfig-NT-sfs.txt" "${DATA}/postxconfig-NT_FH00.txt" + # Provide ensemble header information for SFS + if [[ "${ENSMEM}" == "000" ]]; then + export e1=1 + else + export e1=3 + fi + export e2="${ENSMEM:1:2}" + export e3="${NMEM_ENS}" + ;; + *) + echo "FATAL ERROR: Unknown NET ${NET}, unable to determine appropriate post files" + exit 20 + ;; + esac + fi } # Disable variable not used warnings # shellcheck disable=SC2034 -WW3_predet(){ - echo "SUB ${FUNCNAME[0]}: WW3 before run type determination" - - if [[ ! -d "${COMOUT_WAVE_HISTORY}" ]]; then mkdir -p "${COMOUT_WAVE_HISTORY}"; fi - if [[ ! -d "${COMOUT_WAVE_RESTART}" ]]; then mkdir -p "${COMOUT_WAVE_RESTART}"; fi - if [[ ! -d "${DATAoutput}/WW3_OUTPUT" ]]; then mkdir -p "${DATAoutput}/WW3_OUTPUT"; fi - if [[ ! -d "${DATArestart}/WW3_RESTART" ]]; then mkdir -p "${DATArestart}/WW3_RESTART"; fi - - # Link the output and restart directories to the DATA directory - ${NLN} "${DATAoutput}/WW3_OUTPUT" "${DATA}/WW3_OUTPUT" - ${NLN} "${DATArestart}/WW3_RESTART" "${DATA}/WW3_RESTART" - - # Files from wave prep and wave init jobs - # Copy mod_def files for wave grids - local ww3_grid - #if shel, only 1 waveGRD which is linked to mod_def.ww3 - cpreq "${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${waveGRD}.bin" "${DATA}/mod_def.ww3" - - #If pnt_wght file exists, use it to speed up initialization for unstructured grids - # this file does not exist for structured, and the model can run without it (just slower init) - if [[ -f "${FIXgfs}/wave/pnt_wght.${waveGRD}.nc" ]]; then - cpreq "${FIXgfs}/wave/pnt_wght.${waveGRD}.nc" "${DATA}/pnt_wght.ww3.nc" - fi - - # TODO: These are generated by waveprep job, but that job is not used in v17 - # so these files are not generated. - # TODO: Remove these lines or enable waveprep job - if [[ "${WW3ICEINP}" == "YES" ]]; then - local wavicefile="${COMIN_WAVE_PREP}/${RUN}.${WAVEICE_FID}.t${current_cycle:8:2}z.ice" - if [[ ! -f "${wavicefile}" ]]; then - echo "FATAL ERROR: WW3ICEINP='${WW3ICEINP}', but missing ice file '${wavicefile}', ABORT!" - exit 1 - fi - cpreq "${wavicefile}" "${DATA}/ice.${WAVEICE_FID}" - fi - - if [[ "${WW3CURINP}" == "YES" ]]; then - local wavcurfile="${COMIN_WAVE_PREP}/${RUN}.${WAVECUR_FID}.t${current_cycle:8:2}z.cur" - if [[ ! -f "${wavcurfile}" ]]; then - echo "FATAL ERROR: WW3CURINP='${WW3CURINP}', but missing current file '${wavcurfile}', ABORT!" - exit 1 - fi - cpreq "${wavcurfile}" "${DATA}/current.${WAVECUR_FID}" - fi - - # Fix files - #if wave mesh is not the same as the ocean mesh, copy it in the file - if [[ "${MESH_WAV}" == "${MESH_OCN:-mesh.mx${OCNRES}.nc}" ]]; then - echo "Wave is on the same mesh as ocean" - else - echo "Wave is NOT on the same mesh as ocean" - cpreq "${FIXgfs}/wave/${MESH_WAV}" "${DATA}/" - fi +WW3_predet() { + echo "SUB ${FUNCNAME[0]}: WW3 before run type determination" + + if [[ ! -d "${COMOUT_WAVE_HISTORY}" ]]; then mkdir -p "${COMOUT_WAVE_HISTORY}"; fi + if [[ ! -d "${COMOUT_WAVE_RESTART}" ]]; then mkdir -p "${COMOUT_WAVE_RESTART}"; fi + if [[ ! -d "${DATAoutput}/WW3_OUTPUT" ]]; then mkdir -p "${DATAoutput}/WW3_OUTPUT"; fi + if [[ ! -d "${DATArestart}/WW3_RESTART" ]]; then mkdir -p "${DATArestart}/WW3_RESTART"; fi + + # Link the output and restart directories to the DATA directory + ${NLN} "${DATAoutput}/WW3_OUTPUT" "${DATA}/WW3_OUTPUT" + ${NLN} "${DATArestart}/WW3_RESTART" "${DATA}/WW3_RESTART" + + # Files from wave prep and wave init jobs + # Copy mod_def files for wave grids + local ww3_grid + #if shel, only 1 waveGRD which is linked to mod_def.ww3 + cpreq "${COMIN_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${waveGRD}.bin" "${DATA}/mod_def.ww3" + + #If pnt_wght file exists, use it to speed up initialization for unstructured grids + # this file does not exist for structured, and the model can run without it (just slower init) + if [[ -f "${FIXgfs}/wave/pnt_wght.${waveGRD}.nc" ]]; then + cpreq "${FIXgfs}/wave/pnt_wght.${waveGRD}.nc" "${DATA}/pnt_wght.ww3.nc" + fi + + # TODO: These are generated by waveprep job, but that job is not used in v17 + # so these files are not generated. + # TODO: Remove these lines or enable waveprep job + if [[ "${WW3ICEINP}" == "YES" ]]; then + local wavicefile="${COMIN_WAVE_PREP}/${RUN}.${WAVEICE_FID}.t${current_cycle:8:2}z.ice" + if [[ ! -f "${wavicefile}" ]]; then + echo "FATAL ERROR: WW3ICEINP='${WW3ICEINP}', but missing ice file '${wavicefile}', ABORT!" + exit 1 + fi + cpreq "${wavicefile}" "${DATA}/ice.${WAVEICE_FID}" + fi + + if [[ "${WW3CURINP}" == "YES" ]]; then + local wavcurfile="${COMIN_WAVE_PREP}/${RUN}.${WAVECUR_FID}.t${current_cycle:8:2}z.cur" + if [[ ! -f "${wavcurfile}" ]]; then + echo "FATAL ERROR: WW3CURINP='${WW3CURINP}', but missing current file '${wavcurfile}', ABORT!" + exit 1 + fi + cpreq "${wavcurfile}" "${DATA}/current.${WAVECUR_FID}" + fi + + # Fix files + #if wave mesh is not the same as the ocean mesh, copy it in the file + if [[ "${MESH_WAV}" == "${MESH_OCN:-mesh.mx${OCNRES}.nc}" ]]; then + echo "Wave is on the same mesh as ocean" + else + echo "Wave is NOT on the same mesh as ocean" + cpreq "${FIXgfs}/wave/${MESH_WAV}" "${DATA}/" + fi } # shellcheck disable=SC2034 -CICE_predet(){ - echo "SUB ${FUNCNAME[0]}: CICE before run type determination" +CICE_predet() { + echo "SUB ${FUNCNAME[0]}: CICE before run type determination" - if [[ ! -d "${COMOUT_ICE_HISTORY}" ]]; then mkdir -p "${COMOUT_ICE_HISTORY}"; fi - if [[ ! -d "${COMOUT_ICE_RESTART}" ]]; then mkdir -p "${COMOUT_ICE_RESTART}"; fi - if [[ ! -d "${COMIN_ICE_INPUT}" ]]; then mkdir -p "${COMIN_ICE_INPUT}"; fi - if [[ ! -d "${DATAoutput}/CICE_OUTPUT" ]]; then mkdir -p "${DATAoutput}/CICE_OUTPUT"; fi - if [[ ! -d "${DATArestart}/CICE_RESTART" ]]; then mkdir -p "${DATArestart}/CICE_RESTART"; fi + if [[ ! -d "${COMOUT_ICE_HISTORY}" ]]; then mkdir -p "${COMOUT_ICE_HISTORY}"; fi + if [[ ! -d "${COMOUT_ICE_RESTART}" ]]; then mkdir -p "${COMOUT_ICE_RESTART}"; fi + if [[ ! -d "${COMIN_ICE_INPUT}" ]]; then mkdir -p "${COMIN_ICE_INPUT}"; fi + if [[ ! -d "${DATAoutput}/CICE_OUTPUT" ]]; then mkdir -p "${DATAoutput}/CICE_OUTPUT"; fi + if [[ ! -d "${DATArestart}/CICE_RESTART" ]]; then mkdir -p "${DATArestart}/CICE_RESTART"; fi - # Link the output and restart directories to the DATA directory - ${NLN} "${DATAoutput}/CICE_OUTPUT" "${DATA}/CICE_OUTPUT" - ${NLN} "${DATArestart}/CICE_RESTART" "${DATA}/CICE_RESTART" + # Link the output and restart directories to the DATA directory + ${NLN} "${DATAoutput}/CICE_OUTPUT" "${DATA}/CICE_OUTPUT" + ${NLN} "${DATArestart}/CICE_RESTART" "${DATA}/CICE_RESTART" - # CICE does not have a concept of high frequency output like FV3 - # Convert output settings into an explicit list for CICE - # shellcheck disable=SC2312 - mapfile -t CICE_OUTPUT_FH < <(seq "${FHMIN}" "${FHOUT_ICE}" "${FHMAX}") || exit 10 + # CICE does not have a concept of high frequency output like FV3 + # Convert output settings into an explicit list for CICE + # shellcheck disable=SC2312 + mapfile -t CICE_OUTPUT_FH < <(seq "${FHMIN}" "${FHOUT_ICE}" "${FHMAX}") || exit 10 - # Fix files - cpreq "${FIXgfs}/cice/${ICERES}/${CICE_GRID}" "${DATA}/" - cpreq "${FIXgfs}/cice/${ICERES}/${CICE_MASK}" "${DATA}/" - cpreq "${FIXgfs}/cice/${ICERES}/${MESH_ICE}" "${DATA}/" + # Fix files + cpreq "${FIXgfs}/cice/${ICERES}/${CICE_GRID}" "${DATA}/" + cpreq "${FIXgfs}/cice/${ICERES}/${CICE_MASK}" "${DATA}/" + cpreq "${FIXgfs}/cice/${ICERES}/${MESH_ICE}" "${DATA}/" } # shellcheck disable=SC2034 -MOM6_predet(){ - echo "SUB ${FUNCNAME[0]}: MOM6 before run type determination" - - if [[ ! -d "${COMOUT_OCEAN_HISTORY}" ]]; then mkdir -p "${COMOUT_OCEAN_HISTORY}"; fi - if [[ ! -d "${COMOUT_OCEAN_RESTART}" ]]; then mkdir -p "${COMOUT_OCEAN_RESTART}"; fi - if [[ ! -d "${COMIN_OCEAN_INPUT}" ]]; then mkdir -p "${COMIN_OCEAN_INPUT}"; fi - if [[ ! -d "${DATAoutput}/MOM6_OUTPUT" ]]; then mkdir -p "${DATAoutput}/MOM6_OUTPUT"; fi - if [[ ! -d "${DATArestart}/MOM6_RESTART" ]]; then mkdir -p "${DATArestart}/MOM6_RESTART"; fi - - # Link the output and restart directories to the DATA directory - ${NLN} "${DATAoutput}/MOM6_OUTPUT" "${DATA}/MOM6_OUTPUT" - ${NLN} "${DATArestart}/MOM6_RESTART" "${DATA}/MOM6_RESTART" - - # MOM6 does not have a concept of high frequency output like FV3 - # Convert output settings into an explicit list for MOM6 - MOM6_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT_OCN}" "${FHMAX}") - - # If using stochastic parameterizations, create a seed that does not exceed the - # largest signed integer - local imem=${MEMBER#0} - local base_seed=$((current_cycle*10000 + imem*100)) - - if [[ "${DO_OCN_SPPT:-}" == "YES" ]]; then - ISEED_OCNSPPT=$((base_seed + 8)),$((base_seed + 9)),$((base_seed + 10)),$((base_seed + 11)),$((base_seed + 12)) - fi - - if [[ "${DO_OCN_PERT_EPBL:-}" == "YES" ]]; then - ISEED_EPBL=$((base_seed + 13)),$((base_seed + 14)),$((base_seed + 15)),$((base_seed + 16)),$((base_seed + 17)) - fi - - # Fix files for ocean; ocean_hgrid, ocean_mosaic, ocean_mask, etc. - # MOM_channels is configurable based on resolution, but is treated as a fix file - # MOM_override is a template that allows user to override default namelist settings, but is also treated as a fix file - cpreq "${FIXgfs}/mom6/${OCNRES}/"* "${DATA}/INPUT/" # TODO: These need to be explicit - - # Add to the MOM_override file, to have ISO timestamp - cat >> "${DATA}/INPUT/MOM_override" << EOF +MOM6_predet() { + echo "SUB ${FUNCNAME[0]}: MOM6 before run type determination" + + if [[ ! -d "${COMOUT_OCEAN_HISTORY}" ]]; then mkdir -p "${COMOUT_OCEAN_HISTORY}"; fi + if [[ ! -d "${COMOUT_OCEAN_RESTART}" ]]; then mkdir -p "${COMOUT_OCEAN_RESTART}"; fi + if [[ ! -d "${COMIN_OCEAN_INPUT}" ]]; then mkdir -p "${COMIN_OCEAN_INPUT}"; fi + if [[ ! -d "${DATAoutput}/MOM6_OUTPUT" ]]; then mkdir -p "${DATAoutput}/MOM6_OUTPUT"; fi + if [[ ! -d "${DATArestart}/MOM6_RESTART" ]]; then mkdir -p "${DATArestart}/MOM6_RESTART"; fi + + # Link the output and restart directories to the DATA directory + ${NLN} "${DATAoutput}/MOM6_OUTPUT" "${DATA}/MOM6_OUTPUT" + ${NLN} "${DATArestart}/MOM6_RESTART" "${DATA}/MOM6_RESTART" + + # MOM6 does not have a concept of high frequency output like FV3 + # Convert output settings into an explicit list for MOM6 + MOM6_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT_OCN}" "${FHMAX}") + + # If using stochastic parameterizations, create a seed that does not exceed the + # largest signed integer + local imem=${MEMBER#0} + local base_seed=$((current_cycle * 10000 + imem * 100)) + + if [[ "${DO_OCN_SPPT:-}" == "YES" ]]; then + ISEED_OCNSPPT=$((base_seed + 8)),$((base_seed + 9)),$((base_seed + 10)),$((base_seed + 11)),$((base_seed + 12)) + fi + + if [[ "${DO_OCN_PERT_EPBL:-}" == "YES" ]]; then + ISEED_EPBL=$((base_seed + 13)),$((base_seed + 14)),$((base_seed + 15)),$((base_seed + 16)),$((base_seed + 17)) + fi + + # Fix files for ocean; ocean_hgrid, ocean_mosaic, ocean_mask, etc. + # MOM_channels is configurable based on resolution, but is treated as a fix file + # MOM_override is a template that allows user to override default namelist settings, but is also treated as a fix file + cpreq "${FIXgfs}/mom6/${OCNRES}/"* "${DATA}/INPUT/" # TODO: These need to be explicit + + # Add to the MOM_override file, to have ISO timestamp + cat >> "${DATA}/INPUT/MOM_override" << EOF !#Write ISO date stamped output with 3-hourly (0.125) frequency to ocean.stats ascii file #override ISO_DATE_STAMPED_STDOUT = True #override ENERGYSAVEDAYS = 0.125 EOF - # Copy coupled grid_spec - local spec_file - spec_file="${FIXgfs}/cpl/a${CASE}o${OCNRES}/grid_spec.nc" - # Test that the file exists and is not zero-sized - if [[ -s "${spec_file}" ]]; then - cpreq "${spec_file}" "${DATA}/INPUT/" - else - echo "FATAL ERROR: coupled grid_spec file '${spec_file}' does not exist or is size 0" - exit 3 - fi + # Copy coupled grid_spec + local spec_file + spec_file="${FIXgfs}/cpl/a${CASE}o${OCNRES}/grid_spec.nc" + # Test that the file exists and is not zero-sized + if [[ -s "${spec_file}" ]]; then + cpreq "${spec_file}" "${DATA}/INPUT/" + else + echo "FATAL ERROR: coupled grid_spec file '${spec_file}' does not exist or is size 0" + exit 3 + fi } # shellcheck disable=SC2178 -CMEPS_predet(){ - echo "SUB ${FUNCNAME[0]}: CMEPS before run type determination" +CMEPS_predet() { + echo "SUB ${FUNCNAME[0]}: CMEPS before run type determination" - if [[ ! -d "${COMOUT_MED_RESTART}" ]]; then mkdir -p "${COMOUT_MED_RESTART}"; fi - if [[ ! -d "${DATArestart}/CMEPS_RESTART" ]]; then mkdir -p "${DATArestart}/CMEPS_RESTART"; fi + if [[ ! -d "${COMOUT_MED_RESTART}" ]]; then mkdir -p "${COMOUT_MED_RESTART}"; fi + if [[ ! -d "${DATArestart}/CMEPS_RESTART" ]]; then mkdir -p "${DATArestart}/CMEPS_RESTART"; fi - # Link the restart directory to the DATA directory - ${NLN} "${DATArestart}/CMEPS_RESTART" "${DATA}/CMEPS_RESTART" + # Link the restart directory to the DATA directory + ${NLN} "${DATArestart}/CMEPS_RESTART" "${DATA}/CMEPS_RESTART" } # shellcheck disable=SC2034 -GOCART_predet(){ - echo "SUB ${FUNCNAME[0]}: GOCART before run type determination" +GOCART_predet() { + echo "SUB ${FUNCNAME[0]}: GOCART before run type determination" - if [[ ! -d "${COMOUT_CHEM_HISTORY}" ]]; then mkdir -p "${COMOUT_CHEM_HISTORY}"; fi + if [[ ! -d "${COMOUT_CHEM_HISTORY}" ]]; then mkdir -p "${COMOUT_CHEM_HISTORY}"; fi - # FHMAX gets modified when IAU is on, so keep origianl value for GOCART output - GOCART_MAX=${FHMAX} + # FHMAX gets modified when IAU is on, so keep origianl value for GOCART output + GOCART_MAX=${FHMAX} - # GOCART output times can't be computed here because they may depend on FHROT + # GOCART output times can't be computed here because they may depend on FHROT } diff --git a/ush/fv3gfs_remap_weights.sh b/ush/fv3gfs_remap_weights.sh index 15dfc73e3f0..518b51c2767 100755 --- a/ush/fv3gfs_remap_weights.sh +++ b/ush/fv3gfs_remap_weights.sh @@ -10,54 +10,74 @@ #BSUB -extsched 'CRAYLINUX[]' set -ax - . $MODULESHOME/init/sh +source "${MODULESHOME}/init/sh" module load PrgEnv-intel #-------------------------------------------------- -export home_dir=/gpfs/hps3/emc/global/noscrub/$LOGNAME/git/fv3gfs/gfs.v15.0.0 -export script_dir=$home_dir/ush -export exec_dir=$home_dir/exec -export fix_fv3_dir=$home_dir/fix -export fregrid=$home_dir/exec/fregrid_parallel -export TMPDIR=/gpfs/hps/ptmp/$LOGNAME/fv3_weight - +export home_dir="/gpfs/hps3/emc/global/noscrub/${LOGNAME}/git/fv3gfs/gfs.v15.0.0" +export script_dir="${home_dir}/ush" +export exec_dir="${home_dir}/exec" +export fix_fv3_dir="${home_dir}/fix" +export fregrid="${home_dir}/exec/fregrid_parallel" +export TMPDIR="/gpfs/hps/ptmp/${LOGNAME}/fv3_weight" #--global lat-lon array size #---------------------------------------------------------- for GG in 1deg 0p5deg 0p25deg 0p125deg; do -#---------------------------------------------------------- + #---------------------------------------------------------- -if [ $GG = 1deg ]; then export nlon=360 ; export nlat=180 ;fi -if [ $GG = 0p5deg ]; then export nlon=720 ; export nlat=360 ;fi -if [ $GG = 0p25deg ]; then export nlon=1440 ; export nlat=720 ;fi -if [ $GG = 0p125deg ]; then export nlon=2880 ; export nlat=1440 ;fi + case "${GG}" in + 1deg) + export nlon=360 + export nlat=180 + ;; + 0p5deg) + export nlon=720 + export nlat=360 + ;; + 0p25deg) + export nlon=1440 + export nlat=720 + ;; + 0p125deg) + export nlon=2880 + export nlat=1440 + ;; + *) + msg="FATAL: Unsupported grid name ${GG}" + export err=100 + err_exit "${msg}" + ;; + esac -#---------------------------------------------------------- -for CASE in C48 C96 C192 C384 C768 C1152 C3072; do -#---------------------------------------------------------- -max_core=24 -export NODES=3; export thread=1 -##if [ $CASE = C3072 ]; then exportNODES=21; export thread=4; fi -export npes=$(((NODES-1)*max_core/thread)) - -export workdir=$TMPDIR/${CASE}_${GG} -mkdir -p $workdir; cd $workdir ||exit 8 - -export native_grid=$fix_fv3_dir/$CASE/${CASE}_mosaic.nc -export remap_file=$fix_fv3_dir/$CASE/remap_weights_${CASE}_${GG}.nc - -#NOTE: we are placing the first process on a node by itself to get the memory it needs -# these npes will be tightly packed on the remaining nodes - -aprun -n 1 -d 24 $fregrid --input_mosaic $native_grid \ - --nlon $nlon --nlat $nlat \ - --remap_file $remap_file \ - --debug : \ - -n $npes -d $thread $fregrid --input_mosaic $native_grid \ - --nlon $nlon --nlat $nlat \ - --remap_file $remap_file \ - --debug + #---------------------------------------------------------- + for CASE in C48 C96 C192 C384 C768 C1152 C3072; do + #---------------------------------------------------------- + max_core=24 + export NODES=3 + export thread=1 + ##if [[ ${CASE} = C3072 ]]; then exportNODES=21; export thread=4; fi + export npes=$(((NODES - 1) * max_core / thread)) -done + export workdir="${TMPDIR}/${CASE}_${GG}" + mkdir -p "${workdir}" + cd "${workdir}" || exit 8 + + export native_grid="${fix_fv3_dir}/${CASE}/${CASE}_mosaic.nc" + export remap_file="${fix_fv3_dir}/${CASE}/remap_weights_${CASE}_${GG}.nc" + + #NOTE: we are placing the first process on a node by itself to get the memory it needs + # these npes will be tightly packed on the remaining nodes + + aprun -n 1 -d 24 "${fregrid}" --input_mosaic "${native_grid}" \ + --nlon "${nlon}" --nlat "${nlat}" \ + --remap_file "${remap_file}" \ + --debug : \ + -n "${npes}" -d "${thread}" "${fregrid}" --input_mosaic "${native_grid}" \ + --nlon "${nlon}" --nlat "${nlat}" \ + --remap_file "${remap_file}" \ + --debug + + done done exit diff --git a/ush/gaussian_sfcanl.sh b/ush/gaussian_sfcanl.sh index 70780e63a8a..ba692404fe5 100755 --- a/ush/gaussian_sfcanl.sh +++ b/ush/gaussian_sfcanl.sh @@ -23,35 +23,12 @@ # CASE Forecast model and restart resolution. Defaults to C768. # CASE_HIST History file output resolution. Defaults to $CASE. # DONST Process NST fields when 'yes'. Default is 'no'. -# OUTPUT_FILE Output gaussian analysis file format. Default is "nemsio" -# Set to "netcdf" for netcdf output file -# Otherwise, output in nemsio. # FIXWGTS Weight file to use for interpolation -# DATA Working directory -# (if nonexistent will be made, used and deleted) -# Defaults to current working directory # COMOUT Output directory # (if nonexistent will be made) # defaults to current working directory -# XC Suffix to add to executables. Defaults to none. # GAUSFCANLEXE Program executable. # Defaults to $EXECgfs/gaussian_sfcanl.x -# INISCRIPT Preprocessing script. Defaults to none. -# LOGSCRIPT Log posting script. Defaults to none. -# ENDSCRIPT Postprocessing script -# defaults to none -# PGMOUT Executable standard output -# defaults to $pgmout, then to '&1' -# PGMERR Executable standard error -# defaults to $pgmerr, then to '&1' -# pgmout Executable standard output default -# pgmerr Executable standard error default -# REDOUT standard output redirect ('1>' or '1>>') -# defaults to '1>', or to '1>>' to append if $PGMOUT is a file -# REDERR standard error redirect ('2>' or '2>>') -# defaults to '2>', or to '2>>' to append if $PGMERR is a file -# VERBOSE Verbose flag (YES or NO) -# defaults to NO # gfs_ver Version number of gfs directory. Default is # v15.0.0. # OMP_NUM_ @@ -60,15 +37,11 @@ # Default is none. # # Exported Shell Variables: -# PGM Current program name # pgm -# ERR Last return code # err # # Modules and files referenced: -# scripts : $INISCRIPT -# $LOGSCRIPT -# $ENDSCRIPT +# scripts : # # programs : $GAUSFCANLEXE # @@ -77,10 +50,9 @@ # ${FIXgfs}/am/global_hyblev.l65.txt # # input data : ${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile*.nc +# ${COMIN_ATMOS_ANALYSIS}/increment.sfc.i006.tile${i}.nc" # -# output data: $PGMOUT -# $PGMERR -# $COMOUT/${APREFIX}analysis.sfc.a006.nc +# output data: $COMOUT/${APREFIX}analysis.sfc.a006.nc # # Remarks: # @@ -95,103 +67,78 @@ # # Attributes: # Language: POSIX shell -# Machine: IBM SP # ################################################################################ CASE=${CASE:-C768} CASE_HIST=${CASE_HIST:-${CASE}} resh=${CASE_HIST:1} -LONB_CASE=$((resh*4)) -LATB_CASE=$((resh*2)) -LONB_SFC=${LONB_SFC:-$LONB_CASE} -LATB_SFC=${LATB_SFC:-$LATB_CASE} +LONB_CASE=$((resh * 4)) +LATB_CASE=$((resh * 2)) +LONB_SFC=${LONB_SFC:-${LONB_CASE}} +LATB_SFC=${LATB_SFC:-${LATB_CASE}} DONST=${DONST:-"NO"} LEVS=${LEVS:-64} -LEVSP1=$(($LEVS+1)) +LEVSP1=$((LEVS + 1)) FIXWGTS=${FIXWGTS:-${FIXorog}/${CASE}/fv3_SCRIP_${CASE}_GRIDSPEC_lon${LONB_SFC}_lat${LATB_SFC}.gaussian.neareststod.nc} # Filenames. -XC=${XC:-} -GAUSFCANLEXE=${GAUSFCANLEXE:-$EXECgfs/gaussian_sfcanl.x} +GAUSFCANLEXE=${GAUSFCANLEXE:-${EXECgfs}/gaussian_sfcanl.x} SIGLEVEL=${SIGLEVEL:-${FIXgfs}/am/global_hyblev.l${LEVSP1}.txt} # Other variables. -export PGMOUT=${PGMOUT:-${pgmout:-'&1'}} -export PGMERR=${PGMERR:-${pgmerr:-'&2'}} -export REDOUT=${REDOUT:-'1>'} -export REDERR=${REDERR:-'2>'} # Set defaults ################################################################################ # Preprocessing -${INISCRIPT:-} -pwd=$(pwd) -if [[ ! -d "${COMOUT_ATMOS_ANALYSIS}" ]]; then - mkdir -p "${COMOUT_ATMOS_ANALYSIS}" -fi ################################################################################ # Make surface analysis -export PGM=$GAUSFCANLEXE -export pgm=$PGM -$LOGSCRIPT - -iy=${PDY:0:4} -im=${PDY:4:2} -id=${PDY:6:2} -ih=${cyc} - -export OMP_NUM_THREADS=${OMP_NUM_THREADS_SFC:-1} # input interpolation weights -${NLN} "${FIXWGTS}" "./weights.nc" +cpreq "${FIXWGTS}" "./weights.nc" # input analysis tiles (with nst records) -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile1.nc" "./anal.tile1.nc" -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile2.nc" "./anal.tile2.nc" -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile3.nc" "./anal.tile3.nc" -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile4.nc" "./anal.tile4.nc" -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile5.nc" "./anal.tile5.nc" -${NLN} "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile6.nc" "./anal.tile6.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile1.nc" "./anal.tile1.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile2.nc" "./anal.tile2.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile3.nc" "./anal.tile3.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile4.nc" "./anal.tile4.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile5.nc" "./anal.tile5.nc" +cpreq "${COMIN_ATMOS_RESTART}/${PDY}.${cyc}0000.sfcanl_data.tile6.nc" "./anal.tile6.nc" # input orography tiles -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile1.nc" "./orog.tile1.nc" -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile2.nc" "./orog.tile2.nc" -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile3.nc" "./orog.tile3.nc" -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile4.nc" "./orog.tile4.nc" -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile5.nc" "./orog.tile5.nc" -${NLN} "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile6.nc" "./orog.tile6.nc" - -${NLN} "${SIGLEVEL}" "./vcoord.txt" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile1.nc" "./orog.tile1.nc" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile2.nc" "./orog.tile2.nc" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile3.nc" "./orog.tile3.nc" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile4.nc" "./orog.tile4.nc" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile5.nc" "./orog.tile5.nc" +cpreq "${FIXorog}/${CASE}/${CASE}.mx${OCNRES}_oro_data.tile6.nc" "./orog.tile6.nc" -# output gaussian global surface analysis files -${NLN} "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.sfc.a006.nc" "./sfc.gaussian.analysis.file" +cpreq "${SIGLEVEL}" "./vcoord.txt" # Namelist uses booleans now -if [[ ${DONST} == "YES" ]]; then do_nst='.true.'; else do_nst='.false.'; fi +if [[ "${DONST}" == "YES" ]]; then + do_nst=".true." +else + do_nst=".false." +fi -#Add soil increments to gdas gaussian sfcanal if they are not added by gcycle (i.e., when landiau=true) +# Add soil increments to gdas gaussian sfcanal if they are not added by gcycle (i.e., when landiau=true) LSOIL_INCR=${LSOIL_INCR:-2} -if [[ "${DO_LAND_IAU:-.false.}" == ".true." ]]; then +if [[ "${DO_LAND_IAU:-.false.}" == ".true." ]]; then for i in $(seq 1 6); do - sfc_inc="${COMOUT_ATMOS_ANALYSIS}/increment.sfc.i006.tile${i}.nc" - if [[ ! -f "${sfc_inc}" ]]; then - echo "Error! gaussian sfc analysis missing increment file ${sfc_inc}" - exit 1 - else - ${NLN} "${sfc_inc}" "./sfc_inc.tile${i}.nc" - fi + sfc_inc="${COMIN_ATMOS_ANALYSIS}/increment.sfc.i006.tile${i}.nc" + cpreq "${sfc_inc}" "./sfc_inc.tile${i}.nc" done fi # Executable namelist -cat < fort.41 - &setup - yy=${iy}, - mm=${im}, - dd=${id}, - hh=${ih}, +cat << EOF > fort.41 +&setup + yy=${PDY:0:4}, + mm=${PDY:4:2}, + dd=${PDY:6:2}, + hh=${cyc}, igaus=${LONB_SFC}, jgaus=${LATB_SFC}, donst=${do_nst}, @@ -200,19 +147,25 @@ cat < fort.41 add_soil_inc=${DO_LAND_IAU}, lsoil_incr=${LSOIL_INCR}, sfc_inc_file="./sfc_inc", - / +/ EOF +cat fort.41 +export pgm="${GAUSFCANLEXE}" +export OMP_NUM_THREADS=${OMP_NUM_THREADS_SFC:-1} ${APRUNSFC} "${GAUSFCANLEXE}" - export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: ${GAUSFCANLEXE} returned non-zero exit status!" - exit "${err}" + echo "FATAL ERROR: ${GAUSFCANLEXE} returned non-zero exit status!" + exit "${err}" +fi + +# output gaussian global surface analysis files +if [[ -f "sfc.gaussian.analysis.file" ]]; then + cpfs "./sfc.gaussian.analysis.file" "${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.sfc.a006.nc" fi ################################################################################ # Postprocessing -cd "${pwd}" exit 0 diff --git a/ush/getdump.sh b/ush/getdump.sh index 7c853f21de0..55f4a9fc5ab 100755 --- a/ush/getdump.sh +++ b/ush/getdump.sh @@ -12,23 +12,23 @@ DUMP_SUFFIX=${DUMP_SUFFIX:-""} # Exit if SOURCE_DIR does not exist if [[ ! -s "${SOURCE_DIR}" ]]; then - echo "***ERROR*** DUMP SOURCE_DIR=${SOURCE_DIR} does not exist" - exit 99 + echo "***ERROR*** DUMP SOURCE_DIR=${SOURCE_DIR} does not exist" + exit 99 fi - + # Create TARGET_DIR if is does not exist if [[ ! -s "${TARGET_DIR}" ]]; then - mkdir -p "${TARGET_DIR}" + mkdir -p "${TARGET_DIR}" fi # Set file prefix prefix="${RUN}.t${HH}z." # Link dump files from SOURCE_DIR to TARGET_DIR -cd "${SOURCE_DIR}" +cd "${SOURCE_DIR}" || exit 1 if [[ -s "${prefix}updated.status.tm00.bufr_d" ]]; then - for file in $(ls ${prefix}*); do - ${NLN} "${SOURCE_DIR}/${file}" "${TARGET_DIR}/${file}" + for file in "${prefix}"*; do + ${NLN} "${SOURCE_DIR}/${file}" "${TARGET_DIR}/${file}" done else echo "***ERROR*** ${prefix}updated.status.tm00.bufr_d NOT FOUND in ${SOURCE_DIR}" diff --git a/ush/getges.sh b/ush/getges.sh index f7a6c95eaa0..2922261b267 100755 --- a/ush/getges.sh +++ b/ush/getges.sh @@ -48,123 +48,104 @@ # Example 5. Get the 24-hour GFS forecast sigma file valid at 1998100112. # getges -t sigcur -v 1998100112 -f 24 -e gfs sigfile # -# History: 1996 December Iredell Initial implementation -# 1997 March Iredell Nine new filetypes -# 1997 April Iredell Two new filetypes and -f option -# 1997 December Iredell Four new filetypes -# 1998 April Iredell 4-digit year allowed; -# sigges internal date no longer checked -# 1998 May Iredell T170L42 defaulted; four new filetypes -# and two filetypes deleted -# 1998 June Rogers Nam types added -# 1998 September Iredell high is default resolution -# 2000 March Iredell Cdas and -n option -# 2000 June Iredell Eight new filetypes -# 2002 April Treadon T254L64 defaulted; add angle dependent -# bias correction file -# 2003 March Iredell GFS network out to 384 hours -# 2003 August Iredell Hourly global guesses -# 2005 September Treadon Add satellite data count file (satcnt) -# 2006 September Gayno Add high-res snow analysis -# 2009 January Rogers Added sfluxgrb file -# 2011 April Rogers Added GFS pg2ges file -# 2016 May Menlove Changed GETGES_COM variable to $COMINmodel -# 2016 November Iredell Adapted getges for NEMS GSM -# Also removed a lot of dead wood -# ################################################################################ #------------------------------------------------------------------------------- # Set some default parameters. -fhbeg=03 # hour to begin searching backward for guess -fhinc=03 # hour to increment backward in search -fhend=384 # hour to end searching backward for guess +fhbeg=03 # hour to begin searching backward for guess +fhinc=03 # hour to increment backward in search +fhend=384 # hour to end searching backward for guess #------------------------------------------------------------------------------- # Get options and arguments. -netwk=global # default network -envir=prod # default environment -fhour=any # default forecast hour -quiet=YES # default quiet mode -resol=high # default resolution -typef=sigges # default filetype -valid=${PDY}${cyc} # default valid date +netwk=global # default network +envir=prod # default environment +fhour=any # default forecast hour +quiet=YES # default quiet mode +resol=high # default resolution +typef=sigges # default filetype +valid=${PDY}${cyc} # default valid date err=0 -while getopts n:e:f:qr:t:v: opt;do - case $opt in - n) netwk="$OPTARG";; - e) envir="$OPTARG";; - f) fhour="$OPTARG";; - q) quiet=NO;; - r) resol="$OPTARG";; - t) typef="$OPTARG";; - v) valid="$OPTARG";; - \?) err=1;; - esac +while getopts n:e:f:qr:t:v: opt; do + case "${opt}" in + n) netwk="${OPTARG}" ;; + e) envir="${OPTARG}" ;; + f) fhour="${OPTARG}" ;; + q) quiet=NO ;; + r) resol="${OPTARG}" ;; + t) typef="${OPTARG}" ;; + v) valid="${OPTARG}" ;; + \?) err=1 ;; + *) + echo: "Unknown option ${opt}!" + exit 2 + ;; + esac done -shift $(($OPTIND-1)) +shift $((OPTIND - 1)) gfile=$1 -if [[ -z $valid ]];then - echo "$0: either -v option or environment variables PDY and cyc must be set" >&2 -elif [[ $# -gt 1 ]];then - echo "$0: too many positional arguments" >&2 -elif [[ $err -ne 0 ]];then - echo "$0: invalid option" >&2 +if [[ -z "${valid}" ]]; then + echo "$0: either -v option or environment variables PDY and cyc must be set" >&2 +elif [[ $# -gt 1 ]]; then + echo "$0: too many positional arguments" >&2 +elif [[ "${err}" -ne 0 ]]; then + echo "$0: invalid option" >&2 fi -if [[ $gfile = '?' || $# -gt 1 || $err -ne 0 || -z $valid ||\ - $netwk = '?' || $envir = '?' || $fhour = '?' || $resol = '?' ||\ - $typef = '?' || $valid = '?' ]];then - echo "Usage: getges.sh [-n network] [-e environment] [-f fhour] [-q] [-r resolution]" >&2 - echo " [-t filetype] [-v valid] [gfile]" >&2 - if [[ $netwk = '?' ]];then - echo " network choices:" >&2 - echo " global (default), namopl, gdas, gfs, cdas, etc." >&2 - elif [[ $envir = '?' ]];then - echo " environment choices:" >&2 - echo " prod (default), test, para, dump, prx" >&2 - echo " (some network values allowed for compatibility)" >&2 - elif [[ $fhour = '?' ]];then - echo " fhour is optional specific forecast hour" >&2 - elif [[ $resol = '?' ]];then - echo " resolution choices:" >&2 - echo " high (default), 25464, 17042, 12628, low, 6228, namopl, any" >&2 - elif [[ $typef = '?' ]];then - echo " filetype choices:" >&2 - echo " sigges (default), siggm3, siggm2, siggm1, siggp1, siggp2, siggp3," >&2 - echo " sfcges, sfcgm3, sfcgm2, sfcgm1, sfcgp1, sfcgp2, sfcgp3," >&2 - echo " sfgges, sfggp3, biascr, satang, satcnt, gesfil" >&2 - echo " pgbges, pgiges, pgbgm6, pgigm6, pgbgm3, pgigm3, pgbgp3, pgigp3," >&2 - echo " sigcur, sfccur, pgbcur, pgicur, prepqc, tcvg12, tcvges, tcvitl," >&2 - echo " enggrb, enggri, icegrb, icegri, snogrb, snogri, sstgrb, sstgri," >&2 - echo " pg2cur, pg2ges, restrt," >&2 - echo " natges, natgm3, natgm2, natgm1, natgp1, natgp2, natgp3, natcur," >&2 - echo " nsfges, nsfgm3, nsfgm2, nsfgm1, nsfgp1, nsfgp2, nsfgp3, nsfcur," >&2 - echo " nstcur, nflges, nflgp3," >&2 - elif [[ $valid = '?' ]];then - echo " valid is the valid date in yyyymmddhh or yymmddhh form" >&2 - echo " (default is environmental variable $PDY$cyc)" >&2 - elif [[ $gfile = '?' ]];then - echo " gfile is the guess file to write" >&2 - echo " (default is to write the guess file name to stdout)" >&2 - else - echo " (Note: set a given option to '?' for more details)" >&2 - fi - exit 1 + +if [[ "${gfile}" == '?' || $# -gt 1 || "${err}" -ne 0 || -z "${valid}" || + "${netwk}" == '?' || "${envir}" == '?' || "${fhour}" == '?' || "${resol}" == '?' || + "${typef}" == '?' || "${valid}" == '?' ]]; then + echo "Usage: getges.sh [-n network] [-e environment] [-f fhour] [-q] [-r resolution]" >&2 + echo " [-t filetype] [-v valid] [gfile]" >&2 + if [[ "${netwk}" == '?' ]]; then + echo " network choices:" >&2 + echo " global (default), namopl, gdas, gfs, cdas, etc." >&2 + elif [[ "${envir}" == '?' ]]; then + echo " environment choices:" >&2 + echo " prod (default), test, para, dump, prx" >&2 + echo " (some network values allowed for compatibility)" >&2 + elif [[ "${fhour}" == '?' ]]; then + echo " fhour is optional specific forecast hour" >&2 + elif [[ "${resol}" == '?' ]]; then + echo " resolution choices:" >&2 + echo " high (default), 25464, 17042, 12628, low, 6228, namopl, any" >&2 + elif [[ "${typef}" == '?' ]]; then + echo " filetype choices:" >&2 + echo " sigges (default), siggm3, siggm2, siggm1, siggp1, siggp2, siggp3," >&2 + echo " sfcges, sfcgm3, sfcgm2, sfcgm1, sfcgp1, sfcgp2, sfcgp3," >&2 + echo " sfgges, sfggp3, biascr, satang, satcnt, gesfil" >&2 + echo " pgbges, pgiges, pgbgm6, pgigm6, pgbgm3, pgigm3, pgbgp3, pgigp3," >&2 + echo " sigcur, sfccur, pgbcur, pgicur, prepqc, tcvg12, tcvges, tcvitl," >&2 + echo " enggrb, enggri, icegrb, icegri, snogrb, snogri, sstgrb, sstgri," >&2 + echo " pg2cur, pg2ges, restrt," >&2 + echo " natges, natgm3, natgm2, natgm1, natgp1, natgp2, natgp3, natcur," >&2 + echo " nsfges, nsfgm3, nsfgm2, nsfgm1, nsfgp1, nsfgp2, nsfgp3, nsfcur," >&2 + echo " nstcur, nflges, nflgp3," >&2 + elif [[ "${valid}" == '?' ]]; then + echo " valid is the valid date in yyyymmddhh or yymmddhh form" >&2 + echo " (default is environmental variable ${PDY}${cyc})" >&2 + elif [[ "${gfile}" == '?' ]]; then + echo " gfile is the guess file to write" >&2 + echo " (default is to write the guess file name to stdout)" >&2 + else + echo " (Note: set a given option to '?' for more details)" >&2 + fi + exit 1 fi -if [[ $envir != prod && $envir != test && $envir != para && $envir != dump && $envir != pr? && $envir != dev ]];then - netwk=$envir - envir=prod - echo '************************************************************' >&2 - echo '* WARNING: Using "-e" is deprecated in this case. *' >&2 - echo '* Please use "-n" instead. *' >&2 - echo '************************************************************' >&2 +if [[ "${envir}" != prod && "${envir}" != test && "${envir}" != para && "${envir}" != dump && "${envir}" != pr? && "${envir}" != dev ]]; then + netwk="${envir}" + envir=prod + echo '************************************************************' >&2 + echo '* WARNING: Using "-e" is deprecated in this case. *' >&2 + echo '* Please use "-n" instead. *' >&2 + echo '************************************************************' >&2 fi -if [[ "$netwk" = "namopl" || "$resol" = "namopl" ]];then - netwk=namopl - typef=restrt - resol=namopl +if [[ "${netwk}" == "namopl" || "${resol}" == "namopl" ]]; then + netwk=namopl + typef=restrt + resol=namopl fi if [[ "${resol}" == "57464" || "${resol}" == "38264" || "${resol}" == "19064" || "${resol}" == "25464" || "${resol}" == "17042" || "${resol}" == "12628" ]]; then resol=high @@ -172,30 +153,27 @@ fi if [[ "${resol}" == "6228" ]]; then resol=low fi -resolsuf="" -if [[ ${resol} == *deg ]]; then - resolsuf=.$resol -fi -fhbeg=$(${NHOUR:?} $valid) -if [[ ${fhbeg} -le 0 ]]; then +fhbeg=$(${NHOUR:?} "${valid}") +if [[ "${fhbeg}" -le 0 ]]; then fhbeg=03 fi -((fhbeg=(10#${fhbeg}-1)/3*3+3)) -if [[ $fhbeg -lt 10 ]]; then +((fhbeg = (10#${fhbeg} - 1) / 3 * 3 + 3)) +if [[ "${fhbeg}" -lt 10 ]]; then fhbeg="0${fhbeg}" fi -if [[ $typef = enggrb ]];then - typef=icegrb - echo '************************************************************' >&2 - echo '* WARNING: Using "-t enggrb" is now deprecated. *' >&2 - echo '* Please use "-t icegrb". *' >&2 - echo '************************************************************' >&2 -elif [[ $typef = enggri ]];then - typef=icegri - echo '************************************************************' >&2 - echo '* WARNING: Using "-t enggri" is now deprecated. *' >&2 - echo '* Please use "-t icegri". *' >&2 - echo '************************************************************' >&2 + +if [[ "${typef}" == enggrb ]]; then + typef=icegrb + echo '************************************************************' >&2 + echo '* WARNING: Using "-t enggrb" is now deprecated. *' >&2 + echo '* Please use "-t icegrb". *' >&2 + echo '************************************************************' >&2 +elif [[ "${typef}" == enggri ]]; then + typef=icegri + echo '************************************************************' >&2 + echo '* WARNING: Using "-t enggri" is now deprecated. *' >&2 + echo '* Please use "-t icegri". *' >&2 + echo '************************************************************' >&2 fi #------------------------------------------------------------------------------- @@ -204,1209 +182,1485 @@ geslist="" getlist00="" # GDAS -if [[ "$netwk" = "gdas" ]];then - if [ -z "$COMINgdas" ]; then - echo "getges.sh ERROR: The \$COMINgdas variable must be defined." >&2 - exit 1 - fi - fhend=12 - case $typef in - biascr) geslist=' - $COMINgdas/gdas.t${cyc}z.abias' - ;; - biascr_pc) geslist=' - $COMINgdas/gdas.t${cyc}z.abias_pc' - ;; - biascr_air) geslist=' - $COMINgdas/gdas.t${cyc}z.abias_air' - ;; - radstat) geslist=' - $COMINgdas/gdas.t${cyc}z.radstat' - ;; - pgbges) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrbh$fh - $COMINgdas/gdas.t${cyc}z.pgrbf$fh' - ;; - pg2ges) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$gh' - ;; - pgbgm6) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrbh$fhm6 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhm6' - ;; - pgbgm3) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrbh$fhm3 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhm3' - ;; - pgbgp3) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrbh$fhp3 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhp3' - ;; - pgbcur) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrbh$fh - $COMINgdas/gdas.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pg2cur) geslist=' - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$gh' - fhbeg=00 - ;; - prepqc) geslist=' - $COMINgdas/gdas.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvg12) geslist=' - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=12 - fhend=12 - ;; - tcvges) geslist=' - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=06 - fhend=06 - ;; - tcvitl) geslist=' - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $COMINgdas/gdas.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $COMINgdas/gdas.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogrb_574) geslist=' - $COMINgdas/gdas.t${cyc}z.snogrb_t574.1152.576' - fhbeg=00 - fhinc=06 - ;; - snogrb_1534) geslist=' - $COMINgdas/gdas.t${cyc}z.snogrb_t1534.3072.1536' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $COMINgdas/gdas.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - natges) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$gh.nemsio' - ;; - natgm3) geslist=' - $COMINgdas/gdas.t${cyc}z.atm.f$ghm3.nemsio' - ;; - natgm2) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$ghm2.nemsio' - ;; - natgm1) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$ghm1.nemsio' - ;; - natgp1) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$ghp1.nemsio' - ;; - natgp2) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$ghp2.nemsio' - ;; - natgp3) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$ghp3.nemsio' - ;; - natcur) geslist=' - $COMINgdas/gdas.t${cyc}z.atmf$gh.nemsio' - getlist00=' - $COMINgdas/gdas.t${cyc}z.atmanl.nemsio' - fhbeg=00 - ;; - nsfges) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$gh.nemsio' - ;; - nsfgm3) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghm3.nemsio' - ;; - nsfgm2) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghm2.nemsio' - ;; - nsfgm1) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghm1.nemsio' - ;; - nsfgp1) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghp1.nemsio' - ;; - nsfgp2) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghp2.nemsio' - ;; - nsfgp3) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$ghp3.nemsio' - ;; - nsfcur) geslist=' - $COMINgdas/gdas.t${cyc}z.sfcf$gh.nemsio' - getlist00=' - $COMINgdas/gdas.t${cyc}z.sfcanl.nemsio' - fhbeg=00 - ;; - nstcur) geslist=' - $COMINgdas/gdas.t${cyc}z.nstf$gh.nemsio' - getlist00=' - $COMINgdas/gdas.t${cyc}z.nstanl.nemsio' - fhbeg=00 - ;; - nflges) geslist=' - $COMINgdas/gdas.t${cyc}z.flxf$gh.nemsio' - ;; - nflgp3) geslist=' - $COMINgdas/gdas.t${cyc}z.flxf$ghp3.nemsio' - ;; - nflcur) geslist=' - $COMINgdas/gdas.t${cyc}z.flxf$gh.nemsio' - fhbeg=00 - ;; - esac +if [[ "${netwk}" == "gdas" ]]; then + if [[ -z "${COMINgdas}" ]]; then + echo "getges.sh ERROR: The \${COMINgdas} variable must be defined." >&2 + exit 1 + fi + fhend=12 + # shellcheck disable=SC2016 + case "${typef}" in + biascr) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.abias' + ;; + biascr_pc) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.abias_pc' + ;; + biascr_air) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.abias_air' + ;; + radstat) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.radstat' + ;; + pgbges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fh}' + ;; + pg2ges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${gh}' + ;; + pgbgm6) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhm6} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhm6}' + ;; + pgbgm3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhm3} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhm3}' + ;; + pgbgp3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhp3} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhp3}' + ;; + pgbcur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pg2cur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${gh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvg12) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=12 + fhend=12 + ;; + tcvges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=06 + fhend=06 + ;; + tcvitl) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogrb_574) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.snogrb_t574.1152.576' + fhbeg=00 + fhinc=06 + ;; + snogrb_1534) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.snogrb_t1534.3072.1536' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + natges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${gh}.nemsio' + ;; + natgm3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atm.f${ghm3}.nemsio' + ;; + natgm2) + geslist=' + + ${COMINgdas}/gdas.t${cyc}z.atmf${ghm2}.nemsio' + ;; + natgm1) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${ghm1}.nemsio' + ;; + natgp1) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp1}.nemsio' + ;; + natgp2) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp2}.nemsio' + ;; + natgp3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp3}.nemsio' + ;; + natcur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.atmf${gh}.nemsio' + getlist00=' + ${COMINgdas}/gdas.t${cyc}z.atmanl.nemsio' + fhbeg=00 + ;; + nsfges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${gh}.nemsio' + ;; + nsfgm3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm3}.nemsio' + ;; + nsfgm2) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm2}.nemsio' + ;; + nsfgm1) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm1}.nemsio' + ;; + nsfgp1) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp1}.nemsio' + ;; + nsfgp2) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp2}.nemsio' + ;; + nsfgp3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp3}.nemsio' + ;; + nsfcur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.sfcf${gh}.nemsio' + getlist00=' + ${COMINgdas}/gdas.t${cyc}z.sfcanl.nemsio' + fhbeg=00 + ;; + nstcur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.nstf${gh}.nemsio' + getlist00=' + ${COMINgdas}/gdas.t${cyc}z.nstanl.nemsio' + fhbeg=00 + ;; + nflges) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.flxf${gh}.nemsio' + ;; + nflgp3) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.flxf${ghp3}.nemsio' + ;; + nflcur) + geslist=' + ${COMINgdas}/gdas.t${cyc}z.flxf${gh}.nemsio' + fhbeg=00 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac # CFS-CDAS -elif [[ "$netwk" = "cfs-cdas" ]];then - if [ -z "$COMINcfs_cdas" ]; then - echo "getges.sh ERROR: The \$COMINcfs_cdas variable must be defined." >&2 - exit 1 - fi - fhend=12 - case $typef in - sigges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fh' - ;; - siggm3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhm3' - ;; - siggm2) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhm2' - ;; - siggm1) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhm1' - ;; - siggp1) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhp1' - ;; - siggp2) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhp2' - ;; - siggp3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fhp3' - ;; - sfcges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fh}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fh' - ;; - sfcgm3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhm3}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhm3' - ;; - sfcgm2) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhm2}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhm2' - ;; - sfcgm1) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhm1}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhm1' - ;; - sfcgp1) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhp1}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhp1' - ;; - sfcgp2) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhp2}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhp2' - ;; - sfcgp3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf${fhp3}.LIS - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fhp3' - ;; - biascr) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.abias' - ;; - satang) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.satang' - ;; - satcnt) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.satcnt' - ;; - gesfil) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.gesfile' - fhbeg=00 - fhend=00 - ;; - sfgges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sfluxgrbf$fh' - ;; - sfggp3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sfluxgrbf$fhp3' - ;; - pgbges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbh$fh - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbf$fh' - ;; - pgiges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbih$fh - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbif$fh' - ;; - pgbgm6) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbh$fhm6 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbf$fhm6' - ;; - pgigm6) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbih$fhm6 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbif$fhm6' - ;; - pgbgm3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbh$fhm3 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbf$fhm3' - ;; - pgigm3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbih$fhm3 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbif$fhm3' - ;; - pgbgp3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbh$fhp3 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbf$fhp3' - ;; - pgigp3) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbih$fhp3 - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbif$fhp3' - ;; - sigcur) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sf$fh' - getlist00=' - $COMINcfs_cdas/cdas1.t${cyc}z.sanl' - fhbeg=00 - ;; - sfccur) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.bf$fh' - getlist00=' - $COMINcfs_cdas/cdas1.t${cyc}z.sfcanl' - fhbeg=00 - ;; - pgbcur) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbh$fh - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pgicur) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbih$fh - $COMINcfs_cdas/cdas1.t${cyc}z.pgrbif$fh' - fhbeg=00 - ;; - prepqc) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvg12) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=12 - fhend=12 - ;; - tcvges) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=06 - fhend=06 - ;; - tcvitl) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - icegri) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.engicegrb.index' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogrb_high) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb_t574 - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb_t382' - fhbeg=00 - fhinc=06 - ;; - snogrb_382) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb_t382' - fhbeg=00 - fhinc=06 - ;; - snogrb_574) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb_t574' - fhbeg=00 - fhinc=06 - ;; - snogri) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.snogrb.index' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - sstgri) geslist=' - $COMINcfs_cdas/cdas1.t${cyc}z.sstgrb.index' - fhbeg=00 - fhinc=06 - ;; - esac +elif [[ "${netwk}" == "cfs-cdas" ]]; then + if [[ -z "${COMINcfs_cdas}" ]]; then + echo "getges.sh ERROR: The \${COMINcfs_cdas} variable must be defined." >&2 + exit 1 + fi + fhend=12 + # shellcheck disable=SC2016 + case "${typef}" in + sigges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fh}' + ;; + siggm3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhm3}' + ;; + siggm2) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhm2}' + ;; + siggm1) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhm1}' + ;; + siggp1) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhp1}' + ;; + siggp2) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhp2}' + ;; + siggp3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fhp3}' + ;; + sfcges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fh}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fh}' + ;; + sfcgm3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm3}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm3}' + ;; + sfcgm2) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm2}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm2}' + ;; + sfcgm1) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm1}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhm1}' + ;; + sfcgp1) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp1}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp1}' + ;; + sfcgp2) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp2}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp2}' + ;; + sfcgp3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp3}.LIS + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fhp3}' + ;; + biascr) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.abias' + ;; + satang) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.satang' + ;; + satcnt) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.satcnt' + ;; + gesfil) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.gesfile' + fhbeg=00 + fhend=00 + ;; + sfgges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sfluxgrbf${fh}' + ;; + sfggp3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sfluxgrbf${fhp3}' + ;; + pgbges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbh${fh} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbf${fh}' + ;; + pgiges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbih${fh} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbif${fh}' + ;; + pgbgm6) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbh${fhm6} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbf${fhm6}' + ;; + pgigm6) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbih${fhm6} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbif${fhm6}' + ;; + pgbgm3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbh${fhm3} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbf${fhm3}' + ;; + pgigm3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbih${fhm3} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbif${fhm3}' + ;; + pgbgp3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbh${fhp3} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbf${fhp3}' + ;; + pgigp3) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbih${fhp3} + + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbif${fhp3}' + ;; + sigcur) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sf${fh}' + getlist00=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sanl' + fhbeg=00 + ;; + sfccur) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.bf${fh}' + getlist00=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sfcanl' + fhbeg=00 + ;; + pgbcur) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbh${fh} + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pgicur) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbih${fh} + + ${COMINcfs_cdas}/cdas1.t${cyc}z.pgrbif${fh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvg12) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=12 + fhend=12 + ;; + tcvges) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=06 + fhend=06 + ;; + tcvitl) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + icegri) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.engicegrb.index' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogrb_high) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb_t574 + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb_t382' + fhbeg=00 + fhinc=06 + ;; + snogrb_382) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb_t382' + fhbeg=00 + fhinc=06 + ;; + snogrb_574) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb_t574' + fhbeg=00 + fhinc=06 + ;; + snogri) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.snogrb.index' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + sstgri) + geslist=' + ${COMINcfs_cdas}/cdas1.t${cyc}z.sstgrb.index' + fhbeg=00 + fhinc=06 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac # GFS -elif [[ "$netwk" = "gfs" ]];then - if [ -z "$COMINgfs" ]; then - echo "getges.sh ERROR: The \$COMINgfs variable must be defined." >&2 - exit 1 - fi - fhend=384 - case $typef in - pgbcur) geslist=' - $COMINgfs/gfs.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pg2cur) geslist=' - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$gh' - fhbeg=00 - ;; - prepqc) geslist=' - $COMINgfs/gfs.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvitl) geslist=' - $COMINgfs/gfs.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $COMINgfs/gfs.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $COMINgfs/gfs.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogrb_1534) geslist=' - $COMINgfs/gfs.t${cyc}z.snogrb_t1534.3072.1536' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $COMINgfs/gfs.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - natcur) geslist=' - $COMINgfs/gfs.t${cyc}z.atm.f$gh.nemsio' - getlist00=' - $COMINgfs/gfs.t${cyc}z.atmanl.nemsio' - fhbeg=00 - ;; - nsfcur) geslist=' - $COMINgfs/gfs.t${cyc}z.sfcf$gh.nemsio' - getlist00=' - $COMINgfs/gfs.t${cyc}z.sfcanl.nemsio' - fhbeg=00 - ;; - nstcur) geslist=' - $COMINgfs/gfs.t${cyc}z.nstf$gh.nemsio' - getlist00=' - $COMINgfs/gfs.t${cyc}z.nstanl.nemsio' - fhbeg=00 - ;; - nflcur) geslist=' - $COMINgfs/gfs.t${cyc}z.flxf$gh.nemsio' - fhbeg=00 - ;; - esac +elif [[ "${netwk}" == "gfs" ]]; then + if [[ -z "${COMINgfs}" ]]; then + echo "getges.sh ERROR: The \${COMINgfs} variable must be defined." >&2 + exit 1 + fi + fhend=384 + # shellcheck disable=SC2016 + case "${typef}" in + pgbcur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pg2cur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${gh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvitl) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogrb_1534) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.snogrb_t1534.3072.1536' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + natcur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.atm.f${gh}.nemsio' + getlist00=' + + ${COMINgfs}/gfs.t${cyc}z.atmanl.nemsio' + fhbeg=00 + ;; + nsfcur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.sfcf${gh}.nemsio' + getlist00=' + ${COMINgfs}/gfs.t${cyc}z.sfcanl.nemsio' + fhbeg=00 + ;; + nstcur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.nstf${gh}.nemsio' + getlist00=' + ${COMINgfs}/gfs.t${cyc}z.nstanl.nemsio' + fhbeg=00 + ;; + nflcur) + geslist=' + ${COMINgfs}/gfs.t${cyc}z.flxf${gh}.nemsio' + fhbeg=00 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac # CDAS -elif [[ "$netwk" = "cdas" ]];then - if [ -z "$COMINcdas" ]; then - echo "getges.sh ERROR: The \$COMINcdas variable must be defined." >&2 - exit 1 - fi - fhbeg=06 - fhend=06 - case $typef in - sigges) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fh' - ;; - siggm3) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhm3' - ;; - siggm2) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhm2' - ;; - siggm1) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhm1' - ;; - siggp1) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhp1' - ;; - siggp2) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhp2' - ;; - siggp3) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fhp3' - ;; - sfcges) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fh' - ;; - sfcgm3) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhm3' - ;; - sfcgm2) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhm2' - ;; - sfcgm1) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhm1' - ;; - sfcgp1) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhp1' - ;; - sfcgp2) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhp2' - ;; - sfcgp3) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fhp3' - ;; - biascr) geslist=' - $COMINcdas/cdas.t${cyc}z.abias' - ;; - satang) geslist=' - $COMINcdas/cdas.t${cyc}z.satang' - ;; - satcnt) geslist=' - $COMINcdas/cdas.t${cyc}z.satcnt' - ;; - gesfil) geslist=' - $COMINcdas/cdas.t${cyc}z.gesfile' - fhbeg=00 - fhend=00 - ;; - pgbges) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbf$fh' - ;; - pgiges) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbif$fh' - ;; - pgbgm6) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbf$fhm6' - ;; - pgigm6) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbif$fhm6' - ;; - pgbgm3) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbf$fhm3' - ;; - pgigm3) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbif$fhm3' - ;; - pgbgp3) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbf$fhp3' - ;; - pgigp3) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbif$fhp3' - ;; - sigcur) geslist=' - $COMINcdas/cdas.t${cyc}z.sf$fh' - getlist00=' - $COMINcdas/cdas.t${cyc}z.sanl' - fhbeg=00 - ;; - sfccur) geslist=' - $COMINcdas/cdas.t${cyc}z.bf$fh' - getlist00=' - $COMINcdas/cdas.t${cyc}z.sfcanl' - fhbeg=00 - ;; - pgbcur) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pgicur) geslist=' - $COMINcdas/cdas.t${cyc}z.pgrbif$fh' - fhbeg=00 - ;; - prepqc) geslist=' - $COMINcdas/cdas.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvg12) geslist=' - $COMINcdas/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=12 - fhend=12 - ;; - tcvges) geslist=' - $COMINcdas/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=06 - fhend=06 - ;; - tcvitl) geslist=' - $COMINcdas/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $COMINcdas/cdas.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - icegri) geslist=' - $COMINcdas/cdas.t${cyc}z.engicegrb.index' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $COMINcdas/cdas.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogri) geslist=' - $COMINcdas/cdas.t${cyc}z.snogrb.index' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $COMINcdas/cdas.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - sstgri) geslist=' - $COMINcdas/cdas.t${cyc}z.sstgrb.index' - fhbeg=00 - fhinc=06 - ;; - esac +elif [[ "${netwk}" == "cdas" ]]; then + if [[ -z "${COMINcdas}" ]]; then + echo "getges.sh ERROR: The \${COMINcdas} variable must be defined." >&2 + exit 1 + fi + fhbeg=06 + fhend=06 + # shellcheck disable=SC2016 + case ${typef} in + sigges) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fh}' + ;; + siggm3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhm3}' + ;; + siggm2) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhm2}' + ;; + siggm1) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhm1}' + ;; + siggp1) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhp1}' + ;; + siggp2) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhp2}' + ;; + siggp3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fhp3}' + ;; + sfcges) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fh}' + ;; + sfcgm3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhm3}' + ;; + sfcgm2) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhm2}' + ;; + sfcgm1) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhm1}' + ;; + sfcgp1) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhp1}' + ;; + sfcgp2) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhp2}' + ;; + sfcgp3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fhp3}' + ;; + biascr) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.abias' + ;; + satang) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.satang' + ;; + satcnt) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.satcnt' + ;; + gesfil) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.gesfile' + fhbeg=00 + fhend=00 + ;; + pgbges) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbf${fh}' + ;; + pgiges) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbif${fh}' + ;; + pgbgm6) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbf${fhm6}' + ;; + pgigm6) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbif${fhm6}' + ;; + pgbgm3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbf${fhm3}' + ;; + pgigm3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbif${fhm3}' + ;; + pgbgp3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbf${fhp3}' + ;; + pgigp3) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbif${fhp3}' + ;; + sigcur) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sf${fh}' + getlist00=' + ${COMINcdas}/cdas.t${cyc}z.sanl' + fhbeg=00 + ;; + sfccur) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.bf${fh}' + getlist00=' + ${COMINcdas}/cdas.t${cyc}z.sfcanl' + fhbeg=00 + ;; + pgbcur) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pgicur) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.pgrbif${fh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvg12) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=12 + fhend=12 + ;; + tcvges) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=06 + fhend=06 + ;; + tcvitl) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + icegri) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.engicegrb.index' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogri) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.snogrb.index' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + sstgri) + geslist=' + ${COMINcdas}/cdas.t${cyc}z.sstgrb.index' + fhbeg=00 + fhinc=06 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac # CDC CDAS -elif [[ "$netwk" = "cdc" ]];then - if [ -z "$COMINcdc" ]; then - echo "getges.sh ERROR: The \$COMINcdc variable must be defined." >&2 - exit 1 - fi - fhbeg=06 - fhend=06 - case $typef in - sigges) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fh' - ;; - siggm3) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhm3' - ;; - siggm2) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhm2' - ;; - siggm1) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhm1' - ;; - siggp1) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhp1' - ;; - siggp2) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhp2' - ;; - siggp3) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fhp3' - ;; - sfcges) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fh' - ;; - sfcgm3) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhm3' - ;; - sfcgm2) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhm2' - ;; - sfcgm1) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhm1' - ;; - sfcgp1) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhp1' - ;; - sfcgp2) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhp2' - ;; - sfcgp3) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fhp3' - ;; - biascr) geslist=' - $COMINcdc/cdas.t${cyc}z.abias' - ;; - satang) geslist=' - $COMINcdc/cdas.t${cyc}z.satang' - ;; - satcnt) geslist=' - $COMINcdc/cdas.t${cyc}z.satcnt' - ;; - gesfil) geslist=' - $COMINcdc/cdas.t${cyc}z.gesfile' - fhbeg=00 - fhend=00 - ;; - pgbges) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbf$fh' - ;; - pgiges) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbif$fh' - ;; - pgbgm6) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbf$fhm6' - ;; - pgigm6) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbif$fhm6' - ;; - pgbgm3) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbf$fhm3' - ;; - pgigm3) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbif$fhm3' - ;; - pgbgp3) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbf$fhp3' - ;; - pgigp3) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbif$fhp3' - ;; - sigcur) geslist=' - $COMINcdc/cdas.t${cyc}z.sf$fh' - getlist00=' - $COMINcdc/cdas.t${cyc}z.sanl' - fhbeg=00 - ;; - sfccur) geslist=' - $COMINcdc/cdas.t${cyc}z.bf$fh' - getlist00=' - $COMINcdc/cdas.t${cyc}z.sfcanl' - fhbeg=00 - ;; - pgbcur) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pgicur) geslist=' - $COMINcdc/cdas.t${cyc}z.pgrbif$fh' - fhbeg=00 - ;; - prepqc) geslist=' - $COMINcdc/cdas.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvg12) geslist=' - $COMINcdc/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=12 - fhend=12 - ;; - tcvges) geslist=' - $COMINcdc/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=06 - fhend=06 - ;; - tcvitl) geslist=' - $COMINcdc/cdas.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $COMINcdc/cdas.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - icegri) geslist=' - $COMINcdc/cdas.t${cyc}z.engicegrb.index' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $COMINcdc/cdas.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogri) geslist=' - $COMINcdc/cdas.t${cyc}z.snogrb.index' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $COMINcdc/cdas.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - sstgri) geslist=' - $COMINcdc/cdas.t${cyc}z.sstgrb.index' - fhbeg=00 - fhinc=06 - ;; - esac +elif [[ "${netwk}" == "cdc" ]]; then + if [[ -z "${COMINcdc}" ]]; then + echo "getges.sh ERROR: The \${COMINcdc} variable must be defined." >&2 + exit 1 + fi + fhbeg=06 + fhend=06 + # shellcheck disable=SC2016 + case "${typef}" in + sigges) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fh}' + ;; + siggm3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhm3}' + ;; + siggm2) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhm2}' + ;; + siggm1) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhm1}' + ;; + siggp1) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhp1}' + ;; + siggp2) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhp2}' + ;; + siggp3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fhp3}' + ;; + sfcges) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fh}' + ;; + sfcgm3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhm3}' + ;; + sfcgm2) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhm2}' + ;; + sfcgm1) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhm1}' + ;; + sfcgp1) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhp1}' + ;; + sfcgp2) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhp2}' + ;; + sfcgp3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fhp3}' + ;; + biascr) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.abias' + ;; + satang) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.satang' + ;; + satcnt) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.satcnt' + ;; + gesfil) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.gesfile' + fhbeg=00 + fhend=00 + ;; + pgbges) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbf${fh}' + ;; + pgiges) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbif${fh}' + ;; + pgbgm6) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbf${fhm6}' + ;; + pgigm6) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbif${fhm6}' + ;; + pgbgm3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbf${fhm3}' + ;; + pgigm3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbif${fhm3}' + ;; + pgbgp3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbf${fhp3}' + ;; + pgigp3) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbif${fhp3}' + ;; + sigcur) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sf${fh}' + getlist00=' + ${COMINcdc}/cdas.t${cyc}z.sanl' + fhbeg=00 + ;; + sfccur) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.bf${fh}' + getlist00=' + ${COMINcdc}/cdas.t${cyc}z.sfcanl' + fhbeg=00 + ;; + pgbcur) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pgicur) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.pgrbif${fh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvg12) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=12 + fhend=12 + ;; + tcvges) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=06 + fhend=06 + ;; + tcvitl) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + icegri) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.engicegrb.index' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogri) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.snogrb.index' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + sstgri) + geslist=' + ${COMINcdc}/cdas.t${cyc}z.sstgrb.index' + fhbeg=00 + fhinc=06 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac # Any resolution production -elif [[ "$netwk" = "global" ]];then - if [ -z "$COMINgdas" ]; then - echo "getges.sh ERROR: The \$COMINgdas variable must be defined." >&2 - exit 1 - fi - if [ -z "$COMINgfs" ]; then - echo "getges.sh ERROR: The \$COMINgfs variable must be defined." >&2 - exit 1 - fi - GETGES_NWG=${GETGES_NWG:-${GESROOT:?}} - case $typef in - biascr) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.abias - $COMINgdas/gdas.t${cyc}z.abias - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.abias - $COMINgfs/gfs.t${cyc}z.abias' - fhbeg=06 - fhinc=06 - ;; - pgbges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbh$fh - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbf$fh - $COMINgdas/gdas.t${cyc}z.pgrbh$fh - $COMINgdas/gdas.t${cyc}z.pgrbf$fh - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrbf$fh - $COMINgfs/gfs.t${cyc}z.pgrbf$fh' - ;; - pgbgm6) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbh$fhm6 - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbf$fhm6 - $COMINgdas/gdas.t${cyc}z.pgrbh$fhm6 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhm6 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrbf$fhm6 - $COMINgfs/gfs.t${cyc}z.pgrbf$fhm6' - ;; - pgbgm3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbh$fhm3 - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbf$fhm3 - $COMINgdas/gdas.t${cyc}z.pgrbh$fhm3 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhm3 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrbf$fhm3 - $COMINgfs/gfs.t${cyc}z.pgrbf$fhm3' - ;; - pgbgp3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbh$fhp3 - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbf$fhp3 - $COMINgdas/gdas.t${cyc}z.pgrbh$fhp3 - $COMINgdas/gdas.t${cyc}z.pgrbf$fhp3 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrbf$fhp3 - $COMINgfs/gfs.t${cyc}z.pgrbf$fhp3' - ;; - pg2ges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$gh - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$gh - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$gh - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$gh' - ;; - pg2gm6) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm6 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm6 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm6 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm6' - ;; - pg2gm5) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm5 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm5 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm5 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm5' - ;; - pg2gm4) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm4 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm4 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm4 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm4' - ;; - pg2gm3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm3 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm3 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm3 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm3' - ;; - pg2gm2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm2 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm2 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm2 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm2' - ;; - pg2gm1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghm1 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghm1 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghm1 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghm1' - ;; - pg2gp1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghp1 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghp1 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghp1 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghp1' - ;; - pg2gp2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghp2 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghp2 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghp2 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghp2' - ;; - pg2gp3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p25.f$ghp3 - $COMINgdas/gdas.t${cyc}z.pgrb2.0p25.f$ghp3 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p25.f$ghp3 - $COMINgfs/gfs.t${cyc}z.pgrb2.0p25.f$ghp3' - ;; - pgbcur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbh$fh - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrbf$fh - $COMINgdas/gdas.t${cyc}z.pgrbh$fh - $COMINgdas/gdas.t${cyc}z.pgrbf$fh - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrbf$fh - $COMINgfs/gfs.t${cyc}z.pgrbf$fh' - fhbeg=00 - ;; - pg2cur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.pgrb2.0p50.f$gh - $COMINgdas/gdas.t${cyc}z.pgrb2.0p50.f$gh - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.pgrb2.0p50.f$gh - $COMINgfs/gfs.t${cyc}z.pgrb2.0p50.f$gh' - fhbeg=00 - ;; - prepqc) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.prepbufr - $COMINgdas/gdas.t${cyc}z.prepbufr - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.prepbufr - $COMINgfs/gfs.t${cyc}z.prepbufr' - fhbeg=00 - fhend=00 - ;; - tcvg12) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.syndata.tcvitals.tm00 - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.syndata.tcvitals.tm00 - $COMINgfs/gfs.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=12 - fhend=12 - ;; - tcvges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.syndata.tcvitals.tm00 - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.syndata.tcvitals.tm00 - $COMINgfs/gfs.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=06 - fhend=06 - ;; - tcvitl) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.syndata.tcvitals.tm00 - $COMINgdas/gdas.t${cyc}z.syndata.tcvitals.tm00 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.syndata.tcvitals.tm00 - $COMINgfs/gfs.t${cyc}z.syndata.tcvitals.tm00' - fhbeg=00 - fhend=00 - ;; - icegrb) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.engicegrb - $COMINgdas/gdas.t${cyc}z.engicegrb - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.engicegrb - $COMINgfs/gfs.t${cyc}z.engicegrb' - fhbeg=00 - fhinc=06 - ;; - snogrb) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.snogrb - $COMINgdas/gdas.t${cyc}z.snogrb - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.snogrb - $COMINgfs/gfs.t${cyc}z.snogrb' - fhbeg=00 - fhinc=06 - ;; - snogrb_574) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.snogrb_t574.1152.576 - $COMINgdas/gdas.t${cyc}z.snogrb_t574.1152.576 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.snogrb_t574.1152.576 - $COMINgfs/gfs.t${cyc}z.snogrb_t574.1152.576' - fhbeg=00 - fhinc=06 - ;; - snogrb_1534) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.snogrb_t1534.3072.1536 - $COMINgdas/gdas.t${cyc}z.snogrb_t1534.3072.1536 - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.snogrb_t1534.3072.1536 - $COMINgfs/gfs.t${cyc}z.snogrb_t1534.3072.1536' - fhbeg=00 - fhinc=06 - ;; - sstgrb) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sstgrb - $COMINgdas/gdas.t${cyc}z.sstgrb - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sstgrb - $COMINgfs/gfs.t${cyc}z.sstgrb' - fhbeg=00 - fhinc=06 - ;; - natges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$gh.nemsio' - ;; - natgm3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atm.f$ghm3.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghm3.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atm.f$ghm3.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghm3.nemsio' - ;; - natgm2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$ghm2.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghm2.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$ghm2.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghm2.nemsio' - ;; - natgm1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$ghm1.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghm1.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$ghm1.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghm1.nemsio' - ;; - natgp1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$ghp1.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghp1.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$ghp1.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghp1.nemsio' - ;; - natgp2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$ghp2.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghp2.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$ghp2.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghp2.nemsio' - ;; - natgp3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$ghp3.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$ghp3.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$ghp3.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$ghp3.nemsio' - ;; - natcur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.atmf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.atmf$gh.nemsio' - getlist00=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.atmanl.nemsio - $COMINgdas/gdas.t${cyc}z.atmanl.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.atmanl.nemsio - $COMINgfs/gfs.t${cyc}z.atmanl.nemsio' - fhbeg=00 - ;; - nsfges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$gh.nemsio' - ;; - nsfgm3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghm3.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghm3.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghm3.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghm3.nemsio' - ;; - nsfgm2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghm2.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghm2.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghm2.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghm2.nemsio' - ;; - nsfgm1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghm1.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghm1.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghm1.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghm1.nemsio' - ;; - nsfgp1) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghp1.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghp1.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghp1.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghp1.nemsio' - ;; - nsfgp2) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghp2.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghp2.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghp2.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghp2.nemsio' - ;; - nsfgp3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$ghp3.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$ghp3.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$ghp3.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$ghp3.nemsio' - ;; - nsfcur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.sfcf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.sfcf$gh.nemsio' - getlist00=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.sfcanl.nemsio - $COMINgdas/gdas.t${cyc}z.sfcanl.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.sfcanl.nemsio - $COMINgfs/gfs.t${cyc}z.sfcanl.nemsio' - fhbeg=00 - ;; - nstcur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.nstf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.nstf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.nstf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.nstf$gh.nemsio' - getlist00=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.nstanl.nemsio - $COMINgdas/gdas.t${cyc}z.nstanl.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.nstanl.nemsio - $COMINgfs/gfs.t${cyc}z.nstanl.nemsio' - fhbeg=00 - ;; - nflges) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.flxf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.flxf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.flxf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.flxf$gh.nemsio' - ;; - nflgp3) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.flxf$ghp3.nemsio - $COMINgdas/gdas.t${cyc}z.flxf$ghp3.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.flxf$ghp3.nemsio - $COMINgfs/gfs.t${cyc}z.flxf$ghp3.nemsio' - ;; - nflcur) geslist=' - $GETGES_NWG/$envir/gdas.$day/gdas.t${cyc}z.flxf$gh.nemsio - $COMINgdas/gdas.t${cyc}z.flxf$gh.nemsio - $GETGES_NWG/$envir/gfs.$day/gfs.t${cyc}z.flxf$gh.nemsio - $COMINgfs/gfs.t${cyc}z.flxf$gh.nemsio' - fhbeg=00 - ;; - esac +elif [[ "${netwk}" == "global" ]]; then + if [[ -z "${COMINgdas}" ]]; then + echo "getges.sh ERROR: The \${COMINgdas} variable must be defined." >&2 + exit 1 + fi + if [[ -z "${COMINgfs}" ]]; then + echo "getges.sh ERROR: The \${COMINgfs} variable must be defined." >&2 + exit 1 + fi + GETGES_NWG=${GETGES_NWG:-${GESROOT:?}} + # shellcheck disable=SC2016 + case "${typef}" in + biascr) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.abias + ${COMINgdas}/gdas.t${cyc}z.abias + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.abias + ${COMINgfs}/gfs.t${cyc}z.abias' + fhbeg=06 + fhinc=06 + ;; + pgbges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbh${fh} + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbf${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fh} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrbf${fh} + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fh}' + ;; + pgbgm6) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbh${fhm6} + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbf${fhm6} + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhm6} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhm6} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrbf${fhm6} + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fhm6}' + ;; + pgbgm3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbh${fhm3} + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbf${fhm3} + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhm3} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhm3} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrbf${fhm3} + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fhm3}' + ;; + pgbgp3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbh${fhp3} + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbf${fhp3} + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fhp3} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fhp3} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrbf${fhp3} + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fhp3}' + ;; + pg2ges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${gh} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${gh} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${gh} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${gh}' + ;; + pg2gm6) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm6} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm6} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm6} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm6}' + ;; + pg2gm5) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm5} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm5} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm5} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm5}' + ;; + pg2gm4) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm4} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm4} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm4} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm4}' + ;; + pg2gm3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm3} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm3} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm3} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm3}' + ;; + pg2gm2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm2} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm2} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm2} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm2}' + ;; + pg2gm1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghm1} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghm1} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghm1} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghm1}' + ;; + pg2gp1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghp1} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghp1} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghp1} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghp1}' + ;; + pg2gp2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghp2} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghp2} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghp2} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghp2}' + ;; + pg2gp3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p25.f${ghp3} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p25.f${ghp3} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p25.f${ghp3} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p25.f${ghp3}' + ;; + pgbcur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbh${fh} + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrbf${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbh${fh} + ${COMINgdas}/gdas.t${cyc}z.pgrbf${fh} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrbf${fh} + ${COMINgfs}/gfs.t${cyc}z.pgrbf${fh}' + fhbeg=00 + ;; + pg2cur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.pgrb2.0p50.f${gh} + ${COMINgdas}/gdas.t${cyc}z.pgrb2.0p50.f${gh} + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.pgrb2.0p50.f${gh} + ${COMINgfs}/gfs.t${cyc}z.pgrb2.0p50.f${gh}' + fhbeg=00 + ;; + prepqc) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.prepbufr + ${COMINgdas}/gdas.t${cyc}z.prepbufr + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.prepbufr + ${COMINgfs}/gfs.t${cyc}z.prepbufr' + fhbeg=00 + fhend=00 + ;; + tcvg12) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgfs}/gfs.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=12 + fhend=12 + ;; + tcvges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgfs}/gfs.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=06 + fhend=06 + ;; + tcvitl) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgdas}/gdas.t${cyc}z.syndata.tcvitals.tm00 + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.syndata.tcvitals.tm00 + ${COMINgfs}/gfs.t${cyc}z.syndata.tcvitals.tm00' + fhbeg=00 + fhend=00 + ;; + icegrb) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.engicegrb + ${COMINgdas}/gdas.t${cyc}z.engicegrb + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.engicegrb + ${COMINgfs}/gfs.t${cyc}z.engicegrb' + fhbeg=00 + fhinc=06 + ;; + snogrb) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.snogrb + ${COMINgdas}/gdas.t${cyc}z.snogrb + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.snogrb + ${COMINgfs}/gfs.t${cyc}z.snogrb' + fhbeg=00 + fhinc=06 + ;; + snogrb_574) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.snogrb_t574.1152.576 + ${COMINgdas}/gdas.t${cyc}z.snogrb_t574.1152.576 + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.snogrb_t574.1152.576 + ${COMINgfs}/gfs.t${cyc}z.snogrb_t574.1152.576' + fhbeg=00 + fhinc=06 + ;; + snogrb_1534) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.snogrb_t1534.3072.1536 + ${COMINgdas}/gdas.t${cyc}z.snogrb_t1534.3072.1536 + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.snogrb_t1534.3072.1536 + ${COMINgfs}/gfs.t${cyc}z.snogrb_t1534.3072.1536' + fhbeg=00 + fhinc=06 + ;; + sstgrb) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sstgrb + ${COMINgdas}/gdas.t${cyc}z.sstgrb + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sstgrb + ${COMINgfs}/gfs.t${cyc}z.sstgrb' + fhbeg=00 + fhinc=06 + ;; + natges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${gh}.nemsio' + ;; + natgm3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atm.f${ghm3}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghm3}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atm.f${ghm3}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghm3}.nemsio' + ;; + natgm2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${ghm2}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghm2}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${ghm2}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghm2}.nemsio' + ;; + natgm1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${ghm1}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghm1}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${ghm1}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghm1}.nemsio' + ;; + natgp1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${ghp1}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp1}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${ghp1}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghp1}.nemsio' + ;; + natgp2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${ghp2}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp2}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${ghp2}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghp2}.nemsio' + ;; + natgp3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${ghp3}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${ghp3}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${ghp3}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${ghp3}.nemsio' + ;; + natcur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmf${gh}.nemsio' + getlist00=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.atmanl.nemsio + ${COMINgdas}/gdas.t${cyc}z.atmanl.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.atmanl.nemsio + ${COMINgfs}/gfs.t${cyc}z.atmanl.nemsio' + fhbeg=00 + ;; + nsfges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${gh}.nemsio' + ;; + nsfgm3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghm3}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm3}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghm3}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghm3}.nemsio' + ;; + nsfgm2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghm2}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm2}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghm2}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghm2}.nemsio' + ;; + nsfgm1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghm1}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghm1}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghm1}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghm1}.nemsio' + ;; + nsfgp1) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghp1}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp1}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghp1}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghp1}.nemsio' + ;; + nsfgp2) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghp2}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp2}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghp2}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghp2}.nemsio' + ;; + nsfgp3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${ghp3}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${ghp3}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${ghp3}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${ghp3}.nemsio' + ;; + nsfcur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcf${gh}.nemsio' + getlist00=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.sfcanl.nemsio + ${COMINgdas}/gdas.t${cyc}z.sfcanl.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.sfcanl.nemsio + ${COMINgfs}/gfs.t${cyc}z.sfcanl.nemsio' + fhbeg=00 + ;; + nstcur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.nstf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.nstf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.nstf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.nstf${gh}.nemsio' + # shellcheck disable=SC2034 + getlist00=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.nstanl.nemsio + ${COMINgdas}/gdas.t${cyc}z.nstanl.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.nstanl.nemsio + ${COMINgfs}/gfs.t${cyc}z.nstanl.nemsio' + fhbeg=00 + ;; + nflges) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.flxf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.flxf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.flxf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.flxf${gh}.nemsio' + ;; + nflgp3) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.flxf${ghp3}.nemsio + ${COMINgdas}/gdas.t${cyc}z.flxf${ghp3}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.flxf${ghp3}.nemsio + ${COMINgfs}/gfs.t${cyc}z.flxf${ghp3}.nemsio' + ;; + nflcur) + geslist=' + ${GETGES_NWG}/${envir}/gdas.${day}/gdas.t${cyc}z.flxf${gh}.nemsio + ${COMINgdas}/gdas.t${cyc}z.flxf${gh}.nemsio + ${GETGES_NWG}/${envir}/gfs.${day}/gfs.t${cyc}z.flxf${gh}.nemsio + ${COMINgfs}/gfs.t${cyc}z.flxf${gh}.nemsio' + fhbeg=00 + ;; + *) + msg="FATAL ERROR: Unknown ${netwk} guess type ${typef}" + export err=101 + err_exit "${msg}" + ;; + esac fi # Check validity of options. -if [[ $fhour != any ]];then - fhbeg=$fhour - fhend=$fhour +if [[ "${fhour}" != any ]]; then + fhbeg="${fhour}" + fhend="${fhour}" fi -if [[ $valid -lt 20000000 ]];then - valid=20$valid - echo '************************************************************' >&2 - echo '* WARNING: A 2-digit year was converted to a 4-digit year. *' >&2 - echo '* Please use full a 4-digit year in this utility. *' >&2 - echo '************************************************************' >&2 +if [[ "${valid}" -lt 20000000 ]]; then + valid="20${valid}" + echo '************************************************************' >&2 + echo '* WARNING: A 2-digit year was converted to a 4-digit year. *' >&2 + echo '* Please use full a 4-digit year in this utility. *' >&2 + echo '************************************************************' >&2 fi -if [[ -z "$geslist" ]];then - echo getges.sh: filetype $typef or resolution $resol not recognized >&2 - exit 2 +if [[ -z "${geslist}" ]]; then + echo "getges.sh: filetype ${typef} or resolution ${resol} not recognized" >&2 + exit 2 fi #------------------------------------------------------------------------------- # Loop until guess is found. -fh=$fhbeg -if [ -z "$PDY" ];then echo "getges.sh WARNING: \$PDY variable not set" >&2; fi -while [[ $fh -le $fhend ]];do - ((fhm6=10#${fh}-6)) - if [[ ${fhm6} -lt 10 && ${fhm6} -ge 0 ]]; then - fhm6=0${fhm6} - fi - ((fhm5=10#${fh}-5)) - if [[ ${fhm5} -lt 10 && ${fhm5} -ge 0 ]]; then - fhm5=0${fhm5} - fi - ((fhm4=10#${fh}-4)) - if [[ ${fhm4} -lt 10 && ${fhm4} -ge 0 ]]; then - fhm4=0${fhm4} - fi - ((fhm3=10#${fh}-3)) - if [[ ${fhm3} -lt 10 && ${fhm3} -ge 0 ]]; then - fhm3=0${fhm3} - fi - ((fhm2=10#${fh}-2)) - if [[ ${fhm2} -lt 10 && ${fhm2} -ge 0 ]]; then - fhm2=0${fhm2} - fi - ((fhm1=10#${fh}-1)) - if [[ ${fhm1} -lt 10 && ${fhm1} -ge 0 ]]; then - fhm1=0${fhm1} - fi - ((fhp1=10#${fh}+1)) - if [[ ${fhp1} -lt 10 ]]; then - fhp1=0${fhp1} - fi - ((fhp2=10#${fh}+2)) - if [[ ${fhp2} -lt 10 ]]; then - fhp2=0${fhp2} - fi - ((fhp3=10#${fh}+3)) - if [[ ${fhp3} -lt 10 ]]; then - fhp3=0${fhp3} - fi - gh=$fh;[[ $gh -lt 100 ]]&&gh=0$gh - ghm6=$fhm6;[[ $ghm6 -lt 100 ]]&&ghm6=0$ghm6 - ghm5=$fhm5;[[ $ghm5 -lt 100 ]]&&ghm5=0$ghm5 - ghm4=$fhm4;[[ $ghm4 -lt 100 ]]&&ghm4=0$ghm4 - ghm3=$fhm3;[[ $ghm3 -lt 100 ]]&&ghm3=0$ghm3 - ghm2=$fhm2;[[ $ghm2 -lt 100 ]]&&ghm2=0$ghm2 - ghm1=$fhm1;[[ $ghm1 -lt 100 ]]&&ghm1=0$ghm1 - ghp1=$fhp1;[[ $ghp1 -lt 100 ]]&&ghp1=0$ghp1 - ghp2=$fhp2;[[ $ghp2 -lt 100 ]]&&ghp2=0$ghp2 - ghp3=$fhp3;[[ $ghp3 -lt 100 ]]&&ghp3=0$ghp3 - id=$(date --utc +%Y%m%d%H -d "${valid:0:8} ${valid:8:2} - ${fh} hours") +fh=${fhbeg} +if [[ -z "${PDY}" ]]; then echo "getges.sh WARNING: \${PDY} variable not set" >&2; fi +while [[ "${fh}" -le "${fhend}" ]]; do + ((fhm6 = 10#${fh} - 6)) + if [[ ${fhm6} -lt 10 && ${fhm6} -ge 0 ]]; then + fhm6=0${fhm6} + fi + ((fhm5 = 10#${fh} - 5)) + if [[ ${fhm5} -lt 10 && ${fhm5} -ge 0 ]]; then + fhm5=0${fhm5} + fi + ((fhm4 = 10#${fh} - 4)) + if [[ ${fhm4} -lt 10 && ${fhm4} -ge 0 ]]; then + fhm4=0${fhm4} + fi + ((fhm3 = 10#${fh} - 3)) + if [[ ${fhm3} -lt 10 && ${fhm3} -ge 0 ]]; then + fhm3=0${fhm3} + fi + ((fhm2 = 10#${fh} - 2)) + if [[ ${fhm2} -lt 10 && ${fhm2} -ge 0 ]]; then + fhm2=0${fhm2} + fi + ((fhm1 = 10#${fh} - 1)) + if [[ ${fhm1} -lt 10 && ${fhm1} -ge 0 ]]; then + fhm1=0${fhm1} + fi + ((fhp1 = 10#${fh} + 1)) + if [[ ${fhp1} -lt 10 ]]; then + fhp1=0${fhp1} + fi + ((fhp2 = 10#${fh} + 2)) + if [[ ${fhp2} -lt 10 ]]; then + fhp2=0${fhp2} + fi + ((fhp3 = 10#${fh} + 3)) + if [[ ${fhp3} -lt 10 ]]; then + fhp3=0${fhp3} + fi + gh="${fh}" + [[ "${gh}" -lt 100 ]] && gh="0${gh}" + ghm6="${fhm6}" + [[ "${ghm6}" -lt 100 ]] && ghm6="0${ghm6}" + ghm5="${fhm5}" + [[ "${ghm5}" -lt 100 ]] && ghm5="0${ghm5}" + ghm4="${fhm4}" + [[ "${ghm4}" -lt 100 ]] && ghm4="0${ghm4}" + ghm3="${fhm3}" + [[ "${ghm3}" -lt 100 ]] && ghm3="0${ghm3}" + ghm2="${fhm2}" + [[ "${ghm2}" -lt 100 ]] && ghm2="0${ghm2}" + ghm1="${fhm1}" + [[ "${ghm1}" -lt 100 ]] && ghm1="0${ghm1}" + ghp1="${fhp1}" + [[ "${ghp1}" -lt 100 ]] && ghp1="0${ghp1}" + ghp2="${fhp2}" + [[ "${ghp2}" -lt 100 ]] && ghp2="0${ghp2}" + ghp3="${fhp3}" + [[ "${ghp3}" -lt 100 ]] && ghp3="0${ghp3}" + id=$(date --utc +%Y%m%d%H -d "${valid:0:8} ${valid:8:2} - ${fh} hours") - day=$(echo $id | xargs | cut -c8) - cyc=$(echo $id | xargs | rev | cut -c1-2 | rev) - eval list=\$getlist$fh - if [[ -z "${list}" ]]; then - list=${geslist} - fi - for ges_var in $list;do - # Replace variables in guess with their values - eval ges_val=$ges_var - # Replace the current PDY with the valid date - ges=${ges_val/$PDY\//$day/} - if [[ "${quiet}" == "NO" ]]; then - echo Checking: "${ges}" >&2 - fi - if [[ -r "${ges}" ]]; then - break 2 - fi - done - fh=$((10#${fh}+10#${fhinc})) - if [[ ${fh} -lt 10 ]]; then - fh=0${fh} - fi + day="${id:0:8}" + cyc="${id:8:2}" + list_name="getlist${fh}" + list="${!list_name}" + if [[ -z "${list}" ]]; then + list=${geslist} + fi + for ges_var in ${list}; do + # Replace variables in guess with their values + eval ges_val="${ges_var}" + # Replace the current PDY with the valid date + ges=${ges_val/${PDY}\//${day}/} + if [[ "${quiet}" == "NO" ]]; then + echo Checking: "${ges}" >&2 + fi + if [[ -r "${ges}" ]]; then + break 2 + fi + done + fh=$((10#${fh} + 10#${fhinc})) + if [[ ${fh} -lt 10 ]]; then + fh=0${fh} + fi done -if [[ $fh -gt $fhend ]];then - echo getges.sh: unable to find $netwk.$envir.$typef.$resol.$valid >&2 - exit 8 +if [[ "${fh}" -gt "${fhend}" ]]; then + echo "getges.sh: unable to find ${netwk}.${envir}.${typef}.${resol}.${valid}" >&2 + exit 8 fi +err= #------------------------------------------------------------------------------- # Either copy guess to a file or write guess name to standard output. -if [[ -z "$gfile" ]];then - echo ${ges} - err=$? +if [[ -z "${gfile}" ]]; then + echo "${ges}" + err=0 else - cpfs ${ges} ${gfile} - err=$? + cpfs "${ges}" "${gfile}" + err=$? fi -exit ${err} +exit "${err}" diff --git a/ush/getioda.sh b/ush/getioda.sh new file mode 100755 index 00000000000..f2db4d0a434 --- /dev/null +++ b/ush/getioda.sh @@ -0,0 +1,67 @@ +#! /usr/bin/env bash + +YMD=${1:-""} +HH=${2:-""} +RUN=${3:-""} +SOURCE_DIR=${4:-${IODADIR}/${RUN}${DUMP_SUFFIX}.${YMD}/${HH}} +TARGET_DIR=${5:-${ROTDIR}/${RUN}.${YMD}/${HH}} + +DUMP_SUFFIX=${DUMP_SUFFIX:-""} + +# Exit if SOURCE_DIR does not exist +if [[ ! -s "${SOURCE_DIR}" ]]; then + echo "FATAL ERROR: DUMP SOURCE_DIR=${SOURCE_DIR} does not exist" + exit 99 +fi + +# Create TARGET_DIR if is does not exist +if [[ ! -s "${TARGET_DIR}" ]]; then + mkdir -p "${TARGET_DIR}" +fi + +# Set file prefix +prefix="${RUN}.t${HH}z." + +# loop through top level component directories (e.g. atmos, ocean, land, ice) +for compdir in "${SOURCE_DIR}"/*/; do + compdir=${compdir%*/} + compdir=${compdir##*/} + # Skip if not a directory + if [[ ! -d "${SOURCE_DIR}/${compdir}/" ]]; then + continue + fi + # check if status file does not exist + # Check if any status log files exist using array expansion + set +f + status_files=("${SOURCE_DIR}/${compdir}/${prefix}"*status.log) + if [[ ! -e "${status_files[0]}" ]]; then + echo "FATAL ERROR: completion log file NOT FOUND in ${SOURCE_DIR}/${compdir}" + exit 99 + fi + echo "Processing component directory: ${compdir}" + set -f + # Create component directory in TARGET_DIR if it does not exist + if [[ ! -s "${TARGET_DIR}/${compdir}" ]]; then + mkdir -p "${TARGET_DIR}/${compdir}" + fi + # Link files from SOURCE_DIR to TARGET_DIR + if [[ ! -d "${SOURCE_DIR}/${compdir}" ]]; then + echo "FATAL ERROR: '${SOURCE_DIR}/${compdir}' does not exist, ABORT!" + exit 99 + fi + # Use shell globbing instead of iterating over ls output. Enable nullglob so the loop + # simply skips when no matches are found. + set +f + shopt -s nullglob + for source_file in "${SOURCE_DIR}/${compdir}/${prefix}"*; do + if [[ ! -e "${source_file}" ]]; then + continue + fi + targ_file=$(basename "${source_file}") + cpreq "${source_file}" "${TARGET_DIR}/${compdir}/${targ_file}" + done + shopt -u nullglob + set -f +done + +exit 0 diff --git a/ush/gfs_bfr2gpk.sh b/ush/gfs_bfr2gpk.sh index 0ff2a400539..4123fe2408d 100755 --- a/ush/gfs_bfr2gpk.sh +++ b/ush/gfs_bfr2gpk.sh @@ -9,7 +9,7 @@ # # # Log: # # K. Brill/HPC 04/12/05 # -######################################################################### +######################################################################### # Set GEMPAK paths. @@ -30,10 +30,13 @@ date cat "${COMOUT_ATMOS_BUFR}/bufr."*".${PDY}${cyc}" > bufr.combined date +snd=${outfilbase}.snd +sfc=${outfilbase}.sfc + namsnd << EOF > /dev/null SNBUFR = bufr.combined -SNOUTF = ${outfilbase}.snd -SFOUTF = ${outfilbase}.sfc +SNOUTF = ${snd} +SFOUTF = ${sfc} SNPRMF = sngfs.prm SFPRMF = sfgfs.prm TIMSTN = 170/2150 @@ -46,13 +49,13 @@ date /bin/rm ./*.nts -snd=${outfilbase}.snd -sfc=${outfilbase}.sfc -cpfs "${snd}" "${COMOUT_ATMOS_GEMPAK}/${snd}" -cpfs "${sfc}" "${COMOUT_ATMOS_GEMPAK}/${sfc}" +snd_out=${outfilbase}.soundings.bufr +sfc_out=${outfilbase}.sfc.bufr +cpfs "${snd}" "${COMOUT_ATMOS_GEMPAK}/${snd_out}" +cpfs "${sfc}" "${COMOUT_ATMOS_GEMPAK}/${sfc_out}" if [[ ${SENDDBN} == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" MODEL GFS_PTYP_SFC "${job}" "${COMOUT_ATMOS_GEMPAK}/${sfc}" - "${DBNROOT}/bin/dbn_alert" MODEL GFS_PTYP_SND "${job}" "${COMOUT_ATMOS_GEMPAK}/${snd}" + "${DBNROOT}/bin/dbn_alert" MODEL GFS_PTYP_SFC "${job}" "${COMOUT_ATMOS_GEMPAK}/${sfc_out}" + "${DBNROOT}/bin/dbn_alert" MODEL GFS_PTYP_SND "${job}" "${COMOUT_ATMOS_GEMPAK}/${snd_out}" fi echo "done" > "${DATA}/gembufr.done" diff --git a/ush/gfs_bufr.sh b/ush/gfs_bufr.sh index 63f94493b54..e1b880b9ea3 100755 --- a/ush/gfs_bufr.sh +++ b/ush/gfs_bufr.sh @@ -31,33 +31,33 @@ workdir="${5}" cd "${workdir}" || exit 2 if [[ "${F00FLAG}" == "YES" ]]; then - f00flag=".true." + f00flag=".true." else - f00flag=".false." + f00flag=".false." fi export pgm="gfs_bufr.x" #. prep_step if [[ "${MAKEBUFR}" == "YES" ]]; then - bufrflag=".true." + bufrflag=".true." else - bufrflag=".false." + bufrflag=".false." fi # check if read in bufr_ij_gfs_${CASE}.txt export CASE=${CASE_HIST:-${CASE}} -if [[ -s "${PARMgfs}/product/bufr_ij_gfs_${CASE}.txt" ]]; then - # use predetermined grid point(i,j) in bufr_gfs_${CASE}.txt - ${NLN} "${PARMgfs}/product/bufr_ij_gfs_${CASE}.txt" fort.7 - np1=0 +if [[ -s "${PARMgfs}/product/bufr_ij_gfs_${CASE}.txt" ]]; then + # use predetermined grid point(i,j) in bufr_gfs_${CASE}.txt + ${NLN} "${PARMgfs}/product/bufr_ij_gfs_${CASE}.txt" fort.7 + np1=0 else - # find the nearest neighbor grid point(i,j) in the code - np1=1 - echo "No bufr_ij_gfs_${CASE}.txt For CASE ${CASE}" - echo "Find the nearest neighbor grid (i,j) in the code" + # find the nearest neighbor grid point(i,j) in the code + np1=1 + echo "No bufr_ij_gfs_${CASE}.txt For CASE ${CASE}" + echo "Find the nearest neighbor grid (i,j) in the code" fi ##fformat="netcdf" @@ -81,14 +81,14 @@ EOF filename="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.log.f${fhr}.${logfm}" if [[ -z ${filename} ]]; then - echo "FATAL ERROR: COULD NOT LOCATE logf${fhr} file" - exit 2 + echo "FATAL ERROR: COULD NOT LOCATE logf${fhr} file" + exit 2 fi filename="${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.log.f${fhr_p}.${logfm}" if [[ -z ${filename} ]]; then - echo "FATAL ERROR: COULD NOT LOCATE logf${fhr_p} file" - exit 2 + echo "FATAL ERROR: COULD NOT LOCATE logf${fhr_p} file" + exit 2 fi #------------------------------------------------------------------ @@ -100,17 +100,16 @@ ${NLN} "${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.sfc.f${fhr_p}.${atmfm}" "flxf${fh ${NLN} "${PARMgfs}/product/bufr_gfs_${CLASS}.tbl" fort.1 ${NLN} "${STNLIST:-${PARMgfs}/product/bufr_stalist.meteo.gfs}" fort.8 - #------------------------------------------------------------------ "${EXECgfs}/${pgm}" < gfsparm > "out_gfs_bufr_${fhr}" export err=$? if [[ ${err} -ne 0 ]]; then - echo "WARNING GFS postsnd job error, Please check files " - echo "${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.f${fhr}.${atmfm}" - echo "${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.sfc.f${fhr}.${atmfm}" - exit "${err}" + echo "FATAL ERROR: GFS postsnd job error, Please check files " + echo "${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.atm.f${fhr}.${atmfm}" + echo "${COMIN_ATMOS_HISTORY}/${RUN}.${cycle}.sfc.f${fhr}.${atmfm}" + err_exit fi exit 0 diff --git a/ush/gfs_bufr_netcdf.sh b/ush/gfs_bufr_netcdf.sh deleted file mode 100755 index 9b905acbaa6..00000000000 --- a/ush/gfs_bufr_netcdf.sh +++ /dev/null @@ -1,103 +0,0 @@ -#! /usr/bin/env bash - -# -# UTILITY SCRIPT NAME : gfsbufr.sh -# AUTHOR : Hua-Lu Pan -# DATE WRITTEN : 02/03/97 -# -# Abstract: This utility script produces BUFR file of -# station forecasts from the GFS suite. -# -# Input: none -# Script History Log: -# 2016-10-30 H Chuang: Tranistion to read nems output. -# Change to read flux file fields in gfs_bufr -# so remove excution of gfs_flux -# 2018-03-22 Guang Ping Lou: Making it works for either 1 hourly or 3 hourly output -# 2018-05-22 Guang Ping Lou: Making it work for both GFS and FV3GFS -# 2018-05-30 Guang Ping Lou: Make sure all files are available. -# 2019-10-10 Guang Ping Lou: Read in NetCDF files -# echo "History: February 2003 - First implementation of this utility script" -# - -if test "$F00FLAG" = "YES" -then - f00flag=".true." -else - f00flag=".false." -fi - -hh=$FSTART -while test $hh -le $FEND -do - hh=$( expr $hh + $FINT ) - if test $hh -lt 10 - then - hh=0$hh - fi -done - -export pgm="gfs_bufr.x" -#. prep_step - -if test "$MAKEBUFR" = "YES" -then - bufrflag=".true." -else - bufrflag=".false." -fi - -CLASS="class1fv3" -cat << EOF > gfsparm - &NAMMET - levs=$LEVS,makebufr=$bufrflag, - dird="$COMOUT/bufr.${cycle}/bufr", - nstart=$FSTART,nend=$FEND,nint=$FINT, - nend1=$NEND1,nint1=$NINT1,nint3=$NINT3, - nsfc=80,f00=$f00flag, -/ -EOF - -hh=$FSTART - if test $hh -lt 100 - then - hh1=$(echo "${hh#"${hh%??}"}") - hh=$hh1 - fi - -sleep_interval=10 -max_tries=360 -while test $hh -le $FEND -do - if test $hh -lt 100 - then - hh2=0$hh - else - hh2=$hh - fi - - filename="${COMIN}/${RUN}.${cycle}.logf${hh2}.txt" - if ! wait_for_file "${filename}" "${sleep_interval}" "${max_tries}" ; then - err_exit "FATAL ERROR COULD NOT LOCATE logf${hh2} file" - fi - -#------------------------------------------------------------------ - ${NLN} $COMIN/${RUN}.${cycle}.atm.f${hh2}.nc sigf${hh} - ${NLN} $COMIN/${RUN}.${cycle}.sfc.f${hh2}.nc flxf${hh} - - hh=$( expr $hh + $FINT ) - if test $hh -lt 10 - then - hh=0$hh - fi -done - -# define input BUFR table file. -${NLN} ${PARMgfs}/product/bufr_gfs_${CLASS}.tbl fort.1 -${NLN} ${STNLIST:-${PARMgfs}/product/bufr_stalist.meteo.gfs} fort.8 -${NLN} ${PARMgfs}/product/bufr_ij13km.txt fort.7 - -${APRUN_POSTSND} "${EXECgfs}/${pgm}" < gfsparm > "out_gfs_bufr_${FEND}" -export err=$? - -exit ${err} diff --git a/ush/gfs_sndp.sh b/ush/gfs_sndp.sh index 3d1cd01401c..5ebd81c121c 100755 --- a/ush/gfs_sndp.sh +++ b/ush/gfs_sndp.sh @@ -7,56 +7,52 @@ # 1) 2004-09-10 Steve Gilbert First Implementation ################################################################ - # Create "collectives" consisting of groupings of the soundings - # into files designated by geographical region. Each input - # file gfs_collective*.list (1-9) contains the list of stations to - # put in a particular collective output file. +# Create "collectives" consisting of groupings of the soundings +# into files designated by geographical region. Each input +# file gfs_collective*.list (1-9) contains the list of stations to +# put in a particular collective output file. export m=$1 -mkdir $DATA/$m -cd $DATA/$m - cpreq ${FIXgfs}/product/gfs_collective${m}.list $DATA/$m/. - CCCC=KWBC - file_list=gfs_collective${m}.list +mkdir -p "${DATA}/${m}" +cd "${DATA}/${m}" || exit 2 +cpreq "${FIXgfs}/product/gfs_collective${m}.list" "${DATA}/${m}/" +CCCC=KWBC +file_list=gfs_collective${m}.list - if [ $m -le 2 ] - then - WMOHEAD=JUSA4$m - elif [ $m -le 6 ] - then - WMOHEAD=JUSB4$m - else - WMOHEAD=JUSX4$m - fi +if [[ ${m} -le 2 ]]; then + WMOHEAD="JUSA4${m}" +elif [[ ${m} -le 6 ]]; then + WMOHEAD="JUSB4${m}" +else + WMOHEAD="JUSX4${m}" +fi - for stn in $(cat $file_list) - do - cpreq "${COMOUT_ATMOS_BUFR}/bufr.${stn}.${PDY}${cyc}" "${DATA}/${m}/bufrin" - export pgm=tocsbufr.x - #. prep_step - export FORT11=$DATA/${m}/bufrin - export FORT51=./bufrout - ${EXECgfs}/${pgm} << EOF +while IFS= read -r stn; do + cpreq "${COMIN_ATMOS_BUFR}/bufr.${stn}.${PDY}${cyc}" "${DATA}/${m}/bufrin" + export pgm=tocsbufr.x + #. prep_step + export FORT11="${DATA}/${m}/bufrin" + export FORT51=./bufrout + "${EXECgfs}/${pgm}" << EOF &INPUT - BULHED="$WMOHEAD",KWBX="$CCCC", + BULHED="${WMOHEAD}",KWBX="${CCCC}", NCEP2STD=.TRUE., SEPARATE=.TRUE., MAXFILESIZE=600000 / EOF - export err=$?; - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR Failed during execution of ${pgm}" - exit "${err}" - fi - - cat "${DATA}/${m}/bufrout" >> "${DATA}/${m}/gfs_collective${m}.fil" - rm -f "${DATA}/${m}/bufrin" "${DATA}/${m}/bufrout" - done - - if [[ ${SENDDBN} == 'YES' ]] ; then - cpfs "${DATA}/${m}/gfs_collective${m}.fil" "${COMOUT_ATMOS_WMO}/gfs_collective${m}.postsnd_${cyc}" - "${DBNROOT}/bin/dbn_alert" NTC_LOW BUFR "${job}" \ - "${COMOUT_ATMOS_WMO}/gfs_collective${m}.postsnd_${cyc}" + export err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR Failed during execution of ${pgm}" + exit "${err}" fi - cpfs "${DATA}/${m}/gfs_collective${m}.fil" "${COMOUT_ATMOS_BUFR}/." + cat "${DATA}/${m}/bufrout" >> "${DATA}/${m}/gfs_collective${m}.fil" + rm -f "${DATA}/${m}/bufrin" "${DATA}/${m}/bufrout" +done < "${file_list}" + +if [[ "${SENDDBN}" == 'YES' ]]; then + cpfs "${DATA}/${m}/gfs_collective${m}.fil" "${COMOUT_ATMOS_WMO}/gfs_collective${m}.postsnd_${cyc}" + "${DBNROOT}/bin/dbn_alert" NTC_LOW BUFR "${job}" \ + "${COMOUT_ATMOS_WMO}/gfs_collective${m}.postsnd_${cyc}" +fi +cpfs "${DATA}/${m}/gfs_collective${m}.fil" "${COMOUT_ATMOS_BUFR}/." diff --git a/ush/gfs_truncate_enkf.sh b/ush/gfs_truncate_enkf.sh deleted file mode 100755 index 7225b4e5925..00000000000 --- a/ush/gfs_truncate_enkf.sh +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env bash - -member=$1 -export SIGINP=$2 -export SIGOUT=$3 -export JCAP=$4 -export LATB=$5 -export LONB=$6 - -DATATMP=$DATA/$member -mkdir -p $DATATMP -cd $DATATMP - -export LEVS=${LEVS_LORES:-64} - -export CHGRESSH=${CHGRESSH:-${USHgfs}/global_chgres.sh} -export CHGRESEXEC=${CHGRESEXEC-${EXECgfs}/global_chgres} -export OROGRAPHY=${OROGRAPHY_LORES:-${FIXgfs}/am/global_orography.t$JCAP.$LONB.$LATB.grb} -export OROGRAPHY_UF=${OROGRAPHY_UF_LORES:-${FIXgfs}/am/global_orography_uf.t$JCAP.$LONB.$LATB.grb} -export LONSPERLAT=${LONSPERLAT_LORES:-${FIXgfs}/am/global_lonsperlat.t${JCAP}.$LONB.$LATB.txt} -export SLMASK=${SLMASK_LORES:-${FIXgfs}/am/global_slmask.t$JCAP.$LONB.$LATB.grb} -export MTNVAR=${MTNVAR_LORES:-${FIXgfs}/am/global_mtnvar.t$JCAP.$LONB.$LATB.f77} -export SIGLEVEL=${SIGLEVEL_LORES:-${FIXgfs}/am/global_hyblev.l${LEVS}.txt} -export O3CLIM=${O3CLIM:-${FIXgfs}/am/global_o3clim.txt} - -use_ufo=.true. - -NTRAC=3 -IALB=0 -idvc_a=2 -idvt=21 -IDSL=1 -IDVM=0 -LATCH=8 -OUTTYP=2 -export CHGRESTHREAD=${CHGRESTHREAD_LORES:-2} -export CHGRESVARS="use_ufo=$use_ufo,IALB=$ialb,ntrac=$NTRAC,idvc=$idvc_a,idvt=$idvt,idsl=$IDSL,IDVM=$IDVM,OUTTYP=$OUTTYP," - -export DATA=$DATATMP - -export APRUNC=${APRUNC:-""} -export VERBOSE=YES - -echo "execute $CHGRESSH for $member" -$CHGRESSH -rc=$? - -export ERR=$rc -export err=$ERR - -exit $err - diff --git a/ush/global_cycle.sh b/ush/global_cycle.sh index 661833898bb..0918e943a11 100755 --- a/ush/global_cycle.sh +++ b/ush/global_cycle.sh @@ -205,9 +205,9 @@ CYCLEXEC=${CYCLEXEC:-${EXECgfs}/global_cycle${XC}} FHOUR=${FHOUR:-00} CRES=${CASE:1} -JCAP_CASE=$((2*CRES-2)) -LONB_CASE=$((4*CRES)) -LATB_CASE=$((2*CRES)) +JCAP_CASE=$((2 * CRES - 2)) +LONB_CASE=$((4 * CRES)) +LATB_CASE=$((2 * CRES)) DELTSFC=${DELTSFC:-0} LSOIL=${LSOIL:-4} @@ -225,10 +225,10 @@ DONST=${DONST:-"NO"} DO_SFCCYCLE=${DO_SFCCYCLE:-.true.} GCYCLE_DO_SOILINCR=${GCYCLE_DO_SOILINCR:-.false.} GCYCLE_DO_SNOWINCR=${GCYCLE_DO_SNOWINCR:-.false.} -if [[ "${GCYCLE_DO_SOILINCR}" == ".true." ]] || [[ "${GCYCLE_DO_SNOWINCR}" == ".true." ]] ; then - DO_LANDINCR=".true." +if [[ "${GCYCLE_DO_SOILINCR}" == ".true." ]] || [[ "${GCYCLE_DO_SNOWINCR}" == ".true." ]]; then + DO_LANDINCR=".true." else - DO_LANDINCR=".false." + DO_LANDINCR=".false." fi GCYCLE_INTERP_LANDINCR=${GCYCLE_INTERP_LANDINCR:-.false.} zsea1=${zsea1:-0} @@ -330,7 +330,6 @@ cat << EOF > fort.36 / EOF - cat << EOF > fort.37 &NAMSFCD NST_FILE="${NST_FILE}", @@ -341,7 +340,7 @@ cat << EOF > fort.37 / EOF -${APRUNCY} "${CYCLEXEC}" 1>"${PGMOUT}" 2>"${PGMERR}" +${APRUNCY} "${CYCLEXEC}" 1> "${PGMOUT}" 2> "${PGMERR}" export err=$? diff --git a/ush/global_savefits.sh b/ush/global_savefits.sh index da62bf6ad9e..b23f1f694db 100755 --- a/ush/global_savefits.sh +++ b/ush/global_savefits.sh @@ -1,5 +1,5 @@ #! /usr/bin/env bash - + ######################################################## # save fit and horiz files for all analysis cycles ######################################################## @@ -10,7 +10,7 @@ export fh1=06 export fh2=00 # #dir=${FIT_DIR}/${EXP} -dir=${FIT_DIR} +dir="${FIT_DIR}" mkdir -p "${dir}" cd "${dir}" || exit 8 cpreq "${COMOUT}/f${fh1}.raob.${PDY}${cyc}" . @@ -24,8 +24,8 @@ cpreq "${COMOUT}/f${fh2}.acft.${PDY}${cyc}" . export typ=anl #dir=${HORZ_DIR}/${EXP}/${typ} -dir=${HORZ_DIR}/${typ} -mkdir -p ${dir} +dir="${HORZ_DIR}/${typ}" +mkdir -p "${dir}" cd "${dir}" || exit 8 cpreq "${COMOUT}/adpupa.mand.${typ}.${PDY}${cyc}" "adpupa.mand.${PDY}${cyc}" cpreq "${COMOUT}/adpsfc.${typ}.${PDY}${cyc}" "adpsfc.${PDY}${cyc}" @@ -36,35 +36,35 @@ cpreq "${COMOUT}/aircft.${typ}.${PDY}${cyc}" "aircft.${PDY}${cyc}" # save fit and horiz files for forecasts verifying at 00Z and 12Z cycles ######################################################################### if [[ "${cyc}" == "00" || "${cyc}" == "12" ]]; then - if [[ "${cyc}" == "00" ]]; then - export fh1=24 - export fh2=48 - fi - if [[ "${cyc}" == "12" ]]; then - export fh1=12 - export fh2=36 - fi - #dir=${FIT_DIR}/${EXP} - dir=${FIT_DIR} - mkdir -p "${dir}" - cd "${dir}" || exit 8 - cpreq "${COMOUT}/f${fh1}.raob.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh2}.raob.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh1}.sfc.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh2}.sfc.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh1}.acar.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh2}.acar.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh1}.acft.${PDY}${cyc}" . - cpreq "${COMOUT}/f${fh2}.acft.${PDY}${cyc}" . - export typ=fcs - #dir=${HORZ_DIR}/${EXP}/${typ} - dir=${HORZ_DIR}/${typ} - mkdir -p "${dir}" - cd "${dir}" || exit 8 - cpreq "${COMOUT}/adpupa.mand.${typ}.${PDY}${cyc}" "adpupa.mand.${PDY}${cyc}" - cpreq "${COMOUT}/adpsfc.${typ}.${PDY}${cyc}" "adpsfc.${PDY}${cyc}" - cpreq "${COMOUT}/sfcshp.${typ}.${PDY}${cyc}" "sfcshp.${PDY}${cyc}" - cpreq "${COMOUT}/aircar.${typ}.${PDY}${cyc}" "aircar.${PDY}${cyc}" - cpreq "${COMOUT}/aircft.${typ}.${PDY}${cyc}" "aircft.${PDY}${cyc}" + if [[ "${cyc}" == "00" ]]; then + export fh1=24 + export fh2=48 + fi + if [[ "${cyc}" == "12" ]]; then + export fh1=12 + export fh2=36 + fi + #dir=${FIT_DIR}/${EXP} + dir="${FIT_DIR}" + mkdir -p "${dir}" + cd "${dir}" || exit 8 + cpreq "${COMOUT}/f${fh1}.raob.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh2}.raob.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh1}.sfc.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh2}.sfc.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh1}.acar.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh2}.acar.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh1}.acft.${PDY}${cyc}" . + cpreq "${COMOUT}/f${fh2}.acft.${PDY}${cyc}" . + export typ=fcs + #dir=${HORZ_DIR}/${EXP}/${typ} + dir="${HORZ_DIR}/${typ}" + mkdir -p "${dir}" + cd "${dir}" || exit 8 + cpreq "${COMOUT}/adpupa.mand.${typ}.${PDY}${cyc}" "adpupa.mand.${PDY}${cyc}" + cpreq "${COMOUT}/adpsfc.${typ}.${PDY}${cyc}" "adpsfc.${PDY}${cyc}" + cpreq "${COMOUT}/sfcshp.${typ}.${PDY}${cyc}" "sfcshp.${PDY}${cyc}" + cpreq "${COMOUT}/aircar.${typ}.${PDY}${cyc}" "aircar.${PDY}${cyc}" + cpreq "${COMOUT}/aircft.${typ}.${PDY}${cyc}" "aircft.${PDY}${cyc}" fi ######################################################################### diff --git a/ush/interp_atmos_master.sh b/ush/interp_atmos_master.sh index 00bbde65043..b43b05c889b 100755 --- a/ush/interp_atmos_master.sh +++ b/ush/interp_atmos_master.sh @@ -4,9 +4,9 @@ # Generate 0.25 / 0.5 / 1 degree interpolated grib2 files for each input grib2 file # trim's RH and tweaks sea-ice cover -input_file=${1:-"pgb2file_in"} # Input pressure grib2 file -output_file_prefix=${2:-"pgb2file_out"} # Prefix for output grib2 file; the prefix is appended by resolution e.g. _0p25 -grid_string=${3:-"0p25"} # Target grids; e.g. "0p25" or "0p25:0p50"; If multiple, they need to be ":" seperated +input_file=${1:-"pgb2file_in"} # Input pressure grib2 file +output_file_prefix=${2:-"pgb2file_out"} # Prefix for output grib2 file; the prefix is appended by resolution e.g. _0p25 +grid_string=${3:-"0p25"} # Target grids; e.g. "0p25" or "0p25:0p50"; If multiple, they need to be ":" seperated # wgrib2 options for regridding defaults="-set_grib_type same -set_bitmap 1 -set_grib_max_bits 16" @@ -32,42 +32,42 @@ IFS=':' read -ra grids <<< "${grid_string}" output_grids="" for grid in "${grids[@]}"; do - gridopt="grid${grid}" - output_grids="${output_grids} -new_grid ${!gridopt} ${output_file_prefix}_${grid}" + gridopt="grid${grid}" + output_grids="${output_grids} -new_grid ${!gridopt} ${output_file_prefix}_${grid}" done #shellcheck disable=SC2086 ${WGRIB2} "${input_file}" ${defaults} \ - ${interp_winds} \ - ${interp_bilinear} \ - ${interp_neighbor} \ - ${interp_budget} \ - ${increased_bits} \ - ${output_grids} + ${interp_winds} \ + ${interp_bilinear} \ + ${interp_neighbor} \ + ${interp_budget} \ + ${increased_bits} \ + ${output_grids} export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: WGRIB2 failed to generate interpolated grib2 file!" - exit "${err}" + echo "FATAL ERROR: WGRIB2 failed to generate interpolated grib2 file!" + exit "${err}" fi # trim and mask for all grids for grid in "${grids[@]}"; do - trim_rh "${output_file_prefix}_${grid}" - export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Failed during the execution of trim_rh" - exit "${err}" - fi - # shellcheck disable=SC2312 - var_count=$(${WGRIB2} "${output_file_prefix}_${grid}" -match "LAND|ICEC" |wc -l) - if [[ "${var_count}" -eq 2 ]]; then - mod_icec "${output_file_prefix}_${grid}" + trim_rh "${output_file_prefix}_${grid}" export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Failed during execution of mod_icec" - exit "${err}" + echo "FATAL ERROR: Failed during the execution of trim_rh" + exit "${err}" + fi + # shellcheck disable=SC2312 + var_count=$(${WGRIB2} "${output_file_prefix}_${grid}" -match "LAND|ICEC" | wc -l) + if [[ "${var_count}" -eq 2 ]]; then + mod_icec "${output_file_prefix}_${grid}" + export err=$? + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: Failed during execution of mod_icec" + exit "${err}" + fi fi - fi done exit 0 diff --git a/ush/interp_atmos_sflux.sh b/ush/interp_atmos_sflux.sh index 2aff2cc58aa..859691cdf73 100755 --- a/ush/interp_atmos_sflux.sh +++ b/ush/interp_atmos_sflux.sh @@ -3,9 +3,9 @@ # This script takes in a master flux file and creates interpolated flux files at various interpolated resolutions # Generate 0.25 / 0.5 / 1 degree interpolated grib2 flux files for each input sflux grib2 file -input_file=${1:-"sfluxfile_in"} # Input sflux grib2 file -output_file_prefix=${2:-"sfluxfile_out"} # Prefix for output sflux grib2 file; the prefix is appended by resolution e.g. _0p25 -grid_string=${3:-"1p00"} # Target grids; e.g. "0p25" or "0p25:0p50"; If multiple, they need to be ":" seperated +input_file=${1:-"sfluxfile_in"} # Input sflux grib2 file +output_file_prefix=${2:-"sfluxfile_out"} # Prefix for output sflux grib2 file; the prefix is appended by resolution e.g. _0p25 +grid_string=${3:-"1p00"} # Target grids; e.g. "0p25" or "0p25:0p50"; If multiple, they need to be ":" seperated # wgrib2 options for regridding defaults="-set_grib_type same -set_bitmap 1 -set_grib_max_bits 16" @@ -28,22 +28,22 @@ IFS=':' read -ra grids <<< "${grid_string}" output_grids="" for grid in "${grids[@]}"; do - gridopt="grid${grid}" - output_grids="${output_grids} -new_grid ${!gridopt} ${output_file_prefix}_${grid}" + gridopt="grid${grid}" + output_grids="${output_grids} -new_grid ${!gridopt} ${output_file_prefix}_${grid}" done #shellcheck disable=SC2086 ${WGRIB2} "${input_file}" ${defaults} \ - ${interp_winds} \ - ${interp_bilinear} \ - ${interp_neighbor} \ - ${interp_budget} \ - ${increased_bits} \ - ${output_grids} + ${interp_winds} \ + ${interp_bilinear} \ + ${interp_neighbor} \ + ${interp_budget} \ + ${increased_bits} \ + ${output_grids} export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: WGRIB2 failed to interpolate surface flux parameters to a new grib2 file" - exit "${err}" + echo "FATAL ERROR: WGRIB2 failed to interpolate surface flux parameters to a new grib2 file" + exit "${err}" fi exit 0 diff --git a/ush/jjob_header.sh b/ush/jjob_header.sh index 5de17f73a49..f69524b732a 100755 --- a/ush/jjob_header.sh +++ b/ush/jjob_header.sh @@ -46,8 +46,8 @@ source "${HOMEgfs}/ush/preamble.sh" OPTIND=1 while getopts "c:e:" option; do case "${option}" in - c) read -ra configs <<< "${OPTARG}" ;; - e) env_job=${OPTARG} ;; + c) read -ra configs <<< "${OPTARG}" ;; + e) env_job=${OPTARG} ;; :) export err=1 err_exit "[${BASH_SOURCE[0]}]: ${option} requires an argument" @@ -58,7 +58,7 @@ while getopts "c:e:" option; do ;; esac done -shift $((OPTIND-1)) +shift $((OPTIND - 1)) if [[ -z ${env_job} ]]; then export err=1 @@ -74,11 +74,10 @@ if [[ ${WIPE_DATA:-YES} == "YES" ]]; then fi mkdir -p "${DATA}" if ! cd "${DATA}"; then - export err=1 - err_exit "[${BASH_SOURCE[0]}]: ${DATA} does not exist" + export err=1 + err_exit "[${BASH_SOURCE[0]}]: ${DATA} does not exist" fi - ############################################## # Determine Job Output Name on System ############################################## @@ -89,7 +88,6 @@ export pgmerr=errfile # Needs to be set for err_chk/err_exit export pgm=${pgm:-} - ############################################## # Run setpdy and initialize PDY variables ############################################## @@ -97,7 +95,6 @@ export cycle="t${cyc}z" setpdy.sh || true source ./PDY || true - ############################# # Source relevant config files ############################# @@ -106,16 +103,15 @@ for config in "${configs[@]:-''}"; do source "${EXPDIR}/config.${config}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "[${BASH_SOURCE[0]}]: Unable to load config config.${config}" + err_exit "[${BASH_SOURCE[0]}]: Unable to load config config.${config}" fi done - ########################################## # Source machine runtime environment ########################################## source "${HOMEgfs}/env/${machine}.env" "${env_job}" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "[${BASH_SOURCE[0]}]: Error while sourcing machine environment ${machine}.env for job ${env_job}" + err_exit "[${BASH_SOURCE[0]}]: Error while sourcing machine environment ${machine}.env for job ${env_job}" fi diff --git a/ush/link_crtm_fix.sh b/ush/link_crtm_fix.sh index 7a3654b8405..9f0d583b94f 100755 --- a/ush/link_crtm_fix.sh +++ b/ush/link_crtm_fix.sh @@ -6,30 +6,30 @@ # 3. Nowhere. Give up. Whine. CRTM_FIX="${1:-${CRTM_FIX:-MISSING}}" -if [[ "${CRTM_FIX}" == "MISSING" ]] ; then - echo "Please specify CRTM fix location. Giving up." 1>&2 - exit 19 +if [[ "${CRTM_FIX}" == "MISSING" ]]; then + echo "Please specify CRTM fix location. Giving up." 1>&2 + exit 19 fi -if [[ ! -d "${CRTM_FIX}" ]] ; then - echo "${CRTM_FIX}: \${CRTM_FIX} is not a directory. Giving up." 1>&2 - exit 38 +if [[ ! -d "${CRTM_FIX}" ]]; then + echo "${CRTM_FIX}: \${CRTM_FIX} is not a directory. Giving up." 1>&2 + exit 38 fi for what in "amsre_aqua" "imgr_g11" "imgr_g12" "imgr_g13" \ - "imgr_g15" "imgr_mt1r" "imgr_mt2" "seviri_m10" \ - "ssmi_f13" "ssmi_f14" "ssmi_f15" "ssmis_f16" \ - "ssmis_f17" "ssmis_f18" "ssmis_f19" "ssmis_f20" \ - "tmi_trmm" "v.seviri_m10" "imgr_insat3d" "abi_gr" "ahi_himawari8" ; do - ${NLN} "${CRTM_FIX}/${what}.TauCoeff.bin" "${what}.TauCoeff.bin" - ${NLN} "${CRTM_FIX}/${what}.SpcCoeff.bin" "${what}.SpcCoeff.bin" + "imgr_g15" "imgr_mt1r" "imgr_mt2" "seviri_m10" \ + "ssmi_f13" "ssmi_f14" "ssmi_f15" "ssmis_f16" \ + "ssmis_f17" "ssmis_f18" "ssmis_f19" "ssmis_f20" \ + "tmi_trmm" "v.seviri_m10" "imgr_insat3d" "abi_gr" "ahi_himawari8"; do + ${NLN} "${CRTM_FIX}/${what}.TauCoeff.bin" "${what}.TauCoeff.bin" + ${NLN} "${CRTM_FIX}/${what}.SpcCoeff.bin" "${what}.SpcCoeff.bin" done -for what in 'Aerosol' 'Cloud' ; do - ${NLN} "${CRTM_FIX}/${what}Coeff.bin" "${what}Coeff.bin" +for what in 'Aerosol' 'Cloud'; do + ${NLN} "${CRTM_FIX}/${what}Coeff.bin" "${what}Coeff.bin" done -for what in "${CRTM_FIX}/"*Emis* ; do - ${NLN} "${what}" "$(basename "${what}")" +for what in "${CRTM_FIX}/"*Emis*; do + ${NLN} "${what}" "$(basename "${what}")" done exit 0 diff --git a/ush/make_tif.sh b/ush/make_tif.sh index b5adfdc6f3b..70987cf51ec 100755 --- a/ush/make_tif.sh +++ b/ush/make_tif.sh @@ -15,15 +15,15 @@ ORIG=KWBC PDYHH="${PDY}${cyc}" if [[ "${HEADER}" == "YES" ]]; then - INPATH="${DATA}/${outname}" - SUB=DFAX1064 - "${HOMEgfs}/ush/make_NTC_file.pl" "${WMO}" "${ORIG}" "${PDYHH}" "${SUB}" "${INPATH}" "${OUTPATH}" -# -# Send the graphic to TOC + INPATH="${DATA}/${outname}" + SUB=DFAX1064 + "${HOMEgfs}/ush/make_NTC_file.pl" "${WMO}" "${ORIG}" "${PDYHH}" "${SUB}" "${INPATH}" "${OUTPATH}" + # + # Send the graphic to TOC - cpfs "${OUTPATH}" "${COMOUT_ATMOS_WMO}/gfs_500_hgt_tmp_nh_anl_${cyc}.tif" - if [[ "${SENDDBN}" == "YES" ]]; then + cpfs "${OUTPATH}" "${COMOUT_ATMOS_WMO}/gfs_500_hgt_tmp_nh_anl_${cyc}.tif" + if [[ "${SENDDBN}" == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" GRIB_LOW "${NET}" "${job}" "${COMOUT_ATMOS_WMO}/gfs_500_hgt_tmp_nh_anl_${cyc}.tif" - fi + "${DBNROOT}/bin/dbn_alert" GRIB_LOW "${NET}" "${job}" "${COMOUT_ATMOS_WMO}/gfs_500_hgt_tmp_nh_anl_${cyc}.tif" + fi fi diff --git a/ush/minmon_xtrct_costs.pl b/ush/minmon_xtrct_costs.pl index 765526b40d1..3dfd8f47951 100755 --- a/ush/minmon_xtrct_costs.pl +++ b/ush/minmon_xtrct_costs.pl @@ -214,11 +214,13 @@ if( -e $filename2 ) { my $newfile2 = "${tankdir}/${filename2}"; - system("cpfs $filename2 $newfile2"); + system("cpfs $filename2 ${newfile2}") == 0 + or die "cpfs failed to copy ${filename2} to ${newfile2} with exit code $?"; } if( -e $filename3 ) { my $newfile3 = "${tankdir}/${filename3}"; - system("cpfs $filename3 $newfile3"); + system("cpfs ${filename3} ${newfile3}") == 0 + or die "cpfs failed to copy ${filename3} to ${newfile3} with exit code $?"; } } # $rc still == 0 after reading gmon_cost.txt diff --git a/ush/minmon_xtrct_gnorms.pl b/ush/minmon_xtrct_gnorms.pl index d4913b0619b..c0e9e1e0a54 100755 --- a/ush/minmon_xtrct_gnorms.pl +++ b/ush/minmon_xtrct_gnorms.pl @@ -111,7 +111,8 @@ sub updateGnormData { print OUTFILE @filearray; close( OUTFILE ); - system("cpfs $outfile $gdfile"); + system("cpfs ${outfile} ${gdfile}") == 0 + or die "cpfs failed to copy ${outfile} to ${gdfile} with exit code $?"; } @@ -419,17 +420,20 @@ sub updateGnormData { } if( -e $filename2 ) { - system("cpfs $filename2 ${tankdir}/."); + system("cpfs ${filename2} ${tankdir}/.") == 0 + or die "cpfs failed to copy ${filename2} to ${tankdir} with exit code $?"; } my $gdfile = "gnorm_data.txt"; if( -e $gdfile ) { - system("cpfs $gdfile ${tankdir}/."); + system("cpfs ${gdfile} ${tankdir}/.") == 0 + or die "cpfs failed to copy ${gdfile} to ${tankdir} with exit code $?"; } my $errmsg = "${cdate}.errmsg.txt"; if( -e $errmsg ) { - system("cpfs $errmsg ${tankdir}/."); + system("cpfs ${errmsg} ${tankdir}/.") == 0 + or die "cpfs failed to copy ${errmsg} to ${tankdir} with exit code $?"; } } # $rc still == 0 after reading gmon_gnorm.txt diff --git a/ush/minmon_xtrct_reduct.pl b/ush/minmon_xtrct_reduct.pl index 7290a27ba5c..b2d10755ac1 100755 --- a/ush/minmon_xtrct_reduct.pl +++ b/ush/minmon_xtrct_reduct.pl @@ -77,7 +77,8 @@ if( -e $outfile ) { my $newfile = "${tankdir}/${outfile}"; - system("cpfs $outfile $newfile"); + system("cpfs ${outfile} ${newfile}") == 0 + or die "cpfs failed to copy ${outfile} to ${newfile} with exit code $?"; } } else { # $infile does not exist diff --git a/ush/module-setup.sh b/ush/module-setup.sh index 4065c67e4cd..13e41879804 100755 --- a/ush/module-setup.sh +++ b/ush/module-setup.sh @@ -3,9 +3,9 @@ set -u source "${HOMEgfs}/ush/detect_machine.sh" -if [[ ${MACHINE_ID} = hera* ]] ; then +if [[ ${MACHINE_ID} = hera* ]]; then # We are on NOAA Hera - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /apps/lmod/lmod/init/bash fi export LMOD_SYSTEM_DEFAULT_MODULES=contrib @@ -13,9 +13,9 @@ if [[ ${MACHINE_ID} = hera* ]] ; then module reset set -u -elif [[ ${MACHINE_ID} = ursa* ]] ; then +elif [[ ${MACHINE_ID} = ursa* ]]; then # We are on NOAA Ursa - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /apps/lmod/lmod/init/bash fi export LMOD_SYSTEM_DEFAULT_MODULES=lmod @@ -23,9 +23,9 @@ elif [[ ${MACHINE_ID} = ursa* ]] ; then module reset set -u -elif [[ ${MACHINE_ID} = hercules* ]] ; then +elif [[ ${MACHINE_ID} = hercules* ]]; then # We are on Hercules - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /apps/other/lmod/lmod/init/bash fi export LMOD_SYSTEM_DEFAULT_MODULES=contrib @@ -33,9 +33,9 @@ elif [[ ${MACHINE_ID} = hercules* ]] ; then module reset set -u -elif [[ ${MACHINE_ID} = orion* ]] ; then +elif [[ ${MACHINE_ID} = orion* ]]; then # We are on Orion - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /apps/lmod/lmod/init/bash fi #export LMOD_SYSTEM_DEFAULT_MODULES=git/2.28.0 # contrib has a lot of stuff we shouldn't put in MODULEPATH @@ -43,30 +43,29 @@ elif [[ ${MACHINE_ID} = orion* ]] ; then module purge # reset causes issues on Orion sometimes. #set -u - elif [[ ${MACHINE_ID} = wcoss2 ]]; then # We are on WCOSS2 # Ignore default modules of the same version lower in the search path (req'd by spack-stack) #export LMOD_TMOD_FIND_FIRST=yes #TODO: Uncomment this when using spack-stack for the entire workflow module reset -elif [[ ${MACHINE_ID} = cheyenne* ]] ; then +elif [[ ${MACHINE_ID} = cheyenne* ]]; then # We are on NCAR Cheyenne - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /glade/u/apps/ch/modulefiles/default/localinit/localinit.sh fi module purge -elif [[ ${MACHINE_ID} = stampede* ]] ; then +elif [[ ${MACHINE_ID} = stampede* ]]; then # We are on TACC Stampede - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /opt/apps/lmod/lmod/init/bash fi module purge -elif [[ ${MACHINE_ID} = gaeac5 ]] ; then +elif [[ ${MACHINE_ID} = gaeac5 ]]; then # We are on GAEA C5. - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then # We cannot simply load the module command. The GAEA # /etc/profile modifies a number of module-related variables # before loading the module command. Without those variables, @@ -77,14 +76,14 @@ elif [[ ${MACHINE_ID} = gaeac5 ]] ; then module reset elif [[ ${MACHINE_ID} = gaeac6 ]]; then # We are on GAEA C6. - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /opt/cray/pe/lmod/lmod/init/bash fi module reset elif [[ ${MACHINE_ID} = expanse* ]]; then # We are on SDSC Expanse - if ( ! eval module help > /dev/null 2>&1 ) ; then + if (! eval module help > /dev/null 2>&1); then source /etc/profile.d/modules.sh fi module purge @@ -109,7 +108,7 @@ fi # If this function exists in the environment, run it; else do not ftype=$(type -t set_strict || echo "") if [[ "${ftype}" == "function" ]]; then - set_strict + set_strict else - set +u + set +u fi diff --git a/ush/month_name.sh b/ush/month_name.sh index 02af45149d7..c84133356a5 100755 --- a/ush/month_name.sh +++ b/ush/month_name.sh @@ -5,7 +5,7 @@ # SCRIPT: month_name.sh # # This script returns the name/abreviation of a month -# in a small text file, month_name.txt. It also echos the +# in a small text file, month_name.txt. It also echos the # name/abreviation to stdout. The form of the returned # name/abreviation is specified by the script arguments. # @@ -17,7 +17,7 @@ # ----------- ------ ---------------------------- # # 6/06 Mon Jun -# 8/08 Month August +# 8/08 Month August # 9/09 MON SEP # 11 MONTH NOVEMBER # @@ -26,7 +26,7 @@ # by either of the following methods: # # MM=`cat month_name.txt` after executing month_name.sh -# - OR - +# - OR - # MM=`month_name.sh 5 MON` (for example) # # @@ -36,77 +36,100 @@ # #################################################################### - typeset -Z2 month_num - - - month_num=$1 - month_spec=$2 - - case ${month_num} in - - 01) Mon=Jan - Month=January ;; - - 02) Mon=Feb - Month=February ;; - - 03) Mon=Mar - Month=March ;; - - 04) Mon=Apr - Month=April ;; - - 05) Mon=May - Month=May ;; - - 06) Mon=Jun - Month=June ;; - - 07) Mon=Jul - Month=July ;; - - 08) Mon=Aug - Month=August ;; - - 09) Mon=Sep - Month=September ;; - - 10) Mon=Oct - Month=October ;; - - 11) Mon=Nov - Month=November ;; - - 12) Mon=Dec - Month=December ;; +typeset -Z2 month_num + +month_num=$1 +month_spec=$2 + +case ${month_num} in + + 01) + Mon=Jan + Month=January + ;; + + 02) + Mon=Feb + Month=February + ;; + + 03) + Mon=Mar + Month=March + ;; + + 04) + Mon=Apr + Month=April + ;; + + 05) + Mon=May + Month=May + ;; + + 06) + Mon=Jun + Month=June + ;; + + 07) + Mon=Jul + Month=July + ;; + + 08) + Mon=Aug + Month=August + ;; + + 09) + Mon=Sep + Month=September + ;; + + 10) + Mon=Oct + Month=October + ;; + + 11) + Mon=Nov + Month=November + ;; + + 12) + Mon=Dec + Month=December + ;; *) echo "FATAL ERROR input month number (${month_num}) is invalid" exit 2 + ;; - esac - +esac - if [[ "${month_spec}" == "Mon" ]]; then +if [[ "${month_spec}" == "Mon" ]]; then echo "${Mon}" echo "${Mon}" > month_name.txt - elif [[ "${month_spec}" == "Month" ]]; then +elif [[ "${month_spec}" == "Month" ]]; then echo "${Month}" echo "${Month}" > month_name.txt - elif [[ "${month_spec}" == "MON" ]]; then +elif [[ "${month_spec}" == "MON" ]]; then MON="${Mon^^}" echo "${MON}" echo "${MON}" > month_name.txt - elif [[ "${month_spec}" == "MONTH" ]]; then +elif [[ "${month_spec}" == "MONTH" ]]; then MONTH="${Month^^}" echo "${MONTH}" echo "${MONTH}" > month_name.txt - fi +fi diff --git a/ush/ocnice_extractvars.sh b/ush/ocnice_extractvars.sh index 96f6558d07b..2e6eb0237ea 100755 --- a/ush/ocnice_extractvars.sh +++ b/ush/ocnice_extractvars.sh @@ -18,69 +18,69 @@ fhout_ocnice=${5} comout_rfcst_prod_ocnice=${6} if [[ ! -d "${subdata}" ]]; then - mkdir -p "${subdata}" + mkdir -p "${subdata}" fi -for (( nh = FHMIN_GFS + fhout_ocnice; nh <= FHMAX_GFS; nh = nh + fhout_ocnice )); do - fnh=$(printf "%3.3d" "${nh}") +for ((nh = FHMIN_GFS + fhout_ocnice; nh <= FHMAX_GFS; nh = nh + fhout_ocnice)); do + fnh=$(printf "%3.3d" "${nh}") - if [[ ${component_name} == "ocn" ]]; then - if [[ "${datares}" == "native" ]]; then - com_dir=${COMIN_OCEAN_HISTORY} - infile="${com_dir}/${RUN}.ocean.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}.nc" - new_infile=${subdata}/${RUN}.ocean.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}_ext.nc - else - com_dir=${COMIN_OCEAN_NETCDF} - infile="${com_dir}/${datares}/${RUN}.ocean.t${cyc}z.${datares}.f${fnh}.nc" - new_infile=${subdata}/${RUN}.ocean.t${cyc}z.${datares}.f${fnh}_ext.nc - fi - # For ocean products, add an argument to extract a subset of levels - otherargs=(-d "${depthvar_name},""${zmin},""${zmax}") - elif [[ ${component_name} == "ice" ]]; then - if [[ "${datares}" == "native" ]]; then - com_dir=${COMIN_ICE_HISTORY} - infile="${com_dir}/${RUN}.ice.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}.nc" - new_infile=${subdata}/${RUN}.ice.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}_ext.nc - else - com_dir=${COMIN_ICE_NETCDF} - infile="${com_dir}/${datares}/${RUN}.ice.t${cyc}z.${datares}.f${fnh}.nc" - new_infile=${subdata}/${RUN}.ice.t${cyc}z.${datares}.f${fnh}_ext.nc + if [[ ${component_name} == "ocn" ]]; then + if [[ "${datares}" == "native" ]]; then + com_dir=${COMIN_OCEAN_HISTORY} + infile="${com_dir}/${RUN}.ocean.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}.nc" + new_infile=${subdata}/${RUN}.ocean.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}_ext.nc + else + com_dir=${COMIN_OCEAN_NETCDF} + infile="${com_dir}/${datares}/${RUN}.ocean.t${cyc}z.${datares}.f${fnh}.nc" + new_infile=${subdata}/${RUN}.ocean.t${cyc}z.${datares}.f${fnh}_ext.nc + fi + # For ocean products, add an argument to extract a subset of levels + otherargs=(-d "${depthvar_name},""${zmin},""${zmax}") + elif [[ ${component_name} == "ice" ]]; then + if [[ "${datares}" == "native" ]]; then + com_dir=${COMIN_ICE_HISTORY} + infile="${com_dir}/${RUN}.ice.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}.nc" + new_infile=${subdata}/${RUN}.ice.t${cyc}z.${fhout_ocnice}hr_avg.f${fnh}_ext.nc + else + com_dir=${COMIN_ICE_NETCDF} + infile="${com_dir}/${datares}/${RUN}.ice.t${cyc}z.${datares}.f${fnh}.nc" + new_infile=${subdata}/${RUN}.ice.t${cyc}z.${datares}.f${fnh}_ext.nc + fi + otherargs=() fi - otherargs=() - fi - outfile=${subdata}/${RUN}.${component_name}.t${cyc}z.${datares}.f${fnh}.nc + outfile=${subdata}/${RUN}.${component_name}.t${cyc}z.${datares}.f${fnh}.nc - if [[ -f "${infile}" ]]; then #check if input file exists before extraction - if ! cpfs "${infile}" "${new_infile}"; then - echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." - exit 1 - fi - varsrequested=$(paste -s "${varlist}") - varsinfile=$(cdo -showname "${new_infile}") - varsavailable="" - for i in ${varsrequested}; do - # Check if variable from parm file is available in netcdf file. If variable is not in netcdf file, do not try to extract that variable. - if [[ ${varsinfile} == *"${i}"* ]]; then - varsavailable+="${i}," - else - echo "WARNING: ${i} is not available in ${new_infile}." - fi - done - if [[ -z "${varsavailable}" ]]; then - echo "WARNING: No variables from parm file ${varlist} are available in netcdf file ${new_infile}." - else - ocnice_vars=${varsavailable::-1} - ncks -v "${ocnice_vars}" "${otherargs[@]}" "${new_infile}" "${outfile}" - fi - if [[ ${datacompress} -eq 1 ]]; then - ${COMPRSCMD} "${outfile}" - copy_to_comout "${outfile}.bz2" "${comout_rfcst_prod_ocnice}" + if [[ -f "${infile}" ]]; then #check if input file exists before extraction + if ! cpfs "${infile}" "${new_infile}"; then + echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." + exit 1 + fi + varsrequested=$(paste -s "${varlist}") + varsinfile=$(cdo -showname "${new_infile}") + varsavailable="" + for i in ${varsrequested}; do + # Check if variable from parm file is available in netcdf file. If variable is not in netcdf file, do not try to extract that variable. + if [[ ${varsinfile} == *"${i}"* ]]; then + varsavailable+="${i}," + else + echo "WARNING: ${i} is not available in ${new_infile}." + fi + done + if [[ -z "${varsavailable}" ]]; then + echo "WARNING: No variables from parm file ${varlist} are available in netcdf file ${new_infile}." + else + ocnice_vars=${varsavailable::-1} + ncks -v "${ocnice_vars}" "${otherargs[@]}" "${new_infile}" "${outfile}" + fi + if [[ ${datacompress} -eq 1 ]]; then + ${COMPRSCMD} "${outfile}" + copy_to_comout "${outfile}.bz2" "${comout_rfcst_prod_ocnice}" + else + copy_to_comout "${outfile}" "${comout_rfcst_prod_ocnice}" + fi else - copy_to_comout "${outfile}" "${comout_rfcst_prod_ocnice}" + echo "WARNING: ${infile} does not exist in ${com_dir}." fi - else - echo "WARNING: ${infile} does not exist in ${com_dir}." - fi done # nh exit 0 diff --git a/ush/ozn_xtrct.sh b/ush/ozn_xtrct.sh index a84c00f45b7..d45674bdb12 100755 --- a/ush/ozn_xtrct.sh +++ b/ush/ozn_xtrct.sh @@ -5,16 +5,16 @@ # # This script performs the data extraction from the oznstat # diagnostic files. The resulting data (*.ieee_d) files, GrADS -# control files and stdout files will be moved to the +# control files and stdout files will be moved to the # $TANKverf_ozn. # -# Calling scripts must define: +# Calling scripts must define: # $TANKverf_ozn # $PDY # $cyc # -# Return values are -# 0 = normal +# Return values are +# 0 = normal # 2 = unable to generate satype list; may indicate no diag # files found in oznstat file #------------------------------------------------------------------ @@ -22,33 +22,32 @@ #-------------------------------------------------- # check_diag_files # -# Compare $satype (which contains the contents of +# Compare $satype (which contains the contents of # gdas_oznmon_satype.txt to $avail_satype which is # determined by the contents of the oznstat file. # Report any missing diag files in a file named # bad_diag.$PDY$cyc # check_diag_files() { - pdate=$1 - found_satype=$2 - avail_satype=$3 + pdate=$1 + found_satype=$2 + avail_satype=$3 - out_file="bad_diag.${pdate}" + out_file="bad_diag.${pdate}" - printf "\n\n--> check_diag_files\n" + printf "\n\n--> check_diag_files\n" - for type in ${found_satype}; do - len_check=$(echo "${avail_satype}" | grep "${type}" | wc -c) + for type in ${found_satype}; do + if ! grep -q "${type}" <<< "${avail_satype}"; then + echo "missing diag file -- diag_${type}_ges.${pdate}.gz not found" >> "./${out_file}" + fi + done - if [[ ${len_check} -le 1 ]]; then - echo "missing diag file -- diag_${type}_ges.${pdate}.gz not found" >> "./${out_file}" - fi - done - - echo "<-- check_diag_files"; echo ""; echo "" + echo "<-- check_diag_files" + echo "" + echo "" } - iret=0 VALIDATE_DATA=${VALIDATE_DATA:-0} nregion=${nregion:-6} @@ -56,13 +55,13 @@ DO_DATA_RPT=${DO_DATA_RPT:-0} netcdf_boolean=".false." if [[ ${OZNMON_NETCDF} -eq 1 ]]; then - netcdf_boolean=".true." + netcdf_boolean=".true." fi OZNMON_NEW_HDR=${OZNMON_NEW_HDR:-0} new_hdr="F" if [[ ${OZNMON_NEW_HDR} -eq 1 ]]; then - new_hdr="T" + new_hdr="T" fi #------------------------------------------------------------------ @@ -70,28 +69,25 @@ fi # validate=".FALSE." if [[ ${VALIDATE_DATA} -eq 1 ]]; then - if [[ ! -e ${ozn_val_file} && ! -h ${ozn_val_file} ]]; then - echo "WARNING: VALIDATE_DATA set to 1, but unable to locate ${ozn_val_file}" - echo " Setting VALIDATE_DATA to 0/OFF" - VALIDATE_DATA=0 - else - validate=".TRUE." - val_file=$(basename "${ozn_val_file}") - cpreq "${ozn_val_file}" "${val_file}" - tar -xvf "${val_file}" - fi + if [[ ! -e ${ozn_val_file} && ! -L ${ozn_val_file} ]]; then + echo "WARNING: VALIDATE_DATA set to 1, but unable to locate ${ozn_val_file}" + echo " Setting VALIDATE_DATA to 0/OFF" + VALIDATE_DATA=0 + else + validate=".TRUE." + val_file=$(basename "${ozn_val_file}") + cpreq "${ozn_val_file}" "${val_file}" + tar -xvf "${val_file}" + fi fi echo "VALIDATE_DATA, validate = ${VALIDATE_DATA}, ${validate} " - - #------------------------------------------------------------------ -# ozn_ptype here is the processing type which is intended to be "ges" +# ozn_ptype here is the processing type which is intended to be "ges" # or "anl". Default is "ges". # ozn_ptype=${ozn_ptype:-"ges anl"} - #--------------------------------------------------------------------------- # Build satype list from the available diag files. # @@ -99,58 +95,63 @@ ozn_ptype=${ozn_ptype:-"ges anl"} # a problem, reported by an iret value of 2 # -avail_satype=$(ls -1 d*ges* | sed -e 's/_/ /g;s/\./ /' | gawk '{ print $2 "_" $3 }') +declare -a avail_satype +ges_file_pattern='(diag_)(.*)(_ges)' +for ges_file in *; do + if [[ "${ges_file}" =~ ${ges_file_pattern} ]]; then + avail_satype+=("${BASH_REMATCH[2]}") + fi +done if [[ ${DO_DATA_RPT} -eq 1 ]]; then - if [[ -e ${SATYPE_FILE} ]]; then - satype=$(cat "${SATYPE_FILE}") - check_diag_files "${PDY}${cyc}" "${satype}" "${avail_satype}" - else - echo "WARNING: missing ${SATYPE_FILE}" - fi + if [[ -e ${SATYPE_FILE} ]]; then + satype=$(cat "${SATYPE_FILE}") + check_diag_files "${PDY}${cyc}" "${satype}" "${avail_satype[*]}" + else + echo "WARNING: missing ${SATYPE_FILE}" + fi fi len_satype=$(echo -n "${satype}" | wc -c) if [[ ${len_satype} -le 1 ]]; then - satype=${avail_satype} + satype="${avail_satype[*]}" fi echo "${satype}" - len_satype=$(echo -n "${satype}" | wc -c) if [[ ${DO_DATA_RPT} -eq 1 && ${len_satype} -lt 1 ]]; then - iret=2 + iret=2 else - #-------------------------------------------------------------------- - # Copy extraction programs to working directory - # - cpreq "${EXECgfs}/oznmon_time.x" ./oznmon_time.x - cpreq "${EXECgfs}/oznmon_horiz.x" ./oznmon_horiz.x - - #--------------------------------------------------------------------------- - # Outer loop over $ozn_ptype (default values 'ges', 'anl') - # - for ptype in ${ozn_ptype}; do - - iyy="${PDY:0:4}" - imm="${PDY:4:2}" - idd="${PDY:6:2}" - ihh=${cyc} - - for type in ${avail_satype}; do - if [[ -f "diag_${type}_${ptype}.${PDY}${cyc}.gz" ]]; then - mv "diag_${type}_${ptype}.${PDY}${cyc}.gz" "${type}.${ptype}.gz" - gunzip "./${type}.${ptype}.gz" - - echo "processing ptype, type: ${ptype}, ${type}" - rm -f input - -cat << EOF > input + #-------------------------------------------------------------------- + # Copy extraction programs to working directory + # + cpreq "${EXECgfs}/oznmon_time.x" ./oznmon_time.x + cpreq "${EXECgfs}/oznmon_horiz.x" ./oznmon_horiz.x + + #--------------------------------------------------------------------------- + # Outer loop over $ozn_ptype (default values 'ges', 'anl') + # + for ptype in ${ozn_ptype}; do + + iyy="${PDY:0:4}" + imm="${PDY:4:2}" + idd="${PDY:6:2}" + ihh=${cyc} + + for type in "${avail_satype[@]}"; do + if [[ -f "diag_${type}_${ptype}.${PDY}${cyc}.gz" ]]; then + mv "diag_${type}_${ptype}.${PDY}${cyc}.gz" "${type}.${ptype}.gz" + gunzip "./${type}.${ptype}.gz" + + echo "processing ptype, type: ${ptype}, ${type}" + rm -f input + + cat << EOF > input &INPUT satname='${type}', iyy=${iyy}, @@ -173,28 +174,27 @@ cat << EOF > input / EOF + echo "oznmon_time.x HAS STARTED ${type}" - echo "oznmon_time.x HAS STARTED ${type}" - - ./oznmon_time.x < input > "stdout.time.${type}.${ptype}" + ./oznmon_time.x < input > "stdout.time.${type}.${ptype}" - echo "oznmon_time.x HAS ENDED ${type}" + echo "oznmon_time.x HAS ENDED ${type}" - if [[ ! -d ${TANKverf_ozn}/time ]]; then - mkdir -p "${TANKverf_ozn}/time" - fi - cpfs "${type}.${ptype}.ctl" "${TANKverf_ozn}/time/" - cpfs "${type}.${ptype}.${PDY}${cyc}.ieee_d" "${TANKverf_ozn}/time/" - - if compgen -G "bad*" > /dev/null; then - for bad_file in bad*; do - cpfs "${bad_file}" "${TANKverf_ozn}/time/" - done - fi - - rm -f input + if [[ ! -d ${TANKverf_ozn}/time ]]; then + mkdir -p "${TANKverf_ozn}/time" + fi + cpfs "${type}.${ptype}.ctl" "${TANKverf_ozn}/time/" + cpfs "${type}.${ptype}.${PDY}${cyc}.ieee_d" "${TANKverf_ozn}/time/" -cat << EOF > input + if compgen -G "bad*" > /dev/null; then + for bad_file in bad*; do + cpfs "${bad_file}" "${TANKverf_ozn}/time/" + done + fi + + rm -f input + + cat << EOF > input &INPUT satname='${type}', iyy=${iyy}, @@ -209,38 +209,37 @@ cat << EOF > input / EOF - echo "oznmon_horiz.x HAS STARTED ${type}" - - ./oznmon_horiz.x < input > "stdout.horiz.${type}.${ptype}" + echo "oznmon_horiz.x HAS STARTED ${type}" - echo "oznmon_horiz.x HAS ENDED ${type}" + ./oznmon_horiz.x < input > "stdout.horiz.${type}.${ptype}" - if [[ ! -d ${TANKverf_ozn}/horiz ]]; then - mkdir -p "${TANKverf_ozn}/horiz" - fi - cpfs "${type}.${ptype}.ctl" "${TANKverf_ozn}/horiz/" + echo "oznmon_horiz.x HAS ENDED ${type}" - ${COMPRESS} "${type}.${ptype}.${PDY}${cyc}.ieee_d" - cpfs "${type}.${ptype}.${PDY}${cyc}.ieee_d.${Z}" "${TANKverf_ozn}/horiz/" + if [[ ! -d ${TANKverf_ozn}/horiz ]]; then + mkdir -p "${TANKverf_ozn}/horiz" + fi + cpfs "${type}.${ptype}.ctl" "${TANKverf_ozn}/horiz/" + ${COMPRESS} "${type}.${ptype}.${PDY}${cyc}.ieee_d" + cpfs "${type}.${ptype}.${PDY}${cyc}.ieee_d.${Z}" "${TANKverf_ozn}/horiz/" - echo "finished processing ptype, type: ${ptype}, ${type}" + echo "finished processing ptype, type: ${ptype}, ${type}" - else - echo "diag file for ${type}.${ptype} not found" - fi + else + echo "diag file for ${type}.${ptype} not found" + fi - done # type in satype + done # type in satype - done # ptype in $ozn_ptype + done # ptype in $ozn_ptype - tar -cvf stdout.horiz.tar stdout.horiz* - ${COMPRESS} stdout.horiz.tar - cpfs "stdout.horiz.tar.${Z}" "${TANKverf_ozn}/horiz/" + tar -cvf stdout.horiz.tar stdout.horiz* + ${COMPRESS} stdout.horiz.tar + cpfs "stdout.horiz.tar.${Z}" "${TANKverf_ozn}/horiz/" - tar -cvf stdout.time.tar stdout.time* - ${COMPRESS} stdout.time.tar - cpfs "stdout.time.tar.${Z}" "${TANKverf_ozn}/time/" + tar -cvf stdout.time.tar stdout.time* + ${COMPRESS} stdout.time.tar + cpfs "stdout.time.tar.${Z}" "${TANKverf_ozn}/time/" fi -exit ${iret} +exit "${iret}" diff --git a/ush/parsing_model_configure_FV3.sh b/ush/parsing_model_configure_FV3.sh index 40b0814c2c3..a5f141cd253 100755 --- a/ush/parsing_model_configure_FV3.sh +++ b/ush/parsing_model_configure_FV3.sh @@ -3,78 +3,78 @@ # parsing model_configure for UFSWM FV3 # shellcheck disable=SC2034 -FV3_model_configure(){ +FV3_model_configure() { -local restile=${CASE_HIST:1} + local restile=${CASE_HIST:1} -# Prepare local variables for use in model_configure.IN from UFSWM -# The ones already defined are left commented as a reminder + # Prepare local variables for use in model_configure.IN from UFSWM + # The ones already defined are left commented as a reminder -local model_start_date -if [[ "${DOIAU}" == "YES" ]]; then - model_start_date="${previous_cycle}" -else - model_start_date="${current_cycle}" -fi + local model_start_date + if [[ "${DOIAU}" == "YES" ]]; then + model_start_date="${previous_cycle}" + else + model_start_date="${current_cycle}" + fi -local SYEAR=${model_start_date:0:4} -local SMONTH=${model_start_date:4:2} -local SDAY=${model_start_date:6:2} -local SHOUR=${model_start_date:8:2} -# FHMAX -local FHROT=${IAU_FHROT:-0} -local DT_ATMOS=${DELTIM} -local RESTART_INTERVAL="${FV3_RESTART_FH[*]}" -local RESTART_FH="${CMEPS_RESTART_FH:-" "}" -# QUILTING -local QUILTING_RESTART="${QUILTING_RESTART:-${QUILTING}}" -local WRITE_GROUP=${WRITE_GROUP:-1} -local WRTTASK_PER_GROUP=${WRTTASK_PER_GROUP:-24} -local ITASKS=1 -local OUTPUT_HISTORY=${OUTPUT_HISTORY:-".true."} -if [[ "${DO_JEDIATMVAR:-}" == "YES" ]]; then - local HISTORY_FILE_ON_NATIVE_GRID=".true." -else - local HISTORY_FILE_ON_NATIVE_GRID=".false." -fi -local WRITE_DOPOST=${WRITE_DOPOST:-".false."} -local WRITE_NSFLIP=${WRITE_NSFLIP:-".false."} -local NUM_FILES=${NUM_FILES:-2} -local FILENAME_BASE="'atm' 'sfc'" -# OUTPUT_GRID -local OUTPUT_FILE="'${OUTPUT_FILETYPE_ATM}' '${OUTPUT_FILETYPE_SFC}'" -local ZSTANDARD_LEVEL=${zstandard_level:-0} -local IDEFLATE=${ideflate:-0} # netCDF zlib lossless compression (0-9); 0: no compression -local QUANTIZE_NSD=${quantize_nsd:-0} # netCDF compression -local ICHUNK2D=$((4*restile)) -local JCHUNK2D=$((2*restile)) -local ICHUNK3D=$((4*restile)) -local JCHUNK3D=$((2*restile)) -local KCHUNK3D=1 -local IMO=${LONB_IMO} -local JMO=${LATB_JMO} -local OUTPUT_FH=${FV3_OUTPUT_FH_NML} -local IAU_OFFSET=${IAU_OFFSET:-0} -local USE_FV3_ROUTEHANDLES=.false. + local SYEAR=${model_start_date:0:4} + local SMONTH=${model_start_date:4:2} + local SDAY=${model_start_date:6:2} + local SHOUR=${model_start_date:8:2} + # FHMAX + local FHROT=${IAU_FHROT:-0} + local DT_ATMOS=${DELTIM} + local RESTART_INTERVAL="${FV3_RESTART_FH[*]}" + local RESTART_FH="${CMEPS_RESTART_FH:-" "}" + # QUILTING + local QUILTING_RESTART="${QUILTING_RESTART:-${QUILTING}}" + local WRITE_GROUP=${WRITE_GROUP:-1} + local WRTTASK_PER_GROUP=${WRTTASK_PER_GROUP:-24} + local ITASKS=1 + local OUTPUT_HISTORY=${OUTPUT_HISTORY:-".true."} + if [[ "${DO_JEDIATMVAR:-}" == "YES" || "${DO_HISTORY_FILE_ON_NATIVE_GRID:-"NO"}" == "YES" ]]; then + local HISTORY_FILE_ON_NATIVE_GRID=".true." + else + local HISTORY_FILE_ON_NATIVE_GRID=".false." + fi + local WRITE_DOPOST=${WRITE_DOPOST:-".false."} + local WRITE_NSFLIP=${WRITE_NSFLIP:-".false."} + local NUM_FILES=${NUM_FILES:-2} + local FILENAME_BASE="'atm' 'sfc'" + # OUTPUT_GRID + local OUTPUT_FILE="'${OUTPUT_FILETYPE_ATM}' '${OUTPUT_FILETYPE_SFC}'" + local ZSTANDARD_LEVEL=${zstandard_level:-0} + local IDEFLATE=${ideflate:-0} # netCDF zlib lossless compression (0-9); 0: no compression + local QUANTIZE_NSD=${quantize_nsd:-0} # netCDF compression + local ICHUNK2D=$((4 * restile)) + local JCHUNK2D=$((2 * restile)) + local ICHUNK3D=$((4 * restile)) + local JCHUNK3D=$((2 * restile)) + local KCHUNK3D=1 + local IMO=${LONB_IMO} + local JMO=${LATB_JMO} + local OUTPUT_FH=${FV3_OUTPUT_FH_NML} + local IAU_OFFSET=${IAU_OFFSET:-0} + local USE_FV3_ROUTEHANDLES=.false. -#set FV3 output directory: -local FV3ATM_OUTPUT_DIR="./FV3ATM_OUTPUT" + #set FV3 output directory: + local FV3ATM_OUTPUT_DIR="./FV3ATM_OUTPUT" -# Ensure the template exists -if [[ "${DO_NEST:-NO}" == "YES" ]] ; then - local NEST_IMO=${npx_nest} - local NEST_JMO=${npy_nest} - template="${PARMgfs}/ufs/input_global_nest.nml.IN" -else - template="${PARMgfs}/ufs/model_configure.IN" -fi -if [[ ! -f ${template} ]]; then - echo "FATAL ERROR: template '${template}' does not exist, ABORT!" - exit 1 -fi -rm -f "${DATA}/model_configure" -atparse < "${template}" >> "${DATA}/model_configure" -echo "Rendered model_configure" -cat "${DATA}/model_configure" + # Ensure the template exists + if [[ "${DO_NEST:-NO}" == "YES" ]]; then + local NEST_IMO=${npx_nest} + local NEST_JMO=${npy_nest} + template="${PARMgfs}/ufs/input_global_nest.nml.IN" + else + template="${PARMgfs}/ufs/model_configure.IN" + fi + if [[ ! -f ${template} ]]; then + echo "FATAL ERROR: template '${template}' does not exist, ABORT!" + exit 1 + fi + rm -f "${DATA}/model_configure" + atparse < "${template}" >> "${DATA}/model_configure" + echo "Rendered model_configure" + cat "${DATA}/model_configure" } diff --git a/ush/parsing_namelists_CICE.sh b/ush/parsing_namelists_CICE.sh index b2b0a97aca3..6bcb52cc10a 100755 --- a/ush/parsing_namelists_CICE.sh +++ b/ush/parsing_namelists_CICE.sh @@ -4,149 +4,148 @@ # Disable variable not used warnings # shellcheck disable=SC2034 -CICE_namelists(){ +CICE_namelists() { -# "warm_start" here refers to whether CICE model is warm starting or not. -# Per JM, in the case of the Prototypes, the sea-ice ICs were obtained from CPC. -# CPC sea-ice initial conditions are created from SIS2 sea-ice model. -# Hence, the prototypes always set this to "initial" -# in order for the CICE model to _initialize_ from the SIS2 ICs. -# However, in the SOCA cycled system, if starting from a previously cycled SOCA run, -# the CICE ICs are obtained from the previous cycle of the UFS S2S, -# so the CICE namelist should be set to "continue" -# TODO: Is there a way to interrogate the restart file to know if this is a -# SIS2 restart or a CICE restart, instead of relying on "${warm_start}" -if [[ "${warm_start}" = ".true." ]]; then - local runtype="continue" - local use_restart_time=".true." -else - local runtype="initial" - local use_restart_time=".false." -fi + # "warm_start" here refers to whether CICE model is warm starting or not. + # Per JM, in the case of the Prototypes, the sea-ice ICs were obtained from CPC. + # CPC sea-ice initial conditions are created from SIS2 sea-ice model. + # Hence, the prototypes always set this to "initial" + # in order for the CICE model to _initialize_ from the SIS2 ICs. + # However, in the SOCA cycled system, if starting from a previously cycled SOCA run, + # the CICE ICs are obtained from the previous cycle of the UFS S2S, + # so the CICE namelist should be set to "continue" + # TODO: Is there a way to interrogate the restart file to know if this is a + # SIS2 restart or a CICE restart, instead of relying on "${warm_start}" + if [[ "${warm_start}" = ".true." ]]; then + local runtype="continue" + local use_restart_time=".true." + else + local runtype="initial" + local use_restart_time=".false." + fi -# Get correct MPI options for NPROC and grid -local processor_shape=${cice6_processor_shape:-'slenderX2'} -local shape=${processor_shape#${processor_shape%?}} -local NPX=$(( ntasks_cice6 / shape )) #number of processors in x direction -local NPY=$(( ntasks_cice6 / NPX )) #number of processors in y direction -if (( $(( NX_GLB % NPX )) == 0 )); then - local block_size_x=$(( NX_GLB / NPX )) -else - local block_size_x=$(( (NX_GLB / NPX) + 1 )) -fi -if (( $(( NY_GLB % NPY )) == 0 )); then - local block_size_y=$(( NY_GLB / NPY )) -else - local block_size_y=$(( (NY_GLB / NPY) + 1 )) -fi + # Get correct MPI options for NPROC and grid + local processor_shape=${cice6_processor_shape:-'slenderX2'} + local shape=${processor_shape#"${processor_shape%?}"} + local NPX=$((ntasks_cice6 / shape)) #number of processors in x direction + local NPY=$((ntasks_cice6 / NPX)) #number of processors in y direction + if (($((NX_GLB % NPX)) == 0)); then + local block_size_x=$((NX_GLB / NPX)) + else + local block_size_x=$(((NX_GLB / NPX) + 1)) + fi + if (($((NY_GLB % NPY)) == 0)); then + local block_size_y=$((NY_GLB / NPY)) + else + local block_size_y=$(((NY_GLB / NPY) + 1)) + fi -local sec stepsperhr npt -sec=$(to_seconds "${current_cycle:8:2}0000") -stepsperhr=$((3600/ICETIM)) -npt=$((FHMAX*stepsperhr)) # Need this in order for dump_last to work + local sec stepsperhr npt + sec=$(to_seconds "${current_cycle:8:2}0000") + stepsperhr=$((3600 / ICETIM)) + npt=$((FHMAX * stepsperhr)) # Need this in order for dump_last to work -# Prepare local variables for use in ice_in_template from UFSWM -# The ones already defined are left commented as a reminder -# setup_nml section -local SYEAR=${current_cycle:0:4} -local SMONTH=${current_cycle:4:2} -local SDAY=${current_cycle:6:2} -local SECS=${sec} -local DT_CICE=${ICETIM} -local CICE_NPT=${npt} -local CICE_RUNTYPE=${runtype} -local CICE_RUNID="unknown" -local CICE_USE_RESTART_TIME=${use_restart_time} -local CICE_RESTART_DIR="./CICE_RESTART/" -local CICE_RESTART_FILE="cice_model.res" -local CICE_ICE_IC='cice_model.res.nc' -local CICE_RESTART_DEFLATE=0 -local CICE_RESTART_CHUNK=0,0 -local CICE_RESTART_STRIDE=-99 -local CICE_RESTART_ROOT=-99 -local CICE_RESTART_REARR="box" -local CICE_RESTART_IOTASKS=-99 -local CICE_RESTART_FORMAT="pnetcdf2" -local CICE_DUMPFREQ="y" # "h","d","m" or "y" for restarts at intervals of "hours", "days", "months" or "years" -local CICE_DUMPFREQ_N=10000 # Set this to a really large value, as cice, mom6 and cmeps restart interval is controlled by ufs.configure -local CICE_DIAGFREQ=$(( 86400 / DT_CICE )) # frequency of diagnostic output in timesteps, recommended for 1x per day -if [[ "${RUN}" == "gefs" ]]; then - local CICE_DIAGFREQ1=$((( FHOUT_ICE * 3600 )/ DT_CICE )) # Number of timesteps within FHOUT_ICE - local CICE_HISTFREQ_N="0, 0, 0, ${CICE_DIAGFREQ1}, 1" -else - local CICE_HISTFREQ_N="0, 0, ${FHOUT_ICE}, 0, 1" -fi -local CICE_hist_suffix="'x','x','x','x','x'" -if [[ "${RUN}" =~ "gdas" ]]; then - local CICE_HIST_AVG=".false., .false., .false., .false., .false." # DA needs instantaneous -else - local CICE_HIST_AVG=".true., .true., .true., .true., .true." # GFS long forecaset wants averaged over CICE_HISTFREQ_N -fi -local CICE_HISTORY_FORMAT="pnetcdf2" -local CICE_HISTORY_DIR="./CICE_OUTPUT/" -local CICE_INCOND_DIR="./CICE_OUTPUT/" -local CICE_HISTORY_IOTASKS=-99 -local CICE_HISTORY_REARR="box" -local CICE_HISTORY_ROOT=-99 -local CICE_HISTORY_STRIDE=-99 -local CICE_HISTORY_CHUNK=0,0 -local CICE_HISTORY_DEFLATE=0 -local CICE_HISTORY_PREC=4 -# grid_nml section -# CICE_GRID -# CICE_MASK -local CICE_GRIDATM="A" # A-grid for atmosphere (FV3) -local CICE_GRIDOCN="A" # A-grid for ocean (MOM6) -local CICE_GRIDICE="B" # B-grid for seaice (CICE6) -# tracer_nml section -local CICE_TR_POND_LVL=".true." # Use level melt ponds -# (if CICE_TR_POND_LVL=true): - # -- if true, initialize the level ponds from restart (if runtype=continue) - # -- if false, re-initialize level ponds to zero (if runtype=initial or continue) -local CICE_RESTART_POND_LVL=".false." # Restart level ponds from restart file (if runtype=continue) -# thermo_nml section -local CICE_KTHERM=2 # 0=zero-layer thermodynamics, 1=fixed-salinity profile, 2=mushy thermodynamics -# dynamics_nml section -# NONE -# shortwave_nml section -# NONE -# ponds_nml section -# NONE -# snow_nml section -# NONE -# forcing_nml section -local CICE_FRAZIL_FWSALT=${FRAZIL_FWSALT:-".true."} -local CICE_TFREEZE_OPTION=${tfrz_option:-"mushy"} -# domain_nml section -local CICE_NPROC=${ntasks_cice6} -# NX_GLB -# NY_GLB -local CICE_BLCKX=${block_size_x} -local CICE_BLCKY=${block_size_y} -local CICE_DECOMP=${processor_shape} -# ice_prescribed_nml section -local CICE_PRESCRIBED="false" -local MESH_DICE="none" -local stream_files_dice="none" + # Prepare local variables for use in ice_in_template from UFSWM + # The ones already defined are left commented as a reminder + # setup_nml section + local SYEAR=${current_cycle:0:4} + local SMONTH=${current_cycle:4:2} + local SDAY=${current_cycle:6:2} + local SECS=${sec} + local DT_CICE=${ICETIM} + local CICE_NPT=${npt} + local CICE_RUNTYPE=${runtype} + local CICE_RUNID="unknown" + local CICE_USE_RESTART_TIME=${use_restart_time} + local CICE_RESTART_DIR="./CICE_RESTART/" + local CICE_RESTART_FILE="cice_model.res" + local CICE_ICE_IC='cice_model.res.nc' + local CICE_RESTART_DEFLATE=0 + local CICE_RESTART_CHUNK=0,0 + local CICE_RESTART_STRIDE=-99 + local CICE_RESTART_ROOT=-99 + local CICE_RESTART_REARR="box" + local CICE_RESTART_IOTASKS=-99 + local CICE_RESTART_FORMAT="pnetcdf2" + local CICE_RESTART_MOD='none' + local CICE_DUMPFREQ="y" # "h","d","m" or "y" for restarts at intervals of "hours", "days", "months" or "years" + local CICE_DUMPFREQ_N=10000 # Set this to a really large value, as cice, mom6 and cmeps restart interval is controlled by ufs.configure + local CICE_DIAGFREQ=$((86400 / DT_CICE)) # frequency of diagnostic output in timesteps, recommended for 1x per day + if [[ "${RUN}" == "gefs" ]]; then + local CICE_DIAGFREQ1=$(((FHOUT_ICE * 3600) / DT_CICE)) # Number of timesteps within FHOUT_ICE + local CICE_HISTFREQ_N="0, 0, 0, ${CICE_DIAGFREQ1}, 1" + else + local CICE_HISTFREQ_N="0, 0, ${FHOUT_ICE}, 0, 1" + fi + local CICE_hist_suffix="'x','x','x','x','x'" + if [[ "${RUN}" =~ "gdas" ]]; then + local CICE_HIST_AVG=".false., .false., .false., .false., .false." # DA needs instantaneous + else + local CICE_HIST_AVG=".true., .true., .true., .true., .true." # GFS long forecaset wants averaged over CICE_HISTFREQ_N + fi + local CICE_HISTORY_FORMAT="pnetcdf2" + local CICE_HISTORY_DIR="./CICE_OUTPUT/" + local CICE_INCOND_DIR="./CICE_OUTPUT/" + local CICE_HISTORY_IOTASKS=-99 + local CICE_HISTORY_REARR="box" + local CICE_HISTORY_ROOT=-99 + local CICE_HISTORY_STRIDE=-99 + local CICE_HISTORY_CHUNK=0,0 + local CICE_HISTORY_DEFLATE=0 + local CICE_HISTORY_PREC=4 + # grid_nml section + # CICE_GRID + # CICE_MASK + local CICE_GRIDATM="A" # A-grid for atmosphere (FV3) + local CICE_GRIDOCN="A" # A-grid for ocean (MOM6) + local CICE_GRIDICE="B" # B-grid for seaice (CICE6) + # tracer_nml section + local CICE_TR_POND_LVL=".true." # Use level melt ponds + # (if CICE_TR_POND_LVL=true): + # -- if true, initialize the level ponds from restart (if runtype=continue) + # -- if false, re-initialize level ponds to zero (if runtype=initial or continue) + local CICE_RESTART_POND_LVL=".false." # Restart level ponds from restart file (if runtype=continue) + # thermo_nml section + local CICE_KTHERM=2 # 0=zero-layer thermodynamics, 1=fixed-salinity profile, 2=mushy thermodynamics + # dynamics_nml section + # NONE + # shortwave_nml section + # NONE + # ponds_nml section + # NONE + # snow_nml section + # NONE + # forcing_nml section + local CICE_FRAZIL_FWSALT=${FRAZIL_FWSALT:-".true."} + local CICE_TFREEZE_OPTION=${tfrz_option:-"mushy"} + # domain_nml section + local CICE_NPROC=${ntasks_cice6} + # NX_GLB + # NY_GLB + local CICE_BLCKX=${block_size_x} + local CICE_BLCKY=${block_size_y} + local CICE_DECOMP=${processor_shape} + # ice_prescribed_nml section + local CICE_PRESCRIBED="false" + local MESH_DICE="none" + local stream_files_dice="none" + # Ensure the template exists + local template=${CICE_TEMPLATE:-"${PARMgfs}/ufs/ice_in.IN"} + if [[ ! -f "${template}" ]]; then + echo "FATAL ERROR: template '${template}' does not exist, ABORT!" + exit 1 + fi + rm -f "${DATA}/ice_in" + atparse < "${template}" >> "${DATA}/ice_in" + echo "Rendered ice_in:" + cat "${DATA}/ice_in" - -# Ensure the template exists -local template=${CICE_TEMPLATE:-"${PARMgfs}/ufs/ice_in.IN"} -if [[ ! -f "${template}" ]]; then - echo "FATAL ERROR: template '${template}' does not exist, ABORT!" - exit 1 -fi -rm -f "${DATA}/ice_in" -atparse < "${template}" >> "${DATA}/ice_in" -echo "Rendered ice_in:" -cat "${DATA}/ice_in" - -# Create a ice.restart_file when runtype is "continue" -# This file is not needed when runtype is "initial" -rm -f "${DATA}/ice.restart_file" -if [[ "${runtype}" == "continue" ]]; then - echo "${DATA}/cice_model.res.nc" > "${DATA}/ice.restart_file" -fi + # Create a ice.restart_file when runtype is "continue" + # This file is not needed when runtype is "initial" + rm -f "${DATA}/ice.restart_file" + if [[ "${runtype}" == "continue" ]]; then + echo "${DATA}/cice_model.res.nc" > "${DATA}/ice.restart_file" + fi } diff --git a/ush/parsing_namelists_FV3.sh b/ush/parsing_namelists_FV3.sh index 4b6bfff80fe..dfdfecacb52 100755 --- a/ush/parsing_namelists_FV3.sh +++ b/ush/parsing_namelists_FV3.sh @@ -4,495 +4,495 @@ # Disable variable not used warnings # shellcheck disable=SC2034 -FV3_namelists(){ - -# setup the tables -DIAG_TABLE=${DIAG_TABLE:-${PARMgfs}/ufs/fv3/diag_table} -DIAG_TABLE_APPEND=${DIAG_TABLE_APPEND:-${PARMgfs}/ufs/fv3/diag_table_aod} -DATA_TABLE=${DATA_TABLE:-${PARMgfs}/ufs/MOM6_data_table.IN} -FIELD_TABLE=${FIELD_TABLE:-${PARMgfs}/ufs/fv3/field_table} - -# set cdmbgwd -if (( gwd_opt == 2 )) && [[ ${do_gsl_drag_ls_bl} == ".true." ]]; then - cdmbgwd=${cdmbgwd_gsl} -fi - -# ensure non-prognostic tracers are set -dnats=${dnats:-0} - -# build the diag_table -{ -echo "UFS_Weather_Model_Forecast" -if [[ "${DOIAU}" = "YES" ]]; then - echo "${previous_cycle:0:4} ${previous_cycle:4:2} ${previous_cycle:6:2} ${previous_cycle:8:2} 0 0" -else - echo "${current_cycle:0:4} ${current_cycle:4:2} ${current_cycle:6:2} ${current_cycle:8:2} 0 0" -fi -cat "${DIAG_TABLE}" -if [[ -n "${AERO_DIAG_TABLE:-}" ]]; then - cat "${AERO_DIAG_TABLE}" -fi -cat "${DIAG_TABLE_APPEND}" -} >> diag_table_template - -local template=diag_table_template -local SYEAR=${current_cycle:0:4} -local SMONTH=${current_cycle:4:2} -local SDAY=${current_cycle:6:2} -local CHOUR=${current_cycle:8:2} -local MOM6_OUTPUT_DIR="./MOM6_OUTPUT" - -atparse < "${template}" >> "diag_table" - - -# copy data table -cpreq "${DATA_TABLE}" data_table - -# build field_table -if [[ -n "${AERO_FIELD_TABLE:-}" ]]; then - nrec=$(wc -l < "${FIELD_TABLE}") - prec=${nrec} - if (( dnats > 0 )); then - prec=$( grep -F -n TRACER "${FIELD_TABLE}" 2> /dev/null | tail -n "${dnats}" | head -1 | cut -d: -f1 ) - prec=${prec:-0} - prec=$(( prec > 0 ? prec - 1 : prec )) - fi - { \ - head -n "${prec}" "${FIELD_TABLE}" ; \ - cat "${AERO_FIELD_TABLE}" ; \ - tail -n $(( nrec - prec )) "${FIELD_TABLE}" ; \ - } > field_table - # add non-prognostic tracers from additional table - dnats=$(( dnats + dnats_aero )) -else - cpreq "${FIELD_TABLE}" field_table -fi - -# Set variables for global_control.nml template - -local BLOCKSIZE=${blocksize} -local CHKSUM_DEBUG=${chksum_debug} -local DYCORE_ONLY=${dycore_only} -local CCPP_SUITE=${CCPP_SUITE} - -local MAX_OUTPUT_FIELDS=300 - -local DOMAINS_STACK_SIZE=${domains_stack_size:-3000000} -local PRINT_MEMORY_USAGE=${print_memory_usage:-".false."} - -local INPES=${layout_x} -local JNPES=${layout_y} -local IO_LAYOUT=${io_layout} -local NPX=${npx} -local NPY=${npy} -local NTILES=${ntiles} -local NPZ=${npz} -local DZ_MIN=${dz_min:-"6"} -local PSM_BC=${psm_bc:-"0"} -local MAKE_NH=${make_nh} -local FV_DEBUG=${fv_debug:-".false."} -local RANGE_WARN=${range_warn:-".true."} -local N_SPONGE=${n_sponge:-"10"} -local NUDGE_QV=${nudge_qv:-".false."} -local NUDGE_DZ=${nudge_dz:-".false."} -local TAU=${tau:-10.} -local FAST_TAU_W_SEC=${fast_tau_w_sec:-"0.2"} -local RF_CUTOFF=${rf_cutoff:-"7.5e2"} -local D2_BG_K1=${d2_bg_k1:-"0.15"} -local D2_BG_K2=${d2_bg_k2:-"0.02"} -local KORD_TM=${kord_tm:-"-9"} -local KORD_MT=${kord_mt:-"9"} -local KORD_WZ=${kord_wz:-"9"} -local KORD_TR=${kord_tr:-"9"} -local HYDROSTATIC=${hydrostatic} -local PHYS_HYDROSTATIC=${phys_hydrostatic} -local USE_HYDRO_PRESSURE=${use_hydro_pressure} -local UPDATE_FULL_OMEGA=${pass_full_omega_to_physics_in_non_hydrostatic_mode:-".false."} -local K_SPLIT=${k_split} -local N_SPLIT=${n_split} -local NWAT=${nwat:-2} -local NA_INIT=${na_init} -local DNATS=${dnats} -local FV_SG_ADJ=${fv_sg_adj:-"450"} -local NORD=${nord:-3} -local DDDMP=${dddmp:-0.1} -local D4_BG=${d4_bg:-0.15} -local VTDM4=${vtdm4} -local DELT_MAX=${delt_max:-"0.002"} -local DO_VORT_DAMP=${do_vort_damp} -local EXTERNAL_IC=${external_ic} -local EXTERNAL_ETA=${external_eta:-.true.} -local GFS_PHIL=${gfs_phil:-".false."} -local NGGPS_IC=${nggps_ic} -local MOUNTAIN=${mountain} -local NCEP_IC=${ncep_ic} -local D_CON=${d_con} -local HORD_MT=${hord_mt} -local HORD_VT=${hord_xx} -local HORD_TM=${hord_xx} -local HORD_DP=${hord_dp} -local HORD_TR=${hord_tr:-"8"} -local ADJUST_DRY_MASS=${adjust_dry_mass:-".true."} -local DRY_MASS=${dry_mass:-98320.0} -local CONSV_TE=${consv_te} -local DO_SAT_ADJ=${do_sat_adj:-".false."} -local PRINT_FREQ=${print_freq} -local WARM_START=${warm_start} -local NO_DYCORE=${no_dycore} -local AGRID_VEL_RST=${agrid_vel_rst:-".true."} -local READ_INCREMENT=${read_increment} -local RES_LATLON_DYNAMICS=${res_latlon_dynamics} -local ATM_IGNORE_RST_CKSUM=.false. -local INCREMENT_FILE_ON_NATIVE_GRID=${increment_file_on_native_grid:-.false.} - -local FILTERED_TERRAIN=${filtered_terrain} -local NPZP=${LEVS} #levp -local GFS_DWINDS=${gfs_dwinds} - -local FHZERO=${FHZERO:-6} -local H2O_PHYS=${h2o_phys:-".true."} -local LDIAG3D=${ldiag3d:-".false."} -local QDIAG3D=${qdiag3d:-".false."} -local PRINT_DIFF_PGR=${print_diff_pgr:-".false."} -local FHCYC=${FHCYC} -local USE_UFO=${use_ufo:-".true."} -local PRE_RAD=${pre_rad:-".false."} -local IMP_PHYSICS=${imp_physics:-"99"} - -local default_dt_inner=$(( DELTIM/2 )) -local IOVR=${iovr:-"3"} -local LTAEROSOL=${ltaerosol:-".false."} -local MRAEROSOL=.false. -local LTHAILAWARE=.false. -local LRADAR=${lradar:-".true."} -local TTENDLIM=${ttendlim:-"-999"} -local DT_INNER=${dt_inner:-"${default_dt_inner}"} -local SEDI_SEMI=${sedi_semi:-".true."} -local DECFL=${decfl:-"10"} -local OZ_PHYS_NEW=${oz_phys:-".false."} -local OZ_PHYS_OLD=${oz_phys_2015:-".true."} -local LSOIL_LSM=${lsoil_lsm:-"4"} -local DO_MYNNEDMF=${do_mynnedmf:-".false."} -local DO_MYNNSFCLAY=${do_mynnsfclay:-".false."} -local ICLOUD_BL=${icloud_bl:-"1"} -local BL_MYNN_EDMF=${bl_mynn_edmf:-"1"} -local BL_MYNN_TKEADVECT=${bl_mynn_tkeadvect:-".true."} -local BL_MYNN_EDMF_MOM=${bl_mynn_edmf_mom:-"1"} -local TTE_EDMF=${tte_edmf:-".false."} -local CSCALE=${cscale:-"1.0"} -local DO_NGW_EC=${do_ngw_ec:-".false."} -local DO_UGWP=${do_ugwp:-".false."} -local DO_TOFD=${do_tofd:-".false."} -local GWD_OPT=${gwd_opt:-"2"} -local DO_UGWP_V0=${do_ugwp_v0:-".false."} -local DO_UGWP_V1=${do_ugwp_v1:-".true."} -local DO_UGWP_V0_OROG_ONLY=${do_ugwp_v0_orog_only:-".false."} -local DO_UGWP_V0_NST_ONLY=${do_ugwp_v0_nst_only:-".false."} -local DO_GSL_DRAG_LS_BL=${do_gsl_drag_ls_bl:-".true."} -local DO_GSL_DRAG_SS=${do_gsl_drag_ss:-".true."} -local DO_GSL_DRAG_TOFD=${do_gsl_drag_tofd:-".true."} -local DO_GWD_OPT_PSL=${do_gwd_opt_psl:-".false."} -local DO_UGWP_V1_OROG_ONLY=${do_ugwp_v1_orog_only:-".false."} -local MIN_LAKEICE=${min_lakeice:-"0.15"} -local MIN_SEAICE=${min_seaice:-"0.15"} -local USE_CICE_ALB=${use_cice_alb:-".false."} - -local PDFCLD=${pdfcld:-".false."} -local FHSWR=${FHSWR:-"3600."} -local FHLWR=${FHLWR:-"3600."} -local IALB=${IALB:-"1"} -local IEMS=${IEMS:-"1"} -local IAER=${IAER} -local ICLIQ_SW=${icliq_sw:-"2"} -local ICO2=${ICO2} -local ISUBC_SW=${isubc_sw:-"2"} -local ISUBC_LW=${isubc_lw:-"2"} -local ISOL=${ISOL:-"2"} -local LWHTR=${lwhtr:-".true."} -local SWHTR=${swhtr:-".true."} -local CNVGWD=${cnvgwd:-".true."} -local SHAL_CNV=${shal_cnv:-".true."} -local CAL_PRE=${cal_pre:-".true."} -local REDRAG=${redrag:-".true."} -local DSPHEAT=${dspheat:-".true."} -local HYBEDMF=${hybedmf:-".false."} -local SATMEDMF=${satmedmf:-".true."} -local ISATMEDMF=${isatmedmf:-"1"} -local LHEATSTRG=${lheatstrg:-".false."} -local LSEASPRAY=${lseaspray:-".true."} -local RANDOM_CLDS=${random_clds:-".true."} -local TRANS_TRAC=${trans_trac:-".true."} -local CNVCLD=${cnvcld:-".true."} -local XR_CNVCLD=${xr_cnvcld:-".true."} -local IMFSHALCNV=${imfshalcnv:-"2"} -local IMFDEEPCNV=${imfdeepcnv:-"2"} -local PROGSIGMA=${progsigma:-".true."} -local BETASCU=${betascu:-"8.0"} -local BETAMCU=${betamcu:-"1.0"} -local BETADCU=${betadcu:-"2.0"} -local RAS=${ras:-".false."} -local CDMBGWD=${cdmbgwd:-"3.5,0.25"} -local PSL_GWD_DX_FACTOR=${psl_gwd_dx_factor:-"6.0"} -local PRSLRD0=${prslrd0:-"0."} -local IVEGSRC=${ivegsrc:-"1"} -local ISOT=${isot:-"1"} -local LSOIL=${lsoil:-"4"} -local LSM=${lsm:-"2"} -local IOPT_DVEG=${iopt_dveg:-"1"} -local IOPT_CRS=${iopt_crs:-"1"} -local IOPT_BTR=${iopt_btr:-"1"} -local IOPT_RUN=${iopt_run:-"1"} -local IOPT_SFC=${iopt_sfc:-"1"} -local IOPT_TRS=${iopt_trs:-"2"} -local IOPT_DIAG=${iopt_diag:-"2"} -local IOPT_FRZ=${iopt_frz:-"1"} -local IOPT_INF=${iopt_inf:-"1"} -local IOPT_RAD=${iopt_rad:-"1"} -local IOPT_ALB=${iopt_alb:-"2"} -local IOPT_SNF=${iopt_snf:-"4"} -local IOPT_TBOT=${iopt_tbot:-"2"} -local IOPT_STC=${iopt_stc:-"1"} -local DEBUG=${gfs_phys_debug:-".false."} -local NSTF_NAME=${nstf_name} -local NST_ANL=${nst_anl} -local PSAUTCO=${psautco:-"0.0008,0.0005"} -local PRAUTCO=${prautco:-"0.00015,0.00015"} -local LGFDLMPRAD=${lgfdlmprad:-".false."} -local EFFR_IN=${effr_in:-".false."} -local LDIAG_UGWP=${ldiag_ugwp:-".false."} -local DO_RRTMGP=${do_RRTMGP:-".false."} -local ACTIVE_GASES=${active_gases:-"'h2o_co2_o3_n2o_ch4_o2'"} -local NGASES=${ngases:-"6"} -local LW_FILE_GAS=${lw_file_gas:-"'rrtmgp-data-lw-g128-210809.nc'"} -local LW_FILE_CLOUDS=${lw_file_clouds:-"'rrtmgp-cloud-optics-coeffs-lw.nc'"} -local SW_FILE_GAS=${sw_file_gas:-"'rrtmgp-data-sw-g112-210809.nc'"} -local SW_FILE_CLOUDS=${sw_file_clouds:-"'rrtmgp-cloud-optics-coeffs-sw.nc'"} -local RRTMGP_NGPTSSW=${rrtmgp_nGptsSW:-"112"} -local RRTMGP_NGPTSLW=${rrtmgp_nGptsLW:-"128"} -local RRTMGP_NBANDSLW=${rrtmgp_nBandsLW:-"16"} -local RRTMGP_NBANDSSW=${rrtmgp_nBandsSW:-"14"} -local DOGP_CLDOPTICS_LUT=${doGP_cldoptics_LUT:-".false."} -local DOGP_LWSCAT=${doGP_lwscat:-".false."} -local DOGP_SGS_CNV=.true. - -local DO_SPPT=${do_sppt:-".false."} -local DO_SHUM=${do_shum:-".false."} -local DO_SKEB=${do_skeb:-".false."} -local FRAC_GRID=${FRAC_GRID:-".true."} -local CPLCHM=${cplchm:-".false."} -local CPLFLX=${cplflx:-".false."} -local CPLICE=${cplice:-".false."} -local CPLWAV=${cplwav:-".false."} -local CPLWAV2ATM=${cplwav2atm:-".false."} -local USE_MED_FLUX=${use_med_flux:-".false."} -local CPLLND=${cpllnd:-".false."} -local CPLLND2ATM=${cpllnd2atm:-".false."} -local USE_OCEANUV=${use_oceanuv:-".false."} - -# CPL CHM options -if [[ ${cplchm} = ".true." ]]; then - local FSCAV_AERO=${fscav_aero:-'*:0.0'} -else - local FSCAV_AERO='"*:0.3","so2:0.0","msa:0.0","dms:0.0","nh3:0.4","nh4:0.6","bc1:0.6","bc2:0.6","oc1:0.4","oc2:0.4","dust1:0.6","dust2:0.6","dust3:0.6","dust4:0.6","dust5:0.6","seas1:0.5","seas2:0.5","seas3:0.5","seas4:0.5","seas5:0.5"' -fi - -local IAUFHRS=${IAUFHRS} -local IAU_DELTHRS=${IAU_DELTHRS} -local IAU_INC_FILES=${IAU_INC_FILES:-"''"} -local IAU_DRYMASSFIXER=.false. -local IAU_FILTER_INCREMENTS=${IAU_FILTER_INCREMENTS:-".false."} - -# CA options -local DO_CA=".true." -local CA_GLOBAL=${ca_global:-".false."} -local CA_SGS=${ca_sgs:-".true."} -local NCA=${nca:-"1"} -local NCELLS=${ncells:-"5"} -local NLIVES=${nlives:-"12"} -local NSEED=${nseed:-"1"} -local NFRACSEED=${nfracseed:-"0.5"} -local NTHRESH=${nthresh:-"18"} -local CA_TRIGGER=${ca_trigger:-".true."} -local NSPINUP=${nspinup:-"1"} -local ISEED_CA=${ISEED_CA:-"12345"} - -# Land pert options -local LNDP_TYPE=${lndp_type:-2} -local N_VAR_LNDP=${n_var_lndp:-0} - -local LCNORM=${lcnorm:-".false."} -local PERT_MP=${PERT_MP:-".false."} -local PERT_RADTEND=${PERT_RADTEND:-".false."} -local PERT_CLDS=${PERT_CLDS:-".false."} - -if [[ ${DO_SPPT} = ".true." ]]; then - local PERT_CLDS=".true." -fi - -if [[ "${DOIAU}" = "YES" ]]; then - local HIDE_AIAU=" " -else - local HIDE_AIAU="!" -fi - -#GWP options -if [[ ${knob_ugwp_version} -eq 0 ]]; then - local HIDE_UGWPV0=" " - local HIDE_UGWPV1="!" -elif [[ ${knob_ugwp_version} -eq 1 ]]; then - local HIDE_UGWPV0="!" - local HIDE_UGWPV1=" " -else - local HIDE_UGWPV0="!" - local HIDE_UGWPV1="!" -fi - -# Common GWP options -local KNOB_UGWP_SOLVER=${knob_ugwp_solver:-2} -local KNOB_UGWP_SOURCE=${knob_ugwp_source:-1,1,0,0} -local KNOB_UGWP_WVSPEC=${knob_ugwp_wvspec:-1,25,25,25} -local KNOB_UGWP_AZDIR=${knob_ugwp_azdir:-2,4,4,4} -local KNOB_UGWP_STOCH=${knob_ugwp_stoch:-0,0,0,0} -local KNOB_UGWP_EFFAC=${knob_ugwp_effac:-1,1,1,1} -local KNOB_UGWP_DOAXYZ=${knob_ugwp_doaxyz:-1} -local KNOB_UGWP_DOHEAT=${knob_ugwp_doheat:-1} -# UGWP Version 0 options -local KNOB_UGWP_DOKDIS=${knob_ugwp_dokdis:-1} -local KNOB_UGWP_NDX4LH=${knob_ugwp_ndx4lh:-1} -local KNOB_UGWP_VERSION=${knob_ugwp_version:-0} -local LAUNCH_LEVEL=${launch_level:-54} -# UGWP Version 1 options -local KNOB_UGWP_DOKDIS=${knob_ugwp_dokdis:-2} -local KNOB_UGWP_NDX4LH=${knob_ugwp_ndx4lh:-4} -local KNOB_UGWP_VERSION=${knob_ugwp_version:-1} -local KNOB_UGWP_PALAUNCH=${knob_ugwp_palaunch:-275.0e2} -local KNOB_UGWP_NSLOPE=${knob_ugwp_nslope:-1} -local KNOB_UGWP_LZMAX=${knob_ugwp_lzmax:-15.750e3} -local KNOB_UGWP_LZMIN=${knob_ugwp_lzmin:-0.75e3} -local KNOB_UGWP_LZSTAR=${knob_ugwp_lzstar:-2.0e3} -local KNOB_UGWP_TAUMIN=${knob_ugwp_taumin:-0.25e-3} -local KNOB_UGWP_TAUAMP=${knob_ugwp_tauamp:-3.0e-3} -local KNOB_UGWP_LHMET=${knob_ugwp_lhmet:-200.0e3} -local KNOB_UGWP_OROSOLV=${knob_ugwp_orosolv:-\'pss-1986\'} - -# gfdl_cloud_microphysics options -local REIFLAG=${reiflag:-"2"} - -# interpolator_nml options - -# nam sfc options -local FNGLAC="'${FNGLAC}'" -local FNMXIC="'${FNMXIC}'" -local FNTSFC="'${FNTSFC}'" -local FNSNOC="'${FNSNOC}'" -local FNZORC="'${FNZORC}'" -local FNALBC="'${FNALBC}'" -local FNALBC2="'${FNALBC2}'" -local FNAISC="'${FNAISC}'" -local FNTG3C="'${FNTG3C}'" -local FNVEGC="'${FNVEGC}'" -local FNVETC="'${FNVETC}'" -local FNSOTC="'${FNSOTC}'" -local FNSOCC="'${FNSOCC}'" -local FNSMCC="'${FNSMCC}'" -local FNMSKH="'${FNMSKH}'" -local FNTSFA="'${FNTSFA}'" -local FNACNA="'${FNACNA:-}'" -local FNSNOA="'${FNSNOA:-}'" -local FNVMNC="'${FNVMNC:-}'" -local FNVMXC="'${FNVMXC:-}'" -local FNSLPC="'${FNSLPC:-}'" -local FNABSC="'${FNABSC:-}'" -local LDEBUG=${LDEBUG:-".false."} -local FSMCL2=${FSMCL2:+\'${FSMCL2}\'}${FSMCL2:-99999} -local FSMCL3=${FSMCL3:+\'${FSMCL3}\'}${FSMCL3:-99999} -local FSMCL4=${FSMCL4:+\'${FSMCL4}\'}${FSMCL4:-99999} -local LANDICE=${landice:-".true."} -local FTSFS=${FTSFS:-90} -local FAISL=${FAISL:+\'${FAISL}\'}${FAISL:-99999} -local FAISS=${FAISS:+\'${FAISS}\'}${FAISS:-99999} -local FSNOL=${FSNOL:+\'${FSNOL}\'}${FSNOL:-99999} -local FSNOS=${FSNOS:+\'${FSNOS}\'}${FSNOS:-99999} -local FSICL=${FSICL:-99999} -local FSICS=${FSICS:-99999} -local FTSFL=${FTSFL:+\'${FTSFL}\'}${FTSFL:-99999} -local FVETL=${FVETL:+\'${FVETL}\'}${FVETL:-99999} -local FSOTL=${FSOTL:+\'${FSOTL}\'}${FSOTL:-99999} -local FVMNL=${FvmnL:+\'${FvmnL}\'}${FvmnL:-99999} -local FVMXL=${FvmxL:+\'${FvmxL}\'}${FvmxL:-99999} -local FSLPL=${FSLPL:+\'${FSLPL}\'}${FSLPL:-99999} -local FABSL=${FABSL:+\'${FABSL}\'}${FABSL:-99999} -local FNTSFA="'${FNTSFA:-}'" - -#fv_grid_nml options - -#nam stochy options -local NEW_LSCALE=${new_lscale:-".false."} -local STOCHINI=${stochini:-".false."} -local SKEB=${SKEB:-0} -local ISEED_SKEB=${ISEED_SKEB:-${ISEED}} -local SKEB_TAU=${SKEB_TAU:-"-999."} -local SKEB_LSCALE=${SKEB_LSCALE:-"-999."} -local SKEBNORM=${SKEBNORM:-"1"} -local SKEB_NPASS=${SKEB_NPASS:-"30"} -local SKEB_VDOF=${SKEB_VDOF:-"5"} -local SKEBINT=${SKEBINT:-"0"} -local SHUM=${SHUM:-"-999."} -local ISEED_SHUM=${ISEED_SHUM:-${ISEED}} -local SHUM_TAU=${SHUM_TAU:-"-999."} -local SHUM_LSCALE=${SHUM_LSCALE:-"-999."} -local SHUMINT=${SHUMINT:-"0"} -local SPPT=${SPPT:-"-999."} -local ISEED_SPPT=${ISEED_SPPT:-${ISEED}} -local SPPT_TAU=${SPPT_TAU:-"-999."} -local SPPT_LSCALE=${SPPT_LSCALE:-"-999."} -local SPPT_LOGIT=${SPPT_LOGIT:-".true."} -local SPPT_SFCLIMIT=${SPPT_SFCLIMIT:-".true."} -local USE_ZMTNBLCK=${use_zmtnblck:-".true."} -local SPPTINT=${SPPTINT:-"0"} -local PBL_TAPER=${pbl_taper:-"0,0,0,0.125,0.25,0.5,0.75"} -local OCNSPPT=${OCNSPPT:-"0.8,0.4,0.2,0.08,0.04"} -local OCNSPPT_LSCALE=${OCNSPPT_LSCALE:-"500.E3,1000.E3,2000.E3,2000.E3,2000.E3"} -local OCNSPPT_TAU=${OCNSPPT_TAU:-"2.16E4,2.592E5,2.592E6,7.776E6,3.1536E7"} -local ISEED_OCNSPPT=${ISEED_OCNSPPT:-${ISEED}} -local EPBL=${EPBL:-"0.8,0.4,0.2,0.08,0.04"} -local EPBL_LSCALE=${EPBL_LSCALE:-"500.E3,1000.E3,2000.E3,2000.E3,2000.E3"} -local EPBL_TAU=${EPBL_TAU:-"2.16E4,2.592E5,2.592E6,7.776E6,3.1536E7"} -local ISEED_EPBL=${ISEED_EPBL:-${ISEED}} -local LNDP_TYPE=${lndp_type:-"0"} -local LNDP_MODEL_TYPE=${lndp_model_type:-"0"} -local LNDP_TAU=${LNDP_TAU:-"21600"} -local LNDP_LSCALE=${LNDP_SCALE:-"500000"} -local ISEED_LNDP=${ISEED_LNDP:-${ISEED}} -local LNDP_VAR_LIST=${lndp_var_list:-"'XXX'"} -local LNDP_PRT_LIST=${lndp_prt_list:-"-999"} - -local MOM6_OUTPUT_DIR=MOM6_OUTPUT/ -local MOM6_RESTART_SETTING=${MOM6_RESTART_SETTING:-'n'} -local MOM6_RESTART_DIR=MOM6_RESTART/ - -# Land IAU defaults -local DO_LAND_IAU=${DO_LAND_IAU:-".false."} -local LAND_IAU_FHRS=${IAUFHRS} -local LAND_IAU_DELHRS=${IAU_DELTHRS} -local LAND_IAU_INC_FILES="'sfc_inc',''" -local LSOIL_INCR=${LSOIL_INCR:-2} -local LAND_IAU_FILTER_INC=".false." -local LAND_IAU_UPD_STC=".true." -local LAND_IAU_UPD_SLC=".true." -local LAND_IAU_DO_STCSMC_ADJ=".true." -local LAND_IAU_MIN_T_INC=0.0001 -local LAND_IAU_MIN_SLC_INC=0.000001 - -# Check will need to be modified in the future -# once GW is ready to add in land IAU -if [[ "${DO_LAND_IAU}" = ".true." ]]; then - local HIDE_LIAU=" " -else - local HIDE_LIAU="!" -fi - -local global_template="${HOMEgfs}/parm/ufs/global_control.nml.IN" -atparse < "${global_template}" >> "input.nml" +FV3_namelists() { + + # setup the tables + DIAG_TABLE=${DIAG_TABLE:-${PARMgfs}/ufs/fv3/diag_table} + DIAG_TABLE_APPEND=${DIAG_TABLE_APPEND:-${PARMgfs}/ufs/fv3/diag_table_aod} + DATA_TABLE=${DATA_TABLE:-${PARMgfs}/ufs/MOM6_data_table.IN} + FIELD_TABLE=${FIELD_TABLE:-${PARMgfs}/ufs/fv3/field_table} + + # set cdmbgwd + if ((gwd_opt == 2)) && [[ ${do_gsl_drag_ls_bl} == ".true." ]]; then + cdmbgwd=${cdmbgwd_gsl} + fi + + # ensure non-prognostic tracers are set + dnats=${dnats:-0} + + # build the diag_table + { + echo "UFS_Weather_Model_Forecast" + if [[ "${DOIAU}" = "YES" ]]; then + echo "${previous_cycle:0:4} ${previous_cycle:4:2} ${previous_cycle:6:2} ${previous_cycle:8:2} 0 0" + else + echo "${current_cycle:0:4} ${current_cycle:4:2} ${current_cycle:6:2} ${current_cycle:8:2} 0 0" + fi + cat "${DIAG_TABLE}" + if [[ -n "${AERO_DIAG_TABLE:-}" ]]; then + cat "${AERO_DIAG_TABLE}" + fi + cat "${DIAG_TABLE_APPEND}" + } >> diag_table_template + + local template=diag_table_template + local SYEAR=${current_cycle:0:4} + local SMONTH=${current_cycle:4:2} + local SDAY=${current_cycle:6:2} + local CHOUR=${current_cycle:8:2} + local MOM6_OUTPUT_DIR="./MOM6_OUTPUT" + + atparse < "${template}" >> "diag_table" + + # copy data table + cpreq "${DATA_TABLE}" data_table + + # build field_table + if [[ -n "${AERO_FIELD_TABLE:-}" ]]; then + nrec=$(wc -l < "${FIELD_TABLE}") + prec=${nrec} + if ((dnats > 0)); then + # shellcheck disable=SC2312 + prec=$(grep -F -n TRACER "${FIELD_TABLE}" 2> /dev/null | tail -n "${dnats}" | head -1 | cut -d: -f1) + prec=${prec:-0} + prec=$((prec > 0 ? prec - 1 : prec)) + fi + { + head -n "${prec}" "${FIELD_TABLE}" + cat "${AERO_FIELD_TABLE}" + tail -n $((nrec - prec)) "${FIELD_TABLE}" + } > field_table + # add non-prognostic tracers from additional table + dnats=$((dnats + dnats_aero)) + else + cpreq "${FIELD_TABLE}" field_table + fi + + # Set variables for global_control.nml template + + local BLOCKSIZE=${blocksize} + local CHKSUM_DEBUG=${chksum_debug} + local DYCORE_ONLY=${dycore_only} + local CCPP_SUITE=${CCPP_SUITE} + + local MAX_OUTPUT_FIELDS=300 + + local DOMAINS_STACK_SIZE=${domains_stack_size:-3000000} + local PRINT_MEMORY_USAGE=${print_memory_usage:-".false."} + + local INPES=${layout_x} + local JNPES=${layout_y} + local IO_LAYOUT=${io_layout} + local NPX=${npx} + local NPY=${npy} + local NTILES=${ntiles} + local NPZ=${npz} + local DZ_MIN=${dz_min:-"6"} + local PSM_BC=${psm_bc:-"0"} + local MAKE_NH=${make_nh} + local FV_DEBUG=${fv_debug:-".false."} + local RANGE_WARN=${range_warn:-".true."} + local N_SPONGE=${n_sponge:-"10"} + local NUDGE_QV=${nudge_qv:-".false."} + local NUDGE_DZ=${nudge_dz:-".false."} + local TAU=${tau:-10.} + local FAST_TAU_W_SEC=${fast_tau_w_sec:-"0.2"} + local RF_CUTOFF=${rf_cutoff:-"7.5e2"} + local D2_BG_K1=${d2_bg_k1:-"0.15"} + local D2_BG_K2=${d2_bg_k2:-"0.02"} + local KORD_TM=${kord_tm:-"-9"} + local KORD_MT=${kord_mt:-"9"} + local KORD_WZ=${kord_wz:-"9"} + local KORD_TR=${kord_tr:-"9"} + local HYDROSTATIC=${hydrostatic} + local PHYS_HYDROSTATIC=${phys_hydrostatic} + local USE_HYDRO_PRESSURE=${use_hydro_pressure} + local UPDATE_FULL_OMEGA=${pass_full_omega_to_physics_in_non_hydrostatic_mode:-".false."} + local K_SPLIT=${k_split} + local N_SPLIT=${n_split} + local NWAT=${nwat:-2} + local NA_INIT=${na_init} + local DNATS=${dnats} + local FV_SG_ADJ=${fv_sg_adj:-"450"} + local NORD=${nord:-3} + local DDDMP=${dddmp:-0.1} + local D4_BG=${d4_bg:-0.15} + local VTDM4=${vtdm4} + local DELT_MAX=${delt_max:-"0.002"} + local DO_VORT_DAMP=${do_vort_damp} + local EXTERNAL_IC=${external_ic} + local EXTERNAL_ETA=${external_eta:-.true.} + local GFS_PHIL=${gfs_phil:-".false."} + local NGGPS_IC=${nggps_ic} + local MOUNTAIN=${mountain} + local NCEP_IC=${ncep_ic} + local D_CON=${d_con} + local HORD_MT=${hord_mt} + local HORD_VT=${hord_xx} + local HORD_TM=${hord_xx} + local HORD_DP=${hord_dp} + local HORD_TR=${hord_tr:-"8"} + local ADJUST_DRY_MASS=${adjust_dry_mass:-".true."} + local DRY_MASS=${dry_mass:-98320.0} + local CONSV_TE=${consv_te} + local DO_SAT_ADJ=${do_sat_adj:-".false."} + local PRINT_FREQ=${print_freq} + local WARM_START=${warm_start} + local NO_DYCORE=${no_dycore} + local AGRID_VEL_RST=${agrid_vel_rst:-".true."} + local READ_INCREMENT=${read_increment} + local RES_LATLON_DYNAMICS=${res_latlon_dynamics} + local ATM_IGNORE_RST_CKSUM=.false. + local INCREMENT_FILE_ON_NATIVE_GRID=${increment_file_on_native_grid:-.false.} + + local FILTERED_TERRAIN=${filtered_terrain} + local NPZP=${LEVS} #levp + local GFS_DWINDS=${gfs_dwinds} + + local FHZERO=${FHZERO:-6} + local H2O_PHYS=${h2o_phys:-".true."} + local LDIAG3D=${ldiag3d:-".false."} + local QDIAG3D=${qdiag3d:-".false."} + local PRINT_DIFF_PGR=${print_diff_pgr:-".false."} + local FHCYC=${FHCYC} + local USE_UFO=${use_ufo:-".true."} + local PRE_RAD=${pre_rad:-".false."} + local IMP_PHYSICS=${imp_physics:-"99"} + + local default_dt_inner=$((DELTIM / 2)) + local IOVR=${iovr:-"3"} + local LTAEROSOL=${ltaerosol:-".false."} + local MRAEROSOL=.false. + local LTHAILAWARE=.false. + local LRADAR=${lradar:-".true."} + local TTENDLIM=${ttendlim:-"-999"} + local DT_INNER=${dt_inner:-"${default_dt_inner}"} + local SEDI_SEMI=${sedi_semi:-".true."} + local DECFL=${decfl:-"10"} + local OZ_PHYS_NEW=${oz_phys:-".false."} + local OZ_PHYS_OLD=${oz_phys_2015:-".true."} + local LSOIL_LSM=${lsoil_lsm:-"4"} + local DO_MYNNEDMF=${do_mynnedmf:-".false."} + local DO_MYNNSFCLAY=${do_mynnsfclay:-".false."} + local ICLOUD_BL=${icloud_bl:-"1"} + local BL_MYNN_EDMF=${bl_mynn_edmf:-"1"} + local BL_MYNN_TKEADVECT=${bl_mynn_tkeadvect:-".true."} + local BL_MYNN_EDMF_MOM=${bl_mynn_edmf_mom:-"1"} + local TTE_EDMF=${tte_edmf:-".false."} + local CSCALE=${cscale:-"1.0"} + local DO_NGW_EC=${do_ngw_ec:-".false."} + local DO_UGWP=${do_ugwp:-".false."} + local DO_TOFD=${do_tofd:-".false."} + local GWD_OPT=${gwd_opt:-"2"} + local DO_UGWP_V0=${do_ugwp_v0:-".false."} + local DO_UGWP_V1=${do_ugwp_v1:-".true."} + local DO_UGWP_V0_OROG_ONLY=${do_ugwp_v0_orog_only:-".false."} + local DO_UGWP_V0_NST_ONLY=${do_ugwp_v0_nst_only:-".false."} + local DO_GSL_DRAG_LS_BL=${do_gsl_drag_ls_bl:-".true."} + local DO_GSL_DRAG_SS=${do_gsl_drag_ss:-".true."} + local DO_GSL_DRAG_TOFD=${do_gsl_drag_tofd:-".true."} + local DO_GWD_OPT_PSL=${do_gwd_opt_psl:-".false."} + local DO_UGWP_V1_OROG_ONLY=${do_ugwp_v1_orog_only:-".false."} + local MIN_LAKEICE=${min_lakeice:-"0.15"} + local MIN_SEAICE=${min_seaice:-"0.15"} + local USE_CICE_ALB=${use_cice_alb:-".false."} + + local PDFCLD=${pdfcld:-".false."} + local FHSWR=${FHSWR:-"3600."} + local FHLWR=${FHLWR:-"3600."} + local IALB=${IALB:-"1"} + local IEMS=${IEMS:-"1"} + local IAER=${IAER} + local ICLIQ_SW=${icliq_sw:-"2"} + local ICO2=${ICO2} + local ISUBC_SW=${isubc_sw:-"2"} + local ISUBC_LW=${isubc_lw:-"2"} + local ISOL=${ISOL:-"2"} + local LWHTR=${lwhtr:-".true."} + local SWHTR=${swhtr:-".true."} + local CNVGWD=${cnvgwd:-".true."} + local SHAL_CNV=${shal_cnv:-".true."} + local CAL_PRE=${cal_pre:-".true."} + local REDRAG=${redrag:-".true."} + local DSPHEAT=${dspheat:-".true."} + local HYBEDMF=${hybedmf:-".false."} + local SATMEDMF=${satmedmf:-".true."} + local ISATMEDMF=${isatmedmf:-"1"} + local LHEATSTRG=${lheatstrg:-".false."} + local LSEASPRAY=${lseaspray:-".true."} + local RANDOM_CLDS=${random_clds:-".true."} + local TRANS_TRAC=${trans_trac:-".true."} + local CNVCLD=${cnvcld:-".true."} + local XR_CNVCLD=${xr_cnvcld:-".true."} + local IMFSHALCNV=${imfshalcnv:-"2"} + local IMFDEEPCNV=${imfdeepcnv:-"2"} + local PROGSIGMA=${progsigma:-".true."} + local BETASCU=${betascu:-"8.0"} + local BETAMCU=${betamcu:-"1.0"} + local BETADCU=${betadcu:-"2.0"} + local RAS=${ras:-".false."} + local CDMBGWD=${cdmbgwd:-"3.5,0.25"} + local PSL_GWD_DX_FACTOR=${psl_gwd_dx_factor:-"6.0"} + local PRSLRD0=${prslrd0:-"0."} + local IVEGSRC=${ivegsrc:-"1"} + local ISOT=${isot:-"1"} + local LSOIL=${lsoil:-"4"} + local LSM=${lsm:-"2"} + local IOPT_DVEG=${iopt_dveg:-"1"} + local IOPT_CRS=${iopt_crs:-"1"} + local IOPT_BTR=${iopt_btr:-"1"} + local IOPT_RUN=${iopt_run:-"1"} + local IOPT_SFC=${iopt_sfc:-"1"} + local IOPT_TRS=${iopt_trs:-"2"} + local IOPT_DIAG=${iopt_diag:-"2"} + local IOPT_FRZ=${iopt_frz:-"1"} + local IOPT_INF=${iopt_inf:-"1"} + local IOPT_RAD=${iopt_rad:-"1"} + local IOPT_ALB=${iopt_alb:-"2"} + local IOPT_SNF=${iopt_snf:-"4"} + local IOPT_TBOT=${iopt_tbot:-"2"} + local IOPT_STC=${iopt_stc:-"1"} + local DEBUG=${gfs_phys_debug:-".false."} + local NSTF_NAME=${nstf_name} + local NST_ANL=${nst_anl} + local PSAUTCO=${psautco:-"0.0008,0.0005"} + local PRAUTCO=${prautco:-"0.00015,0.00015"} + local LGFDLMPRAD=${lgfdlmprad:-".false."} + local EFFR_IN=${effr_in:-".false."} + local LDIAG_UGWP=${ldiag_ugwp:-".false."} + local DO_RRTMGP=${do_RRTMGP:-".false."} + local ACTIVE_GASES=${active_gases:-"'h2o_co2_o3_n2o_ch4_o2'"} + local NGASES=${ngases:-"6"} + local LW_FILE_GAS=${lw_file_gas:-"'rrtmgp-data-lw-g128-210809.nc'"} + local LW_FILE_CLOUDS=${lw_file_clouds:-"'rrtmgp-cloud-optics-coeffs-lw.nc'"} + local SW_FILE_GAS=${sw_file_gas:-"'rrtmgp-data-sw-g112-210809.nc'"} + local SW_FILE_CLOUDS=${sw_file_clouds:-"'rrtmgp-cloud-optics-coeffs-sw.nc'"} + local RRTMGP_NGPTSSW=${rrtmgp_nGptsSW:-"112"} + local RRTMGP_NGPTSLW=${rrtmgp_nGptsLW:-"128"} + local RRTMGP_NBANDSLW=${rrtmgp_nBandsLW:-"16"} + local RRTMGP_NBANDSSW=${rrtmgp_nBandsSW:-"14"} + local DOGP_CLDOPTICS_LUT=${doGP_cldoptics_LUT:-".false."} + local DOGP_LWSCAT=${doGP_lwscat:-".false."} + local DOGP_SGS_CNV=.true. + + local DO_SPPT=${do_sppt:-".false."} + local DO_SHUM=${do_shum:-".false."} + local DO_SKEB=${do_skeb:-".false."} + local FRAC_GRID=${FRAC_GRID:-".true."} + local CPLCHM=${cplchm:-".false."} + local CPLFLX=${cplflx:-".false."} + local CPLICE=${cplice:-".false."} + local CPLWAV=${cplwav:-".false."} + local CPLWAV2ATM=${cplwav2atm:-".false."} + local USE_MED_FLUX=${use_med_flux:-".false."} + local CPLLND=${cpllnd:-".false."} + local CPLLND2ATM=${cpllnd2atm:-".false."} + local USE_OCEANUV=${use_oceanuv:-".false."} + + # CPL CHM options + if [[ "${cplchm}" = ".true." ]]; then + local FSCAV_AERO=${fscav_aero:-'*:0.0'} + else + local FSCAV_AERO='"*:0.3","so2:0.0","msa:0.0","dms:0.0","nh3:0.4","nh4:0.6","bc1:0.6","bc2:0.6","oc1:0.4","oc2:0.4","dust1:0.6","dust2:0.6","dust3:0.6","dust4:0.6","dust5:0.6","seas1:0.5","seas2:0.5","seas3:0.5","seas4:0.5","seas5:0.5"' + fi + + local IAUFHRS=${IAUFHRS} + local IAU_DELTHRS=${IAU_DELTHRS} + local IAU_INC_FILES=${IAU_INC_FILES:-"''"} + local IAU_DRYMASSFIXER=.false. + local IAU_FILTER_INCREMENTS=${IAU_FILTER_INCREMENTS:-".false."} + + # CA options + local DO_CA=".true." + local CA_GLOBAL=${ca_global:-".false."} + local CA_SGS=${ca_sgs:-".true."} + local NCA=${nca:-"1"} + local NCELLS=${ncells:-"5"} + local NLIVES=${nlives:-"12"} + local NSEED=${nseed:-"1"} + local NFRACSEED=${nfracseed:-"0.5"} + local NTHRESH=${nthresh:-"18"} + local CA_TRIGGER=${ca_trigger:-".true."} + local NSPINUP=${nspinup:-"1"} + local ISEED_CA=${ISEED_CA:-"12345"} + + # Land pert options + local LNDP_TYPE=${lndp_type:-2} + local N_VAR_LNDP=${n_var_lndp:-0} + + local LCNORM=${lcnorm:-".false."} + local PERT_MP=${PERT_MP:-".false."} + local PERT_RADTEND=${PERT_RADTEND:-".false."} + local PERT_CLDS=${PERT_CLDS:-".false."} + + if [[ "${DO_SPPT}" = ".true." ]]; then + local PERT_CLDS=".true." + fi + + if [[ "${DOIAU}" = "YES" ]]; then + local HIDE_AIAU=" " + else + local HIDE_AIAU="!" + fi + + #GWP options + if [[ "${knob_ugwp_version}" -eq 0 ]]; then + local HIDE_UGWPV0=" " + local HIDE_UGWPV1="!" + elif [[ "${knob_ugwp_version}" -eq 1 ]]; then + local HIDE_UGWPV0="!" + local HIDE_UGWPV1=" " + else + local HIDE_UGWPV0="!" + local HIDE_UGWPV1="!" + fi + + # Common GWP options + local KNOB_UGWP_SOLVER=${knob_ugwp_solver:-2} + local KNOB_UGWP_SOURCE=${knob_ugwp_source:-1,1,0,0} + local KNOB_UGWP_WVSPEC=${knob_ugwp_wvspec:-1,25,25,25} + local KNOB_UGWP_AZDIR=${knob_ugwp_azdir:-2,4,4,4} + local KNOB_UGWP_STOCH=${knob_ugwp_stoch:-0,0,0,0} + local KNOB_UGWP_EFFAC=${knob_ugwp_effac:-1,1,1,1} + local KNOB_UGWP_DOAXYZ=${knob_ugwp_doaxyz:-1} + local KNOB_UGWP_DOHEAT=${knob_ugwp_doheat:-1} + # UGWP Version 0 options + local KNOB_UGWP_DOKDIS=${knob_ugwp_dokdis:-1} + local KNOB_UGWP_NDX4LH=${knob_ugwp_ndx4lh:-1} + local KNOB_UGWP_VERSION=${knob_ugwp_version:-0} + local LAUNCH_LEVEL=${launch_level:-54} + # UGWP Version 1 options + local KNOB_UGWP_DOKDIS=${knob_ugwp_dokdis:-2} + local KNOB_UGWP_NDX4LH=${knob_ugwp_ndx4lh:-4} + local KNOB_UGWP_VERSION=${knob_ugwp_version:-1} + local KNOB_UGWP_PALAUNCH=${knob_ugwp_palaunch:-275.0e2} + local KNOB_UGWP_NSLOPE=${knob_ugwp_nslope:-1} + local KNOB_UGWP_LZMAX=${knob_ugwp_lzmax:-15.750e3} + local KNOB_UGWP_LZMIN=${knob_ugwp_lzmin:-0.75e3} + local KNOB_UGWP_LZSTAR=${knob_ugwp_lzstar:-2.0e3} + local KNOB_UGWP_TAUMIN=${knob_ugwp_taumin:-0.25e-3} + local KNOB_UGWP_TAUAMP=${knob_ugwp_tauamp:-3.0e-3} + local KNOB_UGWP_LHMET=${knob_ugwp_lhmet:-200.0e3} + local KNOB_UGWP_OROSOLV=${knob_ugwp_orosolv:-\'pss-1986\'} + + # gfdl_cloud_microphysics options + local REIFLAG=${reiflag:-"2"} + + # interpolator_nml options + + # nam sfc options + local FNGLAC="'${FNGLAC}'" + local FNMXIC="'${FNMXIC}'" + local FNTSFC="'${FNTSFC}'" + local FNSNOC="'${FNSNOC}'" + local FNZORC="'${FNZORC}'" + local FNALBC="'${FNALBC}'" + local FNALBC2="'${FNALBC2}'" + local FNAISC="'${FNAISC}'" + local FNTG3C="'${FNTG3C}'" + local FNVEGC="'${FNVEGC}'" + local FNVETC="'${FNVETC}'" + local FNSOTC="'${FNSOTC}'" + local FNSOCC="'${FNSOCC}'" + local FNSMCC="'${FNSMCC}'" + local FNMSKH="'${FNMSKH}'" + local FNTSFA="'${FNTSFA}'" + local FNACNA="'${FNACNA:-}'" + local FNSNOA="'${FNSNOA:-}'" + local FNVMNC="'${FNVMNC:-}'" + local FNVMXC="'${FNVMXC:-}'" + local FNSLPC="'${FNSLPC:-}'" + local FNABSC="'${FNABSC:-}'" + local LDEBUG=${LDEBUG:-".false."} + local FSMCL2=${FSMCL2:+\'${FSMCL2}\'}${FSMCL2:-99999} + local FSMCL3=${FSMCL3:+\'${FSMCL3}\'}${FSMCL3:-99999} + local FSMCL4=${FSMCL4:+\'${FSMCL4}\'}${FSMCL4:-99999} + local LANDICE=${landice:-".true."} + local FTSFS=${FTSFS:-90} + local FAISL=${FAISL:+\'${FAISL}\'}${FAISL:-99999} + local FAISS=${FAISS:+\'${FAISS}\'}${FAISS:-99999} + local FSNOL=${FSNOL:+\'${FSNOL}\'}${FSNOL:-99999} + local FSNOS=${FSNOS:+\'${FSNOS}\'}${FSNOS:-99999} + local FSICL=${FSICL:-99999} + local FSICS=${FSICS:-99999} + local FTSFL=${FTSFL:+\'${FTSFL}\'}${FTSFL:-99999} + local FVETL=${FVETL:+\'${FVETL}\'}${FVETL:-99999} + local FSOTL=${FSOTL:+\'${FSOTL}\'}${FSOTL:-99999} + local FVMNL=${FvmnL:+\'${FvmnL}\'}${FvmnL:-99999} + local FVMXL=${FvmxL:+\'${FvmxL}\'}${FvmxL:-99999} + local FSLPL=${FSLPL:+\'${FSLPL}\'}${FSLPL:-99999} + local FABSL=${FABSL:+\'${FABSL}\'}${FABSL:-99999} + local FNTSFA="'${FNTSFA:-}'" + + #fv_grid_nml options + + #nam stochy options + local NEW_LSCALE=${new_lscale:-".false."} + local STOCHINI=${stochini:-".false."} + local SKEB=${SKEB:-0} + local ISEED_SKEB=${ISEED_SKEB:-${ISEED}} + local SKEB_TAU=${SKEB_TAU:-"-999."} + local SKEB_LSCALE=${SKEB_LSCALE:-"-999."} + local SKEBNORM=${SKEBNORM:-"1"} + local SKEB_NPASS=${SKEB_NPASS:-"30"} + local SKEB_VDOF=${SKEB_VDOF:-"5"} + local SKEBINT=${SKEBINT:-"0"} + local SHUM=${SHUM:-"-999."} + local ISEED_SHUM=${ISEED_SHUM:-${ISEED}} + local SHUM_TAU=${SHUM_TAU:-"-999."} + local SHUM_LSCALE=${SHUM_LSCALE:-"-999."} + local SHUMINT=${SHUMINT:-"0"} + local SPPT=${SPPT:-"-999."} + local ISEED_SPPT=${ISEED_SPPT:-${ISEED}} + local SPPT_TAU=${SPPT_TAU:-"-999."} + local SPPT_LSCALE=${SPPT_LSCALE:-"-999."} + local SPPT_LOGIT=${SPPT_LOGIT:-".true."} + local SPPT_SFCLIMIT=${SPPT_SFCLIMIT:-".true."} + local USE_ZMTNBLCK=${use_zmtnblck:-".true."} + local SPPTINT=${SPPTINT:-"0"} + local PBL_TAPER=${pbl_taper:-"0,0,0,0.125,0.25,0.5,0.75"} + local OCNSPPT=${OCNSPPT:-"0.8,0.4,0.2,0.08,0.04"} + local OCNSPPT_LSCALE=${OCNSPPT_LSCALE:-"500.E3,1000.E3,2000.E3,2000.E3,2000.E3"} + local OCNSPPT_TAU=${OCNSPPT_TAU:-"2.16E4,2.592E5,2.592E6,7.776E6,3.1536E7"} + local ISEED_OCNSPPT=${ISEED_OCNSPPT:-${ISEED}} + local EPBL=${EPBL:-"0.8,0.4,0.2,0.08,0.04"} + local EPBL_LSCALE=${EPBL_LSCALE:-"500.E3,1000.E3,2000.E3,2000.E3,2000.E3"} + local EPBL_TAU=${EPBL_TAU:-"2.16E4,2.592E5,2.592E6,7.776E6,3.1536E7"} + local ISEED_EPBL=${ISEED_EPBL:-${ISEED}} + local LNDP_TYPE=${lndp_type:-"0"} + local LNDP_MODEL_TYPE=${lndp_model_type:-"0"} + local LNDP_TAU=${LNDP_TAU:-"21600"} + local LNDP_LSCALE=${LNDP_SCALE:-"500000"} + local ISEED_LNDP=${ISEED_LNDP:-${ISEED}} + local LNDP_VAR_LIST=${lndp_var_list:-"'XXX'"} + local LNDP_PRT_LIST=${lndp_prt_list:-"-999"} + + local MOM6_OUTPUT_DIR=MOM6_OUTPUT/ + local MOM6_RESTART_SETTING=${MOM6_RESTART_SETTING:-'n'} + local MOM6_RESTART_DIR=MOM6_RESTART/ + + # Land IAU defaults + local DO_LAND_IAU=${DO_LAND_IAU:-".false."} + local LAND_IAU_FHRS=${IAUFHRS} + local LAND_IAU_DELHRS=${IAU_DELTHRS} + local LAND_IAU_INC_FILES="'sfc_inc',''" + local LSOIL_INCR=${LSOIL_INCR:-2} + local LAND_IAU_FILTER_INC=".false." + local LAND_IAU_UPD_STC=".true." + local LAND_IAU_UPD_SLC=".true." + local LAND_IAU_DO_STCSMC_ADJ=".true." + local LAND_IAU_MIN_T_INC=0.0001 + local LAND_IAU_MIN_SLC_INC=0.000001 + + # Check will need to be modified in the future + # once GW is ready to add in land IAU + if [[ "${DO_LAND_IAU}" = ".true." ]]; then + local HIDE_LIAU=" " + else + local HIDE_LIAU="!" + fi + + local global_template="${HOMEgfs}/parm/ufs/global_control.nml.IN" + atparse < "${global_template}" >> "input.nml" } diff --git a/ush/parsing_namelists_FV3_nest.sh b/ush/parsing_namelists_FV3_nest.sh index 325021e7c38..89e16efca30 100755 --- a/ush/parsing_namelists_FV3_nest.sh +++ b/ush/parsing_namelists_FV3_nest.sh @@ -5,105 +5,104 @@ # Disable variable not used warnings and 'masking return value' warnings # shellcheck disable=SC2034 # shellcheck disable=SC2312 -FV3_namelists_nest(){ - -# First argument tells us which namelist we're writing: -# global = writing input.nml for running global with a nest -# nest = writing input_nest02.nml for running the nest -namelist_mode="${1:-global}" - -if [[ "${namelist_mode}" == "nest" ]] ; then - nml_file=input_nest02.nml - only_input_nml="YES" -else - nml_file=input.nml - only_input_nml="NO" -fi - -# setup the tables -DIAG_TABLE=${DIAG_TABLE:-${PARMgfs}/ufs/fv3/diag_table} -DIAG_TABLE_APPEND=${DIAG_TABLE_APPEND:-${PARMgfs}/ufs/fv3/diag_table_aod} -DATA_TABLE=${DATA_TABLE:-${PARMgfs}/ufs/MOM6_data_table.IN} -FIELD_TABLE=${FIELD_TABLE:-${PARMgfs}/ufs/fv3/field_table} - -# set cdmbgwd -if (( gwd_opt == 2 )) && [[ ${do_gsl_drag_ls_bl} == ".true." ]]; then - cdmbgwd=${cdmbgwd_gsl} -fi - -# ensure non-prognostic tracers are set -dnats=${dnats:-0} - -if [[ "${only_input_nml:-NO}" == "NO" ]] ; then -# build the diag_table -{ -echo "UFS_Weather_Model_Forecast" -if [[ "${DOIAU}" = "YES" ]]; then - echo "${previous_cycle:0:4} ${previous_cycle:4:2} ${previous_cycle:6:2} ${previous_cycle:8:2} 0 0" -else - echo "${current_cycle:0:4} ${current_cycle:4:2} ${current_cycle:6:2} ${current_cycle:8:2} 0 0" -fi -cat "${DIAG_TABLE}" -if [[ -n "${AERO_DIAG_TABLE:-}" ]]; then - cat "${AERO_DIAG_TABLE}" -fi -cat "${DIAG_TABLE_APPEND}" -} >> diag_table_template - -local template=diag_table_template -local SYEAR=${current_cycle:0:4} -local SMONTH=${current_cycle:4:2} -local SDAY=${current_cycle:6:2} -local CHOUR=${current_cycle:8:2} -local MOM6_OUTPUT_DIR="./MOM6_OUTPUT" - -atparse < "${template}" >> "diag_table" - - -# copy data table -cpreq "${DATA_TABLE}" data_table - -# build field_table -if [[ -n "${AERO_FIELD_TABLE:-}" ]]; then - nrec=$(wc -l < "${FIELD_TABLE}") - prec=${nrec} - if (( dnats > 0 )); then - prec=$( grep -F -n TRACER "${FIELD_TABLE}" 2> /dev/null | tail -n "${dnats}" | head -1 | cut -d: -f1 ) - prec=${prec:-0} - prec=$(( prec > 0 ? prec - 1 : prec )) - fi - { \ - head -n "${prec}" "${FIELD_TABLE}" ; \ - cat "${AERO_FIELD_TABLE}" ; \ - tail -n $(( nrec - prec )) "${FIELD_TABLE}" ; \ - } > field_table - # add non-prognostic tracers from additional table - dnats=$(( dnats + dnats_aero )) -else - cpreq "${FIELD_TABLE}" field_table -fi -fi # only_input_nml - -if [[ "${namelist_mode}" == "global" ]] ; then - layout_x_here=${layout_x} - layout_y_here=${layout_y} - ntiles_here=6 - npx_here=${npx} - npy_here=${npy} - k_split_here=${k_split} -else - layout_x_here=${layout_x_nest} - layout_y_here=${layout_y_nest} - ntiles_here=1 - nested_here=.true. - twowaynest_here=${twowaynest:-.true.} - nestupdate_here=${nestupdate:-7} - npx_here=${npx_nest} - npy_here=${npy_nest} - k_split_here=${k_split_nest} -fi - -cat > "${nml_file}" <> diag_table_template + + local template=diag_table_template + local SYEAR=${current_cycle:0:4} + local SMONTH=${current_cycle:4:2} + local SDAY=${current_cycle:6:2} + local CHOUR=${current_cycle:8:2} + local MOM6_OUTPUT_DIR="./MOM6_OUTPUT" + + atparse < "${template}" >> "diag_table" + + # copy data table + cpreq "${DATA_TABLE}" data_table + + # build field_table + if [[ -n "${AERO_FIELD_TABLE:-}" ]]; then + nrec=$(wc -l < "${FIELD_TABLE}") + prec=${nrec} + if ((dnats > 0)); then + prec=$(grep -F -n TRACER "${FIELD_TABLE}" 2> /dev/null | tail -n "${dnats}" | head -1 | cut -d: -f1) + prec=${prec:-0} + prec=$((prec > 0 ? prec - 1 : prec)) + fi + { + head -n "${prec}" "${FIELD_TABLE}" + cat "${AERO_FIELD_TABLE}" + tail -n $((nrec - prec)) "${FIELD_TABLE}" + } > field_table + # add non-prognostic tracers from additional table + dnats=$((dnats + dnats_aero)) + else + cpreq "${FIELD_TABLE}" field_table + fi + fi # only_input_nml + + if [[ "${namelist_mode}" == "global" ]]; then + layout_x_here=${layout_x} + layout_y_here=${layout_y} + ntiles_here=6 + npx_here=${npx} + npy_here=${npy} + k_split_here=${k_split} + else + layout_x_here=${layout_x_nest} + layout_y_here=${layout_y_nest} + ntiles_here=1 + nested_here=.true. + twowaynest_here=${twowaynest:-.true.} + nestupdate_here=${nestupdate:-7} + npx_here=${npx_nest} + npy_here=${npy_nest} + k_split_here=${k_split_nest} + fi + + cat > "${nml_file}" << EOF &atmos_model_nml blocksize = ${blocksize} chksum_debug = ${chksum_debug} @@ -209,24 +208,24 @@ cat > "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF do_schmidt = .true. target_lat = ${TARGET_LAT} target_lon = ${TARGET_LON} stretch_fac = ${stretch_fac} EOF -fi + fi -if [[ "${DO_NEST:-NO}" == "YES" && "${namelist_mode}" == "nest" ]] ; then - cat >> "${nml_file}" <> "${nml_file}" << EOF nested = .true. twowaynest = ${twowaynest:-.true.} ! .true. nestupdate = 7 EOF -fi + fi -cat >> "${nml_file}" <> "${nml_file}" << EOF / &external_ic_nml @@ -250,15 +249,15 @@ cat >> "${nml_file}" <> "${nml_file}" << EOF + case "${CCPP_SUITE:-}" in + "FV3_GFS_v15p2_coupled") + cat >> "${nml_file}" << EOF oz_phys = .false. oz_phys_2015 = .true. EOF - ;; - "FV3_GSD_v0") - cat >> "${nml_file}" << EOF + ;; + "FV3_GSD_v0") + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} ltaerosol = ${ltaerosol:-".false."} lradar = ${lradar:-".false."} @@ -276,9 +275,9 @@ EOF min_seaice = ${min_seaice:-"0.15"} use_cice_alb = ${use_cice_alb:-".false."} EOF - ;; - FV3_GFS_v16_coupled*) - cat >> "${nml_file}" << EOF + ;; + FV3_GFS_v16_coupled*) + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} ltaerosol = ${ltaerosol:-".false."} lradar = ${lradar:-".false."} @@ -294,9 +293,9 @@ EOF min_lakeice = ${min_lakeice:-"0.15"} min_seaice = ${min_seaice:-"0.15"} EOF - ;; - FV3_GFS_v16*) - cat >> "${nml_file}" << EOF + ;; + FV3_GFS_v16*) + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} ltaerosol = ${ltaerosol:-".false."} lradar = ${lradar:-".false."} @@ -313,10 +312,10 @@ EOF min_lakeice = ${min_lakeice:-"0.15"} min_seaice = ${min_seaice:-"0.15"} EOF - ;; - FV3_GFS_v17*) - local default_dt_inner=$(( DELTIM/2 )) - cat >> "${nml_file}" << EOF + ;; + FV3_GFS_v17*) + local default_dt_inner=$((DELTIM / 2)) + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} ltaerosol = ${ltaerosol:-".false."} lradar = ${lradar:-".true."} @@ -349,10 +348,10 @@ EOF min_seaice = ${min_seaice:-"0.15"} use_cice_alb = ${use_cice_alb:-".false."} EOF - ;; - FV3_global_nest*) - local default_dt_inner=$(( DELTIM/2 )) - cat >> "${nml_file}" << EOF + ;; + FV3_global_nest*) + local default_dt_inner=$((DELTIM / 2)) + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} lcnorm = ${lcnorm:-".false."} ltaerosol = ${ltaerosol:-".false."} @@ -385,15 +384,15 @@ EOF min_seaice = ${min_seaice:-"0.15"} use_cice_alb = ${use_cice_alb:-".false."} EOF - ;; - *) - cat >> "${nml_file}" << EOF + ;; + *) + cat >> "${nml_file}" << EOF iovr = ${iovr:-"3"} EOF - ;; -esac + ;; + esac -cat >> "${nml_file}" <> "${nml_file}" << EOF pdfcld = ${pdfcld:-".false."} fhswr = ${FHSWR:-"3600."} fhlwr = ${FHLWR:-"3600."} @@ -471,13 +470,13 @@ cat >> "${nml_file}" <> "${nml_file}" << EOF + if [[ ${cplchm} = ".true." ]]; then + cat >> "${nml_file}" << EOF fscav_aero = ${fscav_aero:-'*:0.0'} EOF -fi + fi -cat >> "${nml_file}" <> "${nml_file}" << EOF do_sppt = ${do_sppt:-".false."} do_shum = ${do_shum:-".false."} do_skeb = ${do_skeb:-".false."} @@ -489,27 +488,27 @@ cat >> "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF pert_mp = .false. pert_radtend = .false. pert_clds = .true. EOF -fi + fi -# Add namelist for IAU -if [[ ${DOIAU} = "YES" ]]; then - cat >> "${nml_file}" << EOF + # Add namelist for IAU + if [[ ${DOIAU} = "YES" ]]; then + cat >> "${nml_file}" << EOF iaufhrs = ${IAUFHRS} iau_delthrs = ${IAU_DELTHRS} iau_inc_files= ${IAU_INC_FILES} iau_drymassfixer = .false. iau_filter_increments = ${IAU_FILTER_INCREMENTS:-".false."} EOF -fi + fi -if [[ ${DO_CA:-"NO"} = "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ ${DO_CA:-"NO"} = "YES" ]]; then + cat >> "${nml_file}" << EOF do_ca = .true. ca_global = ${ca_global:-".false."} ca_sgs = ${ca_sgs:-".true."} @@ -523,24 +522,24 @@ if [[ ${DO_CA:-"NO"} = "YES" ]]; then nspinup = ${nspinup:-"1"} iseed_ca = ${ISEED_CA:-"12345"} EOF -fi + fi -if [[ "${DO_LAND_PERT:-NO}" == "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ "${DO_LAND_PERT:-NO}" == "YES" ]]; then + cat >> "${nml_file}" << EOF lndp_type = ${lndp_type:-2} n_var_lndp = ${n_var_lndp:-0} EOF -fi + fi -# Close &gfs_physics_nml section -cat >> "${nml_file}" << EOF + # Close &gfs_physics_nml section + cat >> "${nml_file}" << EOF / EOF -if [[ "${namelist_mode}" == "global" ]] ; then - cat >> "${nml_file}" << EOF + if [[ "${namelist_mode}" == "global" ]]; then + cat >> "${nml_file}" << EOF &fv_nest_nml - grid_pes = $(( layout_x * layout_y * 6 )),$(( layout_x_nest * layout_y_nest )) + grid_pes = $((layout_x * layout_y * 6)),$((layout_x_nest * layout_y_nest)) tile_coarse = 0,6 num_tile_top = 6 p_split = 1 @@ -549,10 +548,10 @@ if [[ "${namelist_mode}" == "global" ]] ; then nest_joffsets = 0,${nest_joffset} / EOF -fi + fi -if [[ ${knob_ugwp_version} -eq 0 ]]; then - cat >> "${nml_file}" << EOF + if [[ ${knob_ugwp_version} -eq 0 ]]; then + cat >> "${nml_file}" << EOF &cires_ugwp_nml knob_ugwp_solver = ${knob_ugwp_solver:-2} knob_ugwp_source = ${knob_ugwp_source:-1,1,0,0} @@ -568,10 +567,10 @@ if [[ ${knob_ugwp_version} -eq 0 ]]; then launch_level = ${launch_level:-54} / EOF -fi + fi -if [[ ${knob_ugwp_version} -eq 1 ]]; then - cat >> "${nml_file}" << EOF + if [[ ${knob_ugwp_version} -eq 1 ]]; then + cat >> "${nml_file}" << EOF &cires_ugwp_nml knob_ugwp_solver = ${knob_ugwp_solver:-2} knob_ugwp_source = ${knob_ugwp_source:-1,1,0,0} @@ -595,11 +594,11 @@ if [[ ${knob_ugwp_version} -eq 1 ]]; then knob_ugwp_orosolv = ${knob_ugwp_orosolv:-'pss-1986'} / EOF -fi + fi -echo "" >> "${nml_file}" + echo "" >> "${nml_file}" -cat >> "${nml_file}" <> "${nml_file}" << EOF &gfdl_cloud_microphysics_nml sedi_transport = .true. do_sedi_heat = .false. @@ -704,28 +703,28 @@ cat >> "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF grid_file = 'INPUT/grid_spec.nc' EOF -fi + fi -cat >> "${nml_file}" <> "${nml_file}" << EOF ${fv_grid_nml:-} / EOF -# Add namelist for stochastic physics options -echo "" >> "${nml_file}" -#if [ $MEMBER -gt 0 ]; then -if [[ "${DO_SPPT}" = "YES" || "${DO_SHUM}" = "YES" || "${DO_SKEB}" = "YES" || "${DO_LAND_PERT}" = "YES" ]]; then + # Add namelist for stochastic physics options + echo "" >> "${nml_file}" + #if [[ $MEMBER -gt 0 ]]; then + if [[ "${DO_SPPT}" = "YES" || "${DO_SHUM}" = "YES" || "${DO_SKEB}" = "YES" || "${DO_LAND_PERT}" = "YES" ]]; then - cat >> "${nml_file}" << EOF + cat >> "${nml_file}" << EOF &nam_stochy EOF - if [[ ${DO_SKEB} = "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ ${DO_SKEB} = "YES" ]]; then + cat >> "${nml_file}" << EOF skeb = ${SKEB} iseed_skeb = ${ISEED_SKEB:-${ISEED}} skeb_tau = ${SKEB_TAU:-"-999."} @@ -734,19 +733,19 @@ EOF skeb_npass = ${SKEB_NPASS:-"30"} skeb_vdof = ${SKEB_VDOF:-"5"} EOF - fi + fi - if [[ ${DO_SHUM} = "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ ${DO_SHUM} = "YES" ]]; then + cat >> "${nml_file}" << EOF shum = ${SHUM} iseed_shum = ${ISEED_SHUM:-${ISEED}} shum_tau = ${SHUM_TAU:-"-999."} shum_lscale = ${SHUM_LSCALE:-"-999."} EOF - fi + fi - if [[ ${DO_SPPT} = "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ ${DO_SPPT} = "YES" ]]; then + cat >> "${nml_file}" << EOF sppt = ${SPPT} iseed_sppt = ${ISEED_SPPT:-${ISEED}} sppt_tau = ${SPPT_TAU:-"-999."} @@ -756,50 +755,50 @@ EOF use_zmtnblck = ${use_zmtnblck:-".true."} pbl_taper = ${pbl_taper:-"0,0,0,0.125,0.25,0.5,0.75"} EOF - fi + fi - if [[ "${DO_OCN_SPPT:-NO}" == "YES" ]]; then - cat >> "${nml_file}" <> "${nml_file}" << EOF OCNSPPT=${OCNSPPT} OCNSPPT_LSCALE=${OCNSPPT_LSCALE} OCNSPPT_TAU=${OCNSPPT_TAU} ISEED_OCNSPPT=${ISEED_OCNSPPT:-${ISEED}} EOF - fi + fi - if [[ "${DO_OCN_PERT_EPBL:-NO}" == "YES" ]]; then - cat >> "${nml_file}" <> "${nml_file}" << EOF EPBL=${EPBL} EPBL_LSCALE=${EPBL_LSCALE} EPBL_TAU=${EPBL_TAU} ISEED_EPBL=${ISEED_EPBL:-${ISEED}} EOF - fi + fi - if [[ "${DO_OCN_SPPT:-NO}" == "YES" ]]; then - cat >> "${nml_file}" <> "${nml_file}" << EOF OCNSPPT=${OCNSPPT} OCNSPPT_LSCALE=${OCNSPPT_LSCALE} OCNSPPT_TAU=${OCNSPPT_TAU} ISEED_OCNSPPT=${ISEED_OCNSPPT:-${ISEED}} EOF - fi + fi - if [[ "${DO_OCN_PERT_EPBL:-NO}" == "YES" ]]; then - cat >> "${nml_file}" <> "${nml_file}" << EOF EPBL=${EPBL} EPBL_LSCALE=${EPBL_LSCALE} EPBL_TAU=${EPBL_TAU} ISEED_EPBL=${ISEED_EPBL:-${ISEED}} EOF - fi + fi - cat >> "${nml_file}" << EOF + cat >> "${nml_file}" << EOF / EOF - if [[ ${DO_LAND_PERT} = "YES" ]]; then - cat >> "${nml_file}" << EOF + if [[ ${DO_LAND_PERT} = "YES" ]]; then + cat >> "${nml_file}" << EOF &nam_sfcperts lndp_type = ${lndp_type} LNDP_TAU = ${LNDP_TAU} @@ -809,27 +808,27 @@ EOF lndp_prt_list = ${lndp_prt_list} / EOF - else - cat >> "${nml_file}" << EOF + else + cat >> "${nml_file}" << EOF &nam_sfcperts / EOF - fi + fi -else + else - cat >> "${nml_file}" << EOF + cat >> "${nml_file}" << EOF &nam_stochy / &nam_sfcperts / EOF -fi + fi -# Echo out formatted ""${nml_file}"" -echo "====================================" -echo "FV3_namelists_nest(): '${nml_file}'" -cat "${nml_file}" -echo "====================================" + # Echo out formatted ""${nml_file}"" + echo "====================================" + echo "FV3_namelists_nest(): '${nml_file}'" + cat "${nml_file}" + echo "====================================" } diff --git a/ush/parsing_namelists_GOCART.sh b/ush/parsing_namelists_GOCART.sh index 2a08a90b0bc..26399356407 100755 --- a/ush/parsing_namelists_GOCART.sh +++ b/ush/parsing_namelists_GOCART.sh @@ -3,52 +3,52 @@ # Disable variable not used warnings # shellcheck disable=SC2034 GOCART_namelists() { - # copying GOCART configuration files - if [[ -n "${AERO_CONFIG_DIR}" ]]; then + # copying GOCART configuration files + if [[ -n "${AERO_CONFIG_DIR}" ]]; then - local base_in - local fhout_aero_padded - fhout_aero_padded=$(printf "%02d" "${FHOUT_AERO}") - # Only instantaneous AOD is output right now - local inst_aod_freq="${fhout_aero_padded}0000" + local base_in + local fhout_aero_padded + fhout_aero_padded=$(printf "%02d" "${FHOUT_AERO}") + # Only instantaneous AOD is output right now + local inst_aod_freq="${fhout_aero_padded}0000" - # Other gocart fields not currently used - local inst_du_ss_freq="120000" - local tavg_du_ss_freq="120000" - local inst_ca_freq="120000" - local inst_ni_freq="120000" - local inst_su_freq="120000" - local inst_du_bin_freq="010000" - local tavg_du_bin_freq="030000" - local inst_ss_bin_freq="060000" - local inst_ca_bin_freq="120000" - local inst_ni_bin_freq="120000" - local inst_su_bin_freq="120000" - local inst_2d_freq="030000" - local inst_3d_freq="060000" - local tavg_2d_rad_freq="120000" - local tavg_3d_rad_freq="120000" + # Other gocart fields not currently used + local inst_du_ss_freq="120000" + local tavg_du_ss_freq="120000" + local inst_ca_freq="120000" + local inst_ni_freq="120000" + local inst_su_freq="120000" + local inst_du_bin_freq="010000" + local tavg_du_bin_freq="030000" + local inst_ss_bin_freq="060000" + local inst_ca_bin_freq="120000" + local inst_ni_bin_freq="120000" + local inst_su_bin_freq="120000" + local inst_2d_freq="030000" + local inst_3d_freq="060000" + local tavg_2d_rad_freq="120000" + local tavg_3d_rad_freq="120000" - for template_in in "${AERO_CONFIG_DIR}/"*.rc; do - base_in="$(basename "${template_in}")" - atparse < "${template_in}" >> "${DATA}/${base_in}" - status=$? - if [[ ${status} -ne 0 ]]; then - exit "${status}" - fi - done + for template_in in "${AERO_CONFIG_DIR}/"*.rc; do + base_in="$(basename "${template_in}")" + atparse < "${template_in}" >> "${DATA}/${base_in}" + status=$? + if [[ ${status} -ne 0 ]]; then + exit "${status}" + fi + done - # attempt to generate ExtData configuration file if not provided - if [[ ! -f "${DATA}/AERO_ExtData.rc" ]]; then - { \ - echo "PrimaryExports%%" ; \ - cat "${AERO_CONFIG_DIR}/ExtData.other" ; \ - cat "${AERO_CONFIG_DIR}/ExtData.${AERO_EMIS_FIRE:-none}" ; \ - echo "%%" ; \ - } > "${DATA}/AERO_ExtData.rc" - # shellcheck disable=SC2320 - status=$? - if (( status != 0 )); then exit "${status}"; fi + # attempt to generate ExtData configuration file if not provided + if [[ ! -f "${DATA}/AERO_ExtData.rc" ]]; then + { + echo "PrimaryExports%%" + cat "${AERO_CONFIG_DIR}/ExtData.other" + cat "${AERO_CONFIG_DIR}/ExtData.${AERO_EMIS_FIRE:-none}" + echo "%%" + } > "${DATA}/AERO_ExtData.rc" + # shellcheck disable=SC2320 + status=$? + if ((status != 0)); then exit "${status}"; fi + fi fi - fi } diff --git a/ush/parsing_namelists_MOM6.sh b/ush/parsing_namelists_MOM6.sh index bb810b60f7e..b8c7293681c 100755 --- a/ush/parsing_namelists_MOM6.sh +++ b/ush/parsing_namelists_MOM6.sh @@ -2,90 +2,90 @@ # Disable variable not used warnings # shellcheck disable=SC2034 -MOM6_namelists(){ +MOM6_namelists() { -# ================================================================ -# MOM_input -# --------- -# Prepare local variables for use in MOM_input.IN from UFSWM -# The ones already defined are left commented as a reminder -# == MOM options to start from coarsed grained restarts, set to off by default -# options only available for 05 and 1 degree grids -# as restarts are coarsed grained/interpolated from the 0.25 degrees grid -local MOM6_INIT_FROM_Z=${MOM6_INIT_FROM_Z:-True} -local MOM6_WARMSTART_FILE=${MOM6_WARMSTART_FILE:-"none"} -local MOM6_INIT_UV=${MOM6_INIT_UV:-"zero"} -# == MOM_domains section == -# NX_GLB -# NY_GLB -# == MOM section == -# DT_DYNAM_MOM6 -# DT_THERM_MOM6 -# MOM6_THERMO_SPAN -# == MOM_grid_init section == -local MOM6_TOPOEDITS=${TOPOEDITS} -# MOM6_ALLOW_LANDMASK_CHANGES -# == MOM_diag_mediator section == -# MOM6_DIAG_COORD_DEF_Z_FILE -# MOM6_DIAG_MISVAL -# == MOM_diabatic_aux section == -local MOM6_CHLCLIM=${CHLCLIM} -# == MOM_energetic_PBL section == -# MOM6_USE_LI2016 -if [[ "${cplwav}" == ".true." ]] ; then - local MOM6_USE_WAVES="True" -else - local MOM6_USE_WAVES="False" -fi -# == MOM_oda_incupd section == -local ODA_TEMPINC_VAR=${ODA_TEMPINC_VAR:-"Temp"} -local ODA_SALTINC_VAR=${ODA_SALTINC_VAR:-"Salt"} -local ODA_THK_VAR=${ODA_THK_VAR:-"h"} -local ODA_INCUPD_UV="True" -local ODA_UINC_VAR=${ODA_UINC_VAR:-"u"} -local ODA_VINC_VAR=${ODA_VINC_VAR:-"v"} -# ODA_INCUPD -# ODA_INCUPD_NHOURS -# == MOM_surface_forcing section == -# MOM6_RIVER_RUNOFF -# == ocean_stochastics section == -if [[ "${DO_OCN_SPPT}" == "YES" ]]; then - local DO_OCN_SPPT="True" # TODO: This is problematic if DO_OCN_SPPT is going to be used elsewhere -else - local DO_OCN_SPPT="False" -fi -if [[ "${DO_OCN_PERT_EPBL}" == "YES" ]]; then - local PERT_EPBL="True" -else - local PERT_EPBL="False" -fi -local MOM6_HFREEZE=20.0 -# Ensure the template exists -local template=${MOM6_INPUT_TEMPLATE:-"${PARMgfs}/ufs/MOM_input_${OCNRES}.IN"} -if [[ ! -f "${template}" ]]; then - echo "FATAL ERROR: template '${template}' does not exist, ABORT!" - exit 1 -fi -rm -f "${DATA}/INPUT/MOM_input" -atparse < "${template}" >> "${DATA}/INPUT/MOM_input" -echo "Rendered MOM_input:" -cat "${DATA}/INPUT/MOM_input" + # ---------------------------------------------------------------- + # MOM_input + # --------- + # Prepare local variables for use in MOM_input.IN from UFSWM + # The ones already defined are left commented as a reminder + # == MOM options to start from coarsed grained restarts, set to off by default + # options only available for 05 and 1 degree grids + # as restarts are coarsed grained/interpolated from the 0.25 degrees grid + local MOM6_INIT_FROM_Z=${MOM6_INIT_FROM_Z:-True} + local MOM6_WARMSTART_FILE=${MOM6_WARMSTART_FILE:-"none"} + local MOM6_INIT_UV=${MOM6_INIT_UV:-"zero"} + # == MOM_domains section == + # NX_GLB + # NY_GLB + # == MOM section == + # DT_DYNAM_MOM6 + # DT_THERM_MOM6 + # MOM6_THERMO_SPAN + # == MOM_grid_init section == + local MOM6_TOPOEDITS=${TOPOEDITS} + # MOM6_ALLOW_LANDMASK_CHANGES + # == MOM_diag_mediator section == + # MOM6_DIAG_COORD_DEF_Z_FILE + # MOM6_DIAG_MISVAL + # == MOM_diabatic_aux section == + local MOM6_CHLCLIM=${CHLCLIM} + # == MOM_energetic_PBL section == + # MOM6_USE_LI2016 + if [[ "${cplwav}" == ".true." ]]; then + local MOM6_USE_WAVES="True" + else + local MOM6_USE_WAVES="False" + fi + # == MOM_oda_incupd section == + local ODA_TEMPINC_VAR=${ODA_TEMPINC_VAR:-"Temp"} + local ODA_SALTINC_VAR=${ODA_SALTINC_VAR:-"Salt"} + local ODA_THK_VAR=${ODA_THK_VAR:-"h"} + local ODA_INCUPD_UV="True" + local ODA_UINC_VAR=${ODA_UINC_VAR:-"u"} + local ODA_VINC_VAR=${ODA_VINC_VAR:-"v"} + # ODA_INCUPD + # ODA_INCUPD_NHOURS + # == MOM_surface_forcing section == + # MOM6_RIVER_RUNOFF + # == ocean_stochastics section == + if [[ "${DO_OCN_SPPT}" == "YES" ]]; then + local DO_OCN_SPPT="True" # TODO: This is problematic if DO_OCN_SPPT is going to be used elsewhere + else + local DO_OCN_SPPT="False" + fi + if [[ "${DO_OCN_PERT_EPBL}" == "YES" ]]; then + local PERT_EPBL="True" + else + local PERT_EPBL="False" + fi + local MOM6_HFREEZE=20.0 + # Ensure the template exists + local template=${MOM6_INPUT_TEMPLATE:-"${PARMgfs}/ufs/MOM_input_${OCNRES}.IN"} + if [[ ! -f "${template}" ]]; then + echo "FATAL ERROR: template '${template}' does not exist, ABORT!" + exit 1 + fi + rm -f "${DATA}/INPUT/MOM_input" + atparse < "${template}" >> "${DATA}/INPUT/MOM_input" + echo "Rendered MOM_input:" + cat "${DATA}/INPUT/MOM_input" -# ================================================================ -# data_table -# ---------- -# Prepare local variables for use in MOM6_data_table.IN from UFSWM -local MOM6_FRUNOFF=${FRUNOFF} + # ---------------------------------------------------------------- + # data_table + # ---------- + # Prepare local variables for use in MOM6_data_table.IN from UFSWM + local MOM6_FRUNOFF=${FRUNOFF} -# Ensure the template exists -local template=${MOM6_DATA_TABLE_TEMPLATE:-"${PARMgfs}/ufs/MOM6_data_table.IN"} -if [[ ! -f "${template}" ]]; then - echo "FATAL ERROR: template '${template}' does not exist, ABORT!" - exit 1 -fi -rm -f "${DATA}/data_table" -atparse < "${template}" >> "${DATA}/data_table" -echo "Rendered data_table:" -cat "${DATA}/data_table" + # Ensure the template exists + local template=${MOM6_DATA_TABLE_TEMPLATE:-"${PARMgfs}/ufs/MOM6_data_table.IN"} + if [[ ! -f "${template}" ]]; then + echo "FATAL ERROR: template '${template}' does not exist, ABORT!" + exit 1 + fi + rm -f "${DATA}/data_table" + atparse < "${template}" >> "${DATA}/data_table" + echo "Rendered data_table:" + cat "${DATA}/data_table" } diff --git a/ush/parsing_namelists_WW3.sh b/ush/parsing_namelists_WW3.sh index ddcfdb47a26..5f19fdfc58a 100755 --- a/ush/parsing_namelists_WW3.sh +++ b/ush/parsing_namelists_WW3.sh @@ -1,70 +1,82 @@ #! /usr/bin/env bash -WW3_namelists(){ +WW3_namelists() { -# WW3 namelists/input generation + # WW3 namelists/input generation - FHMAX_WAV="${FHMAX_WAV:-384}" + FHMAX_WAV="${FHMAX_WAV:-384}" -# --------------------------------------------------------------------------- # -# Buoy location file + # --------------------------------------------------------------------------- # + # Buoy location file - if [ -f "${PARMgfs}/wave/wave_${NET}.buoys" ] - then - cpreq "${PARMgfs}/wave/wave_${NET}.buoys" "${DATA}/ww3_points.list" - fi + if [[ -f "${PARMgfs}/wave/wave_${NET}.buoys" ]]; then + cpreq "${PARMgfs}/wave/wave_${NET}.buoys" "${DATA}/ww3_points.list" + fi - if [ -f "${DATA}/ww3_points.list" ] - then - set +x - echo "ww3_points.list copied (${PARMgfs}/wave/wave_${NET}.buoys)." - set_trace - else - echo "FATAL ERROR : ww3_points.list (${PARMgfs}/wave/wave_${NET}.buoys) NOT FOUND" - exit 12 - fi + if [[ -f "${DATA}/ww3_points.list" ]]; then + set +x + echo "ww3_points.list copied (${PARMgfs}/wave/wave_${NET}.buoys)." + set_trace + else + echo "FATAL ERROR : ww3_points.list (${PARMgfs}/wave/wave_${NET}.buoys) NOT FOUND" + exit 12 + fi - #set coupling to ice/current - WW3_ICE="F" - WW3_CUR="F" + #set coupling to ice/current + WW3_ICE="F" + WW3_CUR="F" - case ${WW3ICEINP} in - 'YES' ) - WW3_ICE="T";; - 'CPL' ) - WW3_ICE="C";; - esac + case ${WW3ICEINP} in + 'YES') + WW3_ICE="T" + ;; + 'CPL') + WW3_ICE="C" + ;; + *) + msg="FATAL: Unknown WW3ICEIMP ${WW3ICEINP}" + export err=100 + err_exit "${msg}" + ;; + esac - case ${WW3CURINP} in - 'YES' ) - WW3_CUR="T";; - 'CPL' ) - WW3_CUR="C";; - esac + case ${WW3CURINP} in + 'YES') + WW3_CUR="T" + ;; + 'CPL') + WW3_CUR="C" + ;; + *) + msg="FATAL: Unknown WW3CURINP ${WW3CURINP}" + export err=100 + err_exit "${msg}" + ;; + esac - # Variables used in atparse of shel template - export WW3_IC1="F" - export WW3_IC5="F" - export WW3_WLEV="F" - export WW3_ICE - export WW3_CUR - export WW3_OUTPARS="${OUTPARS_WAV}" - export WW3_DTFLD="${DTFLD_WAV}" - export WW3_DTPNT="${DTPNT_WAV}" + # Variables used in atparse of shel template + export WW3_IC1="F" + export WW3_IC5="F" + export WW3_WLEV="F" + export WW3_ICE + export WW3_CUR + export WW3_OUTPARS="${OUTPARS_WAV}" + export WW3_DTFLD="${DTFLD_WAV}" + export WW3_DTPNT="${DTPNT_WAV}" - export WW3_GRD_OUTDIR="./WW3_OUTPUT/" - export WW3_PNT_OUTDIR="./WW3_OUTPUT/" - export WW3_RST_OUTDIR="./WW3_RESTART/" + export WW3_GRD_OUTDIR="./WW3_OUTPUT/" + export WW3_PNT_OUTDIR="./WW3_OUTPUT/" + export WW3_RST_OUTDIR="./WW3_RESTART/" - # Ensure the template exists - local template=${WW3_INPUT_TEMPLATE:-"${PARMgfs}/ufs/ww3_shel.nml.IN"} - if [[ ! -f "${template}" ]]; then - echo "FATAL ERROR: template '${template}' does not exist, ABORT!" - exit 1 - fi - rm -f "${DATA}/ww3_shel.nml" - atparse < "${template}" >> "${DATA}/ww3_shel.nml" - echo "Rendered ww3_shel.nml:" - cat "${DATA}/ww3_shel.nml" + # Ensure the template exists + local template=${WW3_INPUT_TEMPLATE:-"${PARMgfs}/ufs/ww3_shel.nml.IN"} + if [[ ! -f "${template}" ]]; then + echo "FATAL ERROR: template '${template}' does not exist, ABORT!" + exit 1 + fi + rm -f "${DATA}/ww3_shel.nml" + atparse < "${template}" >> "${DATA}/ww3_shel.nml" + echo "Rendered ww3_shel.nml:" + cat "${DATA}/ww3_shel.nml" } diff --git a/ush/parsing_ufs_configure.sh b/ush/parsing_ufs_configure.sh index 75b2cae2264..c860d855b9a 100755 --- a/ush/parsing_ufs_configure.sh +++ b/ush/parsing_ufs_configure.sh @@ -9,124 +9,124 @@ # shellcheck disable=SC2034 UFS_configure() { -echo "SUB ${FUNCNAME[0]}: ufs.configure begins" - -# Setup ufs.configure -local esmf_logkind=${esmf_logkind:-"ESMF_LOGKIND_MULTI"} #options: ESMF_LOGKIND_MULTI_ON_ERROR, ESMF_LOGKIND_MULTI, ESMF_LOGKIND_NONE -local DumpFields=${DumpFields:-false} -local cap_dbug_flag=${cap_dbug_flag:-0} - -# Determine "cmeps_run_type" based on the availability of the mediator restart file -# If it is a warm_start, we already copied the mediator restart to DATA, if it was present -# If the mediator restart was not present, despite being a "warm_start", we put out a WARNING -# in forecast_postdet.sh function CMEPS_postdet -if [[ -f "${DATA}/ufs.cpld.cpl.r.nc" ]]; then - local cmeps_run_type='continue' -else - local cmeps_run_type='startup' -fi - -# Atm-related -local atm_model="fv3" -local atm_petlist_bounds="0 $(( ATMPETS-1 ))" -local atm_omp_num_threads="${ATMTHREADS}" - -local med_model="cmeps" -local med_petlist_bounds="0 $(( MEDPETS-1 ))" -local med_omp_num_threads="${MEDTHREADS}" - -# vector remapping -local MAPUV3D=true - -if [[ "${cpl}" = ".true." ]]; then - local coupling_interval_slow_sec="${CPL_SLOW}" -fi - -local WRITE_ENDOFRUN_RESTART=.false. - -if [[ "${cplflx}" = ".true." ]]; then - - local use_coldstart=${use_coldstart:-".false."} - local use_mommesh=${USE_MOMMESH:-"true"} - - local ocn_model="mom6" - local ocn_petlist_bounds="${ATMPETS} $(( ATMPETS+OCNPETS-1 ))" - local ocn_omp_num_threads="${OCNTHREADS}" - local RUNTYPE="${cmeps_run_type}" - local CMEPS_RESTART_DIR="CMEPS_RESTART/" - local CPLMODE="${cplmode}" - local CMEPS_PIO_FORMAT='pnetcdf' - local CMEPS_PIO_STRIDE=4 - local CMEPS_PIO_IOTASKS=-99 - local CMEPS_PIO_REARR='box' - local CMEPS_PIO_ROOT=-99 - local coupling_interval_fast_sec="${CPL_FAST}" - local RESTART_N=999999 - local ocean_albedo_limit=0.06 - local ATMTILESIZE="${CASE:1}" - local ocean_albedo_limit=0.06 - local pio_rearranger=${pio_rearranger:-"box"} - local MED_history_n=1000000 - - local histaux_enabled=".false." -fi - -if [[ "${cplice}" = ".true." ]]; then - - local ice_model="cice6" - local ice_petlist_bounds="$(( ATMPETS+OCNPETS )) $(( ATMPETS+OCNPETS+ICEPETS-1 ))" - local ice_omp_num_threads="${ICETHREADS}" - local FHMAX="${FHMAX_GFS}" # TODO: How did this get in here hard-wired to FHMAX_GFS? -fi - -if [[ "${cplwav}" = ".true." ]]; then - - local wav_model="ww3" - local wav_petlist_bounds="$(( ATMPETS+OCNPETS+ICEPETS )) $(( ATMPETS+OCNPETS+ICEPETS+WAVPETS-1 ))" - local wav_omp_num_threads="${WAVTHREADS}" - - local WW3_user_histname="false" - local WW3_historync="false" - local WW3_restartnc="true" - local WW3_PIO_FORMAT="pnetcdf" - local WW3_PIO_IOTASKS=-99 - local WW3_PIO_STRIDE=4 - local WW3_PIO_REARR="box" - local WW3_PIO_ROOT=-99 - -fi - -if [[ "${cplchm}" = ".true." ]]; then - - local chm_model="gocart" - local chm_petlist_bounds="0 $(( CHMPETS-1 ))" - local chm_omp_num_threads="${CHMTHREADS}" - local coupling_interval_sec="${CPL_FAST}" - -fi - -#Set ESMF_THREADING variable for ufs configure -if [[ "${USE_ESMF_THREADING}" = "YES" ]]; then - local ESMF_THREADING="true" -else - local ESMF_THREADING="false" -fi - -# Ensure the template exists -if [[ ! -r "${ufs_configure_template}" ]]; then - echo "FATAL ERROR: template '${ufs_configure_template}' does not exist, ABORT!" - exit 1 -else - echo "INFO: using ufs.configure template: '${ufs_configure_template}'" -fi - -rm -f "${DATA}/ufs.configure" -atparse < "${ufs_configure_template}" >> "${DATA}/ufs.configure" -echo "Rendered ufs.configure:" -cat ufs.configure - -cpreq "${HOMEgfs}/sorc/ufs_model.fd/tests/parm/fd_ufs.yaml" fd_ufs.yaml - -echo "SUB ${FUNCNAME[0]}: ufs.configure ends" + echo "SUB ${FUNCNAME[0]}: ufs.configure begins" + + # Setup ufs.configure + local esmf_logkind=${esmf_logkind:-"ESMF_LOGKIND_MULTI"} #options: ESMF_LOGKIND_MULTI_ON_ERROR, ESMF_LOGKIND_MULTI, ESMF_LOGKIND_NONE + local DumpFields=${DumpFields:-false} + local cap_dbug_flag=${cap_dbug_flag:-0} + + # Determine "cmeps_run_type" based on the availability of the mediator restart file + # If it is a warm_start, we already copied the mediator restart to DATA, if it was present + # If the mediator restart was not present, despite being a "warm_start", we put out a WARNING + # in forecast_postdet.sh function CMEPS_postdet + if [[ -f "${DATA}/ufs.cpld.cpl.r.nc" ]]; then + local cmeps_run_type='continue' + else + local cmeps_run_type='startup' + fi + + # Atm-related + local atm_model="fv3" + local atm_petlist_bounds="0 $((ATMPETS - 1))" + local atm_omp_num_threads="${ATMTHREADS}" + + local med_model="cmeps" + local med_petlist_bounds="0 $((MEDPETS - 1))" + local med_omp_num_threads="${MEDTHREADS}" + + # vector remapping + local MAPUV3D=true + + if [[ "${cpl}" = ".true." ]]; then + local coupling_interval_slow_sec="${CPL_SLOW}" + fi + + local WRITE_ENDOFRUN_RESTART=.false. + + if [[ "${cplflx}" = ".true." ]]; then + + local use_coldstart=${use_coldstart:-".false."} + local use_mommesh=${USE_MOMMESH:-"true"} + + local ocn_model="mom6" + local ocn_petlist_bounds="${ATMPETS} $((ATMPETS + OCNPETS - 1))" + local ocn_omp_num_threads="${OCNTHREADS}" + local RUNTYPE="${cmeps_run_type}" + local CMEPS_RESTART_DIR="CMEPS_RESTART/" + local CPLMODE="${cplmode}" + local CMEPS_PIO_FORMAT='pnetcdf' + local CMEPS_PIO_STRIDE=4 + local CMEPS_PIO_IOTASKS=-99 + local CMEPS_PIO_REARR='box' + local CMEPS_PIO_ROOT=-99 + local coupling_interval_fast_sec="${CPL_FAST}" + local RESTART_N=999999 + local ocean_albedo_limit=0.06 + local ATMTILESIZE="${CASE:1}" + local ocean_albedo_limit=0.06 + local pio_rearranger=${pio_rearranger:-"box"} + local MED_history_n=1000000 + + local histaux_enabled=".false." + fi + + if [[ "${cplice}" = ".true." ]]; then + + local ice_model="cice6" + local ice_petlist_bounds="$((ATMPETS + OCNPETS)) $((ATMPETS + OCNPETS + ICEPETS - 1))" + local ice_omp_num_threads="${ICETHREADS}" + local FHMAX="${FHMAX_GFS}" # TODO: How did this get in here hard-wired to FHMAX_GFS? + fi + + if [[ "${cplwav}" = ".true." ]]; then + + local wav_model="ww3" + local wav_petlist_bounds="$((ATMPETS + OCNPETS + ICEPETS)) $((ATMPETS + OCNPETS + ICEPETS + WAVPETS - 1))" + local wav_omp_num_threads="${WAVTHREADS}" + + local WW3_user_histname="false" + local WW3_historync="false" + local WW3_restartnc="true" + local WW3_PIO_FORMAT="pnetcdf" + local WW3_PIO_IOTASKS=-99 + local WW3_PIO_STRIDE=4 + local WW3_PIO_REARR="box" + local WW3_PIO_ROOT=-99 + + fi + + if [[ "${cplchm}" = ".true." ]]; then + + local chm_model="gocart" + local chm_petlist_bounds="0 $((CHMPETS - 1))" + local chm_omp_num_threads="${CHMTHREADS}" + local coupling_interval_sec="${CPL_FAST}" + + fi + + #Set ESMF_THREADING variable for ufs configure + if [[ "${USE_ESMF_THREADING}" = "YES" ]]; then + local ESMF_THREADING="true" + else + local ESMF_THREADING="false" + fi + + # Ensure the template exists + if [[ ! -r "${ufs_configure_template}" ]]; then + echo "FATAL ERROR: template '${ufs_configure_template}' does not exist, ABORT!" + exit 1 + else + echo "INFO: using ufs.configure template: '${ufs_configure_template}'" + fi + + rm -f "${DATA}/ufs.configure" + atparse < "${ufs_configure_template}" >> "${DATA}/ufs.configure" + echo "Rendered ufs.configure:" + cat ufs.configure + + cpreq "${HOMEgfs}/sorc/ufs_model.fd/tests/parm/fd_ufs.yaml" fd_ufs.yaml + + echo "SUB ${FUNCNAME[0]}: ufs.configure ends" } diff --git a/ush/preamble.sh b/ush/preamble.sh index fab7d163a93..df24338ac83 100755 --- a/ush/preamble.sh +++ b/ush/preamble.sh @@ -33,8 +33,9 @@ declare -x PS4='+ $(basename ${BASH_SOURCE[0]:-${FUNCNAME[0]:-"Unknown"}})[${LIN set_strict() { if [[ ${STRICT:-"YES"} == "YES" ]]; then - # Exit on error and undefined variable - set -eu + # Exit on error or undefined variable + # TODO: Also error in a pipeline (e.g. if and command in "cmd | cmd2" fails) + set -eu # -o pipefail fi } @@ -79,7 +80,7 @@ postamble() { # if [[ -v 'POSTAMBLE_CMD' ]]; then - ${POSTAMBLE_CMD} + ${POSTAMBLE_CMD} fi # Calculate the elapsed time @@ -110,10 +111,10 @@ function err_exit() { msg1=${*:-Job ${jobid} failed} if [[ -n "${pgm}" ]]; then - msg1+=", ERROR IN ${pgm}" + msg1+=", ERROR IN ${pgm}" fi if [[ -n "${err}" ]]; then - msg1+=" RETURN CODE ${err}" + msg1+=" RETURN CODE ${err}" fi msg2=" @@ -133,38 +134,38 @@ function err_exit() { # list files in temporary working directory if [[ -n "${DATA}" ]]; then - >&2 echo "${DATA}" - >&2 ls -ltr "${DATA}" + >&2 echo "${DATA}" + >&2 ls -ltr "${DATA}" else - >&2 echo "WARNING: DATA variable not defined" + >&2 echo "WARNING: DATA variable not defined" fi # save standard output if [[ -n "${pgmout}" ]]; then - if [[ -s errfile ]]; then - echo "----- contents of errfile -----" >> "${pgmout}" - cat errfile >> "${pgmout}" - fi - >&2 cat "${pgmout}" + if [[ -s errfile ]]; then + echo "----- contents of errfile -----" >> "${pgmout}" + cat errfile >> "${pgmout}" + fi + >&2 cat "${pgmout}" elif [[ -s errfile ]]; then - >&2 cat errfile + >&2 cat errfile fi # Write to ecflow log: if [[ "${SENDECF}" == "YES" ]]; then - timeout 30 ecflow_client --msg "${ECF_NAME}: ${msg1}" - timeout 30 ssh "${ECF_HOST}" "echo \"${msg}2\" >> ${ECF_JOBOUT:?}" + timeout 30 ecflow_client --msg "${ECF_NAME}: ${msg1}" + timeout 30 ssh "${ECF_HOST}" "echo \"${msg}2\" >> ${ECF_JOBOUT:?}" fi # KILL THE JOB: if [[ "${SENDECF}" == "YES" ]]; then - ecflow_client --kill="${ECF_NAME:?}" + ecflow_client --kill="${ECF_NAME:?}" fi if [[ -n "${PBS_JOBID}" ]]; then - qdel "${PBS_JOBID}" + qdel "${PBS_JOBID}" elif [[ -n "${SLURM_JOB_ID}" ]]; then - scancel "${SLURM_JOB_ID}" + scancel "${SLURM_JOB_ID}" fi } @@ -177,6 +178,7 @@ trap "postamble ${_calling_script} ${start_time} \$?" EXIT source "${HOMEgfs}/ush/bash_utils.sh" # Turn on our settings +shopt -s nullglob # Allow null globs instead of treating * as literal export SHELLOPTS declare -xf set_strict declare -xf set_trace diff --git a/ush/prep_sfc_ice_blend.sh b/ush/prep_sfc_ice_blend.sh index a60adfeb91c..19a411312d3 100755 --- a/ush/prep_sfc_ice_blend.sh +++ b/ush/prep_sfc_ice_blend.sh @@ -66,13 +66,13 @@ pgmout=${pgmout:-"OUTPUT"} #------------------------------------------------------------------------ if [[ -f "${IMS_FILE}" ]]; then - cpfs "${IMS_FILE}" ./ims.grib2 - ${WGRIB2} ims.grib2 -match "ICEC" -grib ims.icec.grib2 - grid173="0 0 0 0 0 0 0 0 4320 2160 0 0 89958000 42000 48 -89958000 359958000 83000 83000 0" - ${COPYGB2} -x -i3 -g "${grid173}" ims.icec.grib2 ims.icec.5min.grib2 + cpfs "${IMS_FILE}" ./ims.grib2 + ${WGRIB2} ims.grib2 -match "ICEC" -grib ims.icec.grib2 + grid173="0 0 0 0 0 0 0 0 4320 2160 0 0 89958000 42000 48 -89958000 359958000 83000 83000 0" + ${COPYGB2} -x -i3 -g "${grid173}" ims.icec.grib2 ims.icec.5min.grib2 else - echo "WARNING: IMS ${IMS_FILE} ice data missing. Can not run program ${pgm}." - exit 3 + echo "WARNING: IMS ${IMS_FILE} ice data missing. Can not run program ${pgm}." + exit 3 fi #------------------------------------------------------------------------ @@ -80,10 +80,9 @@ fi # Copy old blended data to current directory. #------------------------------------------------------------------------ -if [[ ! -f "${FIVE_MIN_ICE_FILE}" ]] -then - echo "WARNING: ${FIVE_MIN_ICE_FILE} data missing. Can not run program ${pgm}." - exit 5 +if [[ ! -f "${FIVE_MIN_ICE_FILE}" ]]; then + echo "WARNING: ${FIVE_MIN_ICE_FILE} data missing. Can not run program ${pgm}." + exit 5 fi #------------------------------------------------------------------------ @@ -118,16 +117,16 @@ export err=$? #------------------------------------------------------------------------ if [[ "${err}" -ne 0 ]]; then - echo "WARNING: ${pgm} completed abnormally. The old ice blend file will be used." - # Exit but do not call err_exit. Calling script will handle use of older file - exit "${err}" + echo "WARNING: ${pgm} completed abnormally. The old ice blend file will be used." + # Exit but do not call err_exit. Calling script will handle use of older file + exit "${err}" else - ${WGRIB2} -set_int 3 51 42000 "${BLENDED_ICE_FILE}" -grib "${BLENDED_ICE_FILE}.corner" - ${CNVGRIB} -g21 "${BLENDED_ICE_FILE}.corner" "${BLENDED_ICE_FILE}.bitmap" - rm -f "${BLENDED_ICE_FILE}" - ${COPYGB} -M "#1.57" -x "${BLENDED_ICE_FILE}.bitmap" "${BLENDED_ICE_FILE}" - cpfs "${BLENDED_ICE_FILE}" "${COMOUT_OBS}" - rm -f "${BLENDED_ICE_FILE}.corner" "${BLENDED_ICE_FILE}.bitmap" + ${WGRIB2} -set_int 3 51 42000 "${BLENDED_ICE_FILE}" -grib "${BLENDED_ICE_FILE}.corner" + ${CNVGRIB} -g21 "${BLENDED_ICE_FILE}.corner" "${BLENDED_ICE_FILE}.bitmap" + rm -f "${BLENDED_ICE_FILE}" + ${COPYGB} -M "#1.57" -x "${BLENDED_ICE_FILE}.bitmap" "${BLENDED_ICE_FILE}" + cpfs "${BLENDED_ICE_FILE}" "${COMOUT_OBS}" + rm -f "${BLENDED_ICE_FILE}.corner" "${BLENDED_ICE_FILE}.bitmap" fi exit 0 diff --git a/ush/prep_sfc_snow.sh b/ush/prep_sfc_snow.sh index 0e017011005..edd523abc17 100755 --- a/ush/prep_sfc_snow.sh +++ b/ush/prep_sfc_snow.sh @@ -44,7 +44,7 @@ # ######################################################################### -source "${USHgfs}/atparse.bash" # include function atparse for parsing @[XYZ] templated files +source "${USHgfs}/atparse.bash" # include function atparse for parsing @[XYZ] templated files #------------------------------------------------------------------------ # The snow2mdl executable and namelist @@ -84,7 +84,7 @@ CLIMO_QC=${CLIMO_QC:-"${FIXgfs}/am/emcsfc_snow_cover_climo.grib2"} #------------------------------------------------------------------------ MODEL_SNOW_FILE=${MODEL_SNOW_FILE:-"snogrb_model"} -OUTPUT_GRIB2=${OUTPUT_GRIB2:-".false."} # grib 1 when false. +OUTPUT_GRIB2=${OUTPUT_GRIB2:-".false."} # grib 1 when false. #------------------------------------------------------------------------ # Do a quick check of the ims data to ensure it exists and is not corrupt. @@ -92,10 +92,10 @@ OUTPUT_GRIB2=${OUTPUT_GRIB2:-".false."} # grib 1 when false. #------------------------------------------------------------------------ if [[ -f ${IMS_FILE} ]]; then - cpreq "${IMS_FILE}" "${DATA}/imssnow96.grib2" + cpreq "${IMS_FILE}" "${DATA}/imssnow96.grib2" else - echo "WARNING: Missing IMS data. Will not run ${SNOW2MDLEXEC}." - exit 7 + echo "WARNING: Missing IMS data. Will not run ${SNOW2MDLEXEC}." + exit 7 fi #------------------------------------------------------------------------ @@ -106,11 +106,11 @@ fi ${WGRIB2} -d 1 "imssnow96.grib2" err=$? if [[ ${err} -ne 0 ]]; then - echo "WARNING: Corrupt IMS data. Will not run ${SNOW2MDLEXEC}." - exit 9 + echo "WARNING: Corrupt IMS data. Will not run ${SNOW2MDLEXEC}." + exit 9 else - tempdate=$(${WGRIB2} -t "imssnow96.grib2" | head -1) || true - IMSDATE=${tempdate#*d=} + tempdate=$(${WGRIB2} -t "imssnow96.grib2" | head -1) || true + IMSDATE=${tempdate#*d=} fi #------------------------------------------------------------------------ @@ -119,24 +119,24 @@ fi #------------------------------------------------------------------------ if [[ ! -f ${AFWA_GLOBAL_FILE} ]]; then - echo "WARNING: Missing AFWS data. Will not run ${SNOW2MDLEXEC}." - exit 3 + echo "WARNING: Missing AFWS data. Will not run ${SNOW2MDLEXEC}." + exit 3 else - cpreq "${AFWA_GLOBAL_FILE}" "${DATA}/snow.usaf.grib2" - ${WGRIB2} -d 1 "snow.usaf.grib2" - err=$? - if [[ ${err} -ne 0 ]]; then - echo "WARNING: Corrupt AFWS data. Will not run ${SNOW2MDLEXEC}." - exit "${err}" - else - tempdate=$(${WGRIB2} -d 1 -t "snow.usaf.grib2") - AFWADATE=${tempdate#*d=} - two_days_ago=$(date --utc -d "${IMSDATE:0:8} ${IMSDATE:8:2} - 48 hours" +%Y%m%d%H) - if [[ ${AFWADATE} -lt ${two_days_ago} ]]; then - echo "WARNING: Found old AFWA data. Will not run ${SNOW2MDLEXEC}." - exit 4 + cpreq "${AFWA_GLOBAL_FILE}" "${DATA}/snow.usaf.grib2" + ${WGRIB2} -d 1 "snow.usaf.grib2" + err=$? + if [[ ${err} -ne 0 ]]; then + echo "WARNING: Corrupt AFWS data. Will not run ${SNOW2MDLEXEC}." + exit "${err}" + else + tempdate=$(${WGRIB2} -d 1 -t "snow.usaf.grib2") + AFWADATE=${tempdate#*d=} + two_days_ago=$(date --utc -d "${IMSDATE:0:8} ${IMSDATE:8:2} - 48 hours" +%Y%m%d%H) + if [[ ${AFWADATE} -lt ${two_days_ago} ]]; then + echo "WARNING: Found old AFWA data. Will not run ${SNOW2MDLEXEC}." + exit 4 + fi fi - fi fi #------------------------------------------------------------------------ @@ -145,12 +145,12 @@ fi export IMSYEAR=${IMSDATE:0:4} export IMSMONTH=${IMSDATE:4:2} export IMSDAY=${IMSDATE:6:2} -export IMSHOUR=0 # emc convention is to use 00Z. +export IMSHOUR=0 # emc convention is to use 00Z. # Render the namelist template if [[ ! -f "${SNOW2MDLNMLTMPL}" ]]; then - echo "FATAL ERROR: template '${SNOW2MDLNMLTMPL}' does not exist, ABORT!" - exit 1 + echo "FATAL ERROR: template '${SNOW2MDLNMLTMPL}' does not exist, ABORT!" + exit 1 fi rm -f ./fort.41 atparse < "${SNOW2MDLNMLTMPL}" >> "./fort.41" @@ -166,12 +166,12 @@ source prep_step err=$? if [[ ${err} -ne 0 ]]; then - echo "WARNING: ${pgm} completed abnormally." - exit "${err}" + echo "WARNING: ${pgm} completed abnormally." + exit "${err}" else - echo "${pgm} completed normally." - cpfs "${MODEL_SNOW_FILE}" "${COMOUT_OBS}" - rm -f "${MODEL_SNOW_FILE}" + echo "${pgm} completed normally." + cpfs "${MODEL_SNOW_FILE}" "${COMOUT_OBS}" + rm -f "${MODEL_SNOW_FILE}" fi rm -f ./fort.41 diff --git a/ush/product_functions.sh b/ush/product_functions.sh index 05b23fbee2b..300bf003927 100755 --- a/ush/product_functions.sh +++ b/ush/product_functions.sh @@ -1,40 +1,40 @@ #! /usr/bin/env bash function trim_rh() { - # trim RH values larger than 100. - local filename=$1 - ${WGRIB2} "${filename}" \ + # trim RH values larger than 100. + local filename=$1 + ${WGRIB2} "${filename}" \ -not_if ':RH:' -grib "${filename}.new" \ -if ':RH:' -rpn "10:*:0.5:+:floor:1000:min:10:/" -set_grib_type same \ -set_scaling -1 0 -grib_out "${filename}.new" - rc=$? - if (( rc == 0 )); then mv "${filename}.new" "${filename}"; fi - return "${rc}" + rc=$? + if ((rc == 0)); then mv "${filename}.new" "${filename}"; fi + return "${rc}" } function mod_icec() { - # modify icec based on land-sea mask - local filename=$1 - ${WGRIB2} "${filename}" \ - -if 'LAND' -rpn 'sto_1' -fi \ - -if 'ICEC' -rpn 'rcl_1:0:==:*' -fi \ - -set_grib_type same \ - -set_scaling same same \ - -grib_out "${filename}.new" - rc=$? - if (( rc == 0 )); then mv "${filename}.new" "${filename}"; fi - return "${rc}" + # modify icec based on land-sea mask + local filename=$1 + ${WGRIB2} "${filename}" \ + -if 'LAND' -rpn 'sto_1' -fi \ + -if 'ICEC' -rpn 'rcl_1:0:==:*' -fi \ + -set_grib_type same \ + -set_scaling same same \ + -grib_out "${filename}.new" + rc=$? + if ((rc == 0)); then mv "${filename}.new" "${filename}"; fi + return "${rc}" } function scale_dec() { - # change the scaling for temperature, precipitable water, and water-equivalent accumlated snow depth - local filename=$1 - ${WGRIB2} "${filename}" -not_if ':(TMP|PWAT|WEASD):' -grib "${filename}.new" \ - -if ':(TMP|PWAT):' -set_grib_type same \ - -set_scaling -1 0 -grib_out "${filename}.new" \ - -if ':(WEASD):' -set_grib_type same \ - -set_scaling 0 0 -grib_out "${filename}.new" - rc=$? - if (( rc == 0 )); then mv "${filename}.new" "${filename}"; fi - return "${rc}" + # change the scaling for temperature, precipitable water, and water-equivalent accumlated snow depth + local filename=$1 + ${WGRIB2} "${filename}" -not_if ':(TMP|PWAT|WEASD):' -grib "${filename}.new" \ + -if ':(TMP|PWAT):' -set_grib_type same \ + -set_scaling -1 0 -grib_out "${filename}.new" \ + -if ':(WEASD):' -set_grib_type same \ + -set_scaling 0 0 -grib_out "${filename}.new" + rc=$? + if ((rc == 0)); then mv "${filename}.new" "${filename}"; fi + return "${rc}" } diff --git a/ush/python/pygfs/task/aero_prepobs.py b/ush/python/pygfs/task/aero_prepobs.py deleted file mode 100644 index a992ada4111..00000000000 --- a/ush/python/pygfs/task/aero_prepobs.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env python3 - -import os -import glob -import gzip -import tarfile -import re -from logging import getLogger -from typing import List, Dict, Any, Union - -from wxflow import (AttrDict, FileHandler, rm_p, rmdir, - Task, add_to_datetime, to_timedelta, to_datetime, - datetime_to_YMD, - chdir, Executable, WorkflowException, - parse_j2yaml, save_as_yaml, logit) - -logger = getLogger(__name__.split('.')[-1]) - - -class AerosolObsPrep(Task): - """ - Class for preparing and managing aerosol observations - """ - def __init__(self, config: Dict[str, Any]) -> None: - super().__init__(config) - - _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': _window_begin, - 'window_end': _window_end, - 'sensors': self.task_config['SENSORS'], - 'data_dir': self.task_config['VIIRS_DATA_DIR'], - 'input_files': '', - 'OPREFIX': f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.", - 'APREFIX': f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z." - } - ) - - # task_config is everything that this task should need - self.task_config = AttrDict(**self.task_config, **local_dict) - - @logit(logger) - def initialize(self) -> None: - """ - List needed raw obs files. - Copy the raw obs files to $DATA/obs. - Link over the needed executable. - Generate corresponding YAML file. - Run IODA converter. - """ - self.task_config.DATA_OBS = os.path.join(self.task_config.DATA, 'obs') - if os.path.exists(self.task_config.DATA_OBS): - rmdir(self.task_config.DATA_OBS) - FileHandler({'mkdir': [self.task_config.DATA_OBS]}).sync() - - self.task_config.prepaero_yaml = [] - for sensor in self.task_config.sensors: - raw_files = self.list_raw_files(sensor) - self.task_config.input_files = self.copy_obs(raw_files) - self.link_obsconvexe() - self.task_config.prepaero_config = self.get_obsproc_config(sensor) - - # generate converter YAML file - template = f"{self.task_config.RUN}.t{self.task_config['cyc']:02d}z.prepaero_viirs_{sensor}.yaml" - _prepaero_yaml = os.path.join(self.task_config.DATA, template) - self.task_config.prepaero_yaml.append(_prepaero_yaml) - logger.debug(f"Generate PrepAeroObs YAML file: {_prepaero_yaml}") - save_as_yaml(self.task_config.prepaero_config, _prepaero_yaml) - logger.info(f"Wrote PrepAeroObs YAML to: {_prepaero_yaml}") - - @logit(logger) - def list_raw_files(self, sensor) -> List[str]: - """ - List all files in the predefined directory that match the predefined sensor and within the time window. - """ - if sensor == 'n20': - sensor = 'j01' - dir1 = os.path.join(self.task_config.data_dir, datetime_to_YMD(self.task_config.window_begin)) - dir2 = os.path.join(self.task_config.data_dir, datetime_to_YMD(self.task_config.window_end)) - - if dir1 == dir2: - files = os.listdir(dir1) - allfiles = [os.path.join(dir1, file) for file in files] - allfiles.sort() - else: - files_1 = os.listdir(dir1) - allfiles_1 = [os.path.join(dir1, file) for file in files_1] - files_2 = os.listdir(dir2) - allfiles_2 = [os.path.join(dir2, file) for file in files_2] - allfiles = sorted(allfiles_1, allfiles_2) - matching_files = [] - try: - for file in allfiles: - basename = os.path.basename(file) - pattern = r"s(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{3})" - match = re.match(pattern, basename.split('_')[3]) - yyyy, mm, dd, HH, MM = match.group(1), match.group(2), match.group(3), match.group(4), match.group(5) - fstart = to_datetime(f'{yyyy}-{mm}-{dd}T{HH}:{MM}Z') - if sensor == basename.split('_')[2]: - # temporally select obs files based on time stamp in the filename. - if (fstart > self.task_config.window_begin) and (fstart < self.task_config.window_end): - matching_files.append(os.path.join(self.task_config.data_dir, file)) - logger.info("Found %d matching files.", len(matching_files)) - except FileNotFoundError: - logger.error("The specified file/directory does not exist.") - raise - return matching_files - - @logit(logger) - def copy_obs(self, inputfiles) -> Dict[str, Any]: - """ - Copy the raw obs files to $DATA/obs. - """ - copylist = [] - destlist = [] - for filename in inputfiles: - basename = os.path.basename(filename) - dest = os.path.join(self.task_config.DATA_OBS, basename) - copylist.append([filename, dest]) - destlist.append(dest) - FileHandler({'copy': copylist}).sync() - - return destlist - - @logit(logger) - def get_obsproc_config(self, sensor) -> Dict[str, Any]: - """ - Compile a dictionary of obs proc configuration from OBSPROCYAML template file - Parameters - ---------- - Returns - ---------- - obsproc_config : Dict - a dictionary containing the fully rendered obs proc yaml configuration - """ - self.task_config.sensor = sensor - # generate JEDI YAML file - logger.info(f"Generate gdas_obsprovider2ioda YAML config: {self.task_config.OBSPROCYAML}") - prepaero_config = parse_j2yaml(self.task_config.OBSPROCYAML, self.task_config) - - return prepaero_config - - @logit(logger) - def link_obsconvexe(self) -> None: - """ - This method links the gdas executable to the run directory - Parameters - ---------- - Task: GDAS task - Returns - ---------- - None - """ - exe_src = self.task_config.OBSPROCEXE - - logger.info(f"Link executable {exe_src} to DATA/") - exe_dest = os.path.join(self.task_config.DATA, os.path.basename(exe_src)) - if os.path.exists(exe_dest): - rm_p(exe_dest) - os.symlink(exe_src, exe_dest) - - return - - @logit(logger) - def runConverter(self) -> None: - """ - Run the IODA converter gdas_obsprovider2ioda.x - """ - chdir(self.task_config.DATA) - exec_cmd = Executable(self.task_config.APRUN_PREPOBSAERO) - exec_name = os.path.join(self.task_config.DATA, 'gdas_obsprovider2ioda.x') - exec_cmd.add_default_arg(exec_name) - - for prepaero_yaml in self.task_config.prepaero_yaml: - try: - logger.debug(f"Executing {exec_cmd} on {prepaero_yaml}") - exec_cmd(f"{prepaero_yaml}") - except OSError: - raise OSError(f"Failed to execute {exec_cmd} on {prepaero_yaml}") - except Exception: - raise WorkflowException(f"An error occured during execution of {exec_cmd} on {prepaero_yaml}") - - pass - - @logit(logger) - def finalize(self) -> None: - """ - Copy the output viirs files to COMOUT_OBS. - Tar and archive the output files. - Tar and archive the raw obs files. - """ - # get list of viirs files - obsfiles = glob.glob(os.path.join(self.task_config['DATA'], '*viirs*nc4')) - copylist = [] - for obsfile in obsfiles: - basename = os.path.basename(obsfile) - src = os.path.join(self.task_config['DATA'], basename) - dest = os.path.join(self.task_config.COMOUT_OBS, basename) - copylist.append([src, dest]) - FileHandler({'copy': copylist}).sync() - - # gzip the files first - for obsfile in obsfiles: - with open(obsfile, 'rb') as f_in, gzip.open(f"{obsfile}.gz", 'wb') as f_out: - f_out.writelines(f_in) - - aeroobs = os.path.join(self.task_config.COMOUT_OBS, f"{self.task_config['APREFIX']}aeroobs") - # open tar file for writing - with tarfile.open(aeroobs, "w") as archive: - for obsfile in obsfiles: - aeroobsgzip = f"{obsfile}.gz" - archive.add(aeroobsgzip, arcname=os.path.basename(aeroobsgzip)) - # get list of raw viirs L2 files - rawfiles = glob.glob(os.path.join(self.task_config.DATA_OBS, 'JRR-AOD*')) - # gzip the raw L2 files first - for rawfile in rawfiles: - with open(rawfile, 'rb') as f_in, gzip.open(f"{rawfile}.gz", 'wb') as f_out: - f_out.writelines(f_in) - - aerorawobs = os.path.join(self.task_config.COMOUT_OBS, f"{self.task_config['APREFIX']}aerorawobs") - # open tar file for writing - with tarfile.open(aerorawobs, "w") as archive: - for rawfile in rawfiles: - aerorawobsgzip = f"{rawfile}.gz" - archive.add(aerorawobsgzip, arcname=os.path.basename(aerorawobsgzip)) - copylist = [] - for prepaero_yaml in self.task_config.prepaero_yaml: - basename = os.path.basename(prepaero_yaml) - dest = os.path.join(self.task_config.COMOUT_OBS, basename) - copylist.append([prepaero_yaml, dest]) - FileHandler({'copy': copylist}).sync() - - pass - - @logit(logger) - def syncObs(self) -> None: - """Create COMOUT_OBS and sync relevant obs from DMPDIR to COMOUT_OBS""" - # get list of files to copy - obslist = [] - obsin_list = glob.glob(os.path.join(self.task_config.COMIN_OBSPROC, '*aod*')) - for ob in obsin_list: - # replace gdas with gcdas in the dest - obslist.append([ob, - os.path.join(self.task_config.COMOUT_OBS, - os.path.basename(ob).replace('gdas', 'gcdas'))]) - # create output directory and copy files - FileHandler({'mkdir': [self.task_config.COMOUT_OBS], 'copy': obslist}).sync() diff --git a/ush/python/pygfs/task/archive.py b/ush/python/pygfs/task/archive.py index d6a60364041..389075472e2 100644 --- a/ush/python/pygfs/task/archive.py +++ b/ush/python/pygfs/task/archive.py @@ -72,7 +72,11 @@ def configure_vrfy(self, arch_dict: Dict[str, Any]) -> (Dict[str, Any]): archive_parm = os.path.join(arch_dict.PARMgfs, "archive") # Collect the dataset to archive locally - arcdir_j2yaml = os.path.join(archive_parm, f"{arch_dict.NET}_arcdir.yaml.j2") + # Select template based on RUN type: ensemble (enkf) or deterministic (NET) + if "enkf" in arch_dict.RUN: + arcdir_j2yaml = os.path.join(archive_parm, "enkf_arcdir.yaml.j2") + else: + arcdir_j2yaml = os.path.join(archive_parm, f"{arch_dict.NET}_arcdir.yaml.j2") # Add the glob.glob function for capturing log filenames arch_dict['glob'] = glob.glob diff --git a/ush/python/pygfs/task/atm_analysis.py b/ush/python/pygfs/task/atm_analysis.py index 75abf124e34..13d1069b620 100644 --- a/ush/python/pygfs/task/atm_analysis.py +++ b/ush/python/pygfs/task/atm_analysis.py @@ -35,6 +35,7 @@ def __init__(self, config: Dict[str, Any]): _res = int(self.task_config.CASE[1:]) _res_anl = int(self.task_config.CASE_ANL[1:]) + _res_his = int(self.task_config.CASE_HIST[1:]) if self.task_config.DOHYBVAR: _BERROR_YAML = f"atmosphere_background_error_hybrid_{self.task_config.STATICB_TYPE}_{self.task_config.LOCALIZATION_TYPE}" @@ -50,6 +51,9 @@ def __init__(self, config: Dict[str, Any]): 'npx_anl': _res_anl + 1, 'npy_anl': _res_anl + 1, 'npz_anl': self.task_config.LEVS - 1, + 'npx_his': _res_his + 1, + 'npy_his': _res_his + 1, + 'npz_his': self.task_config.LEVS - 1, 'npz': self.task_config.LEVS - 1, 'BKG_TSTEP': "PT1H", # Placeholder for 4D applications 'BERROR_YAML': _BERROR_YAML, diff --git a/ush/python/pygfs/task/fetch.py b/ush/python/pygfs/task/fetch.py index 5a3b0d09460..cedebc9abaa 100755 --- a/ush/python/pygfs/task/fetch.py +++ b/ush/python/pygfs/task/fetch.py @@ -3,6 +3,7 @@ import os from logging import getLogger from typing import Any, Dict +import tarfile from wxflow import (Task, htar, logit, parse_j2yaml, chdir) @@ -85,12 +86,10 @@ def execute_pull_data(self, fetchdir_set: Dict[str, Any]) -> None: if on_hpss is True: # htar all files in fnames htar_obj = htar.Htar() htar_obj.xvf(tarball, f_names) - else: # tar all files in fnames - raise NotImplementedError("The fetch job does not yet support pulling from local archives") - -# with tarfile.open(dest, "w") as tar: -# for filename in f_names: -# tar.add(filename) + else: # extract from a specified tarball + with tarfile.open(tarball, "r") as tar: + members = [m for m in tar.getmembers() if m.name in f_names] + tar.extractall(members=members) # Verify all data files were extracted missing_files = [] for f in f_names: diff --git a/ush/python/pygfs/task/oceanice_products.py b/ush/python/pygfs/task/oceanice_products.py index d319608ad14..775d13e07f9 100644 --- a/ush/python/pygfs/task/oceanice_products.py +++ b/ush/python/pygfs/task/oceanice_products.py @@ -170,11 +170,13 @@ def execute(config: Dict, product_grid: str) -> None: None """ - # Run the ocnicepost.x executable - OceanIceProducts.interp(config.DATA, config.APRUN_OCNICEPOST, exec_name="ocnicepost.x") + # Run the ocnicepost.x executable if interpolated variables are wanted + if config.oceanice_yaml.ocnicepost.namelist.write_netcdf or config.oceanice_yaml.ocnicepost.namelist.write_grib2: + OceanIceProducts.interp(config.DATA, config.APRUN_OCNICEPOST, exec_name="ocnicepost.x") - # Index the interpolated grib2 file - OceanIceProducts.index(config, product_grid) + if config.oceanice_yaml.ocnicepost.namelist.write_grib2: + # Index the interpolated grib2 file + OceanIceProducts.index(config, product_grid) @staticmethod @logit(logger) @@ -274,22 +276,40 @@ def subset(config: Dict) -> None: input_file = f"{config.component}.nc" output_file = f"{config.component}_subset.nc" - varlist = config.oceanice_yaml[config.component].subset + + varlist = config.oceanice_yaml[config.component].subset.variables logger.info(f"Subsetting {varlist} from {input_file} to {output_file}") try: # open the netcdf file ds = xr.open_dataset(input_file) - - # subset the variables - ds_subset = ds[varlist] + if config.component == 'ice': + # subset the variables + ds_subset = ds[varlist] + # remove coords that were carried from original file but not used + ds_subset = ds_subset.drop_vars('ELON', errors='ignore') + ds_subset = ds_subset.drop_vars('ELAT', errors='ignore') + ds_subset = ds_subset.drop_vars('NLON', errors='ignore') + ds_subset = ds_subset.drop_vars('NLAT', errors='ignore') + + if config.component == 'ocean': + # subset ocean variables for z_levels in products + levels = config.oceanice_yaml.ocean.namelist.ocean_levels + ds_subset = ds[varlist].sel(z_l=levels) # save global attributes from the old netcdf file into new netcdf file ds_subset.attrs = ds.attrs - # save subsetted variables to a new netcdf file - ds_subset.to_netcdf(output_file) + # save subsetted variables to a new netcdf file and compress + if config.oceanice_yaml[config.component].subset.compress: + compress_with = config.oceanice_yaml[config.component].subset.compress_with + compress_level = config.oceanice_yaml[config.component].subset.compress_level + default_compression = {compress_with: True, "complevel": int(compress_level)} + compress_encoding = {var_name: default_compression for var_name in ds_subset.data_vars} + ds_subset.to_netcdf(output_file, encoding=compress_encoding) + else: + ds_subset.to_netcdf(output_file) except FileNotFoundError: logger.exception(f"FATAL ERROR: Input file not found: {input_file}") @@ -326,6 +346,5 @@ def finalize(config: Dict) -> None: # Copy "component" specific generated data to COM/ directory data_out = config.oceanice_yaml[config.component].data_out - logger.info(f"Copy processed data to COM/ directory") FileHandler(data_out).sync() diff --git a/ush/python/pygfs/task/stage_ic.py b/ush/python/pygfs/task/stage_ic.py index d1e95b8d120..873d4346593 100644 --- a/ush/python/pygfs/task/stage_ic.py +++ b/ush/python/pygfs/task/stage_ic.py @@ -1,58 +1,509 @@ #!/usr/bin/env python3 +""" +Stage Initial Conditions (IC) Task +Overview +-------- +This module constructs cycle and member-specific COM directory path variables +required for initial conditions for the Stage IC task. +""" import os from logging import getLogger -from typing import Any, Dict - -from wxflow import FileHandler, Task, logit, parse_j2yaml +from typing import Any, Dict, Tuple, Optional +from wxflow import FileHandler, Task, logit, parse_j2yaml, AttrDict, to_YMD, to_fv3time, add_to_datetime, to_timedelta logger = getLogger(__name__.split('.')[-1]) class Stage(Task): - """Task to stage initial conditions - """ + """Task to stage initial conditions""" @logit(logger, name="Stage") def __init__(self, config: Dict[str, Any]) -> None: """Constructor for the Stage task - The constructor is responsible for collecting necessary settings based on - the runtime options and RUN. Parameters ---------- config : Dict[str, Any] Incoming configuration for the task from the environment + """ + super().__init__(config) + + @logit(logger) + def _copy_base_config(self) -> Dict[str, Any]: + """Copy essential base configuration from task_config Returns ------- - None + Dict[str, Any] + Dictionary with base configuration values """ - super().__init__(config) + base_keys = [ + 'RUN', 'MODE', 'EXP_WARM_START', 'NMEM_ENS', + 'assim_freq', 'current_cycle', 'previous_cycle', + 'ROTDIR', 'ICSDIR', 'STAGE_IC_YAML_TMPL', 'DO_JEDIATMVAR', + 'OCNRES', 'waveGRD', 'ntiles', 'DOIAU', 'ATMINC_GRID', + 'DO_JEDIOCNVAR', 'DO_STARTMEM_FROM_JEDIICE', + 'DO_WAVE', 'DO_OCN', 'DO_ICE', 'DO_NEST', 'DO_CA', 'DO_AERO_ANL', + 'USE_ATM_ENS_PERTURB_FILES', 'USE_OCN_ENS_PERTURB_FILES', 'DO_GSISOILDA', 'DO_LAND_IAU' + ] + + if self.task_config.get('NET') == 'gfs': + base_keys.append('DOIAU_ENKF') + + return {key: self.task_config[key] for key in base_keys if key in self.task_config} @logit(logger) - def execute_stage(self, stage_dict: Dict[str, Any]) -> None: - """Perform local staging of initial condition files. + def _get_config_vars(self) -> Dict[str, Any]: + """Calculate derived configuration variables + + Returns + ------- + Dict[str, Any] + Dictionary with derived configuration values (rRUN, OCNRES, START_ICE_FROM_ANA) + """ + config_vars = {} + + # Determine rRUN + # For GFS/GCAFS/GCDAS, always use 'gdas' for initial conditions from previous cycles + # TODO: Update when GCDAS/GCAFS-specific ICs become available + config_vars['rRUN'] = "gdas" if self.task_config.RUN in ['gfs', 'gcafs', 'gcdas'] else self.task_config.RUN + + # OCNRES formatting + if "OCNRES" in self.task_config: + config_vars['OCNRES'] = f"{int(self.task_config.OCNRES):03d}" + + # START_ICE_FROM_ANA logic + if self.task_config.get("DO_ICE", False): + config_vars['START_ICE_FROM_ANA'] = False + if self.task_config.get("DO_JEDIOCNVAR", False) and self.task_config.RUN == "gdas": + config_vars['START_ICE_FROM_ANA'] = True + if self.task_config.get("DO_STARTMEM_FROM_JEDIICE", False) and self.task_config.RUN == "enkfgdas": + config_vars['START_ICE_FROM_ANA'] = True + + return config_vars + + @logit(logger) + def _get_cycle_vars(self) -> Dict[str, Any]: + """Calculate current and previous cycle variables + + Returns + ------- + Dict[str, Any] + Dictionary with current and previous cycle variables including half_window + """ + cycle_vars = {} + half_window = self.task_config.assim_freq // 2 + cycle_vars['half_window'] = half_window + + # Current cycle variables + cycle_vars['current_cycle_HH'] = self.task_config.current_cycle.strftime("%H") + cycle_vars['current_cycle_YMD'] = to_YMD(self.task_config.current_cycle) + + if self.task_config.DOIAU and self.task_config.MODE == "cycled": + cycle_vars['model_start_date_current_cycle'] = add_to_datetime(self.task_config.current_cycle, to_timedelta(f"-{half_window}H")) + else: + if self.task_config.get('REPLAY_ICS', False): + cycle_vars['model_start_date_current_cycle'] = add_to_datetime(self.task_config.current_cycle, to_timedelta(f"{half_window}H")) + else: + cycle_vars['model_start_date_current_cycle'] = self.task_config.current_cycle + + cycle_vars['m_prefix'] = to_fv3time(cycle_vars['model_start_date_current_cycle']) + + # Previous cycle variables + previous_cycle_HH = self.task_config.previous_cycle.strftime("%H") + cycle_vars['m_index'] = self.task_config.current_cycle.hour // self.task_config.assim_freq + cycle_vars['p_prefix'] = to_fv3time(self.task_config.previous_cycle) + cycle_vars['previous_cycle_HH'] = previous_cycle_HH + cycle_vars['previous_cycle_YMD'] = to_YMD(self.task_config.previous_cycle) + cycle_vars['mid_cyc'] = int(previous_cycle_HH) + int(half_window) + + return cycle_vars + + @logit(logger) + def _create_cycle_dicts(self, rotdir: str, run: str) -> Dict[str, Dict[str, str]]: + """Create cycle directories for template substitution Parameters ---------- - stage_dict : Dict[str, Any] - Configuration dictionary + rotdir : str + ROTDIR path + run : str + RUN type + + Returns + ------- + Dict[str, Dict[str, str]] + Dictionary containing current_cycle_dict and previous_cycle_dict + """ + return { + 'current_cycle_dict': { + "${ROTDIR}": rotdir, + "${RUN}": run, + "${YMD}": to_YMD(self.task_config.current_cycle), + "${HH}": self.task_config.current_cycle.strftime("%H"), + }, + 'previous_cycle_dict': { + "${ROTDIR}": rotdir, + "${RUN}": run, + "${YMD}": to_YMD(self.task_config.previous_cycle), + "${HH}": self.task_config.previous_cycle.strftime("%H"), + } + } + + @logit(logger) + def _copy_com_templates(self) -> Dict[str, str]: + """Copy COM templates from task_config Returns ------- - None + Dict[str, str] + Dictionary with COM template paths """ + return {key: self.task_config[key] for key in self.task_config.keys() + if key.startswith('COM_') and key.endswith('_TMPL')} + + @logit(logger) + def create_stage_dict(self) -> AttrDict: + """Create staging dictionary with all necessary variables for YAML templates + + Returns + ------- + AttrDict + Dictionary containing all variables needed for staging YAML templates + """ + stage_dict = AttrDict() + + # Copy essential base configuration + stage_dict.update(self._copy_base_config()) + + # Calculate derived configuration + stage_dict.update(self._get_config_vars()) + + # Calculate current and previous cycle variables + stage_dict.update(self._get_cycle_vars()) + + # Create cycle directories for template substitution + stage_dict.update(self._create_cycle_dicts(stage_dict.ROTDIR, stage_dict.RUN)) + + # Copy COM templates + stage_dict.update(self._copy_com_templates()) + + # Add GEFSTYPE if available (for GEFS runs) + if 'GEFSTYPE' in self.task_config: + stage_dict['GEFSTYPE'] = self.task_config.GEFSTYPE + + # Calculate member list based on RUN type + stage_dict['member_list'] = self.get_member_list( + stage_dict.RUN, + stage_dict.NMEM_ENS, + m_index=stage_dict.get('m_index', 0), + gefstype=stage_dict.get('GEFSTYPE', None) + ) + + # Add os.path.exists function for template use + stage_dict['path_exists'] = os.path.exists + return stage_dict + + @logit(logger) + def execute_stage(self, stage_dict: AttrDict) -> None: + """Perform local staging of initial condition files + + Parameters + ---------- + stage_dict : AttrDict + Configuration dictionary with all necessary staging variables + """ if not os.path.isdir(stage_dict.ROTDIR): raise FileNotFoundError(f"FATAL ERROR: The ROTDIR ({stage_dict.ROTDIR}) does not exist!") - # Add the os.path.exists function to the dict for yaml parsing - stage_dict['path_exists'] = os.path.exists + stage_set = parse_j2yaml(stage_dict.STAGE_IC_YAML_TMPL, stage_dict, allow_missing=False) # Parse staging yaml to get list of files to stage stage_set = parse_j2yaml(self.task_config.STAGE_IC_YAML_TMPL, stage_dict, allow_missing=False) + logger.info(stage_set) + + # Write stage_set to a file in DATA for debugging + stage_yaml = f"./stage{stage_dict.member:03}.yaml" + stage_set.save(stage_yaml) + logger.debug(f"Staging yaml written to '{stage_yaml}' for debugging purposes.") # stage files to ROTDIR for key in stage_set.keys(): FileHandler(stage_set[key]).sync() + + @staticmethod + @logit(logger) + def get_member_com_paths(stage_dict: AttrDict, member: int) -> Dict[str, Any]: + """Get member-specific COM paths based on RUN type + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + member : int + Member directory number + + Returns + ------- + Dict[str, Any] + Dictionary of member-specific COM paths + + Raises + ------ + ValueError + If RUN type is unknown or GEFSTYPE is invalid for GEFS runs + """ + + if stage_dict.RUN == 'gefs': + gefstype = stage_dict.get('GEFSTYPE', None) + if gefstype == 'gefs-real-time': + com_path = Stage._get_member_com_paths_gefs_rt(stage_dict, member) + elif gefstype == 'gefs-offline': + com_path = Stage._get_member_com_paths_gefs_offline(stage_dict, member) + else: + raise ValueError(f"Invalid GEFSTYPE '{gefstype}' for RUN 'gefs'.") + elif stage_dict.RUN == 'sfs': + com_path = Stage._get_member_com_paths_gefs_offline(stage_dict, member) + elif stage_dict.RUN in ('gcafs', 'enkfgdas', 'gcdas', 'gdas'): + com_path = Stage._get_member_com_paths_gcafs(stage_dict, member) + elif stage_dict.RUN == 'gfs': + com_path = Stage._get_member_com_paths_gfs(stage_dict, member) + else: + raise ValueError(f"Unknown RUN type: {stage_dict.RUN}") + + return Stage._paths_from_templates(stage_dict, com_path) + + @staticmethod + @logit(logger) + def get_member_list(run: str, nmem_ens: int, m_index: int = 0, gefstype: Optional[str] = None) -> list[int]: + """Get list of member indices based on RUN type + + Parameters + ---------- + run : str + RUN type (e.g., 'gfs', 'gefs', 'enkfgdas', 'gdas', 'gcafs') + nmem_ens : int + Total number of ensemble members + m_index : int, optional + Cycle index for GEFS real-time mapping (default: 0) + gefstype : Optional[str], optional + GEFS type ('gefs-real-time' or 'gefs-offline') + + Returns + ------- + list[int] + List of member indices to process + """ + if run in ['enkfgdas']: + return list(range(1, nmem_ens + 1)) + if run in ['sfs']: + return list(range(0, nmem_ens + 1)) + elif run in ['gefs']: + if gefstype == 'gefs-real-time': + # Map GEFS members to GFS member numbers + # Cycle ranges determine which 30-member range to use based on cycle index + cyc_ranges = {'00': list(range(1, 31)), + '06': list(range(21, 51)), + '12': list(range(41, 71)), + '18': list(range(61, 81)) + list(range(1, 11))} + member_list = [0] + cyc_ranges[f'{m_index:02}'] + return member_list + else: + # GEFS offline uses sequential member numbering + return list(range(0, nmem_ens + 1)) + else: + # Deterministic runs (GFS, GDAS, GCAFS, GCDAS) + # Only member -1 is processed (empty string for MEMDIR) + return [-1] + + @staticmethod + @logit(logger) + def _paths_from_templates(stage_dict: AttrDict, com_path_tuples: Tuple[Tuple[str, str, Dict[str, Any]], ...]) -> Dict[str, str]: + """Generate COM paths from template configurations + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + com_path_tuples : Tuple[Tuple[str, str, Dict[str, Any]], ...] + Tuple of tuples containing path key, template key, and substitution dict + + Returns + ------- + Dict[str, str] + Dictionary mapping COM path keys to resolved file paths + """ + def _replace_template_vars(template: str, var_dict: Dict[str, Any]) -> str: + """Replace template variables in string with actual values + + Parameters + ---------- + template : str + Template string with variables to replace + var_dict : Dict[str, Any] + Dictionary of variable names and values + + Returns + ------- + str + String with variables replaced + """ + replaced_com = template + for var, value in var_dict.items(): + replaced_com = replaced_com.replace(var, value) + return replaced_com + + path_dict = {} + for com_key, template_key, substitution_dict in com_path_tuples: + template_str = stage_dict.get(template_key, '') + if not template_str: + logger.warning("Template key '%s' not found for COM key '%s'", template_key, com_key) + path_dict[com_key] = '' + else: + path_dict[com_key] = _replace_template_vars(template_str, substitution_dict) + return path_dict + + @staticmethod + @logit(logger) + def _get_member_com_paths_gfs(stage_dict: AttrDict, member: int) -> Tuple[Tuple[str, str, Dict[str, Any]], ...]: + """Get member COM paths for GFS + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + member : int + The member directory number + + Returns + ------- + Tuple[Tuple[str, str, Dict[str, Any]], ...] + Tuple of tuples containing path key, template key, and substitution dict + """ + member_str = f"mem{member:03d}" if member >= 0 else '' + current_cycle_mem_dict = {**stage_dict.current_cycle_dict, "${MEMDIR}": member_str} + previous_cycle_mem_dict = {**stage_dict.previous_cycle_dict, "${MEMDIR}": member_str, "${RUN}": stage_dict.rRUN} + + return ( + ('COMIN_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle_mem_dict), + ('COMOUT_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle_mem_dict), + ('COMOUT_ATMOS_RESTART_PREV', 'COM_ATMOS_RESTART_TMPL', previous_cycle_mem_dict), + ('COMOUT_ATMOS_RESTART', 'COM_ATMOS_RESTART_TMPL', current_cycle_mem_dict), + ('COMOUT_ATMOS_ANALYSIS', 'COM_ATMOS_ANALYSIS_TMPL', current_cycle_mem_dict), + ('COMOUT_ICE_ANALYSIS', 'COM_ICE_ANALYSIS_TMPL', current_cycle_mem_dict), + ('COMOUT_ICE_RESTART_PREV', 'COM_ICE_RESTART_TMPL', previous_cycle_mem_dict), + ('COMOUT_OCEAN_RESTART_PREV', 'COM_OCEAN_RESTART_TMPL', previous_cycle_mem_dict), + ('COMOUT_OCEAN_ANALYSIS', 'COM_OCEAN_ANALYSIS_TMPL', current_cycle_mem_dict), + ('COMOUT_MED_RESTART_PREV', 'COM_MED_RESTART_TMPL', previous_cycle_mem_dict), + ('COMOUT_CHEM_ANALYSIS', 'COM_CHEM_ANALYSIS_TMPL', current_cycle_mem_dict), + ('COMOUT_WAVE_RESTART_PREV', 'COM_WAVE_RESTART_TMPL', previous_cycle_mem_dict), + ) + + @staticmethod + @logit(logger) + def _get_member_com_paths_gefs_offline(stage_dict: AttrDict, member: int) -> Tuple[Tuple[str, str, Dict[str, Any]], ...]: + """Get member COM paths for GEFS offline + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + member : int + The member directory number + + Returns + ------- + Tuple[Tuple[str, str, Dict[str, Any]], ...] + Tuple of tuples containing path key, template key, and substitution dict + """ + member_str = f"mem{member:03d}" if member >= 0 else '' + current_cycle = {**stage_dict.current_cycle_dict, "${MEMDIR}": member_str} + previous_cycle = {**stage_dict.previous_cycle_dict, "${MEMDIR}": member_str} + + return ( + ('COMIN_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle), + ('COMOUT_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle), + ('COMOUT_ATMOS_RESTART_PREV', 'COM_ATMOS_RESTART_TMPL', previous_cycle), + ('COMOUT_ATMOS_RESTART', 'COM_ATMOS_RESTART_TMPL', current_cycle), + ('COMOUT_ATMOS_ANALYSIS', 'COM_ATMOS_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ATMOS_HISTORY', 'COM_ATMOS_HISTORY_TMPL', previous_cycle), + ('COMOUT_ICE_ANALYSIS', 'COM_ICE_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ICE_RESTART_PREV', 'COM_ICE_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_RESTART_PREV', 'COM_OCEAN_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_ANALYSIS', 'COM_OCEAN_ANALYSIS_TMPL', current_cycle), + ('COMOUT_MED_RESTART_PREV', 'COM_MED_RESTART_TMPL', previous_cycle), + ('COMOUT_WAVE_RESTART_PREV', 'COM_WAVE_RESTART_TMPL', previous_cycle), + ) + + @staticmethod + @logit(logger) + def _get_member_com_paths_gefs_rt(stage_dict: AttrDict, member: int) -> Tuple[Tuple[str, str, Dict[str, Any]], ...]: + """Get member COM paths for GEFS real-time + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + member : int + The GFS member directory number (already mapped from GEFS) + + Returns + ------- + Tuple[Tuple[str, str, Dict[str, Any]], ...] + Tuple of tuples containing path key, template key, and substitution dict + """ + member_str = f"mem{member:03d}" if member >= 0 else '' + current_cycle = {**stage_dict.current_cycle_dict, "${MEMDIR}": member_str} + previous_cycle = {**stage_dict.previous_cycle_dict, "${MEMDIR}": member_str} + + return ( + ('COMIN_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle), + ('COMOUT_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle), + ('COMOUT_ATMOS_RESTART_PREV', 'COM_ATMOS_RESTART_TMPL', previous_cycle), + ('COMOUT_ATMOS_ANALYSIS', 'COM_ATMOS_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ATMOS_HISTORY', 'COM_ATMOS_HISTORY_TMPL', previous_cycle), + ('COMOUT_ICE_ANALYSIS', 'COM_ICE_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ICE_RESTART_PREV', 'COM_ICE_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_RESTART_PREV', 'COM_OCEAN_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_ANALYSIS', 'COM_OCEAN_ANALYSIS_TMPL', current_cycle), + ('COMOUT_MED_RESTART_PREV', 'COM_MED_RESTART_TMPL', previous_cycle), + ('COMOUT_WAVE_RESTART_PREV', 'COM_WAVE_RESTART_TMPL', previous_cycle), + ) + + @staticmethod + @logit(logger) + def _get_member_com_paths_gcafs(stage_dict: AttrDict, member: int) -> Tuple[Tuple[str, str, Dict[str, Any]], ...]: + """Get member COM paths for GCAFS + + Parameters + ---------- + stage_dict : AttrDict + Staging configuration dictionary + member : int + The member directory number + + Returns + ------- + Tuple[Tuple[str, str, Dict[str, Any]], ...] + Tuple of tuples containing path key, template key, and substitution dict + """ + member_str = f"mem{member:03d}" if member >= 0 else '' + current_cycle_in = {**stage_dict.current_cycle_dict, "${MEMDIR}": member_str, "${RUN}": stage_dict.rRUN} + current_cycle = {**current_cycle_in, "${RUN}": stage_dict.RUN} + previous_cycle = {**stage_dict.previous_cycle_dict, "${MEMDIR}": member_str, "${RUN}": stage_dict.rRUN} + + return ( + ('COMIN_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle_in), + ('COMOUT_ATMOS_INPUT', 'COM_ATMOS_INPUT_TMPL', current_cycle), + ('COMOUT_ATMOS_RESTART_PREV', 'COM_ATMOS_RESTART_TMPL', previous_cycle), + ('COMOUT_ATMOS_RESTART', 'COM_ATMOS_RESTART_TMPL', current_cycle), + ('COMOUT_ATMOS_ANALYSIS', 'COM_ATMOS_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ICE_ANALYSIS', 'COM_ICE_ANALYSIS_TMPL', current_cycle), + ('COMOUT_ICE_RESTART_PREV', 'COM_ICE_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_RESTART_PREV', 'COM_OCEAN_RESTART_TMPL', previous_cycle), + ('COMOUT_OCEAN_ANALYSIS', 'COM_OCEAN_ANALYSIS_TMPL', current_cycle), + ('COMOUT_MED_RESTART_PREV', 'COM_MED_RESTART_TMPL', previous_cycle), + ('COMOUT_WAVE_RESTART_PREV', 'COM_WAVE_RESTART_TMPL', previous_cycle), + ) diff --git a/ush/python/pygfs/utils/archive_vars.py b/ush/python/pygfs/utils/archive_vars.py new file mode 100644 index 00000000000..182d918e996 --- /dev/null +++ b/ush/python/pygfs/utils/archive_vars.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +""" +Archive Variables Utility Module + +Overview +-------- +This module provides utility functions to collect variables needed by YAML templates +for archiving verification (vrfy) data for GFS, GEFS, and GCAFS systems. File set +generation logic (loops, conditionals, path construction) is handled by the YAML +templates themselves. + +Architecture +------------ +Python provides VARIABLES → YAML templates build FILE SETS + +Python Code Responsibilities: + - Compute cycle-specific variables (cycle_HH, cycle_YMDH, cycle_YMD, head) + - Calculate COM directory paths with grid loops (0p25, 0p50, 1p00) + - Extract configuration keys (RUN, DO_* flags, FHMAX*, etc.) + +YAML Template Responsibilities (parm/archive/*_arcdir.yaml.j2): + - Build file sets with source → destination mappings + - Handle loops (forecast hours, grids, basins) + - Apply conditionals (DO_* flags, MODE, RUN type) + - Create mkdir lists for directory creation + +Key Functions +------------- +get_all_yaml_vars(config_dict): + Main entry point - collects all variables for YAML templates + +add_config_vars(config_dict): + Extracts configuration keys and COM* variables (created in job scripts) + +_get_cycle_vars(config_dict): + Computes cycle-specific variables (cycle_HH, cycle_YMDH, cycle_YMD, head) + +Logging +------- +All public operational functions are decorated with @logit(logger). +""" +import os +from logging import getLogger +from typing import Any, Dict +from wxflow import AttrDict, logit, to_YMD, to_YMDH + +logger = getLogger(__name__.split('.')[-1]) + + +class ArchiveVrfyVars: + """ + Utility class for collecting archive verification variables. + + This class provides variables for YAML templates that handle archiving + for three systems: + - GFS: Global Forecast System + - GEFS: Global Ensemble Forecast System + - GCAFS: Global Climate Analysis Forecast System + + The YAML templates (parm/archive/*_arcdir.yaml.j2) contain all file set + generation logic. This class only provides the variables they need. + """ + + @staticmethod + @logit(logger) + def get_all_yaml_vars(config_dict: AttrDict) -> Dict[str, Any]: + """Collect all variables needed for YAML templates. + + This method provides only the VARIABLES needed by the YAML templates + (cycle vars, COM paths, config keys). + + Parameters + ---------- + config_dict : AttrDict + Configuration dictionary from Archive.task_config + + Returns + ------- + Dict[str, Any] + Dictionary containing variables for Jinja2 templates: + - cycle_HH, cycle_YMDH, cycle_YMD, head: Cycle-specific variables + - COMIN_*, COMOUT_*, COM_*: All COM directory paths (from job scripts) + - Config keys: RUN, PSLOT, ROTDIR, DO_* flags, FHMAX*, etc. + """ + # Build arch_dict with variables for Jinja2 templates + arch_dict = AttrDict() + + # Add config variables (config keys, COM* variables from job scripts) + arch_dict.update(ArchiveVrfyVars.add_config_vars(config_dict)) + + # Add cycle-specific variables + arch_dict.update(ArchiveVrfyVars._get_cycle_vars(config_dict)) + + logger.info(f"Collected {len(arch_dict)} variables for YAML templates") + logger.debug(f"arch_dict keys: {list(arch_dict.keys())}") + + return arch_dict + + @staticmethod + @logit(logger) + def add_config_vars(config_dict: AttrDict) -> Dict[str, Any]: + """Collect configuration keys and COM* variables for archive operations. + + Formats resolution variables (OCNRES, ICERES) to 3 digits and extracts + all configuration keys and COM* directory paths needed for archiving. + + Parameters + ---------- + config_dict : AttrDict + Configuration dictionary from Archive.task_config + + Returns + ------- + Dict[str, Any] + Dictionary with config keys and all COM_*, COMIN_*, COMOUT_* variables + """ + general_dict = {} + + # Update resolution keys to be 3 digits if they are part of config_dict + for key in ['OCNRES', 'ICERES']: + if key in config_dict: + config_dict[key] = f"{config_dict[key]:03d}" + + # Configuration keys to extract (if present) + config_keys = ['current_cycle', 'RUN', 'PSLOT', 'ROTDIR', 'PARMgfs', + 'ARCDIR', 'MODE', 'DO_JEDIATMENS', 'DO_FIT2OBS', 'DO_JEDIATMVAR', + 'DO_JEDISNOWDA', 'DO_AERO_ANL', 'DO_PREP_OBS_AERO', 'NET', + 'FHOUT_GFS', 'FHMAX_HF_GFS', 'FHMAX_FITS', 'FHMAX', 'FHOUT', + 'FHMAX_GFS', 'DO_GSISOILDA', 'DO_LAND_IAU'] + + # Add FHMIN_GFS only if RUN does not contain 'enkf' + if 'enkf' not in config_dict.get('RUN', ''): + config_keys.append('FHMIN_GFS') + + # Extract keys if they exist in config_dict + for key in config_keys: + if key in config_dict: + general_dict[key] = config_dict[key] + else: + logger.warning(f"Config key '{key}' not found in config_dict; skipping.") + + # Import COM* directory and template variables created by job scripts + # Job scripts use declare_from_tmpl -rx which exports variables to environment + for key in config_dict.keys(): + if key.startswith(("COM_", "COMIN_", "COMOUT_")): + general_dict[key] = config_dict.get(key) + + logger.info(f"Collected {len(general_dict)} general archive variables") + logger.debug(f"General variables: {list(general_dict.keys())}") + + return general_dict + + @staticmethod + @logit(logger) + def _get_cycle_vars(config_dict: AttrDict) -> Dict[str, Any]: + """Calculate cycle-specific variables. + + Parameters + ---------- + config_dict : AttrDict + Configuration dictionary from Archive.task_config + + Returns + ------- + Dict[str, Any] + Dictionary containing: + - cycle_HH: Cycle hour (e.g., '00', '06') + - cycle_YMDH: Full cycle timestamp (YYYYMMDDHH) + - cycle_YMD: Cycle date (YYYYMMDD) + - head: System head designation (e.g., 'gfs.t00z.') + - VFYARC: Verification archive directory (ROTDIR/vrfyarch) + """ + current_cycle = config_dict.current_cycle + cycle_HH = current_cycle.strftime("%H") + cycle_YMDH = to_YMDH(current_cycle) + cycle_YMD = to_YMD(current_cycle) + + # Archive directory (used by all systems) + VFYARC = os.path.join(config_dict.ROTDIR, "vrfyarch") + + return { + 'cycle_HH': cycle_HH, + 'cycle_YMDH': cycle_YMDH, + 'cycle_YMD': cycle_YMD, + 'VFYARC': VFYARC + } diff --git a/ush/radmon_diag_ck.sh b/ush/radmon_diag_ck.sh index ca9129b6df4..a8e65a57fe5 100755 --- a/ush/radmon_diag_ck.sh +++ b/ush/radmon_diag_ck.sh @@ -2,173 +2,162 @@ #---------------------------------------------------------------- # Check the contents of the radstat file and compare to -# the ${run}_radmon_satype.txt file. Report any missing +# the ${run}_radmon_satype.txt file. Report any missing # or zero sized diag files. -# - - function usage { - echo "Usage: radmon_diag_ck.sh -rad radstat --sat satype --out output " - echo "" - echo " -r,--rad radstat file (required)" - echo " File name or path to radstat file." - echo "" - echo " -s,--sat satype file (required)" - echo " File name or path to satype file." - echo "" - echo " -o,--out output file name (required)" - echo " File name for missing diag file report." - } +# +function usage { + echo "Usage: radmon_diag_ck.sh -rad radstat --sat satype --out output " + echo "" + echo " -r,--rad radstat file (required)" + echo " File name or path to radstat file." + echo "" + echo " -s,--sat satype file (required)" + echo " File name or path to satype file." + echo "" + echo " -o,--out output file name (required)" + echo " File name for missing diag file report." +} echo "--> radmon_diag_ck.sh" - #-------------------------- # Process input arguments # - nargs=$# - if [[ ${nargs} -ne 6 ]]; then - usage - exit 1 - fi - - while [[ $# -ge 1 ]] - do - key="$1" - echo "${key}" - - case ${key} in - -r|--rad) +nargs=$# +if [[ ${nargs} -ne 6 ]]; then + usage + exit 1 +fi + +while [[ $# -ge 1 ]]; do + key="$1" + echo "${key}" + + case ${key} in + -r | --rad) radstat_file="$2" shift # past argument - ;; - -s|--sat) + ;; + -s | --sat) satype_file="$2" shift # past argument - ;; - -o|--out) + ;; + -o | --out) output_file="$2" shift # past argument - ;; - *) - #unspecified key + ;; + *) + #unspecified key echo " unsupported key = ${key}" - ;; - esac + ;; + esac - shift - done + shift +done # set -ax - echo " radstat_file = ${radstat_file}" - echo " satype_file = ${satype_file}" - echo " output_file = ${output_file}" - - missing_diag="" - zero_len_diag="" - - #--------------------------------------------- - # get list of diag files in the radstat file - # - radstat_contents=`tar -tf "${radstat_file}" | grep '_ges' | - gawk -F"diag_" '{print $2}' | - gawk -F"_ges" '{print $1}'` - - - #--------------------------------------------- - # load contents of satype_file into an array - # - satype_contents=$(cat "${satype_file}") - - - #------------------------------------------------- - # compare $satype_contents and $radstat_contents - # report anything missing - # - for sat in ${satype_contents}; do - content_count=$(echo "${radstat_contents}" | grep -c "${sat}" || true) - - if (( content_count <= 0 )); then +echo " radstat_file = ${radstat_file}" +echo " satype_file = ${satype_file}" +echo " output_file = ${output_file}" + +missing_diag="" +zero_len_diag="" + +#--------------------------------------------- +# get list of diag files in the radstat file +# +# shellcheck disable=SC2312 +radstat_contents=$(tar -tf "${radstat_file}" | grep -Po '(?<=diag_).*(?=_ges.*)') + +#--------------------------------------------- +# load contents of satype_file into an array +# +readarray -t satype_contents < "${satype_file}" + +#------------------------------------------------- +# compare $satype_contents and $radstat_contents +# report anything missing +# +for sat in "${satype_contents[@]}"; do + content_count=$(echo "${radstat_contents}" | grep -c "${sat}") + + if [[ "${content_count}" -le 0 ]]; then missing_diag="${missing_diag} ${sat}" - fi - - done - - echo "" - echo "missing_diag = ${missing_diag}" - echo "" - - - #--------------------------------------------------------- - # Check for zero sized diag files. The diag files in - # the radstat file (which is a tar file) are gzipped. - # I find that 0 sized, gzipped file has a size of ~52 - # (I assume that's for header and block size). - # - # So for this check we'll assume anything in the radstat - # file with a size of > 1000 bytes is suspect. (That's - # overkill, 100 is probably sufficient, but I'm the - # nervous type.) So we'll extract, uncompress, and check - # the actual file size of those. Anything with an - # uncompressed size of 0 goes on the zero_len_diag list. - # - - # TODO Rewrite these array parsing commands to avoid using Bash's sloppy word splitting - # File sizes contain only digits and immediately precede the date - # shellcheck disable=SC2207 - sizes=($(tar -vtf "${radstat_file}" --wildcards '*_ges*' | grep -P -o '(\d)+(?= \d{4}-\d{2}-\d{2})')) - # Filenames are the last group of non-whitespace characters - # shellcheck disable=SC2207 - filenames=($(tar -vtf "${radstat_file}" --wildcards '*_ges*' | grep -P -o '\S+$')) - # shellcheck disable= - - - for file_num in "${!filenames[@]}"; do - file_name="${filenames[${file_num}]}" - file_size="${sizes[${file_num}]}" - - if (( file_size <= 1000 )); then - tar -xf "${radstat_file}" "${file_name}" - gunzip "${file_name}" - uz_file_name="${file_name%.*}" - uz_file_size=$(stat -c "%s" "${uz_file_name}") - - - if (( uz_file_size <= 0 )); then + fi + +done + +echo "" +echo "missing_diag = ${missing_diag}" +echo "" + +#--------------------------------------------------------- +# Check for zero sized diag files. The diag files in +# the radstat file (which is a tar file) are gzipped. +# I find that 0 sized, gzipped file has a size of ~52 +# (I assume that's for header and block size). +# +# So for this check we'll assume anything in the radstat +# file with a size of > 1000 bytes is suspect. (That's +# overkill, 100 is probably sufficient, but I'm the +# nervous type.) So we'll extract, uncompress, and check +# the actual file size of those. Anything with an +# uncompressed size of 0 goes on the zero_len_diag list. +# + +declare -A file_sizes + +# Parse the filename and filesize from tar's verbose output and store in an associative array +# Field $6 of verbose tar output is the filename, field $3 is the size +# Caution: this method is not robust if the filename contains spaces +# shellcheck disable=SC2312 +while IFS='|' read -r name size; do + file_sizes[${name}]=${size} +done < <(tar -vtf "${radstat_file}" --wildcards '*_ges*' | awk '$3 ~ /^[0-9]+$/ { print $6 "|" $3 }') + +for file_name in "${!file_sizes[@]}"; do + file_size="${file_sizes["${file_name}"]}" + + if ((file_size <= 1000)); then + tar -xf "${radstat_file}" "${file_name}" + gunzip "${file_name}" + uz_file_name="${file_name%.*}" + uz_file_size=$(stat -c "%s" "${uz_file_name}") + + if ((uz_file_size <= 0)); then # Remove leading diag_ sat=${uz_file_name#diag_} # Remove trailing _ges* sat=${sat%_ges*} zero_len_diag="${zero_len_diag} ${sat}" - fi - - rm -f "${uz_file_name}" - fi + fi - done + rm -f "${uz_file_name}" + fi - echo "" - echo "zero_len_diag = ${zero_len_diag}" - echo "" +done +echo "" +echo "zero_len_diag = ${zero_len_diag}" +echo "" - #----------------------------------------- - # Write results to $output_file - # - if [[ ${#zero_len_diag} -gt 0 ]]; then - for zld in ${zero_len_diag}; do - echo " Zero Length diagnostic file: ${zld}" >> "${output_file}" - done - fi - - if [[ ${#missing_diag} -gt 0 ]]; then - for md in ${missing_diag}; do - echo " Missing diagnostic file : ${md}" >> "${output_file}" - done - fi - +#----------------------------------------- +# Write results to $output_file +# +if [[ ${#zero_len_diag} -gt 0 ]]; then + for zld in ${zero_len_diag}; do + echo " Zero Length diagnostic file: ${zld}" >> "${output_file}" + done +fi + +if [[ ${#missing_diag} -gt 0 ]]; then + for md in ${missing_diag}; do + echo " Missing diagnostic file : ${md}" >> "${output_file}" + done +fi echo "<-- radmon_diag_ck.sh" exit diff --git a/ush/radmon_err_rpt.sh b/ush/radmon_err_rpt.sh index c288f5f3518..7f85f4cfb80 100755 --- a/ush/radmon_err_rpt.sh +++ b/ush/radmon_err_rpt.sh @@ -4,7 +4,7 @@ #### UNIX Script Documentation Block # . . # Script name: radmon_err_rpt.sh -# Script description: Compare the contents of error files from two different +# Script description: Compare the contents of error files from two different # cycles. # # Author: Ed Safford Org: NP23 Date: 2012-02-02 @@ -15,7 +15,7 @@ # in both files are reported. # # This script is run as a child script of radmon_verf_time.sh. The parent -# script creates/copies the error files into a temporary working +# script creates/copies the error files into a temporary working # directory before invoking this script. # # @@ -55,135 +55,130 @@ outfile=${7:-${outfile:?}} # Other variables err=0 -RADMON_SUFFIX=${RADMON_SUFFIX} have_diag_rpt=0 if [[ -s "${diag_rpt}" ]]; then - have_diag_rpt=1 + have_diag_rpt=1 else - err=1 + err=1 fi echo "have_diag_rpt = ${have_diag_rpt}" #----------------------------------------------------------------------------- -# read each line in the $file1 -# search $file2 for the same satname, channel, and region +# read each line in the $file1 +# search $file2 for the same satname, channel, and region # if same combination is in both files, add the values to the output file -# -{ while read myline; do - echo "myline = ${myline}" - bound="" - - echo "${myline}" - satname=$(echo "${myline}" | gawk '{print $1}') - channel=$(echo "${myline}" | gawk '{print $3}') - region=$(echo "${myline}" | gawk '{print $5}') - value1=$(echo "${myline}" | gawk '{print $7}') - bound=$(echo "${myline}" | gawk '{print $9}') - -# -# Check findings against diag_report. If the satellite/instrument is on the -# diagnostic report it means the diagnostic file file for the -# satelite/instrument is missing for this cycle, so skip any additional -# error checking for that source. Otherwise, evaluate as per normal. # - - diag_match="" - diag_match_len=0 - - if [[ ${have_diag_rpt} == 1 ]]; then - diag_match=$(gawk "/${satname}/" "${diag_rpt}") - diag_match_len=$(echo ${#diag_match}) - fi - - - if [[ ${diag_match_len} == 0 ]]; then - - if [[ ${type} == "chan" ]]; then - echo "looking for match for ${satname} and ${channel}" - { while read myline2; do - satname2=$(echo "${myline2}" | gawk '{print $1}') - channel2=$(echo "${myline2}" | gawk '{print $3}') - - if [[ ${satname} == ${satname2} && ${channel} == ${channel2} ]]; then - match="${satname} channel= ${channel}" - echo "match from gawk = ${match}" - break; - else - match="" +{ while read -r myline; do + echo "myline = ${myline}" + bound="" + + echo "${myline}" + satname=$(echo "${myline}" | gawk '{print $1}') + channel=$(echo "${myline}" | gawk '{print $3}') + region=$(echo "${myline}" | gawk '{print $5}') + value1=$(echo "${myline}" | gawk '{print $7}') + bound=$(echo "${myline}" | gawk '{print $9}') + + # + # Check findings against diag_report. If the satellite/instrument is on the + # diagnostic report it means the diagnostic file file for the + # satelite/instrument is missing for this cycle, so skip any additional + # error checking for that source. Otherwise, evaluate as per normal. + # + + diag_match="" + diag_match_len=0 + + if [[ "${have_diag_rpt}" -eq 1 ]]; then + diag_match=$(gawk "/${satname}/" "${diag_rpt}") + diag_match_len=${#diag_match} + fi + + if [[ "${diag_match_len}" -eq 0 ]]; then + + if [[ "${type}" == "chan" ]]; then + echo "looking for match for ${satname} and ${channel}" + { while read -r myline2; do + satname2=$(echo "${myline2}" | gawk '{print $1}') + channel2=$(echo "${myline2}" | gawk '{print $3}') + + if [[ "${satname}" == "${satname2}" && "${channel}" == "${channel2}" ]]; then + match="${satname} channel= ${channel}" + echo "match from gawk = ${match}" + break + else + match="" + fi + + done; } < "${file2}" + + else + match=$(gawk "/${satname}/ && /channel= ${channel} / && /region= ${region} /" "${file2}") + echo match = "${match}" + + match_len=${#match} + if ((match_len > 0)); then + channel2=$(echo "${match}" | gawk '{print $3}') + + if [[ "${channel2}" != "${channel}" ]]; then + match="" + fi fi - done } < "${file2}" - + fi + match_len=${#match} - else - match=$(gawk "/${satname}/ && /channel= ${channel} / && /region= ${region} /" "${file2}") - echo match = "${match}" + if [[ "${match_len}" -gt 0 ]]; then - match_len=$(echo ${#match}) - if (( match_len > 0 )); then - channel2=$(echo "${match}" | gawk '{print $3}') - - if [[ ${channel2} != ${channel} ]]; then - match="" - fi - fi + value2=$(echo "${match}" | gawk '{print $7}') + bound2=$(echo "${match}" | gawk '{print $9}') - fi - match_len=$(echo ${#match}) - - if (( match_len > 0 )); then + if [[ ${type} == "chan" ]]; then + tmpa=" ${satname} channel= ${channel}" + tmpb="" - value2=$(echo "${match}" | gawk '{print $7}') - bound2=$(echo "${match}" | gawk '{print $9}') + elif [[ ${type} == "pen" ]]; then + tmpa="${satname} channel= ${channel} region= ${region}" + tmpb="${cycle1} ${value1} ${bound}" - if [[ ${type} == "chan" ]]; then - tmpa=" ${satname} channel= ${channel}" - tmpb="" + elif [[ ${type} == "cnt" ]]; then + tmpa="${satname} channel= ${channel} region= ${region}" + tmpb="${cycle1} ${value1} ${bound}" - elif [[ ${type} == "pen" ]]; then - tmpa="${satname} channel= ${channel} region= ${region}" - tmpb="${cycle1} ${value1} ${bound}" - - elif [[ ${type} == "cnt" ]]; then - tmpa="${satname} channel= ${channel} region= ${region}" - tmpb="${cycle1} ${value1} ${bound}" - - else - tmpa="${satname} channel= ${channel} region= ${region}" - tmpb="${cycle1}: ${type}= ${value1}" - fi + else + tmpa="${satname} channel= ${channel} region= ${region}" + tmpb="${cycle1}: ${type}= ${value1}" + fi - line1="${tmpa} ${tmpb}" - echo "${line1}" >> "${outfile}" + line1="${tmpa} ${tmpb}" + echo "${line1}" >> "${outfile}" - if [[ ${type} != "chan" ]]; then - tmpc=$(echo "${tmpa}" |sed 's/[a-z]/ /g' | sed 's/[0-9]/ /g' | sed 's/=/ /g' | sed 's/_/ /g' | sed 's/-/ /g') + if [[ ${type} != "chan" ]]; then + tmpc="${tmpa//[a-z0-9\-_\=]/}" - if [[ ${type} == "pen" || ${type} == "cnt" ]]; then - line2=" ${tmpc} ${cycle2} ${value2} ${bound2}" - else - line2=" ${tmpc} ${cycle2}: ${type}= ${value2}" - fi + if [[ ${type} == "pen" || ${type} == "cnt" ]]; then + line2=" ${tmpc} ${cycle2} ${value2} ${bound2}" + else + line2=" ${tmpc} ${cycle2}: ${type}= ${value2}" + fi - echo "${line2}" >> "${outfile}" - fi - - #----------------------------------------- - # add hyperlink to warning entry - # - line3=" http://www.emc.ncep.noaa.gov/gmb/gdas/radiance/es_rad/${RADMON_SUFFIX}/index.html?sat=${satname}®ion=${region}&channel=${channel}&stat=${type}" - if [[ ${channel} -gt 0 ]]; then - echo "${line3}" >> "${outfile}" - echo "" >> "${outfile}" - fi - fi - fi -done } < "${file1}" + echo "${line2}" >> "${outfile}" + fi + #----------------------------------------- + # add hyperlink to warning entry + # + line3=" http://www.emc.ncep.noaa.gov/gmb/gdas/radiance/es_rad/${RADMON_SUFFIX}/index.html?sat=${satname}®ion=${region}&channel=${channel}&stat=${type}" + if [[ "${channel}" -gt 0 ]]; then + echo "${line3}" >> "${outfile}" + echo "" >> "${outfile}" + fi + fi + fi +done; } < "${file1}" ################################################################################ # Post processing -exit ${err} - +exit "${err}" diff --git a/ush/radmon_verf_angle.sh b/ush/radmon_verf_angle.sh index 79046fae44f..1a4d8d5aa3c 100755 --- a/ush/radmon_verf_angle.sh +++ b/ush/radmon_verf_angle.sh @@ -69,14 +69,11 @@ rgnTM=${rgnTM:-} echo " REGIONAL_RR, rgnHH, rgnTM = ${REGIONAL_RR}, ${rgnHH}, ${rgnTM}" netcdf_boolean=".false." -if [[ ${RADMON_NETCDF} -eq 1 ]]; then - netcdf_boolean=".true." +if [[ "${RADMON_NETCDF}" -eq 1 ]]; then + netcdf_boolean=".true." fi echo " RADMON_NETCDF, netcdf_boolean = ${RADMON_NETCDF}, ${netcdf_boolean}" -which prep_step -which startmsg - # File names touch "${pgmout}" @@ -86,11 +83,10 @@ VERBOSE=${VERBOSE:-NO} LITTLE_ENDIAN=${LITTLE_ENDIAN:-0} USE_ANL=${USE_ANL:-0} - if [[ ${USE_ANL} -eq 1 ]]; then - gesanl="ges anl" + gesanl="ges anl" else - gesanl="ges" + gesanl="ges" fi angle_exec=radmon_angle.x @@ -101,12 +97,12 @@ scaninfo=scaninfo.txt # Copy extraction program and supporting files to working directory cpreq "${EXECgfs}/${angle_exec}" ./ -cpreq "${shared_scaninfo}" ./${scaninfo} +cpreq "${shared_scaninfo}" "./${scaninfo}" #-------------------------------------------------------------------- # Run program for given time -export pgm=${angle_exec} +export pgm="${angle_exec}" iyy="${PDY:0:4}" imm="${PDY:4:2}" @@ -117,39 +113,38 @@ touch "./errfile" for type in ${SATYPE}; do - if [[ ! -s ${type} ]]; then - echo "ZERO SIZED: ${type}" - continue - fi - - for dtype in ${gesanl}; do - - echo "pgm = ${pgm}" - echo "pgmout = ${pgmout}" - source prep_step - - if [[ ${dtype} == "anl" ]]; then - data_file="${type}_anl.${PDY}${cyc}.ieee_d" - ctl_file=${type}_anl.ctl - angl_ctl=angle.${ctl_file} - else - data_file="${type}.${PDY}${cyc}.ieee_d" - ctl_file=${type}.ctl - angl_ctl=angle.${ctl_file} - fi - - angl_file="" - if [[ ${REGIONAL_RR} -eq 1 ]]; then - angl_file=${rgnHH}.${data_file}.${rgnTM} - fi - - - if [[ -f input ]]; then - rm -f input - fi - - nchanl=-999 - cat << EOF > input + if [[ ! -s "${type}" ]]; then + echo "ZERO SIZED: ${type}" + continue + fi + + for dtype in ${gesanl}; do + + echo "pgm = ${pgm}" + echo "pgmout = ${pgmout}" + source prep_step + + if [[ "${dtype}" == "anl" ]]; then + data_file="${type}_anl.${PDY}${cyc}.ieee_d" + ctl_file="${type}_anl.ctl" + angl_ctl="angle.${ctl_file}" + else + data_file="${type}.${PDY}${cyc}.ieee_d" + ctl_file="${type}.ctl" + angl_ctl="angle.${ctl_file}" + fi + + angl_file="" + if [[ "${REGIONAL_RR}" -eq 1 ]]; then + angl_file="${rgnHH}.${data_file}.${rgnTM}" + fi + + if [[ -f input ]]; then + rm -f input + fi + + nchanl=-999 + cat << EOF > input &INPUT satname='${type}', iyy=${iyy}, @@ -167,44 +162,42 @@ for type in ${SATYPE}; do / EOF - startmsg - ./${angle_exec} < input >> "${pgmout}" 2>>errfile - export err=$? - - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: ${angle_exec} failed for instrument ${type} and datatype ${dtype}!" - exit "${err}" - fi - - if [[ -s ${angl_file} ]]; then - ${COMPRESS} -f "${angl_file}" - fi + startmsg + "./${angle_exec}" < input >> "${pgmout}" 2>> errfile + export err=$? - if [[ -s ${angl_ctl} ]]; then - ${COMPRESS} -f "${angl_ctl}" - fi + if [[ ${err} -ne 0 ]]; then + echo "FATAL ERROR: ${angle_exec} failed for instrument ${type} and datatype ${dtype}!" + exit "${err}" + fi + if [[ -s "${angl_file}" ]]; then + ${COMPRESS} -f "${angl_file}" + fi - done # for dtype in ${gesanl} loop + if [[ -s "${angl_ctl}" ]]; then + ${COMPRESS} -f "${angl_ctl}" + fi -done # for type in ${SATYPE} loop + done # for dtype in ${gesanl} loop +done # for type in ${SATYPE} loop "${USHgfs}/rstprod.sh" tar_file=radmon_angle.tar if compgen -G "angle*.ieee_d*" > /dev/null || compgen -G "angle*.ctl*" > /dev/null; then - tar -cf "${tar_file}" angle*.ieee_d* angle*.ctl* - ${COMPRESS} ${tar_file} - mv "${tar_file}.${Z}" "${TANKverf_rad}/." - - if [[ ${RAD_AREA} = "rgn" ]]; then - cwd=$(pwd) - cd "${TANKverf_rad}" - tar -xf "${tar_file}.${Z}" - rm -f "${tar_file}.${Z}" - cd "${cwd}" - fi + tar -cf "${tar_file}" angle*.ieee_d* angle*.ctl* + ${COMPRESS} "${tar_file}" + mv "${tar_file}.${Z}" "${TANKverf_rad}/." + + if [[ "${RAD_AREA}" == "rgn" ]]; then + cwd=$(pwd) + cd "${TANKverf_rad}" || exit 1 + tar -xf "${tar_file}.${Z}" + rm -f "${tar_file}.${Z}" + cd "${cwd}" || exit 1 + fi fi ################################################################################ diff --git a/ush/radmon_verf_bcoef.sh b/ush/radmon_verf_bcoef.sh index a4af9155d14..fa92f0d0432 100755 --- a/ush/radmon_verf_bcoef.sh +++ b/ush/radmon_verf_bcoef.sh @@ -4,13 +4,13 @@ #### UNIX Script Documentation Block # . . # Script name: radmon_verf_bcoef.sh -# Script description: Extract bias correction coefficients data from radiance +# Script description: Extract bias correction coefficients data from radiance # diagnostic files. # # Author: Ed Safford Org: NP23 Date: 2012-02-02 # -# Abstract: This script extracts bias correction coefficient related data from -# radiance diagnostic files (which are an output from GSI runs), +# Abstract: This script extracts bias correction coefficient related data from +# radiance diagnostic files (which are an output from GSI runs), # storing the extracted data in small binary files. # # This script is a child script of exgdas_vrfyrad.sh.sms. The parent @@ -35,11 +35,11 @@ # defaults to none # LITTLE_ENDIAN flag for LE machine # defaults to 0 (big endian) -# USE_ANL use analysis files as inputs in addition to +# USE_ANL use analysis files as inputs in addition to # the ges files. Default is 0 (ges only) # # Modules and files referenced: -# scripts : +# scripts : # # programs : $bcoef_exec # @@ -60,8 +60,8 @@ #################################################################### netcdf_boolean=".false." -if [[ ${RADMON_NETCDF} -eq 1 ]]; then - netcdf_boolean=".true." +if [[ "${RADMON_NETCDF}" -eq 1 ]]; then + netcdf_boolean=".true." fi echo " RADMON_NETCDF, netcdf_boolean = ${RADMON_NETCDF}, ${netcdf_boolean}" @@ -77,25 +77,24 @@ SATYPE=${SATYPE:-} LITTLE_ENDIAN=${LITTLE_ENDIAN:-0} USE_ANL=${USE_ANL:-0} - bcoef_exec=radmon_bcoef.x -if [[ ${USE_ANL} -eq 1 ]]; then - gesanl="ges anl" +if [[ "${USE_ANL}" -eq 1 ]]; then + gesanl="ges anl" else - gesanl="ges" + gesanl="ges" fi #-------------------------------------------------------------------- # Copy extraction program and supporting files to working directory -cpreq "${EXECgfs}/${bcoef_exec}" ./${bcoef_exec} -cpreq "${biascr}" ./biascr.txt +cpreq "${EXECgfs}/${bcoef_exec}" "./${bcoef_exec}" +cpreq "${biascr}" ./biascr.txt #-------------------------------------------------------------------- # Run program for given time -export pgm=${bcoef_exec} +export pgm="${bcoef_exec}" iyy="${PDY:0:4}" imm="${PDY:4:2}" @@ -107,39 +106,36 @@ npredr=5 for type in ${SATYPE}; do - if [[ ! -s ${type} ]]; then - echo "ZERO SIZED: ${type}" - continue - fi - - for dtype in ${gesanl}; do - - source prep_step + if [[ ! -s "${type}" ]]; then + echo "ZERO SIZED: ${type}" + continue + fi - if [[ ${dtype} == "anl" ]]; then - data_file="${type}_anl.${PDY}${cyc}.ieee_d" - ctl_file=${type}_anl.ctl - bcoef_ctl=bcoef.${ctl_file} - else - data_file="${type}.${PDY}${cyc}.ieee_d" - ctl_file=${type}.ctl - bcoef_ctl=bcoef.${ctl_file} - fi + for dtype in ${gesanl}; do - if [[ ${REGIONAL_RR} -eq 1 ]]; then - bcoef_file=${rgnHH}.bcoef.${data_file}.${rgnTM} - else - bcoef_file=bcoef.${data_file} - fi + source prep_step + if [[ "${dtype}" == "anl" ]]; then + data_file="${type}_anl.${PDY}${cyc}.ieee_d" + ctl_file="${type}_anl.ctl" + bcoef_ctl="bcoef.${ctl_file}" + else + data_file="${type}.${PDY}${cyc}.ieee_d" + ctl_file="${type}.ctl" + bcoef_ctl="bcoef.${ctl_file}" + fi - if [[ -f input ]]; - then - rm -f input - fi + if [[ "${REGIONAL_RR}" -eq 1 ]]; then + bcoef_file="${rgnHH}.bcoef.${data_file}.${rgnTM}" + else + bcoef_file="bcoef.${data_file}" + fi + if [[ -f input ]]; then + rm -f input + fi - cat << EOF > input + cat << EOF > input &INPUT satname='${type}', npredr=${npredr}, @@ -156,50 +152,46 @@ for type in ${SATYPE}; do netcdf=${netcdf_boolean}, / EOF - startmsg - ./${bcoef_exec} < input >>"${pgmout}" 2>>errfile - export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: ${bcoef_exec} failed for instrument ${type} and datatype ${dtype}" - exit "${err}" - fi - - -#------------------------------------------------------------------- -# move data, control, and stdout files to $TANKverf_rad and compress -# - - if [[ -s ${bcoef_file} ]]; then - ${COMPRESS} "${bcoef_file}" - fi - - if [[ -s ${bcoef_ctl} ]]; then - ${COMPRESS} "${bcoef_ctl}" - fi - - - done # dtype in $gesanl loop + startmsg + "./${bcoef_exec}" < input >> "${pgmout}" 2>> errfile + export err=$? + if [[ "${err}" -ne 0 ]]; then + echo "FATAL ERROR: ${bcoef_exec} failed for instrument ${type} and datatype ${dtype}" + exit "${err}" + fi + + #------------------------------------------------------------------- + # move data, control, and stdout files to $TANKverf_rad and compress + # + + if [[ -s "${bcoef_file}" ]]; then + ${COMPRESS} "${bcoef_file}" + fi + + if [[ -s "${bcoef_ctl}" ]]; then + ${COMPRESS} "${bcoef_ctl}" + fi + + done # dtype in $gesanl loop done # type in $SATYPE loop - "${USHgfs}/rstprod.sh" if compgen -G "bcoef*.ieee_d*" > /dev/null || compgen -G "bcoef*.ctl*" > /dev/null; then - tar_file=radmon_bcoef.tar - tar -cf ${tar_file} bcoef*.ieee_d* bcoef*.ctl* - ${COMPRESS} ${tar_file} - mv "${tar_file}.${Z}" "${TANKverf_rad}" - - if [[ ${RAD_AREA} = "rgn" ]]; then - cwd=$(pwd) - cd "${TANKverf_rad}" || exit 1 - tar -xf "${tar_file}.${Z}" - rm -f "${tar_file}.${Z}" - cd "${cwd}" || exit 1 - fi + tar_file=radmon_bcoef.tar + tar -cf "${tar_file}" bcoef*.ieee_d* bcoef*.ctl* + ${COMPRESS} "${tar_file}" + mv "${tar_file}.${Z}" "${TANKverf_rad}" + + if [[ ${RAD_AREA} = "rgn" ]]; then + cwd=$(pwd) + cd "${TANKverf_rad}" || exit 1 + tar -xf "${tar_file}.${Z}" + rm -f "${tar_file}.${Z}" + cd "${cwd}" || exit 1 + fi fi - ################################################################################ # Post processing diff --git a/ush/radmon_verf_bcor.sh b/ush/radmon_verf_bcor.sh index 134f0d1dd1a..dcf9e2d2ec0 100755 --- a/ush/radmon_verf_bcor.sh +++ b/ush/radmon_verf_bcor.sh @@ -73,26 +73,25 @@ USE_ANL=${USE_ANL:-0} bcor_exec=radmon_bcor.x netcdf_boolean=".false." -if [[ ${RADMON_NETCDF} -eq 1 ]]; then - netcdf_boolean=".true." +if [[ "${RADMON_NETCDF}" -eq 1 ]]; then + netcdf_boolean=".true." fi -if [[ ${USE_ANL} -eq 1 ]]; then - gesanl="ges anl" +if [[ "${USE_ANL}" -eq 1 ]]; then + gesanl="ges anl" else - gesanl="ges" + gesanl="ges" fi - #-------------------------------------------------------------------- # Copy extraction program to working directory -cpreq "${EXECgfs}/${bcor_exec}" ./${bcor_exec} +cpreq "${EXECgfs}/${bcor_exec}" "./${bcor_exec}" #-------------------------------------------------------------------- # Run program for given time -export pgm=${bcor_exec} +export pgm="${bcor_exec}" iyy="${PDY:0:4}" imm="${PDY:4:2}" @@ -103,39 +102,35 @@ touch "./errfile" for type in ${SATYPE}; do - for dtype in ${gesanl}; do - - source prep_step - - if [[ ${dtype} == "anl" ]]; then - data_file="${type}_anl.${PDY}${cyc}.ieee_d" - bcor_file=bcor.${data_file} - ctl_file=${type}_anl.ctl - bcor_ctl=bcor.${ctl_file} - stdout_file=stdout.${type}_anl - bcor_stdout=bcor.${stdout_file} - input_file=${type}_anl - else - data_file="${type}.${PDY}${cyc}.ieee_d" - bcor_file=bcor.${data_file} - ctl_file=${type}.ctl - bcor_ctl=bcor.${ctl_file} - stdout_file=stdout.${type} - bcor_stdout=bcor.${stdout_file} - input_file=${type} - fi - - if [[ -f input ]]; then - rm -f input - fi - - # Check for 0 length input file here and avoid running - # the executable if $input_file doesn't exist or is 0 bytes - # - if [[ -s "${input_file}" ]]; then - nchanl=-999 - - cat << EOF > input + for dtype in ${gesanl}; do + + source prep_step + + if [[ ${dtype} == "anl" ]]; then + data_file="${type}_anl.${PDY}${cyc}.ieee_d" + bcor_file=bcor.${data_file} + ctl_file=${type}_anl.ctl + bcor_ctl=bcor.${ctl_file} + input_file=${type}_anl + else + data_file="${type}.${PDY}${cyc}.ieee_d" + bcor_file=bcor.${data_file} + ctl_file=${type}.ctl + bcor_ctl=bcor.${ctl_file} + input_file=${type} + fi + + if [[ -f input ]]; then + rm -f input + fi + + # Check for 0 length input file here and avoid running + # the executable if $input_file doesn't exist or is 0 bytes + # + if [[ -s "${input_file}" ]]; then + nchanl=-999 + + cat << EOF > input &INPUT satname='${type}', iyy=${iyy}, @@ -153,47 +148,45 @@ for type in ${SATYPE}; do / EOF - startmsg - ./${bcor_exec} < input >> "${pgmout}" 2>>errfile - export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: ${bcor_exec} failed for instrument ${type} and datatype ${dtype}!" - exit "${err}" - fi - + startmsg + "./${bcor_exec}" < input >> "${pgmout}" 2>> errfile + export err=$? + if [[ "${err}" -ne 0 ]]; then + msg="FATAL ERROR: ${bcor_exec} failed for instrument ${type} and datatype ${dtype}!" + err_exit "${msg}" + fi -#------------------------------------------------------------------- -# move data, control, and stdout files to $TANKverf_rad and compress -# + #------------------------------------------------------------------- + # move data, control, and stdout files to $TANKverf_rad and compress + # - if [[ -s ${bcor_file} ]]; then - ${COMPRESS} "${bcor_file}" - fi + if [[ -s "${bcor_file}" ]]; then + ${COMPRESS} "${bcor_file}" + fi - if [[ -s ${bcor_ctl} ]]; then - ${COMPRESS} "${bcor_ctl}" - fi + if [[ -s "${bcor_ctl}" ]]; then + ${COMPRESS} "${bcor_ctl}" + fi - fi - done # dtype in $gesanl loop + fi + done # dtype in $gesanl loop done # type in $SATYPE loop - "${USHgfs}/rstprod.sh" tar_file=radmon_bcor.tar if compgen -G "bcor*.ieee_d*" > /dev/null || compgen -G "bcor*.ctl*" > /dev/null; then - tar -cf "${tar_file}" bcor*.ieee_d* bcor*.ctl* - ${COMPRESS} ${tar_file} - mv "${tar_file}.${Z}" "${TANKverf_rad}/." - - if [[ ${RAD_AREA} = "rgn" ]]; then - cwd=$(pwd) - cd "${TANKverf_rad}" || exit 1 - tar -xf "${tar_file}.${Z}" - rm -f "${tar_file}.${Z}" - cd "${cwd}" || exit 1 - fi + tar -cf "${tar_file}" bcor*.ieee_d* bcor*.ctl* + ${COMPRESS} "${tar_file}" + mv "${tar_file}.${Z}" "${TANKverf_rad}/." + + if [[ ${RAD_AREA} = "rgn" ]]; then + cwd=$(pwd) + cd "${TANKverf_rad}" || exit 1 + tar -xf "${tar_file}.${Z}" + rm -f "${tar_file}.${Z}" + cd "${cwd}" || exit 1 + fi fi ################################################################################ diff --git a/ush/radmon_verf_time.sh b/ush/radmon_verf_time.sh index 0158697304c..9f9ab5471df 100755 --- a/ush/radmon_verf_time.sh +++ b/ush/radmon_verf_time.sh @@ -81,7 +81,6 @@ diag_hdr=diag_hdr.txt diag=diag.txt obs_err=obs_err.txt -obs_hdr=obs_hdr.txt pen_err=pen_err.txt pen_hdr=pen_hdr.txt @@ -91,8 +90,8 @@ count_hdr=count_hdr.txt count_err=count_err.txt netcdf_boolean=".false." -if [[ ${RADMON_NETCDF} -eq 1 ]]; then - netcdf_boolean=".true." +if [[ "${RADMON_NETCDF}" -eq 1 ]]; then + netcdf_boolean=".true." fi DO_DATA_RPT=${DO_DATA_RPT:-1} @@ -108,13 +107,12 @@ LITTLE_ENDIAN=${LITTLE_ENDIAN:-0} time_exec=radmon_time.x USE_ANL=${USE_ANL:-0} -if [[ ${USE_ANL} -eq 1 ]]; then - gesanl="ges anl" +if [[ "${USE_ANL}" -eq 1 ]]; then + gesanl="ges anl" else - gesanl="ges" + gesanl="ges" fi - #-------------------------------------------------------------------- # Copy extraction program and base files to working directory #------------------------------------------------------------------- @@ -126,22 +124,22 @@ idd="${PDY:6:2}" ihh=${cyc} local_base="local_base" -if [[ ${DO_DATA_RPT} -eq 1 ]]; then - - if [[ -e ${base_file}.${Z} ]]; then - cpreq "${base_file}.${Z}" "./${local_base}.${Z}" - ${UNCOMPRESS} "${local_base}.${Z}" - else - cpreq "${base_file}" ./${local_base} - fi - - if [[ ! -s ./${local_base} ]]; then - echo "RED LIGHT: local_base file not found" - else - echo "Confirming local_base file is good = ${local_base}" - tar -xf ./${local_base} - echo "local_base is untarred" - fi +if [[ "${DO_DATA_RPT}" -eq 1 ]]; then + + if [[ -e "${base_file}.${Z}" ]]; then + cpreq "${base_file}.${Z}" "./${local_base}.${Z}" + ${UNCOMPRESS} "${local_base}.${Z}" + else + cpreq "${base_file}" "./${local_base}" + fi + + if [[ ! -s "./${local_base}" ]]; then + echo "RED LIGHT: local_base file not found" + else + echo "Confirming local_base file is good = ${local_base}" + tar -xf "./${local_base}" + echo "local_base is untarred" + fi fi export pgm=${time_exec} @@ -150,41 +148,40 @@ export pgm=${time_exec} #-------------------------------------------------------------------- for type in ${SATYPE}; do - if [[ ! -s ${type} ]]; then - echo "ZERO SIZED: ${type}" - continue - fi - - source prep_step - - for dtype in ${gesanl}; do - - if [[ -f input ]] - then - rm -f input - fi - - if [[ ${dtype} == "anl" ]]; then - data_file="${type}_anl.${PDY}${cyc}.ieee_d" - ctl_file=${type}_anl.ctl - time_ctl=time.${ctl_file} - else - data_file="${type}.${PDY}${cyc}.ieee_d" - ctl_file=${type}.ctl - time_ctl=time.${ctl_file} - fi - - if [[ ${REGIONAL_RR} -eq 1 ]]; then - time_file=${rgnHH}.time.${data_file}.${rgnTM} - else - time_file=time.${data_file} - fi - -#-------------------------------------------------------------------- -# Run program for given satellite/instrument -#-------------------------------------------------------------------- - nchanl=-999 - cat << EOF > input + if [[ ! -s ${type} ]]; then + echo "ZERO SIZED: ${type}" + continue + fi + + source prep_step + + for dtype in ${gesanl}; do + + if [[ -f input ]]; then + rm -f input + fi + + if [[ "${dtype}" == "anl" ]]; then + data_file="${type}_anl.${PDY}${cyc}.ieee_d" + ctl_file="${type}_anl.ctl" + time_ctl="time.${ctl_file}" + else + data_file="${type}.${PDY}${cyc}.ieee_d" + ctl_file="${type}.ctl" + time_ctl="time.${ctl_file}" + fi + + if [[ "${REGIONAL_RR}" -eq 1 ]]; then + time_file="${rgnHH}.time.${data_file}.${rgnTM}" + else + time_file="time.${data_file}" + fi + + #-------------------------------------------------------------------- + # Run program for given satellite/instrument + #-------------------------------------------------------------------- + nchanl=-999 + cat << EOF > input &INPUT satname='${type}', iyy=${iyy}, @@ -202,62 +199,59 @@ for type in ${SATYPE}; do / EOF - ./${time_exec} < input >> stdout."${type}" 2>>errfile - export err=$? + "./${time_exec}" < input >> "stdout.${type}" 2>> errfile + export err=$? - if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: failed to calculate radiance time statistics for instrument ${type} and datatype ${dtype}!" - exit "${err}" - fi + if [[ "${err}" -ne 0 ]]; then + echo "FATAL ERROR: failed to calculate radiance time statistics for instrument ${type} and datatype ${dtype}!" + exit "${err}" + fi -#------------------------------------------------------------------- -# move data, control, and stdout files to $TANKverf_rad and compress -#------------------------------------------------------------------- - cat "stdout.${type}" >> stdout.time + #------------------------------------------------------------------- + # move data, control, and stdout files to $TANKverf_rad and compress + #------------------------------------------------------------------- + cat "stdout.${type}" >> stdout.time - if [[ -s ${time_file} ]]; then - ${COMPRESS} "${time_file}" - fi + if [[ -s "${time_file}" ]]; then + ${COMPRESS} "${time_file}" + fi - if [[ -s ${time_ctl} ]]; then - ${COMPRESS} "${time_ctl}" - fi + if [[ -s "${time_ctl}" ]]; then + ${COMPRESS} "${time_ctl}" + fi - done + done done - "${USHgfs}/rstprod.sh" if compgen -G "time*.ieee_d*" > /dev/null || compgen -G "time*.ctl*" > /dev/null; then - tar_file=radmon_time.tar - tar -cf "${tar_file}" time*.ieee_d* time*.ctl* - ${COMPRESS} ${tar_file} - mv "${tar_file}.${Z}" "${TANKverf_rad}/." - - if [[ ${RAD_AREA} = "rgn" ]]; then - cwd=$(pwd) - cd "${TANKverf_rad}" || exit 1 - tar -xf "${tar_file}.${Z}" - rm -f "${tar_file}.${Z}" - cd "${cwd}" || exit 1 - fi + tar_file=radmon_time.tar + tar -cf "${tar_file}" time*.ieee_d* time*.ctl* + ${COMPRESS} "${tar_file}" + mv "${tar_file}.${Z}" "${TANKverf_rad}/." + + if [[ "${RAD_AREA}" == "rgn" ]]; then + cwd=$(pwd) + cd "${TANKverf_rad}" || exit 1 + tar -xf "${tar_file}.${Z}" + rm -f "${tar_file}.${Z}" + cd "${cwd}" || exit 1 + fi fi - - #################################################################### #------------------------------------------------------------------- # Begin error analysis and reporting #------------------------------------------------------------------- #################################################################### -if [[ ${DO_DATA_RPT} -eq 1 ]]; then +if [[ "${DO_DATA_RPT}" -eq 1 ]]; then -#--------------------------- -# build report disclaimer -# - cat << EOF > ${disclaimer} + #--------------------------- + # build report disclaimer + # + cat << EOF > "${disclaimer}" *********************** WARNING *************************** @@ -266,16 +260,15 @@ RECEIVED. PLEASE DIRECT REPLIES TO edward.safford@noaa.gov *********************** WARNING *************************** EOF + #------------------------------------------------------------------- + # Check for missing diag files + # + tmp_satype="./tmp_satype.txt" + echo "${SATYPE}" > "${tmp_satype}" + "${USHgfs}/radmon_diag_ck.sh" --rad "${radstat}" --sat "${tmp_satype}" --out "${diag}" -#------------------------------------------------------------------- -# Check for missing diag files -# - tmp_satype="./tmp_satype.txt" - echo "${SATYPE}" > ${tmp_satype} - "${USHgfs}/radmon_diag_ck.sh" --rad "${radstat}" --sat "${tmp_satype}" --out "${diag}" - - if [[ -s ${diag} ]]; then - cat << EOF > ${diag_hdr} + if [[ -s "${diag}" ]]; then + cat << EOF > "${diag_hdr}" Problem Reading Diagnostic File @@ -285,137 +278,134 @@ EOF EOF - cat ${diag_hdr} >> ${diag_report} - cat ${diag} >> ${diag_report} - - echo >> ${diag_report} - - rm -f "${diag_hdr}" - fi - -#------------------------------------------------------------------- -# move warning notification to TANKverf -# - if [[ -s ${diag} ]]; then - lines=$(wc -l <${diag}) - echo "lines in diag = ${lines}" - - if [[ ${lines} -gt 0 ]]; then - cat "${diag_report}" - cpfs "${diag}" "${TANKverf_rad}/bad_diag.${PDY}${cyc}" - else - rm -f "${diag_report}" - fi - fi - - - - #---------------------------------------------------------------- - # Identify bad_pen and bad_chan files for this cycle and - # previous cycle - - bad_pen=bad_pen.${PDY}${cyc} - bad_chan=bad_chan.${PDY}${cyc} - low_count=low_count.${PDY}${cyc} - - qdate=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") - pday="${qdate:0:8}" - - prev_bad_pen=bad_pen.${qdate} - prev_bad_chan=bad_chan.${qdate} - prev_low_count=low_count.${qdate} - - prev_bad_pen=${TANKverf_radM1}/${prev_bad_pen} - prev_bad_chan=${TANKverf_radM1}/${prev_bad_chan} - prev_low_count=${TANKverf_radM1}/${prev_low_count} - - if [[ -s ${bad_pen} ]]; then - echo "pad_pen = ${bad_pen}" - fi - if [[ -s ${prev_bad_pen} ]]; then - echo "prev_pad_pen = ${prev_bad_pen}" - fi - - if [[ -s ${bad_chan} ]]; then - echo "bad_chan = ${bad_chan}" - fi - if [[ -s ${prev_bad_chan} ]]; then - echo "prev_bad_chan = ${prev_bad_chan}" - fi - if [[ -s ${low_count} ]]; then - echo "low_count = ${low_count}" - fi - if [[ -s ${prev_low_count} ]]; then - echo "prev_low_count = ${prev_low_count}" - fi - - do_pen=0 - do_chan=0 - do_cnt=0 - - if [[ -s ${bad_pen} && -s ${prev_bad_pen} ]]; then - do_pen=1 - fi - - if [[ -s ${low_count} && -s ${prev_low_count} ]]; then - do_cnt=1 - fi - - #-------------------------------------------------------------------- - # avoid doing the bad_chan report for REGIONAL_RR sources -- because - # they run hourly they often have 0 count channels for off-hour runs. - # - if [[ -s ${bad_chan} && -s ${prev_bad_chan} && REGIONAL_RR -eq 0 ]]; then - do_chan=1 - fi - - #-------------------------------------------------------------------- - # Remove extra spaces in new bad_pen & low_count files - # - if [[ -s ${bad_pen} ]]; then - gawk '{$1=$1}1' "${bad_pen}" > tmp.bad_pen - mv -f tmp.bad_pen "${bad_pen}" - fi - if [[ -s ${low_count} ]]; then - gawk '{$1=$1}1' "${low_count}" > tmp.low_count - mv -f tmp.low_count "${low_count}" - fi - - echo " do_pen, do_chan, do_cnt = ${do_pen}, ${do_chan}, ${do_cnt}" - echo " diag_report = ${diag_report} " - if [[ ${do_pen} -eq 1 || ${do_chan} -eq 1 || ${do_cnt} -eq 1 || -s ${diag_report} ]]; then - - if [[ ${do_pen} -eq 1 ]]; then - - echo "calling radmon_err_rpt for pen" - ${radmon_err_rpt} "${prev_bad_pen}" "${bad_pen}" pen "${qdate}" \ - "${PDY}${cyc}" ${diag_report} ${pen_err} - fi - - if [[ ${do_chan} -eq 1 ]]; then - - echo "calling radmon_err_rpt for chan" - ${radmon_err_rpt} "${prev_bad_chan}" "${bad_chan}" chan "${qdate}" \ - "${PDY}${cyc}" ${diag_report} ${chan_err} - fi - - if [[ ${do_cnt} -eq 1 ]]; then - - echo "calling radmon_err_rpt for cnt" - ${radmon_err_rpt} "${prev_low_count}" "${low_count}" cnt "${qdate}" \ - "${PDY}${cyc}" ${diag_report} ${count_err} - fi - - #------------------------------------------------------------------- - # put together the unified error report with any obs, chan, and - # penalty problems and mail it - - if [[ -s ${obs_err} || -s ${pen_err} || -s ${chan_err} || -s ${count_err} || -s ${diag_report} ]]; then - - echo DOING ERROR REPORTING - - - cat << EOF > ${report} + { + cat "${diag_hdr}" + cat "${diag}" + echo + } >> "${diag_report}" + + rm -f "${diag_hdr}" + fi + + #------------------------------------------------------------------- + # move warning notification to TANKverf + # + if [[ -s "${diag}" ]]; then + lines=$(wc -l < "${diag}") + echo "lines in diag = ${lines}" + + if [[ "${lines}" -gt 0 ]]; then + cat "${diag_report}" + cpfs "${diag}" "${TANKverf_rad}/bad_diag.${PDY}${cyc}" + else + rm -f "${diag_report}" + fi + fi + + #---------------------------------------------------------------- + # Identify bad_pen and bad_chan files for this cycle and + # previous cycle + + bad_pen="bad_pen.${PDY}${cyc}" + bad_chan="bad_chan.${PDY}${cyc}" + low_count="low_count.${PDY}${cyc}" + + qdate=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") + + prev_bad_pen=bad_pen.${qdate} + prev_bad_chan=bad_chan.${qdate} + prev_low_count=low_count.${qdate} + + prev_bad_pen=${TANKverf_radM1}/${prev_bad_pen} + prev_bad_chan=${TANKverf_radM1}/${prev_bad_chan} + prev_low_count=${TANKverf_radM1}/${prev_low_count} + + if [[ -s "${bad_pen}" ]]; then + echo "pad_pen = ${bad_pen}" + fi + if [[ -s "${prev_bad_pen}" ]]; then + echo "prev_pad_pen = ${prev_bad_pen}" + fi + + if [[ -s "${bad_chan}" ]]; then + echo "bad_chan = ${bad_chan}" + fi + if [[ -s "${prev_bad_chan}" ]]; then + echo "prev_bad_chan = ${prev_bad_chan}" + fi + if [[ -s "${low_count}" ]]; then + echo "low_count = ${low_count}" + fi + if [[ -s "${prev_low_count}" ]]; then + echo "prev_low_count = ${prev_low_count}" + fi + + do_pen=0 + do_chan=0 + do_cnt=0 + + if [[ -s "${bad_pen}" && -s "${prev_bad_pen}" ]]; then + do_pen=1 + fi + + if [[ -s "${low_count}" && -s "${prev_low_count}" ]]; then + do_cnt=1 + fi + + #-------------------------------------------------------------------- + # avoid doing the bad_chan report for REGIONAL_RR sources -- because + # they run hourly they often have 0 count channels for off-hour runs. + # + if [[ -s "${bad_chan}" && -s "${prev_bad_chan}" && "${REGIONAL_RR}" -eq 0 ]]; then + do_chan=1 + fi + + #-------------------------------------------------------------------- + # Remove extra spaces in new bad_pen & low_count files + # + if [[ -s "${bad_pen}" ]]; then + gawk '{$1=$1}1' "${bad_pen}" > tmp.bad_pen + mv -f tmp.bad_pen "${bad_pen}" + fi + if [[ -s "${low_count}" ]]; then + gawk '{$1=$1}1' "${low_count}" > tmp.low_count + mv -f tmp.low_count "${low_count}" + fi + + echo " do_pen, do_chan, do_cnt = ${do_pen}, ${do_chan}, ${do_cnt}" + echo " diag_report = ${diag_report} " + if [[ "${do_pen}" -eq 1 || "${do_chan}" -eq 1 || "${do_cnt}" -eq 1 || -s "${diag_report}" ]]; then + + if [[ ${do_pen} -eq 1 ]]; then + + echo "calling radmon_err_rpt for pen" + ${radmon_err_rpt} "${prev_bad_pen}" "${bad_pen}" pen "${qdate}" \ + "${PDY}${cyc}" "${diag_report}" "${pen_err}" + fi + + if [[ "${do_chan}" -eq 1 ]]; then + + echo "calling radmon_err_rpt for chan" + ${radmon_err_rpt} "${prev_bad_chan}" "${bad_chan}" chan "${qdate}" \ + "${PDY}${cyc}" "${diag_report}" "${chan_err}" + fi + + if [[ "${do_cnt}" -eq 1 ]]; then + + echo "calling radmon_err_rpt for cnt" + ${radmon_err_rpt} "${prev_low_count}" "${low_count}" cnt "${qdate}" \ + "${PDY}${cyc}" "${diag_report}" "${count_err}" + fi + + #------------------------------------------------------------------- + # put together the unified error report with any obs, chan, and + # penalty problems and mail it + + if [[ -s "${obs_err}" || -s "${pen_err}" || -s "${chan_err}" || -s "${count_err}" || -s "${diag_report}" ]]; then + + echo DOING ERROR REPORTING + + cat << EOF > "${report}" Radiance Monitor warning report Net: ${RADMON_SUFFIX} @@ -424,16 +414,16 @@ Radiance Monitor warning report EOF - if [[ -s ${diag_report} ]]; then - echo OUTPUTING DIAG_REPORT - cat ${diag_report} >> ${report} - fi + if [[ -s "${diag_report}" ]]; then + echo OUTPUTING DIAG_REPORT + cat "${diag_report}" >> "${report}" + fi - if [[ -s ${chan_err} ]]; then + if [[ -s "${chan_err}" ]]; then - echo OUTPUTING CHAN_ERR + echo OUTPUTING CHAN_ERR - cat << EOF > ${chan_hdr} + cat << EOF > "${chan_hdr}" The following channels report 0 observational counts over the past two cycles: @@ -442,14 +432,14 @@ EOF EOF - cat ${chan_hdr} >> ${report} - cat ${chan_err} >> ${report} + cat "${chan_hdr}" >> "${report}" + cat "${chan_err}" >> "${report}" - fi + fi - if [[ -s ${count_err} ]]; then + if [[ -s "${count_err}" ]]; then - cat << EOF > ${count_hdr} + cat << EOF > "${count_hdr}" @@ -460,14 +450,13 @@ Satellite/Instrument Obs Count Avg Count EOF - cat ${count_hdr} >> ${report} - cat ${count_err} >> ${report} - fi + cat "${count_hdr}" >> "${report}" + cat "${count_err}" >> "${report}" + fi + if [[ -s "${pen_err}" ]]; then - if [[ -s ${pen_err} ]]; then - - cat << EOF > ${pen_hdr} + cat << EOF > "${pen_hdr}" Penalty values outside of the established normal range were found @@ -477,51 +466,53 @@ EOF ============ ======= ====== Cycle Penalty Bound ----- ------- ----- EOF - cat "${pen_hdr}" >> "${report}" - cat "${pen_err}" >> "${report}" - rm -f "${pen_hdr}" - rm -f "${pen_err}" - fi - - echo >> ${report} - cat ${disclaimer} >> ${report} - echo >> ${report} - fi - - #------------------------------------------------------------------- - # dump report to log file - # - if [[ -s ${report} ]]; then - lines=$(wc -l <${report}) - if [[ ${lines} -gt 2 ]]; then - cat ${report} - - cpfs ${report} "${TANKverf_rad}/warning.${PDY}${cyc}" - fi - fi - - fi - - #------------------------------------------------------------------- - # copy new bad_pen, bad_chan, and low_count files to $TANKverf_rad - # - if [[ -s ${bad_chan} ]]; then - mv "${bad_chan}" "${TANKverf_rad}/." - fi - - if [[ -s ${bad_pen} ]]; then - mv "${bad_pen}" "${TANKverf_rad}/." - fi - - if [[ -s ${low_count} ]]; then - mv "${low_count}" "${TANKverf_rad}/." - fi + cat "${pen_hdr}" >> "${report}" + cat "${pen_err}" >> "${report}" + rm -f "${pen_hdr}" + rm -f "${pen_err}" + fi + + { + echo + cat "${disclaimer}" + echo + } >> "${report}" + fi + + #------------------------------------------------------------------- + # dump report to log file + # + if [[ -s "${report}" ]]; then + lines=$(wc -l < "${report}") + if [[ "${lines}" -gt 2 ]]; then + cat "${report}" + + cpfs "${report}" "${TANKverf_rad}/warning.${PDY}${cyc}" + fi + fi + + fi + + #------------------------------------------------------------------- + # copy new bad_pen, bad_chan, and low_count files to $TANKverf_rad + # + if [[ -s "${bad_chan}" ]]; then + mv "${bad_chan}" "${TANKverf_rad}/." + fi + + if [[ -s "${bad_pen}" ]]; then + mv "${bad_pen}" "${TANKverf_rad}/." + fi + + if [[ -s "${low_count}" ]]; then + mv "${low_count}" "${TANKverf_rad}/." + fi fi - for type in ${SATYPE}; do - rm -f "stdout.${type}" - done +for type in ${SATYPE}; do + rm -f "stdout.${type}" +done ################################################################################ #------------------------------------------------------------------- diff --git a/ush/regrid_gsiSfcIncr_to_tile.sh b/ush/regrid_gsiSfcIncr_to_tile.sh index aa922229f6c..ffc3d9b8200 100755 --- a/ush/regrid_gsiSfcIncr_to_tile.sh +++ b/ush/regrid_gsiSfcIncr_to_tile.sh @@ -9,19 +9,13 @@ source "${HOMEgfs}/ush/atparse.bash" # David New, Nov 2025 (parallelization updates) #------------------------------------------------------------------------------------------------- -export PGMOUT=${PGMOUT:-${pgmout:-'&1'}} -export PGMERR=${PGMERR:-${pgmerr:-'&2'}} - -export PGM=${REGRID_EXEC} -export pgm=${PGM} - NMEM_REGRID=${NMEM_REGRID:-1} CASE_IN=${CASE_IN:-${CASE_ENS}} LFHR=${LFHR:-6} # get resolutions -LONB_CASE_IN=$((4*${CASE_IN:1})) -LATB_CASE_IN=$((2*${CASE_IN:1})) +LONB_CASE_IN=$((4 * ${CASE_IN:1})) +LATB_CASE_IN=$((2 * ${CASE_IN:1})) ntiles=6 @@ -29,15 +23,11 @@ APREFIX_ENS="enkfgdas.t${cyc}z." LSOIL_INCR=${LSOIL_INCR:-2} -export n_vars=$(( LSOIL_INCR*2 )) +export n_vars=$((LSOIL_INCR * 2)) -soil_incr_vars="" -for vi in $( seq 1 "${LSOIL_INCR}" ); do - soil_incr_vars=${soil_incr_vars}'"soilt'${vi}'_inc"', -done -for vi in $( seq 1 "${LSOIL_INCR}" ); do - soil_incr_vars=${soil_incr_vars}'"slc'${vi}'_inc"', -done +soilt_incr_vars=$(seq -s ',' -f '"soilt%g_inc"' 1 "${LSOIL_INCR}") +slc_incr_vars=$(seq -s ',' -f '"slc%g_inc"' 1 "${LSOIL_INCR}") +export soil_incr_vars="${soilt_incr_vars},${slc_incr_vars}" if [[ "${DO_LAND_IAU}" = ".true." ]]; then IFS=',' read -ra landifhrs <<< "${IAUFHRS}" @@ -52,119 +42,186 @@ export jres=${LATB_CASE_IN} export ireso=${CASE_OUT:1} export jreso=${CASE_OUT:1} -regrid_nml_tmpl="${PARMgfs}/regrid_sfc/regrid.nml_tmpl" +regrid_nml_tmpl="${PARMgfs}/regrid_sfc/regrid.nml_tmpl" -if (( LFHR >= 0 )); then +if [[ "${LFHR}" -ge 0 ]]; then soilinc_fhrs=("${LFHR}") -else # construct restart times for deterministic member - soilinc_fhrs=("${assim_freq}") # increment file at middle of window - if [[ "${DOIAU:-}" == "YES" ]]; then # Update surface restarts at beginning of window - half_window=$(( assim_freq / 2 )) +else # construct restart times for deterministic member + soilinc_fhrs=("${assim_freq}") # increment file at middle of window + if [[ "${DOIAU:-}" == "YES" ]]; then # Update surface restarts at beginning of window + half_window=$((assim_freq / 2)) soilinc_fhrs+=("${half_window}") fi fi -# # Stage input files -# + +cd "${DATA}" || exit 1 # Create MDMD command file for fixed files -rm -f cmdfile.0 -touch cmdfile.0 -chmod 755 cmdfile.0 +rm -f cmdfile_in.0 +touch cmdfile_in.0 +chmod 755 cmdfile_in.0 # Append fixed files command file to master command file { -echo "#!/bin/bash" + echo "#!/bin/bash" -# input, fixed files -echo "cpreq ${FIXorog}/${CASE_IN}/gaussian.${LONB_CASE_IN}.${LATB_CASE_IN}.nc \ + # input, fixed files + echo "cpreq ${FIXorog}/${CASE_IN}/gaussian.${LONB_CASE_IN}.${LATB_CASE_IN}.nc \ ${DATA}/gaussian_scrip.nc" -# output, fixed files -echo "cpreq ${FIXorog}/${CASE_OUT}/${CASE_OUT}_mosaic.nc \ + # output, fixed files + echo "cpreq ${FIXorog}/${CASE_OUT}/${CASE_OUT}_mosaic.nc \ ${DATA}/${CASE_OUT}_mosaic.nc" -for n in $(seq 1 "${ntiles}"); do - echo "cpreq ${FIXorog}/${CASE_OUT}/sfc/${CASE_OUT}.mx${OCNRES_OUT}.vegetation_type.tile${n}.nc \ + for n in $(seq 1 "${ntiles}"); do + echo "cpreq ${FIXorog}/${CASE_OUT}/sfc/${CASE_OUT}.mx${OCNRES_OUT}.vegetation_type.tile${n}.nc \ ${DATA}/vegetation_type.tile${n}.nc" - echo "cpreq ${FIXorog}/${CASE_OUT}/${CASE_OUT}_grid.tile${n}.nc \ + echo "cpreq ${FIXorog}/${CASE_OUT}/${CASE_OUT}_grid.tile${n}.nc \ ${DATA}/${CASE_OUT}_grid.tile${n}.nc" -done -} > cmdfile.0 + done +} >> cmdfile_in.0 -for imem in $(seq 1 "${NMEM_REGRID}"); do - cmem=$(printf %03i "${imem}") - memchar="mem${cmem}" +if [[ "${NMEM_REGRID}" -gt 1 ]]; then - # If deterministic job, COMOUT_ATMOS_ANALYSIS_MEM is just COMOUT_ATMOS_ANALYSIS - if (( NMEM_REGRID > 1 )); then - MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl \ - COMIN_SOIL_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL + echo "INFO: Preparing to regrid surface increments for ${NMEM_REGRID} ensemble members." + for imem in $(seq 1 "${NMEM_REGRID}"); do - memdir="${DATA}/${memchar}" - mkdir -p "${memdir}" + memdir=$(printf "mem%03i" "${imem}") - if [[ "${imem}" -gt 1 ]]; then - in_dir+=", " - fi - in_dir+="\"./${memchar}/\"" - else - # If deterministic job, memdir is just DATA - memdir="${DATA}" + MEMDIR=${memdir} YMD=${PDY} HH=${cyc} declare_from_tmpl \ + COMIN_SOIL_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL \ + COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL - in_dir="'./'" - fi + # Create MPMD command file for this member + rm -f "cmdfile_in.${imem}" "cmdfile_out.${imem}" + touch "cmdfile_in.${imem}" "cmdfile_out.${imem}" + chmod 755 "cmdfile_in.${imem}" "cmdfile_out.${imem}" - # Create MPMD command file for this member - rm -f "cmdfile.${imem}" - touch "cmdfile.${imem}" - chmod 755 "cmdfile.${imem}" + # Create commands to stage input files + { + echo "#!/bin/bash" - # Create commands to stage input files - { - echo "#!/bin/bash" + echo "mkdir -p ${DATA}/${memdir}" - for FHR in "${soilinc_fhrs[@]}"; do - echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}increment.sfc.i00${FHR}.nc \ - ${memdir}/sfci00${FHR}.nc" - done - - if [[ "${DO_LAND_IAU}" = ".true." ]]; then - for FHI in "${landifhrs[@]}"; do - echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}increment.sfc.i00${FHI}.nc \ - ${memdir}/sfci00${FHI}.nc" + for FHR in "${soilinc_fhrs[@]}"; do + echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}increment.sfc.i00${FHR}.nc \ + ${DATA}/${memdir}/sfci00${FHR}.nc" + done + + if [[ "${DO_LAND_IAU}" = ".true." ]]; then + for FHI in "${landifhrs[@]}"; do + echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}increment.sfc.i00${FHI}.nc \ + ${DATA}/${memdir}/sfci00${FHI}.nc" + done + fi + } >> "cmdfile_in.${imem}" + + # Create commands to copy output files + { + echo "#!/bin/bash" + + if [[ "${DO_LAND_IAU}" = ".false." || "${RUN}" == "gdas" || "${RUN}" == "gfs" ]]; then + for FHR in "${soilinc_fhrs[@]}"; do + for n in $(seq 1 "${ntiles}"); do + echo "cpfs ${DATA}/${memdir}/sfci00${FHR}.mem${imem}.tile${n}.nc \ + ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.i00${FHR}.tile${n}.nc" + done + done + fi + + if [[ "${DO_LAND_IAU}" = ".true." ]]; then + for n in $(seq 1 "${ntiles}"); do + echo "cpfs ${DATA}/${memdir}/sfci.mem${imem}.tile${n}.nc \ + ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.tile${n}.nc" + done + fi + } >> "cmdfile_out.${imem}" + + done # for imem in $(seq 1 "${NMEM_REGRID}"); do + in_dir=$(seq -s ", " -f "'./mem%03g/'" 1 "${NMEM_REGRID}") + +else # deterministic member only (NMEM_REGRID=1) + + echo "INFO: Preparing to regrid surface increments for deterministic member." + + # Create commands to stage input files and append to the cmdfile.0 + { + for FHR in "${soilinc_fhrs[@]}"; do + echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}ensmean_increment.sfc.i00${FHR}.nc \ + ${DATA}/sfci00${FHR}.nc" done - fi - } > "cmdfile.${imem}" -done -# Create master MPMD command file -rm -f cmdfile -touch cmdfile -chmod 755 cmdfile + if [[ "${DO_LAND_IAU}" = ".true." ]]; then + for FHI in "${landifhrs[@]}"; do + echo "cpreq ${COMIN_SOIL_ANALYSIS_MEM}/${APREFIX_ENS}ensmean_increment.sfc.i00${FHI}.nc \ + ${DATA}/sfci00${FHI}.nc" + done + fi + } >> "cmdfile_in.0" + in_dir="'./'" + + # Create commands to copy output files + rm -f cmdfile_out.0 + touch cmdfile_out.0 + chmod 755 cmdfile_out.0 + { + echo "#!/bin/bash" + + if [[ "${DO_LAND_IAU}" = ".false." || "${RUN}" == "gdas" || "${RUN}" == "gfs" ]]; then + for FHR in "${soilinc_fhrs[@]}"; do + for n in $(seq 1 "${ntiles}"); do + echo "cpfs ${DATA}/sfci00${FHR}.mem1.tile${n}.nc \ + ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.i00${FHR}.tile${n}.nc" + done + done + fi + + if [[ "${DO_LAND_IAU}" = ".true." ]]; then + for n in $(seq 1 "${ntiles}"); do + echo "cpfs ${DATA}/sfci.mem1.tile${n}.nc \ + ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.tile${n}.nc" + done + fi + } >> "cmdfile_out.0" + +fi + +# Create master MPMD command files for input and output +rm -f cmdfile_in cmdfile_out +touch cmdfile_in cmdfile_out # Append all members' command files to master command file -{ -echo "${DATA}/cmdfile.0" # fixed files -for imem in $(seq 1 "${NMEM_REGRID}"); do - echo "${DATA}/cmdfile.${imem}" -done -} >> cmdfile +if [[ -f cmdfile_in.0 ]]; then + echo "${DATA}/cmdfile_in.0" >> cmdfile_in +fi +if [[ -f cmdfile_out.0 ]]; then + echo "${DATA}/cmdfile_out.0" >> cmdfile_out +fi +if [[ "${NMEM_REGRID}" -gt 1 ]]; then + for imem in $(seq 1 "${NMEM_REGRID}"); do + if [[ -f "cmdfile_in.${imem}" ]]; then + echo "${DATA}/cmdfile_in.${imem}" >> cmdfile_in + fi + if [[ -f "cmdfile_out.${imem}" ]]; then + echo "${DATA}/cmdfile_out.${imem}" >> cmdfile_out + fi + done +fi # Run MPMD to stage input files -"${USHgfs}/run_mpmd.sh" "cmdfile" && true +"${USHgfs}/run_mpmd.sh" "cmdfile_in" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "run_mpmd.sh failed!" + err_exit "run_mpmd.sh failed to copy input and fix data!" fi +mv mpmd.out mpmd_in.out # Finish defining input/output directory list export out_dir="${in_dir}" -# -# Regrid soil increments and save to COMOUT -# +# Regrid soil increments # Increments for offline analysis # If land IAU --> deterministic only. If no land IAU --> both deterministic and ensemble @@ -180,11 +237,12 @@ if [[ "${DO_LAND_IAU}" = ".false." || "${RUN}" == "gdas" || "${RUN}" == "gfs" ]] atparse < "${regrid_nml_tmpl}" >> "regrid.nml" # Run regrid executable - ${APRUN_REGRID} "${REGRID_EXEC}" 1>"${PGMOUT}" 2>"${PGMERR}" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "${REGRID_EXEC} failed, ABORT!" - fi + export pgm="${REGRID_EXEC}" + ${APRUN_REGRID} "${REGRID_EXEC}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "${REGRID_EXEC} failed to regrid soil increments (without LANDIAU), ABORT!" + fi done fi @@ -202,75 +260,19 @@ if [[ "${DO_LAND_IAU}" = ".true." ]]; then # Run regrid executable export pgm="${REGRID_EXEC}" - ${APRUN_REGRID} "${REGRID_EXEC}" 1>"${PGMOUT}" 2>"${PGMERR}" - export err=$? - if [[ ${err} -ne 0 ]]; then - err_exit "${pgm} failed, ABORT!" - fi -fi - -# -# Save regridded files to COMOUT -# - -for imem in $(seq 1 "${NMEM_REGRID}"); do - cmem=$(printf %03i "${imem}") - memchar="mem${cmem}" - - # If deterministic job, COMOUT_ATMOS_ANALYSIS_MEM is just COMOUT_ATMOS_ANALYSIS - if (( NMEM_REGRID > 1 )); then - MEMDIR=${memchar} YMD=${PDY} HH=${cyc} declare_from_tmpl \ - COMOUT_ATMOS_ANALYSIS_MEM:COM_ATMOS_ANALYSIS_TMPL - - memdir="${DATA}/${memchar}" - else - # If deterministic job, memdir is just DATA - memdir="${DATA}" - fi - - # Create MPMD command file for this member - rm -f "cmdfile.${imem}" - touch "cmdfile.${imem}" - chmod 755 "cmdfile.${imem}" - - { - echo "#!/bin/bash" - - if [[ "${DO_LAND_IAU}" = ".false." || "${RUN}" == "gdas" || "${RUN}" == "gfs" ]]; then - for FHR in "${soilinc_fhrs[@]}"; do - for n in $(seq 1 "${ntiles}"); do - echo "cpfs ${memdir}/sfci00${FHR}.mem${imem}.tile${n}.nc \ - ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.i00${FHR}.tile${n}.nc" - done - done + ${APRUN_REGRID} "${REGRID_EXEC}" + export err=$? + if [[ ${err} -ne 0 ]]; then + err_exit "${pgm} failed to regrid soil increments (with LANDIAU), ABORT!" fi - - if [[ "${DO_LAND_IAU}" = ".true." ]]; then - for n in $(seq 1 "${ntiles}"); do - echo "cpfs ${memdir}/sfci.mem${imem}.tile${n}.nc \ - ${COMOUT_ATMOS_ANALYSIS_MEM}/increment.sfc.tile${n}.nc" - done - fi - } > "cmdfile.${imem}" -done - -# Create master MPMD command file -rm -f cmdfile -touch cmdfile -chmod 755 cmdfile - -# Append all members' command files to master command file -{ -for imem in $(seq 1 "${NMEM_REGRID}"); do - echo "${DATA}/cmdfile.${imem}" -done -} >> cmdfile +fi # Run MPMD to save output files -"${USHgfs}/run_mpmd.sh" "cmdfile" && true +"${USHgfs}/run_mpmd.sh" "cmdfile_out" && true export err=$? if [[ ${err} -ne 0 ]]; then - err_exit "run_mpmd.sh failed!" + err_exit "run_mpmd.sh failed to copy output files to COMOUT, ABORT!" fi +mv mpmd.out mpmd_out.out exit 0 diff --git a/ush/rstprod.sh b/ush/rstprod.sh index 8370c79fa8c..56936eda221 100755 --- a/ush/rstprod.sh +++ b/ush/rstprod.sh @@ -3,15 +3,15 @@ #--------------------------------------------------------- # rstprod.sh # -# Restrict data from select sensors and satellites +# Restrict data from select sensors and satellites #--------------------------------------------------------- # Restrict select sensors and satellites export CHGRP_CMD=${CHGRP_CMD:-"chgrp ${group_name:-rstprod}"} rlist="saphir abi_g16" -for rtype in $rlist; do +for rtype in ${rlist}; do if compgen -G "*${rtype}*" > /dev/null; then - ${CHGRP_CMD} *${rtype}* + ${CHGRP_CMD} ./*"${rtype}"* fi done diff --git a/ush/run_mpmd.sh b/ush/run_mpmd.sh index 6ffbd3106d1..89e65daaa97 100755 --- a/ush/run_mpmd.sh +++ b/ush/run_mpmd.sh @@ -34,12 +34,12 @@ cmdfile=${1:?"run_mpmd requires an input file containing commands to execute in # If USE_CFP is not set, run in serial mode if [[ "${USE_CFP:-}" != "YES" ]]; then - echo "INFO: Using serial mode for MPMD job" - chmod 755 "${cmdfile}" - bash +x "${cmdfile}" > mpmd.out 2>&1 - rc=$? - cat mpmd.out - exit "${rc}" + echo "INFO: Using serial mode for MPMD job" + chmod 755 "${cmdfile}" + bash +x "${cmdfile}" > mpmd.out 2>&1 + rc=$? + cat mpmd.out + exit "${rc}" fi # Set OMP_NUM_THREADS to 1 to avoid oversubscription when doing MPMD @@ -58,56 +58,56 @@ cat << EOF INFO: The proc_num corresponds to the line in '${mpmd_cmdfile}' EOF -if [[ "${launcher:-}" =~ ^srun.* ]]; then # srun-based system e.g. Hera, Orion, etc. - - # Slurm requires a counter in front of each line in the script - # Read the incoming cmdfile and create srun usable cmdfile - nm=0 - # shellcheck disable=SC2312 - while IFS= read -r line; do - echo "${nm} ${line}" >> "${mpmd_cmdfile}" - ((nm=nm+1)) - done < "${cmdfile}" - - set +e - # shellcheck disable=SC2086 - ${launcher:-} ${mpmd_opt:-} -n ${nprocs} "${mpmd_cmdfile}" - err=$? - set_strict - -elif [[ "${launcher:-}" =~ ^mpiexec.* ]]; then # mpiexec - - # Redirect output from each process to its own stdout - # Read the incoming cmdfile and create mpiexec usable cmdfile - nm=0 - echo "#!/bin/bash" >> "${mpmd_cmdfile}" - # shellcheck disable=SC2312 - while IFS= read -r line; do - echo "${line} > mpmd.${nm}.out" >> "${mpmd_cmdfile}" - ((nm=nm+1)) - done < "${cmdfile}" - chmod 755 "${mpmd_cmdfile}" - - # shellcheck disable=SC2086 - ${launcher:-} -np ${nprocs} ${mpmd_opt:-} "${mpmd_cmdfile}" - err=$? +if [[ "${launcher:-}" =~ ^srun.* ]]; then # srun-based system e.g. Hera, Orion, etc. + + # Slurm requires a counter in front of each line in the script + # Read the incoming cmdfile and create srun usable cmdfile + nm=0 + # shellcheck disable=SC2312 + while IFS= read -r line; do + echo "${nm} ${line}" >> "${mpmd_cmdfile}" + ((nm = nm + 1)) + done < "${cmdfile}" + + set +e + # shellcheck disable=SC2086 + ${launcher:-} ${mpmd_opt:-} -n ${nprocs} "${mpmd_cmdfile}" + err=$? + set_strict + +elif [[ "${launcher:-}" =~ ^mpiexec.* ]]; then # mpiexec + + # Redirect output from each process to its own stdout + # Read the incoming cmdfile and create mpiexec usable cmdfile + nm=0 + echo "#!/bin/bash" >> "${mpmd_cmdfile}" + # shellcheck disable=SC2312 + while IFS= read -r line; do + echo "${line} > mpmd.${nm}.out" >> "${mpmd_cmdfile}" + ((nm = nm + 1)) + done < "${cmdfile}" + chmod 755 "${mpmd_cmdfile}" + + # shellcheck disable=SC2086 + ${launcher:-} -np ${nprocs} ${mpmd_opt:-} "${mpmd_cmdfile}" + err=$? else - echo "FATAL ERROR: CFP is not usable with launcher: '${launcher:-}'" - err=1 + echo "FATAL ERROR: CFP is not usable with launcher: '${launcher:-}'" + err=1 fi # On success concatenate processor specific output into a single mpmd.out if [[ ${err} -eq 0 ]]; then - rm -f "${mpmd_cmdfile}" - out_files=$(find . -name 'mpmd.*.out') - for file in ${out_files}; do - cat "${file}" >> mpmd.out - rm -f "${file}" - done - cat mpmd.out + rm -f "${mpmd_cmdfile}" + out_files=$(find . -name 'mpmd.*.out') + for file in ${out_files}; do + cat "${file}" >> mpmd.out + rm -f "${file}" + done + cat mpmd.out fi exit "${err}" diff --git a/ush/syndat_getjtbul.sh b/ush/syndat_getjtbul.sh index 16c41b21efe..0ce21ef7efd 100755 --- a/ush/syndat_getjtbul.sh +++ b/ush/syndat_getjtbul.sh @@ -7,7 +7,7 @@ # 2-digit year starting in column 20 or a 4-digit year # starting in column 20. # Mar 2013, DStokes - modified for WCOSS. Added option to email developer. -# Oct 2013, DStokes - Add check of stormname length and truncate if needed +# Oct 2013, DStokes - Add check of stormname length and truncate if needed # in response to recent problems with JTWC reports. # Remove option to email developer. # @@ -17,142 +17,136 @@ # Imported variables that must be passed in: # DATA - path to working directory -# pgmout - string indicating path to for standard output file # TANK_TROPCY - path to home directory containing tropical cyclone record # data base -cd $DATA +cd "${DATA}" || exit 1 -if [ "$#" -ne '1' ]; then - echo "**NON-FATAL ERROR PROGRAM SYNDAT_GETJTBUL run date not in \ +if [[ "$#" -ne '1' ]]; then + echo "**NON-FATAL ERROR PROGRAM SYNDAT_GETJTBUL run date not in \ positional parameter 1" - -echo "Leaving sub-shell syndat_getjtbul.sh to recover JTWC Bulletins" \ - >> $pgmout -echo " " >> $pgmout - - exit + exit fi run_date=$1 ymd=${run_date:2:6} -echo $PDYm1 -pdym1=$PDYm1 - -echo " " >> $pgmout -echo "Entering sub-shell syndat_getjtbul.sh to recover JTWC Bulletins" \ - >> $pgmout -echo " " >> $pgmout +echo "${PDYm1}" +pdym1=${PDYm1} +echo +echo "Entering sub-shell syndat_getjtbul.sh to recover JTWC Bulletins" +echo -if test ${cyc} -eq "00" -then +if [[ "${cyc}" -eq "00" ]]; then -# For 00Z cycle, need to go to prior day's tank -# --------------------------------------------- + # For 00Z cycle, need to go to prior day's tank + # --------------------------------------------- - jtwcdir=$TANK_TROPCY/${PDY}/wtxtbul - jtwcdirm1=$TANK_TROPCY/$pdym1/wtxtbul + jtwcdir="${TANK_TROPCY}/${PDY}/wtxtbul" + jtwcdirm1="${TANK_TROPCY}/${pdym1}/wtxtbul" else - jtwcdir=$TANK_TROPCY/${PDY}/wtxtbul + jtwcdir="${TANK_TROPCY}/${PDY}/wtxtbul" fi - set +x echo echo " Run date is ${run_date}" echo echo " PDY is ${PDY}" echo -echo " pdym1 is $pdym1" +echo " pdym1 is ${pdym1}" echo echo " ymddir is ${PDY}" echo set_trace -find=$ymd" "${cyc} -echo "looking for string $find in $jtwcdir/tropcyc" >> $pgmout +find="${ymd} ${cyc}" +echo "looking for string ${find} in ${jtwcdir}/tropcyc" rm -f jtwcbul -grep "$ymd ${cyc}" $jtwcdir/tropcyc | grep JTWC > jtwcbul -if [ -s jtwcbul ]; then - echo "String found: contents of JTWC bulletin are:" >> $pgmout - cat jtwcbul >> $pgmout +# shellcheck disable=SC2312 +grep "${ymd} ${cyc}" "${jtwcdir}/tropcyc" | grep JTWC > jtwcbul +if [[ -s jtwcbul ]]; then + echo "String found: contents of JTWC bulletin are:" + cat jtwcbul else - echo "String not found: no JTWC bulletins available for this run" >> $pgmout + echo "String not found: no JTWC bulletins available for this run" fi -if test ${cyc} -eq "00" -then - grep "$ymd ${cyc}" $jtwcdirm1/tropcyc | grep JTWC >> jtwcbul - if [ -s jtwcbul ]; then - echo "String found: contents of JTWC bulletin are:" >> $pgmout - cat jtwcbul >> $pgmout - else - echo "String not found: no JTWC bulletins available for this run" >> $pgmout - fi +if [[ "${cyc}" == "00" ]]; then + # shellcheck disable=SC2312 + grep "${ymd} ${cyc}" "${jtwcdirm1}/tropcyc" | grep JTWC >> jtwcbul + if [[ -s jtwcbul ]]; then + echo "String found: contents of JTWC bulletin are:" + cat jtwcbul + else + echo "String not found: no JTWC bulletins available for this run" + fi fi # Check for and truncate stormnames with length greater than nine characters and leave rest of record intact. # This spell makes no attempt to correct any other potential errors in the record format. perl -wpi.ORIG -e 's/(^.... ... )(\S{9,9})(\S{1,})/$1$2/' jtwcbul diff jtwcbul.ORIG jtwcbul > jtwcbul_changes.txt -if [ -s jtwcbul_changes.txt ]; then - echo "***WARNING: SOME JTWC VITALS SEGMENTS REQUIRED PRELIMINARY MODIFICATION!" - cat jtwcbul_changes.txt +if [[ -s jtwcbul_changes.txt ]]; then + echo "***WARNING: SOME JTWC VITALS SEGMENTS REQUIRED PRELIMINARY MODIFICATION!" + cat jtwcbul_changes.txt fi # Execute bulletin processing -[ -s jtwcbul ] && echo "Processing JTWC bulletin halfs into tcvitals records" >> $pgmout +if [[ -s jtwcbul ]]; then + echo "Processing JTWC bulletin halfs into tcvitals records" +fi -pgm=$(basename ${EXECgfs}/syndat_getjtbul.x) +pgm=$(basename "${EXECgfs}/syndat_getjtbul.x") export pgm -if [ -s prep_step ]; then - set +u - source prep_step - set -u +if [[ -s prep_step ]]; then + set +u + source prep_step + set -u else - [ -f errfile ] && rm errfile - unset FORT00 $(env | grep "^FORT[0-9]\{1,\}=" | awk -F= '{print $1}') + [[ -f errfile ]] && rm errfile + # shellcheck disable=SC2046,SC2312 + unset FORT00 $(env | grep "^FORT[0-9]\{1,\}=" | awk -F= '{print $1}') fi rm -f fnoc export FORT11=jtwcbul export FORT51=fnoc -time -p ${EXECgfs}/${pgm} >> $pgmout 2> errfile +# shellcheck disable=SC2312 +time -p "${EXECgfs}/${pgm}" 2> errfile errget=$? -###cat errfile -cat errfile >> $pgmout +cat errfile rm errfile set +x echo -echo 'The foreground exit status for SYNDAT_GETJTBUL is ' $errget +echo "The foreground exit status for SYNDAT_GETJTBUL is ${errget}" echo set_trace -if [ "$errget" -gt '0' ];then - if [ "$errget" -eq '1' ];then - msg="No JTWC bulletins in $jtwcdir/tropcyc, no JTWC tcvitals \ -available for qctropcy for ${run_date}" - if [[ "$RUN" == "gfs" ]]; then - if [[ "${SENDSDM}" == "YES" ]]; then - export ecf_family=$(echo $ECF_NAME |awk 'BEGIN {FS="/j"} {print $1}') - echo $msg > $COMOUT/${NET}_${RUN}.t${cyc}z.emailbody - echo "export subject='No JTWC bulletins available for ${run_date} ${RUN} run'" >$COMOUT/${NET}_${RUN}.t${cyc}z.emailvar - # JY echo "export maillist='sdm@noaa.gov'" >> $COMOUT/${NET}_${RUN}.t${cyc}z.emailvar - echo "export maillist=$maillist" >> $COMOUT/${NET}_${RUN}.t${cyc}z.emailvar - ecflow_client --run ${ecf_family}/j${RUN}_jtwc_bull_email +if [[ "${errget}" -gt '0' ]]; then + if [[ "${errget}" -eq '1' ]]; then + msg="No JTWC bulletins in ${jtwcdir}/tropcyc, no JTWC tcvitals available for qctropcy for ${run_date}" + if [[ "${RUN}" == "gfs" ]]; then + if [[ "${SENDSDM}" == "YES" ]]; then + ecf_family=$(echo "${ECF_NAME}" | awk 'BEGIN {FS="/j"} {print $1}') + export ecf_family + echo "${msg}" > "${COMOUT}/${NET}_${RUN}.t${cyc}z.emailbody" + echo "export subject='No JTWC bulletins available for ${run_date} ${RUN} run'" > "${COMOUT}/${NET}_${RUN}.t${cyc}z.emailvar" + # JY echo "export maillist='sdm@noaa.gov'" >> $COMOUT/${NET}_${RUN}.t${cyc}z.emailvar + echo "export maillist=${maillist}" >> "${COMOUT}/${NET}_${RUN}.t${cyc}z.emailvar" + ecflow_client --run "${ecf_family}/j${RUN}_jtwc_bull_email" + fi fi - fi - else - echo "**NON-FATAL ERROR PROGRAM SYNDAT_GETJTBUL FOR ${run_date} \ -RETURN CODE $errget" - fi + else + echo "**NON-FATAL ERROR PROGRAM SYNDAT_GETJTBUL FOR ${run_date} \ +RETURN CODE ${errget}" + fi else - echo "program SYNDAT_GETJTBUL completed normally for ${run_date}, JTWC \ + echo "program SYNDAT_GETJTBUL completed normally for ${run_date}, JTWC \ rec. passed to qctropcy" fi set +x @@ -163,13 +157,13 @@ echo "----------------------------------------------------------" echo set_trace -if [ "$errget" -eq '0' ];then - echo "Completed JTWC tcvitals records are:" >> $pgmout - cat fnoc >> $pgmout +if [[ "${errget}" -eq '0' ]]; then + echo "Completed JTWC tcvitals records are:" + cat fnoc fi -echo "Leaving sub-shell syndat_getjtbul.sh to recover JTWC Bulletins" \ - >> $pgmout -echo " " >> "${pgmout}" +echo "Leaving sub-shell syndat_getjtbul.sh to recover JTWC Bulletins" + +echo " " exit diff --git a/ush/syndat_qctropcy.sh b/ush/syndat_qctropcy.sh index 022851c3e45..deef9ad515a 100755 --- a/ush/syndat_qctropcy.sh +++ b/ush/syndat_qctropcy.sh @@ -63,7 +63,7 @@ # (Default: not set) # TIMEIT - optional time and resource reporting (Default: not set) -ARCHSYND=${ARCHSYND:-$COMROOTp3/gfs/prod/syndat} +ARCHSYND=${ARCHSYND:-${COMROOTp3}/gfs/prod/syndat} HOMENHC=${HOMENHC:-/gpfs/dell2/nhc/save/guidance/storm-data/ncep} TANK_TROPCY=${TANK_TROPCY:-${DCOMROOT}/us007003} @@ -71,47 +71,41 @@ slmask=${slmask:-${FIXgfs}/am/syndat_slmask.t126.gaussian} copy_back=${copy_back:-YES} files_override=${files_override:-""} -cd $DATA +cd "${DATA}" || exit 2 msg="Tropical Cyclone tcvitals QC processing has begun" set +x echo -echo $msg +echo "${msg}" echo set_trace -echo $msg >> $pgmout -if [ "$#" -ne '1' ]; then - msg="**NON-FATAL ERROR PROGRAM SYNDAT_QCTROPCY run date not in \ +if [[ "$#" -ne '1' ]]; then + msg="**NON-FATAL ERROR PROGRAM SYNDAT_QCTROPCY run date not in \ positional parameter 1" - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout - msg="**NO TROPICAL CYCLONE tcvitals processed --> non-fatal" - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout - -# Copy null files into "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.$tmmark" and -# "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.$tmmark" so later ftp attempts will find and -# copy the zero-length file and avoid wasting time with multiple attempts -# to remote machine(s) -# (Note: Only do so if files don't already exist) - - if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" ]]; then - touch "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" - fi - if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" ]]; then - touch "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" - fi - - exit + set +x + echo + echo "${msg}" + echo + msg="**NO TROPICAL CYCLONE tcvitals processed --> non-fatal" + echo + echo "${msg}" + echo + + # Copy null files into "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.$tmmark" and + # "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.$tmmark" so later ftp attempts will find and + # copy the zero-length file and avoid wasting time with multiple attempts + # to remote machine(s) + # (Note: Only do so if files don't already exist) + + if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" ]]; then + touch "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" + fi + if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" ]]; then + touch "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" + fi + + exit fi run_date=$1 @@ -124,29 +118,30 @@ set_trace year=${run_date:0:4} - # Copy the seasonal statistics from archive directory to local -cpreq $ARCHSYND/syndat_akavit akavit; touch akavit -cpreq $ARCHSYND/syndat_dateck dateck -cpreq $ARCHSYND/syndat_stmcat.scr stmcat.scr; touch stmcat.scr -cpreq $ARCHSYND/syndat_stmcat stmcat; touch stmcat -cpreq $ARCHSYND/syndat_sthisto sthisto -cpreq $ARCHSYND/syndat_sthista sthista +cpreq "${ARCHSYND}/syndat_akavit" akavit +touch akavit +cpreq "${ARCHSYND}/syndat_dateck" dateck +cpreq "${ARCHSYND}/syndat_stmcat.scr" stmcat.scr +touch stmcat.scr +cpreq "${ARCHSYND}/syndat_stmcat" stmcat +touch stmcat +cpreq "${ARCHSYND}/syndat_sthisto" sthisto +cpreq "${ARCHSYND}/syndat_sthista" sthista touch dateck -dateck_size=$(ls -l dateck | awk '{ print $5 }') -if [ $dateck_size -lt 10 ]; then - msg="***WARNING: Archive run date check file not available or shorter than expected.\ +dateck_size=$(find ./ -name dateck -printf "%s") + +if [[ ${dateck_size} -lt 10 ]]; then + msg="WARNING: Archive run date check file not available or shorter than expected.\ Using dummy date 1900010100 to allow code to continue" - echo 1900010100 > dateck - set +x - echo -e "\n${msg}\n" - set_trace - echo $msg >> $pgmout + echo 1900010100 > dateck + set +x + echo -e "\n${msg}\n" + set_trace fi - # Generate the correct RUNID and FILES value based on $NET, $RUN and $cyc # Copy this into parm file, then cat the remaining switches in the parm file # Note: FILES=T for 00Z GDAS at tm00 (last run of day centered on 00Z) @@ -154,136 +149,133 @@ fi # 12Z GDAS at tm00 (last run of day centered on 12Z) # 18Z GDAS at tm00 (last run of day centered on 18Z) -net=$NET +net="${NET}" files=F, -if [ "$RUN" = 'ndas' ]; then - net=ndas -elif [ "$RUN" = 'gdas' ]; then - files=T, +if [[ "${RUN}" == 'ndas' ]]; then + net=ndas +elif [[ "${RUN}" == 'gdas' ]]; then + files=T, fi -if [ -n "$files_override" ]; then # for testing, typically want FILES=F - files_override=$(echo "$files_override" | tr [a-z] [A-Z] | tr -d [.] | cut -c 1) - if [ "$files_override" = 'T' -o "$files_override" = 'F' ]; then - msg="***WARNING: Variable files setting will be overriden from $files to $files_override. Override expected if testing." - files=$files_override - else - msg="***WARNING: Invalid attempt to override files setting. Will stay with default for this job" - fi - set +x - echo -e "\n${msg}\n" - set_trace - echo $msg >> $pgmout + +if [[ -n "${files_override}" ]]; then # for testing, typically want FILES=F + files_override=${files_override^^} + files_override=${files_override//./} + files_override=${files_override:0:1} + if [[ "${files_override}" == 'T' || "${files_override}" == 'F' ]]; then + msg="WARNING: Variable files setting will be overriden from ${files} to ${files_override}. Override expected if testing." + files=${files_override} + else + msg="WARNING: Invalid attempt to override files setting. Will stay with default for this job" + fi + set +x + echo -e "\n${msg}\n" + set_trace fi -echo " &INPUT RUNID = '${net}_${tmmark}_${cyc}', FILES = $files " > vitchk.inp -cat ${PARMgfs}/relo/syndat_qctropcy.${RUN}.parm >> vitchk.inp +echo " &INPUT RUNID = '${net}_${tmmark}_${cyc}', FILES = ${files} " > vitchk.inp +cat "${PARMgfs}/relo/syndat_qctropcy.${RUN}.parm" >> vitchk.inp # Copy the fixed fields -cpreq ${FIXgfs}/am/syndat_fildef.vit fildef.vit -cpreq ${FIXgfs}/am/syndat_stmnames stmnames - +cpreq "${FIXgfs}/am/syndat_fildef.vit" fildef.vit +cpreq "${FIXgfs}/am/syndat_stmnames" stmnames rm -f nhc fnoc lthistry - ######################################################################### # There are five possible sources of tropical cyclone bogus messages # All are input to program syndat_qctropcy # ------------------------------------------------------------------ -if [ -s ${HOMENHC}/tcvitals ]; then - echo "tcvitals found" >> $pgmout - cpreq ${HOMENHC}/tcvitals nhc +if [[ -s "${HOMENHC}/tcvitals" ]]; then + echo "tcvitals found" + cpreq "${HOMENHC}/tcvitals" nhc else - echo "WARNING: tcvitals not found, create empty tcvitals" >> $pgmout - > nhc + echo "WARNING: tcvitals not found, create empty tcvitals" fi # NHC ... copy into working directory as nhc; copy to archive touch nhc -[ "$copy_back" = 'YES' ] && cat nhc >> $ARCHSYND/syndat_tcvitals.$year +if [[ "${copy_back}" == 'YES' ]]; then + cat nhc >> "${ARCHSYND}/syndat_tcvitals.${year}" +fi mv -f nhc nhc1 -${USHgfs}/parse-storm-type.pl nhc1 > nhc +"${USHgfs}/parse-storm-type.pl" nhc1 > nhc cpreq -p nhc nhc.ORIG # JTWC/FNOC ... execute syndat_getjtbul script to write into working directory # as fnoc; copy to archive -${USHgfs}/syndat_getjtbul.sh ${run_date} +"${USHgfs}/syndat_getjtbul.sh" "${run_date}" touch fnoc -[ "$copy_back" = 'YES' ] && cat fnoc >> $ARCHSYND/syndat_tcvitals.$year +if [[ "${copy_back}" == 'YES' ]]; then + cat fnoc >> "${ARCHSYND}/syndat_tcvitals.${year}" +fi mv -f fnoc fnoc1 -${USHgfs}/parse-storm-type.pl fnoc1 > fnoc +"${USHgfs}/parse-storm-type.pl" fnoc1 > fnoc if [[ "${SENDDBN}" == "YES" ]]; then - $DBNROOT/bin/dbn_alert MODEL SYNDAT_TCVITALS $job $ARCHSYND/syndat_tcvitals.$year + "${DBNROOT}/bin/dbn_alert" MODEL SYNDAT_TCVITALS "${job}" "${ARCHSYND}/syndat_tcvitals.${year}" fi ######################################################################### - -cpreq $slmask slmask.126 - +cpreq "${slmask}" slmask.126 # Execute program syndat_qctropcy -pgm=$(basename ${EXECgfs}/syndat_qctropcy.x) +pgm=$(basename "${EXECgfs}/syndat_qctropcy.x") export pgm -if [ -s prep_step ]; then - set +u - source prep_step - set -u +if [[ -s prep_step ]]; then + set +u + source prep_step + set -u else - [ -f errfile ] && rm errfile - unset FORT00 $(env | grep "^FORT[0-9]\{1,\}=" | awk -F= '{print $1}') + [[ -f errfile ]] && rm errfile + # shellcheck disable=SC2046,SC2312 + unset FORT00 $(env | grep "^FORT[0-9]\{1,\}=" | awk -F= '{print $1}') fi -echo "${run_date}" > run_date.dat +echo "${run_date}" > run_date.dat export FORT11=slmask.126 export FORT12=run_date.dat -${EXECgfs}/${pgm} >> $pgmout 2> errfile +"${EXECgfs}/${pgm}" errqct=$? -###cat errfile -cat errfile >> $pgmout -rm errfile set +x echo -echo "The foreground exit status for SYNDAT_QCTROPCY is " $errqct +echo "The foreground exit status for SYNDAT_QCTROPCY is ${errqct}" echo set_trace -if [ "$errqct" -gt '0' ];then - msg="**NON-FATAL ERROR PROGRAM SYNDAT_QCTROPCY RETURN CODE $errqct" - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout - msg="**NO TROPICAL CYCLONE tcvitals processed --> non-fatal" - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout - -# In the event of a ERROR in PROGRAM SYNDAT_QCTROPCY, copy null files into -# "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.$tmmark" and "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.$tmmark" -# so later ftp attempts will find and copy the zero-length file and avoid -# wasting time with multiple attempts to remote machine(s) -# (Note: Only do so if files don't already exist) - - if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" ]]; then - touch "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" - fi - if [[ ! -s ${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark} ]]; then - touch "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" - fi - - exit +if [[ "${errqct}" -gt '0' ]]; then + msg="**NON-FATAL ERROR PROGRAM SYNDAT_QCTROPCY RETURN CODE ${errqct}" + set +x + echo + echo "${msg}" + echo + set_trace + msg="**NO TROPICAL CYCLONE tcvitals processed --> non-fatal" + set +x + echo + echo "${msg}" + echo + set_trace + + # In the event of a ERROR in PROGRAM SYNDAT_QCTROPCY, copy null files into + # "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.$tmmark" and "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.$tmmark" + # so later ftp attempts will find and copy the zero-length file and avoid + # wasting time with multiple attempts to remote machine(s) + # (Note: Only do so if files don't already exist) + + if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" ]]; then + touch "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" + fi + if [[ ! -s ${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark} ]]; then + touch "${COMOUT_OBS}/${RUN}.${cycle}.jtwc-fnoc.tcvitals.${tmmark}" + fi + + exit fi set +x echo @@ -293,17 +285,16 @@ echo "----------------------------------------------------------" echo set_trace -if [ "$copy_back" = 'YES' ]; then - cat lthistry>>$ARCHSYND/syndat_lthistry.$year - cpfs akavit $ARCHSYND/syndat_akavit - cpfs dateck $ARCHSYND/syndat_dateck - cpfs stmcat.scr $ARCHSYND/syndat_stmcat.scr - cpfs stmcat $ARCHSYND/syndat_stmcat - cpfs sthisto $ARCHSYND/syndat_sthisto - cpfs sthista $ARCHSYND/syndat_sthista +if [[ "${copy_back}" == 'YES' ]]; then + cat lthistry >> "${ARCHSYND}/syndat_lthistry.${year}" + cpfs akavit "${ARCHSYND}/syndat_akavit" + cpfs dateck "${ARCHSYND}/syndat_dateck" + cpfs stmcat.scr "${ARCHSYND}/syndat_stmcat.scr" + cpfs stmcat "${ARCHSYND}/syndat_stmcat" + cpfs sthisto "${ARCHSYND}/syndat_sthisto" + cpfs sthista "${ARCHSYND}/syndat_sthista" fi - diff nhc nhc.ORIG > /dev/null errdiff=$? @@ -311,54 +302,50 @@ errdiff=$? # Update NHC file in ${HOMENHC} ################################### -if test "$errdiff" -ne '0' -then +if [[ "${errdiff}" -ne 0 ]]; then - if [ "$copy_back" = 'YES' -a ${envir} = 'prod' ]; then - if [ -s ${HOMENHC}/tcvitals ]; then - cpfs nhc ${HOMENHC}/tcvitals - fi + if [[ "${copy_back}" == 'YES' && ${envir} == 'prod' ]]; then + if [[ -s "${HOMENHC}/tcvitals" ]]; then + cpfs nhc "${HOMENHC}/tcvitals" + fi - err=$? + err=$? - if [ "$err" -ne '0' ]; then - msg="###ERROR: Previous NHC Synthetic Data Record File \ + if [[ "${err}" -ne 0 ]]; then + msg="###ERROR: Previous NHC Synthetic Data Record File \ ${HOMENHC}/tcvitals not updated by syndat_qctropcy" - else - msg="Previous NHC Synthetic Data Record File \ + else + msg="Previous NHC Synthetic Data Record File \ ${HOMENHC}/tcvitals successfully updated by syndat_qctropcy" - fi + fi - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout - fi + set +x + echo + echo "${msg}" + echo + set_trace + fi else - msg="Previous NHC Synthetic Data Record File ${HOMENHC}/tcvitals \ + msg="Previous NHC Synthetic Data Record File ${HOMENHC}/tcvitals \ not changed by syndat_qctropcy" - set +x - echo - echo $msg - echo - set_trace - echo $msg >> $pgmout + set +x + echo + echo "${msg}" + echo + set_trace fi ################################### - # This is the file that connects to the later RELOCATE and/or PREP scripts cpfs current "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" # Create the DBNet alert if [[ "${SENDDBN}" == "YES" ]]; then - "${DBNROOT}/bin/dbn_alert" "MODEL" "GDAS_TCVITALS" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" + "${DBNROOT}/bin/dbn_alert" "MODEL" "GDAS_TCVITALS" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" fi # Write JTWC/FNOC Tcvitals to /com path since not saved anywhere else diff --git a/ush/tropcy_relocate.sh b/ush/tropcy_relocate.sh index 38caecba3b6..d7b21daba56 100755 --- a/ush/tropcy_relocate.sh +++ b/ush/tropcy_relocate.sh @@ -168,53 +168,46 @@ # #### -qid=$$ - # obtain the center date/time for relocation processing # ----------------------------------------------------- -if [ $# -ne 1 ] ; then - err0=1 +if [[ $# -ne 1 ]]; then + err0=1 else - run_date=$1 - if [ "${#run_date}" -ne '10' ]; then - err0=1 - else - cycle="t${run_date:8:2}z" - err0=0 - fi + run_date=$1 + if [[ "${#run_date}" -ne '10' ]]; then + err0=1 + else + cycle="t${run_date:8:2}z" + err0=0 + fi fi -if test $err0 -ne 0 -then -# problem with obtaining date record so exit - set +x - echo - echo "problem with obtaining date record;" - echo "ABNORMAL EXIT!!!!!!!!!!!" - echo - set_trace - exit 9 +if [[ "${err0}" -ne 0 ]]; then + # problem with obtaining date record so exit + export err="${err0}" + msg="FATAL ERROR: problem with obtaining date record" + err_exit "${msg}" fi -modhr=$(expr ${cyc} % 3) +modhr=$((cyc % 3)) + +cat << EOF + +"CENTER DATE/TIME FOR RELOCATION PROCESSING IS ${run_date}" -set +x -echo -echo "CENTER DATE/TIME FOR RELOCATION PROCESSING IS ${run_date}" -echo -set_trace +EOF #---------------------------------------------------------------------------- # Create variables needed for this script and its children # -------------------------------------------------------- -envir_getges=${envir_getges:-$envir} -if [ $modhr -eq 0 ]; then - network_getges=${network_getges:-global} +envir_getges=${envir_getges:-${envir}} +if [[ "${modhr}" -eq 0 ]]; then + network_getges=${network_getges:-global} else - network_getges=${network_getges:-gfs} + network_getges=${network_getges:-gfs} fi GRIBVERSION=${GRIBVERSION:-"grib2"} @@ -235,173 +228,159 @@ GETTX=${GETTX:-${EXECgfs}/gettrk} echo "Attempt to perform tropical cyclone relocation for ${run_date}" -if [ $modhr -ne 0 ]; then +if [[ "${modhr}" -ne 0 ]]; then -# if center date/time for relocation processing isn't a multiple of 3-hrs, exit -# ----------------------------------------------------------------------------- - - set +x - echo - echo "cannot perform tropical cyclone processing because cycle hour is not a multiple of 3-hrs;" - echo "ABNORMAL EXIT!!!!!!!!!!!" - echo - set_trace - exit 9 + # if center date/time for relocation processing isn't a multiple of 3-hrs, exit + # ----------------------------------------------------------------------------- + export err=9 + msg="FATAL ERROR: cannot perform tropical cyclone processing because cycle hour is not a multiple of 3-hrs" + err_exit "${msg}" fi -for fhr in 6 12 ;do - if [ ! -s tcvitals.m${fhr} ]; then # This should never exist, right ???? - -# create a null tcvitals file for 06 or 12 hours ago -# use getges to overwrite with any found - - >tcvitals.m${fhr} - set +x - echo -echo "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" -echo " Get TCVITALS file valid for -$fhr hrs relative to center" -echo " relocation processing date/time" -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - ${USHgfs}/getges.sh -e $envir_getges -n $network_getges \ - -v ${run_date} -f $fhr -t tcvges tcvitals.m${fhr} - set +x - echo -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - fi +for fhr in 6 12; do + if [[ ! -s "tcvitals.m${fhr}" ]]; then # This should never exist, right ???? + + # create a null tcvitals file for 06 or 12 hours ago + # use getges to overwrite with any found + + rm -f "tcvitals.m${fhr}" + touch "tcvitals.m${fhr}" + cat << EOF + +VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + Get TCVITALS file valid for -${fhr} hrs relative to center + relocation processing date/time +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + "${USHgfs}/getges.sh" -e "${envir_getges}" -n "${network_getges}" \ + -v "${run_date}" -f "${fhr}" -t tcvges "tcvitals.m${fhr}" + cat << EOF + +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + fi done # Next line needed to assure that only an analysis file will have the # relocation codes run on it export CMODEL=gdas -if [ "$GRIBVERSION" = "grib1" ]; then - export gribver=1 - pgpref=pgbg +if [[ "${GRIBVERSION}" == "grib1" ]]; then + export gribver=1 + pgpref=pgbg else - export gribver=2 # default - pgpref=pg2g + export gribver=2 # default + pgpref=pg2g fi -for fhr in $( seq -6 $BKGFREQ 3 ) ; do - - if [ $fhr -lt 0 ]; then - tpref=m$(expr $fhr \* -1) - elif [ $fhr -eq 0 ]; then - tpref=es - elif [ $fhr -gt 0 ]; then - tpref=p$fhr - fi - - sges=sg${tpref}prep - if [[ ${fhr} -lt -3 ]]; then - sges=NULL - fi - echo $sges -# stype=sigg${tpref} - stype=natg${tpref} - if [[ "${RUN}" = cdas1 ]]; then - stype="sigg${tpref}" ## for cfs - fi - pges=pg${tpref}prep - ptype=${pgpref}${tpref} - - if [ $sges != NULL -a ! -s $sges ]; then - set +x - echo -echo "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" -echo " Get global sigma GUESS valid for $fhr hrs relative to center" -echo " relocation processing date/time" -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - ${USHgfs}/getges.sh -e $envir_getges -n $network_getges \ - -v ${run_date} -t $stype $sges - errges=$? - if test $errges -ne 0; then -# problem obtaining global sigma first guess so exit - set +x - echo - echo "problem obtaining global sigma guess valid $fhr hrs relative \ -to center relocation date/time;" - echo "ABNORMAL EXIT!!!!!!!!!!!" - echo - set_trace - exit 9 - fi - -# For center time sigma guess file obtained via getges, store pathname from -# getges into ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.$tmmark and, for now, -# also in ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark - if relocation processing stops -# due to an error or due to no input tcvitals records found, then the center -# time sigma guess will not be modified and this getges file will be read in -# subsequent PREP processing; if relocation processing continues and the -# center sigma guess is modified, then ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark will -# be removed later in this script {the subsequent PREP step will correctly -# update ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark to point to the sgesprep file -# updated here by the relocation} -# ---------------------------------------------------------------------------- - - if [ $fhr = "0" ]; then - "${USHgfs}/getges.sh" -e "${envir_getges}" -n "${network_getges}" -v "${run_date}" \ - -t "${stype}" > "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.${tmmark}" - cpfs "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.${tmmark}" \ - "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.${tmmark}" - fi - set +x - echo -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - fi - if [ ! -s $pges ]; then - set +x - echo -echo "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" -echo " Get global pressure grib GUESS valid for $fhr hrs relative to center" -echo " relocation processing date/time" -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - ${USHgfs}/getges.sh -e $envir_getges -n $network_getges \ - -v ${run_date} -t $ptype $pges - errges=$? - if test $errges -ne 0; then -# problem obtaining global pressure grib guess so exit - set +x - echo - echo "problem obtaining global pressure grib guess valid $fhr hrs \ -relative to center relocation date/time;" - echo "ABNORMAL EXIT!!!!!!!!!!!" - echo - set_trace - exit 9 - fi - set +x - echo -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - echo - set_trace - fi +for fhr in $(seq -6 "${BKGFREQ}" 3); do + + if [[ "${fhr}" -lt 0 ]]; then + tpref="m$((-fhr))" + elif [[ ${fhr} -eq 0 ]]; then + tpref=es + elif [[ ${fhr} -gt 0 ]]; then + tpref="p${fhr}" + fi + + sges="sg${tpref}prep" + if [[ "${fhr}" -lt -3 ]]; then + sges=NULL + fi + echo "${sges}" + # stype=sigg${tpref} + stype="natg${tpref}" + if [[ "${RUN}" == cdas1 ]]; then + stype="sigg${tpref}" ## for cfs + fi + pges="pg${tpref}prep" + ptype="${pgpref}${tpref}" + + if [[ "${sges}" != NULL && ! -s "${sges}" ]]; then + cat << EOF + +VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + Get global sigma GUESS valid for ${fhr} hrs relative to center + relocation processing date/time +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + "${USHgfs}/getges.sh" -e "${envir_getges}" -n "${network_getges}" \ + -v "${run_date}" -t "${stype}" "${sges}" + errges=$? + if [[ "${errges}" -ne 0 ]]; then + # problem obtaining global sigma first guess so exit + export err="${errges}" + msg="FATAL ERROR: problem obtaining global sigma guess valid ${fhr} hrs relative to center relocation date/time" + err_exit "${msg}" + fi + + # For center time sigma guess file obtained via getges, store pathname from + # getges into ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.$tmmark and, for now, + # also in ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark - if relocation processing stops + # due to an error or due to no input tcvitals records found, then the center + # time sigma guess will not be modified and this getges file will be read in + # subsequent PREP processing; if relocation processing continues and the + # center sigma guess is modified, then ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark will + # be removed later in this script {the subsequent PREP step will correctly + # update ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark to point to the sgesprep file + # updated here by the relocation} + # ---------------------------------------------------------------------------- + + if [[ ${fhr} -eq 0 ]]; then + "${USHgfs}/getges.sh" -e "${envir_getges}" -n "${network_getges}" -v "${run_date}" \ + -t "${stype}" > "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.${tmmark}" + cpfs "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pre-relocate_pathname.${tmmark}" \ + "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.${tmmark}" + fi + cat << EOF + +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + fi + if [[ ! -s "${pges}" ]]; then + cat << EOF + +VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + Get global pressure grib GUESS valid for ${fhr} hrs relative to center + relocation processing date/time +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + "${USHgfs}/getges.sh" -e "${envir_getges}" -n "${network_getges}" \ + -v "${run_date}" -t "${ptype}" "${pges}" + errges=$? + if [[ "${errges}" -ne 0 ]]; then + # problem obtaining global pressure grib guess so exit + export err="${errges}" + msg="FATAL ERROR: problem obtaining global pressure grib guess valid ${fhr} hrs relative to center relocation date/time;" + err_exit "${msg}" + fi + cat << EOF + +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +EOF + fi done -if [ -f ${tstsp}syndata.tcvitals.$tmmark ]; then - cpreq ${tstsp}syndata.tcvitals.$tmmark tcvitals.now +if [[ -f "${tstsp}syndata.tcvitals.${tmmark}" ]]; then + cpreq "${tstsp}syndata.tcvitals.${tmmark}" tcvitals.now else - cpreq "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" "tcvitals.now" + cpreq "${COMOUT_OBS}/${RUN}.${cycle}.syndata.tcvitals.${tmmark}" "tcvitals.now" fi +if [[ -s tcvitals.m12 ]]; then cat tcvitals.m12 > VITL; fi +if [[ -s tcvitals.m6 ]]; then cat tcvitals.m6 >> VITL; fi +if [[ -s tcvitals.now ]]; then cat tcvitals.now >> VITL; fi -[ -s tcvitals.m12 ] && cat tcvitals.m12 > VITL -[ -s tcvitals.m6 ] && cat tcvitals.m6 >> VITL -[ -s tcvitals.now ] && cat tcvitals.now >> VITL - -MP_PULSE=0 -MP_TIMEOUT=600 +export MP_PULSE=0 +export MP_TIMEOUT=600 GDATE10=$(date --utc +%Y%m%d%H -d "${run_date:0:8} ${run_date:8:2} - 6 hours") +export GDATE10 # make unique combined tcvitals file for t-12, t-6 and t+0 -- # if tcvitals does not contains record from current time, skip relocation @@ -410,199 +389,179 @@ GDATE10=$(date --utc +%Y%m%d%H -d "${run_date:0:8} ${run_date:8:2} - 6 hours") grep "${PDY} ${cyc}" VITL errgrep=$? -> tcvitals -if [ $errgrep -ne 0 ] ; then - echo "NO TCVITAL RECORDS FOUND FOR ${run_date} - EXIT TROPICAL CYCLONE \ +rm -f tcvitals +touch tcvitals +if [[ "${errgrep}" -ne 0 ]]; then + echo "NO TCVITAL RECORDS FOUND FOR ${run_date} - EXIT TROPICAL CYCLONE \ RELOCATION PROCESSING" -# The existence of ${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.$tmmark file will tell the -# subsequent PREP processing that RELOCATION processing occurred, echo -# "NO RECORDS to process" into it to further tell PREP processing that records -# were not processed by relocation and the global sigma guess was NOT -# modified by tropical cyclone relocation (because no tcvitals records were -# found) -# Note: When tropical cyclone relocation does run to completion and the -# global sigma guess is modified, the parent script to this will echo -# "RECORDS PROCESSED" into ${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.$tmmark -# assuming it doesn't already exist (meaning "NO RECORDS to process" -# was NOT echoed into it here) -# ---------------------------------------------------------------------------- - - echo "NO RECORDS to process" > "${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.${tmmark}" - if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" ]]; then - touch "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" - fi + # The existence of ${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.$tmmark file will tell the + # subsequent PREP processing that RELOCATION processing occurred, echo + # "NO RECORDS to process" into it to further tell PREP processing that records + # were not processed by relocation and the global sigma guess was NOT + # modified by tropical cyclone relocation (because no tcvitals records were + # found) + # Note: When tropical cyclone relocation does run to completion and the + # global sigma guess is modified, the parent script to this will echo + # "RECORDS PROCESSED" into ${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.$tmmark + # assuming it doesn't already exist (meaning "NO RECORDS to process" + # was NOT echoed into it here) + # ---------------------------------------------------------------------------- + + echo "NO RECORDS to process" > "${COMOUT_OBS}/${RUN}.${cycle}.tropcy_relocation_status.${tmmark}" + if [[ ! -s "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" ]]; then + touch "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" + fi else - cat VITL >>tcvitals - grep "${PDY} ${cyc}" VITL > tcvitals.now1 - - -# create model forecast track location file -# $DATA/$RUN.$cycle.relocate.model_track.tm00 -# -------------------------------------------- - - ${USHgfs}/tropcy_relocate_extrkr.sh - err=$? - if [ $err -ne 0 ]; then - -# problem: script tropcy_relocate_extrkr.sh failed -# ------------------------------------------------ - - set +x - echo - echo "${USHgfs}/tropcy_relocate_extrkr.sh failed" - echo "ABNORMAL EXIT!!!!!!!!!!!" - echo - set_trace - exit 9 - fi - -# relocate model tropical cyclone vortices in ges sigma files -# ----------------------------------------------------------- - - rm -f fort.* - - ${NLN} $DATA/tcvitals.now1 fort.11 - ${NLN} $DATA/model_track.all fort.30 - ${NLN} $DATA/rel_inform1 fort.62 - ${NLN} $DATA/tcvitals.relocate0 fort.65 - - i1=20 - i2=53 - for fhr in $( seq -3 $BKGFREQ 3 ) ; do - - if [ $fhr -lt 0 ]; then - tpref=m$(expr $fhr \* -1) - elif [ $fhr -eq 0 ]; then - tpref=es - elif [ $fhr -gt 0 ]; then - tpref=p$fhr - fi - - ${NLN} $DATA/sg${tpref}prep fort.$i1 - ${NLN} $DATA/sg${tpref}prep.relocate fort.$i2 - - i1=$((i1+1)) - i2=$((i2+BKGFREQ)) - - done - -# if LATB or LONB is unset or <= 0, the sigma header values are used -# ------------------------------------------------------------------ - - set +u - [ -z "$LONB" ] && LONB=0 - [ -z "$LATB" ] && LATB=0 - set -u - - i1=0 - for gesfhr in $( seq 3 $BKGFREQ 9 ) ; do - - echo ${gesfhr} ${LONB} ${LATB} ${BKGFREQ} > "parm.${i1}" - - i1=$((i1+1)) - - done - -# setup and run the mpi relocation code -# ------------------------------------- - - export MP_EUILIB=us - export MP_EUIDEVICE=sn_all - export MP_USE_BULK_XFER=yes - export RELOX_threads=${RELOX_threads:-16} - export KMP_STACKSIZE=1024m - export OMP_NUM_THREADS=$RELOX_threads - export MP_TASK_AFFINITY=core:$RELOX_threads - - ${APRNRELOC:-mpirun.lsf} $RELOX >stdo.prints - errSTATUS=$? - -# copy relocation print output here and there -# ------------------------------------------- - - cat $DATA/stdo.prints >> $pgmout - cat $DATA/stdo.[0-9]* >> $pgmout - cat $DATA/stdo.prints >> relocate.out - cat $DATA/stdo.[0-9]* >> relocate.out - -# check for success -# ----------------- - - echo; set_trace - if [ "$errSTATUS" -gt '0' ]; then - exit 9 - fi - -# further check for success -# ------------------------- - - for fhr in $( seq -3 $BKGFREQ 3 ) ; do - - if [ $fhr -lt 0 ]; then - tpref=m$(expr $fhr \* -1) - elif [ $fhr -eq 0 ]; then - tpref=es - elif [ $fhr -gt 0 ]; then - tpref=p$fhr - fi - - sges=sg${tpref}prep - - if [ -s $sges.relocate ] ; then - mv $sges.relocate $sges - else - -# problem: $sges.relocate does not exist -# -------------------------------------- - - echo "FATAL ERROR: The file ${sges}.relocate does not exist" - exit 9 - fi - done - - if [ -s tcvitals.relocate0 ]; then - mv tcvitals.relocate0 tcvitals - else - >tcvitals - fi - rm -f RELOCATE_GES cmd - - - cpfs "rel_inform1" "${COMOUT_OBS}/${RUN}.${cycle}.inform.relocate.${tmmark}" - cpfs "tcvitals" "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" - if [[ "${SENDDBN}" == "YES" ]]; then - if test "$RUN" = "gdas1" - then - "${DBNROOT}/bin/dbn_alert" "MODEL" "GDAS1_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.inform.relocate.${tmmark}" - "${DBNROOT}/bin/dbn_alert" "MODEL" "GDAS1_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" - fi - if test "$RUN" = "gfs" - then - "${DBNROOT}/bin/dbn_alert" "MODEL" "GFS_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.inform.relocate.${tmmark}" - "${DBNROOT}/bin/dbn_alert" "MODEL" "GFS_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" - fi - fi - -# -------------------------------------------------------------------------- -# Since relocation processing has ended sucessfully (and the center sigma -# guess has been modified), remove ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark (which -# had earlier had getges center sigma guess pathname written into it - in -# case of error or no input tcvitals records found) - the subsequent PREP -# step will correctly update ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark to point to -# the sgesprep file updated here by the relocation -# -------------------------------------------------------------------------- - - rm -f "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.${tmmark}" - - echo "TROPICAL CYCLONE RELOCATION PROCESSING SUCCESSFULLY COMPLETED FOR ${run_date}" + cat VITL >> tcvitals + grep "${PDY} ${cyc}" VITL > tcvitals.now1 + + # create model forecast track location file + # $DATA/$RUN.$cycle.relocate.model_track.tm00 + # -------------------------------------------- + + "${USHgfs}/tropcy_relocate_extrkr.sh" + err=$? + if [[ "${err}" -ne 0 ]]; then + + # problem: script tropcy_relocate_extrkr.sh failed + # ------------------------------------------------ + export err + echo "FATAL ERROR: ${USHgfs}/tropcy_relocate_extrkr.sh failed" + err_exit "${msg}" + fi + + # relocate model tropical cyclone vortices in ges sigma files + # ----------------------------------------------------------- + + rm -f fort.* + + ${NLN} "${DATA}/tcvitals.now1" fort.11 + ${NLN} "${DATA}/model_track.all" fort.30 + ${NLN} "${DATA}/rel_inform1" fort.62 + ${NLN} "${DATA}/tcvitals.relocate0" fort.65 + + i1=20 + i2=53 + for ((fhr = -3; fhr <= 3; fhr += BKGFREQ)); do + if [[ "${fhr}" -lt 0 ]]; then + tpref="m$((-fhr))" + elif [[ "${fhr}" -eq 0 ]]; then + tpref=es + elif [[ "${fhr}" -gt 0 ]]; then + tpref="p${fhr}" + fi + + ${NLN} "${DATA}/sg${tpref}prep" "fort.${i1}" + ${NLN} "${DATA}/sg${tpref}prep.relocate" "fort.${i2}" + + i1=$((i1 + 1)) + i2=$((i2 + BKGFREQ)) + + done + + # if LATB or LONB is unset or <= 0, the sigma header values are used + # ------------------------------------------------------------------ + + if [[ -z "${LONB}" ]]; then LONB=0; fi + if [[ -z "${LATB}" ]]; then LATB=0; fi + + i1=0 + for ((gesfhr = 3; gesfhr <= 0; gesfhr += BKGFREQ)); do + echo "${gesfhr} ${LONB} ${LATB} ${BKGFREQ}" > "parm.${i1}" + i1=$((i1 + 1)) + done + + # setup and run the mpi relocation code + # ------------------------------------- + + export MP_EUILIB=us + export MP_EUIDEVICE=sn_all + export MP_USE_BULK_XFER=yes + export RELOX_threads=${RELOX_threads:-16} + export KMP_STACKSIZE=1024m + export OMP_NUM_THREADS=${RELOX_threads} + export MP_TASK_AFFINITY=core:${RELOX_threads} + + ${APRNRELOC:-mpirun.lsf} "${RELOX}" > stdo.prints + errSTATUS=$? + + # copy relocation print output here and there + # ------------------------------------------- + + cat "${DATA}/stdo.prints" + cat "${DATA}/stdo.[0-9]"* + cat "${DATA}/stdo.prints" >> relocate.out + cat "${DATA}/stdo.[0-9]"* >> relocate.out + + # check for success + # ----------------- + + echo + if [[ "${errSTATUS}" -gt '0' ]]; then + export err="${errSTATUS}" + err_exit + fi + + # further check for success + # ------------------------- + + for ((fhr = -3; fhr <= 3; fhr += BKGFREQ)); do + if [[ "${fhr}" -lt 0 ]]; then + tpref="m$((-fhr))" + elif [[ "${fhr}" -eq 0 ]]; then + tpref=es + elif [[ "${fhr}" -gt 0 ]]; then + tpref="p${fhr}" + fi + + sges="sg${tpref}prep" + + if [[ -s "${sges}.relocate" ]]; then + mv "${sges}.relocate" "${sges}" + else + + # problem: $sges.relocate does not exist + # -------------------------------------- + + export err=9 + msg="FATAL ERROR: The file ${sges}.relocate does not exist" + err_exit "${msg}" + fi + done + + if [[ -s tcvitals.relocate0 ]]; then + mv tcvitals.relocate0 tcvitals + else + rm -f tcvitals + touch tcvitals + fi + rm -f RELOCATE_GES cmd + + cpfs "rel_inform1" "${COMOUT_OBS}/${RUN}.${cycle}.inform.relocate.${tmmark}" + cpfs "tcvitals" "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" + if [[ "${SENDDBN}" == "YES" ]]; then + "${DBNROOT}/bin/dbn_alert" "MODEL" "${RUN^^}_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.inform.relocate.${tmmark}" + "${DBNROOT}/bin/dbn_alert" "MODEL" "${RUN^^}_TCI" "${job}" "${COMOUT_OBS}/${RUN}.${cycle}.tcvitals.relocate.${tmmark}" + fi + + # -------------------------------------------------------------------------- + # Since relocation processing has ended sucessfully (and the center sigma + # guess has been modified), remove ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark (which + # had earlier had getges center sigma guess pathname written into it - in + # case of error or no input tcvitals records found) - the subsequent PREP + # step will correctly update ${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.$tmmark to point to + # the sgesprep file updated here by the relocation + # -------------------------------------------------------------------------- + + rm -f "${COMOUT_OBS}/${RUN}.${cycle}.sgesprep_pathname.${tmmark}" + + echo "TROPICAL CYCLONE RELOCATION PROCESSING SUCCESSFULLY COMPLETED FOR ${run_date}" # end GFDL ges manipulation # ------------------------- fi - exit 0 - diff --git a/ush/tropcy_relocate_extrkr.sh b/ush/tropcy_relocate_extrkr.sh index 42b53df4cf1..8427908ba6b 100755 --- a/ush/tropcy_relocate_extrkr.sh +++ b/ush/tropcy_relocate_extrkr.sh @@ -3,18 +3,13 @@ # This script is executed by the script tropcy_relocate.sh # -------------------------------------------------------- -export machine=${machine:-ZEUS} -export machine=$(echo $machine|tr '[a-z]' '[A-Z]') -#if [ $machine = ZEUS ] ; then -# module load intel -# module load mpt -#fi +export machine=${machine^^} +export err pgm # Variable "gribver" defines if input GRIB data is in # GRIB1 (gribver=1) or GRIB2 (gribver=2) format. export gribver=${gribver:-1} -user=$LOGNAME # PDYcyc - 10 digit date # RUN - network run (gfs, gdas, etc) # DATA - working directory @@ -24,14 +19,14 @@ user=$LOGNAME export APRNGETTX=${APRNGETTX:-""} TIMEIT="" -[ -s $DATA/timex ] && TIMEIT=$DATA/timex - -vdir=${vdir:-$DATA/trakout} -if [ ! -d ${vdir} ]; then - mkdir -p ${vdir} +if [[ -s "${DATA}/timex" ]]; then + TIMEIT="${DATA}/timex" fi -cd $vdir +vdir=${vdir:-${DATA}/trakout} +mkdir -p "${vdir}" + +cd "${vdir}" || exit 1 # This script kicks off the hurricane tracker system. You have the option of # running the tracker on several operational models (the system will @@ -40,7 +35,6 @@ cd $vdir # will ONLY be able to read GRIB data. To run the tracker, fill in the # required fields below on the "export" lines, then llsubmit this script. - # ------------------- # 1. ENTER MODEL TYPE # ------------------- @@ -55,8 +49,7 @@ cd $vdir # # Example: export CMODEL=gfs -export CMODEL=${CMODEL:-$RUN} - +export CMODEL=${CMODEL:-${RUN}} # ------------------- # 2. ENTER FILE NAME @@ -81,7 +74,6 @@ export CMODEL=${CMODEL:-$RUN} export INPFILE=${INPFILE:-} - # ------------------------------- # 3. ENTER FORECAST HOUR INTERVAL # ------------------------------- @@ -105,8 +97,7 @@ export FHINT=${FHINT:-03} # # Enter the starting date, in yyyymmddhh format, of the forecast: -export YYYYMMDDHH=$GDATE10 - +export YYYYMMDDHH=${GDATE10} # ------------------------- # 5. ENTER STORM IDENTIFIER @@ -118,7 +109,6 @@ export YYYYMMDDHH=$GDATE10 export INPSTORM= - # ----------------------------------------- # 6. ENTER NAME OF AUXILIARY TC VITALS FILE # ----------------------------------------- @@ -143,7 +133,6 @@ export INPSTORM= export AUXTCVIT= - # ----------------------------------------------------- # ENTER THRESHOLDS FOR USE IN VERIFYING STORM STRUCTURE # ----------------------------------------------------- @@ -175,7 +164,6 @@ export V850THRESH=3.000 # Set the default for background files to be 3 hourly export BKGFREQ=${BKGFREQ:-1} - # This script is the second in a set of 2 that starts the tracker for either # operational or user-defined model output. This script makes sure that the # data files exist, it also pulls all of the needed data records out of the @@ -184,29 +172,24 @@ export BKGFREQ=${BKGFREQ:-1} # updates the TC Vitals (if necessary). It then executes the gettrk # executable, which actually does the tracking. - -inpstorm=${INPSTORM} inpfile=${INPFILE} fhint=${FHINT} cmodel=${CMODEL} symdh=${YYYYMMDDHH} -auxtcvit=${AUXTCVIT} -user=$LOGNAME -#export TMPDIR=/nfstmp/${user}/trak/${RANDOM} -export TMPDIR=$DATA/trak/${RANDOM} -if [ ! -d $TMPDIR ]; then mkdir -p $TMPDIR; fi -if [ -s ${TMPDIR}/tmpsynvit ]; then rm ${TMPDIR}/tmpsynvit; fi -if [ -s ${TMPDIR}/tmprawvit ]; then rm ${TMPDIR}/tmprawvit; fi +export TMPDIR=${DATA}/trak/${RANDOM} +mkdir -p "${TMPDIR}" +rm -f "${TMPDIR}/tmpsynvit" +rm -f "${TMPDIR}/tmprawvit" export flag_pgb=${flag_pgb:-q} -wgrib_parmlist=" HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 SurfaceU SurfaceV ABSV:850 ABSV:700 PRMSL:MSL MSLET" +wgrib_parmlist="HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 SurfaceU SurfaceV ABSV:850 ABSV:700 PRMSL:MSL MSLET" -export maxtime=22 # Max number of forecast time levels +export maxtime=22 # Max number of forecast time levels -if [ ! -d ${vdir} ]; then mkdir -p ${vdir}; fi -if [ ! -d ${TMPDIR} ]; then mkdir -p ${TMPDIR}; fi +mkdir -p "${vdir}" +mkdir -p "${TMPDIR}" scc=${symdh:0:2} syy=${symdh:2:2} @@ -216,100 +199,124 @@ shh=${symdh:8:2} dishh=${shh} symd=${symdh:0:8} -case ${shh} in - 0|00) dishh="00";; - 3|03) dishh="03";; - 6|06) dishh="06";; - 12) dishh="12";; - 15) dishh="15";; - 18) dishh="18";; -esac - #---------------------------------------------------# # Convert the input model to lowercase letters and # check to see if it's a valid model, and assign a # model ID number to it. #---------------------------------------------------# -cmodel=$(echo ${cmodel} | tr "[A-Z]" "[a-z]") +cmodel=${cmodel,,} case ${cmodel} in - gdas) set +x; echo " "; echo " ++ operational GDAS chosen"; set_trace; - fcstlen=9 ; - fcsthrs="" - for fhr in $( seq 0 $BKGFREQ 9); do - fhrchar=$(printf %02d $fhr) - fcsthrs="$fcsthrs $fhrchar" - done - atcfnum=72 ; - atcfname="gdas" ; - atcfout="gdas" ; - if [ $BKGFREQ -eq 1 ]; then - atcffreq=100 - elif [ $BKGFREQ -eq 3 ]; then - atcffreq=300 - fi - mslpthresh=0.0015 - v850thresh=1.5000 - modtyp='global' - file_sequence="onebig" - lead_time_units='hours' - export PHASEFLAG=n - export WCORE_DEPTH=1.0 - #export PHASE_SCHEME=vtt - #export PHASE_SCHEME=cps - export PHASE_SCHEME=both - export STRUCTFLAG=n - export IKEFLAG=n - export trkrtype='tracker' - # g2_jpdtn sets the variable that will be used as "JPDTN" for - # the call to getgb2, if gribver=2. jpdtn=1 for ens data, - # jpdtn=0 for deterministic data. - g2_jpdtn=0 - model=8;; - gfs) set +x; echo " "; echo " ++ operational GFS chosen"; set_trace; - fcsthrsgfs=' 00 06 12 18 24 30 36 42 48 54 60 66 72 78'; - gfsdir=$COMIN; - gfsgfile=gfs.t${dishh}z.pgrbf; - model=1;; - mrf) set +x; echo " "; echo " ++ operational MRF chosen"; set_trace; - fcsthrsmrf=' 00 12 24 36 48 60 72'; - mrfdir=$COMIN; - mrfgfile=drfmr.t${dishh}z.pgrbf; - model=2;; - ukmet) set +x; echo " "; echo " ++ operational UKMET chosen"; set_trace; - fcsthrsukmet=' 00 12 24 36 48 60 72'; - ukmetdir=$COMIN; - ukmetgfile=ukmet.t${dishh}z.ukmet; - model=3;; - ecmwf) set +x; echo " "; echo " ++ operational ECMWF chosen"; set_trace; - fcsthrsecmwf=' 00 24 48 72'; - ecmwfdir=$COMIN; - ecmwfgfile=ecmgrb25.t12z; - model=4;; - ngm) set +x; echo " "; echo " ++ operational NGM chosen"; set_trace; - fcsthrsngm=' 00 06 12 18 24 30 36 42 48'; - ngmdir=$COMIN; - ngmgfile=ngm.t${dishh}z.pgrb.f; - model=5;; - nam) set +x; echo " "; echo " ++ operational Early NAM chosen"; set_trace; - fcsthrsnam=' 00 06 12 18 24 30 36 42 48'; - namdir=$COMIN; - namgfile=nam.t${dishh}z.awip32; - model=6;; - ngps) set +x; echo " "; echo " ++ operational NAVGEM chosen"; set_trace; - fcsthrsngps=' 00 12 24 36 48 60 72'; - #ngpsdir=/com/hourly/prod/hourly.${symd}; - ngpsdir=$OMIN; - ngpsgfile=fnoc.t${dishh}z; - model=7;; - other) set +x; echo " "; echo " Model selected by user is ${cmodel}, which is a "; - echo "user-defined model, NOT operational...."; echo " "; set_trace; - model=9;; - *) set +x; echo " "; echo " !!! Model selected is not recognized."; - echo " Model= ---> ${cmodel} <--- ..... Please submit the script again...."; - echo " "; set_trace; exit 8;; + gdas) + echo " " + echo " ++ operational GDAS chosen" + fcsthrs="" + for fhr in $(seq 0 "${BKGFREQ}" 9); do + fhrchar=$(printf %02d "${fhr}") + fcsthrs="${fcsthrs} ${fhrchar}" + done + atcfnum=72 + atcfname="gdas" + if [[ "${BKGFREQ}" -eq 1 ]]; then + atcffreq=100 + elif [[ "${BKGFREQ}" -eq 3 ]]; then + atcffreq=300 + fi + modtyp='global' + file_sequence="onebig" + lead_time_units='hours' + export PHASEFLAG=n + export WCORE_DEPTH=1.0 + export PHASE_SCHEME=both + export STRUCTFLAG=n + export IKEFLAG=n + export trkrtype='tracker' + # g2_jpdtn sets the variable that will be used as "JPDTN" for + # the call to getgb2, if gribver=2. jpdtn=1 for ens data, + # jpdtn=0 for deterministic data. + g2_jpdtn=0 + model=8 + ;; + gfs) + echo " " + echo " ++ operational GFS chosen" + fcsthrsgfs='00 06 12 18 24 30 36 42 48 54 60 66 72 78' + gfsdir="${COMIN}" + gfsgfile=gfs.t${dishh}z.pgrbf + model=1 + ;; + mrf) + echo " " + echo " ++ operational MRF chosen" + fcsthrsmrf='00 12 24 36 48 60 72' + mrfdir="${COMIN}" + mrfgfile=drfmr.t${dishh}z.pgrbf + model=2 + ;; + ukmet) + echo " " + echo " ++ operational UKMET chosen" + fcsthrsukmet='00 12 24 36 48 60 72' + ukmetdir="${COMIN}" + ukmetgfile=ukmet.t${dishh}z.ukmet + model=3 + ;; + ecmwf) + echo " " + echo " ++ operational ECMWF chosen" + ecmwfdir="${COMIN}" + ecmwfgfile=ecmgrb25.t12z + model=4 + ;; + ngm) + set +x + echo " " + echo " ++ operational NGM chosen" + set_trace + fcsthrsngm='00 06 12 18 24 30 36 42 48' + ngmdir="${COMIN}" + ngmgfile=ngm.t${dishh}z.pgrb.f + model=5 + ;; + nam) + echo " " + echo " ++ operational Early NAM chosen" + fcsthrsnam='00 06 12 18 24 30 36 42 48' + namdir="${COMIN}" + namgfile=nam.t${dishh}z.awip32 + model=6 + ;; + ngps) + echo " " + echo " ++ operational NAVGEM chosen" + fcsthrsngps='00 12 24 36 48 60 72' + #ngpsdir=/com/hourly/prod/hourly.${symd}; + ngpsdir="${COMIN}" + ngpsgfile=fnoc.t${dishh}z + model=7 + ;; + other) + cat << EOF +Model selected by user is ${cmodel}, which is a +user-defined model, NOT operational.... + +EOF + model=9 + ;; + *) + msg=$( + cat << EOF + +FATAL ERROR: Model selected is not recognized. +Model= ---> ${cmodel} <--- ..... Please submit the script again.... + +EOF + ) + err=8 + err_exit "${msg}" + ;; esac @@ -323,14 +330,11 @@ esac # if the model is user-defined. #------------------------------------------------- -fct=1 -while [ ${fct} -le 14 ]; -do - fh[${fct}]=99 - let fct=fct+1 +export fh +for ((fct = 1; fct <= 14; fct++)); do + fh[fct]=99 done - #------------------------------------------------------# # Set the directories for the operational files. For # a user-specified model, we need to process the @@ -338,142 +342,125 @@ done # data directory, etc..... #------------------------------------------------------# -if [ ${cmodel} = 'other' ]; then - -# This next bit of code tears apart the input file name to get the -# data directory and data file names. pos1, pos2, pos3 and pos4 -# refer to character string positions in the filename string. The -# idea of this next bit of code is to pull the file name apart to -# get a shell for the file name, so that if a user has a file -# name such as pgbf00.97090100, the script knows where in the -# string to substitute the forecast hours. IMPORTANT NOTE: The -# file name that the user enters must have the characters "XX" in -# in place of the forecast hour characters "00" in order for this -# to work. -# -# pos1= character position immediately before "00" starts -# pos2= character position at which "00" starts -# pos3= character position immediately after "00" -# pos4= character position of last character in name - - otherdir=$(dirname ${inpfile}) - fname=$(basename ${inpfile}) - - pos2=$(echo ${fname} | awk '{ match($0,/XX/); print RSTART }') - pos4=$(echo ${fname} | awk '{ match($0,/$/); print RSTART }') - let pos4=pos4-1 - let pos1=pos2-1 - let pos3=pos2+2 - - if [ ${pos2} -eq 0 ]; then - set +x - echo " " - echo " !!! ERROR! Something wrong with name of input file name for the" - echo " analysis file. Either the input file is missing, or you did not" - echo " replace the forecast hour characters 00 with XX. Please check the" - echo " name in the kickoff script and qsub it again. Exiting....." - echo " " - set_trace - exit 8 - fi - - fnamebeg=$(echo ${fname} | cut -c1-${pos1}) - if [ ${pos4} -ge ${pos3} ]; then - fnameend=$(echo ${fname} | cut -c${pos3}-${pos4}) - else - fnameend="" - fi - - fflag='y' - fhour=0 - fcsthrsother='' - fhrct=0 - while [ ${fflag} = 'y' ]; - do - - if [ ${fhrct} -eq 14 ]; then - set +x - echo " " - echo " !!! Exiting loop, only processing 14 forecast files ...." - echo " " - set_trace - break +if [[ "${cmodel}" == 'other' ]]; then + + # This next bit of code tears apart the input file name to get the + # data directory and data file names. pos1, pos2, pos3 and pos4 + # refer to character string positions in the filename string. The + # idea of this next bit of code is to pull the file name apart to + # get a shell for the file name, so that if a user has a file + # name such as pgbf00.97090100, the script knows where in the + # string to substitute the forecast hours. IMPORTANT NOTE: The + # file name that the user enters must have the characters "XX" in + # in place of the forecast hour characters "00" in order for this + # to work. + # + # pos1= character position immediately before "00" starts + # pos2= character position at which "00" starts + # pos3= character position immediately after "00" + # pos4= character position of last character in name + + otherdir=$(dirname "${inpfile}") + fname=$(basename "${inpfile}") + + fnamebeg=$(grep -Po '.*(?=XX)' <<< "${fname}") + fnameend=$(grep -Po '(?<=XX).*($)' <<< "${fname}") + + if [[ -z "${fnamebeg}" ]]; then + read -r -d '' msg << EOF +FATAL ERROR: Something wrong with name of input file name for the +analysis file. Either the input file is missing, or you did not +replace the forecast hour characters 00 with XX. Please check the +name in the kickoff script and qsub it again. +EOF + err=8 + err_exit "${msg}" fi - if [ ${fhour} -lt 10 ]; then - fhour=0${fhour} - fi + fflag='y' + fhour=0 + fcsthrsother='' + fhrct=0 + while [[ ${fflag} == 'y' ]]; do - if [ -s ${otherdir}/${fnamebeg}${fhour}${fnameend} ]; then - maxhour=${fhour} - fcsthrsother=${fcsthrsother}" ${fhour}" - set +x - echo " " - echo " +++ Found file ${fnamebeg}${fhour}${fnameend}" - echo " " - set_trace - let fhrct=fhrct+1 - else - fflag='n' - fi + if [[ "${fhrct}" -eq 14 ]]; then + cat << EOF - let fhour=fhour+fhint - - done - - if [ ! -s ${otherdir}/${fnamebeg}00${fnameend} ]; then - set +x - echo " " - echo " !!! ERROR in $(basename $0)" - echo " !!! Input analysis file cannot be found." - echo " !!! The tracker is looking for this file in: " - echo " !!! ----> ${otherdir}/${fnamebeg}00${fnameend}" - echo " !!! Please check the directory to make sure the file" - echo " !!! is there and then submit this job again." - echo " " - set_trace - exit 8 - fi - - set +x - echo " " - echo " Max forecast hour is $maxhour" - echo " List of forecast hours: $fcsthrsother" - echo " " - set_trace - -# -------------------------------------------------- -# In order for the fortran program to know how many -# forecast times there are and what those forecast -# hours are, we need to include this information in -# the namelist file. So first, put this information -# into an array, then at the end of this script, -# we'll put it into the namelist file. - - fhour=0 - fct=1 - while [ ${fct} -le 14 ]; - do - - if [ ${fhour} -le ${maxhour} ]; then - fh[${fct}]=${fhour} - else - fh[${fct}]=99 +!!! Exiting loop, only processing 14 forecast files .... + +EOF + break + fi + + fhour=$(printf '%02d' "${fhour}") + + if [[ -s "${otherdir}/${fnamebeg}${fhour}${fnameend}" ]]; then + maxhour=${fhour} + fcsthrsother="${fcsthrsother} ${fhour}" + cat << EOF + ++++ Found file ${fnamebeg}${fhour}${fnameend} + +EOF + fhrct=$((fhrct + 1)) + else + fflag='n' + fi + + fhour=$((fhour + fhint)) + + done + + if [[ ! -s "${otherdir}/${fnamebeg}00${fnameend}" ]]; then + msg=$( + cat << EOF + +!!! FATAL ERROR in $(basename "$0"): +!!! Input analysis file cannot be found. +!!! The tracker is looking for this file in: +!!! ----> ${otherdir}/${fnamebeg}00${fnameend} +!!! Please check the directory to make sure the file +!!! is there and then submit this job again. + +EOF + ) + err=8 + err_exit "${msg}" fi - let fct=fct+1 - let fhour=fhour+fhint + cat << EOF - done +Max forecast hour is ${maxhour} +List of forecast hours: ${fcsthrsother} +EOF + + # -------------------------------------------------- + # In order for the fortran program to know how many + # forecast times there are and what those forecast + # hours are, we need to include this information in + # the namelist file. So first, put this information + # into an array, then at the end of this script, + # we'll put it into the namelist file. + + fhour=0 + for ((fcnt = 1; fcnt <= 14; fcnt++)); do + if [[ "${fhour}" -le "${maxhour}" ]]; then + fh[fct]=${fhour} + else + fh[fct]=99 + fi + fhour=$((fhour + fhint)) + done fi -cpfs $DATA/tcvitals ${vdir}/vitals.${symd}${dishh} +cpfs "${DATA}/tcvitals" "${vdir}/vitals.${symd}${dishh}" -grep -v TEST ${vdir}/vitals.${symd}${dishh} | \ - awk 'substr($0,6,1) !~ /[8-9]/ {print $0}' >${vdir}/tempvit.nonameless +# shellcheck disable=SC2312 +grep -v TEST "${vdir}/vitals.${symd}${dishh}" | + awk 'substr($0,6,1) !~ /[8-9]/ {print $0}' > "${vdir}/tempvit.nonameless" -mv ${vdir}/tempvit.nonameless ${vdir}/vitals.${symd}${dishh} +mv "${vdir}/tempvit.nonameless" "${vdir}/vitals.${symd}${dishh}" #--------------------------------------------------------------# # Now run a fortran program that will read all the TC vitals @@ -492,18 +479,16 @@ syy6=${ymdh6ago:2:2} smm6=${ymdh6ago:4:2} sdd6=${ymdh6ago:6:2} shh6=${ymdh6ago:8:2} -symd6=${ymdh6ago:2:6} ymdh6ahead=$(date --utc +%Y%m%d%H -d "${symd} ${dishh} + 6 hours") syyp6=${ymdh6ahead:2:2} smmp6=${ymdh6ahead:4:2} sddp6=${ymdh6ahead:6:2} shhp6=${ymdh6ahead:8:2} -symdp6=${ymdh6ahead:2:6} vit_incr=6 -cat<$TMPDIR/suv_input +cat << EOF > "${TMPDIR}/suv_input" &datenowin dnow%yy=${syy}, dnow%mm=${smm}, dnow%dd=${sdd}, dnow%hh=${dishh}/ &dateoldin dold%yy=${syy6}, dold%mm=${smm6}, @@ -513,17 +498,20 @@ cat<$TMPDIR/suv_input &hourinfo vit_hr_incr=${vit_incr}/ EOF -numvitrecs=$(cat ${vdir}/vitals.${symd}${dishh} | wc -l) -if [ ${numvitrecs} -eq 0 ]; then - set +x - echo " " - echo "!!! ERROR -- There are no vitals records for this time period." - echo "!!! File ${vdir}/vitals.${symd}${dishh} is empty." - echo "!!! It could just be that there are no storms for the current" - echo "!!! time. Please check the dates and submit this job again...." - echo " " - set_trace - exit 8 +numvitrecs=$(wc -l "${vdir}/vitals.${symd}${dishh}") +if [[ ${numvitrecs} -eq 0 ]]; then + msg=$( + cat << EOF + +!!! FATAL ERROR: There are no vitals records for this time period. +!!! File ${vdir}/vitals.${symd}${dishh} is empty. +!!! It could just be that there are no storms for the current +!!! time. Please check the dates and submit this job again.... + +EOF + ) + err=8 + err_exit "${msg}" fi # - - - - - - - - - - - - - @@ -543,8 +531,8 @@ fi # was messing up the "(length($4) == 8)" statement logic. # - - - - - - - - - - - - - -sed -e "s/\:/ /g" ${vdir}/vitals.${symd}${dishh} > ${TMPDIR}/tempvit -mv ${TMPDIR}/tempvit ${vdir}/vitals.${symd}${dishh} +sed -e "s/\:/ /g" "${vdir}/vitals.${symd}${dishh}" > "${TMPDIR}/tempvit" +mv "${TMPDIR}/tempvit" "${vdir}/vitals.${symd}${dishh}" awk ' { @@ -560,78 +548,61 @@ awk ' printf ("%s19%s\n",substr($0,1,19),substr($0,20)) } } -} ' ${vdir}/vitals.${symd}${dishh} >${TMPDIR}/vitals.${symd}${dishh}.y4 - -mv ${TMPDIR}/vitals.${symd}${dishh}.y4 ${vdir}/vitals.${symd}${dishh} +} ' "${vdir}/vitals.${symd}${dishh}" > "${TMPDIR}/vitals.${symd}${dishh}.y4" -#cpfs $auxtcvit ${vdir}/vitals.${symd}${dishh} +mv "${TMPDIR}/vitals.${symd}${dishh}.y4" "${vdir}/vitals.${symd}${dishh}" -pgm=$(basename $SUPVX) -if [ -s $DATA/prep_step ]; then - set +e - . $DATA/prep_step - set_strict +pgm=$(basename "${SUPVX}") +if [[ -s "${DATA}/prep_step" ]]; then + source "${DATA}/prep_step" else - [ -f errfile ] && rm errfile - export XLFUNITS=0 - unset $(env | grep XLFUNIT | awk -F= '{print $1}') - - if [ -z "${XLFRTEOPTS:-}" ]; then - export XLFRTEOPTS="unit_vars=yes" - else - export XLFRTEOPTS="${XLFRTEOPTS}:unit_vars=yes" - fi - -fi - -if [ -s fort.* ]; then - rm fort.* + [[ -f errfile ]] && rm errfile + export XLFUNITS=0 + # shellcheck disable=SC2046,SC2312 + unset $(env | grep XLFUNIT | awk -F= '{print $1}') + export XLFRTEOPTS="${XLFRTEOPTS:+${XLFRTEOPTS}:}unit_vars=yes" fi -${NLN} ${vdir}/vitals.${symd}${dishh} fort.31 -${NLN} ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} fort.51 +rm -f fort.* -##$XLF_LINKSSH -#if [ -z $XLF_LINKSSH ] ; then -#if [ -s $XLF_LINKSSH ; then $XLF_LINKSSH ; fi -#fi +${NLN} "${vdir}/vitals.${symd}${dishh}" fort.31 +${NLN} "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}" fort.51 -$TIMEIT $SUPVX <$TMPDIR/suv_input > outout 2> errfile +${TIMEIT} "${SUPVX}" < "${TMPDIR}/suv_input" > outout 2> errfile err=$? -###cat errfile cat errfile >> outout cat outout >> supvit.out -set +u -[ -n "../$pgmout" ] && cat outout >> ../$pgmout -set -u +if [[ -n "${pgmout}" ]]; then + cat outout >> "../${pgmout}" +fi rm outout -set +x -echo -echo 'The foreground exit status for SUPVIT is ' $err -echo -set_trace - -if [ $err -eq 0 ]; then - set +x - echo " " - echo " Normal end for program supvitql (which updates TC vitals file)." - echo " " - set_trace +cat << EOF + +The foreground exit status for SUPVIT is ${err} + +EOF + +if [[ "${err}" -eq 0 ]]; then + cat << EOF + +Normal end for program supvitql (which updates TC vitals file). + +EOF else - set +x - echo " " - echo "!!! ERROR -- An error occurred while running supvitql, " - echo "!!! which is the program that updates the TC Vitals file." - echo "!!! Return code from supvitql = ${err}" - echo "!!! model= ${cmodel}, forecast initial time = ${symd}${dishh}" - echo "!!! Exiting...." - echo " " - set_trace -fi -if [[ ${err} -gt 0 ]]; then - exit 9 -fi + msg=$( + cat << EOF +!!! FATAL ERROR: An error occurred while running supvitql, +!!! which is the program that updates the TC Vitals file. +!!! Return code from supvitql = ${err} +!!! model= ${cmodel}, forecast initial time = ${symd}${dishh} +!!! Exiting.... + +EOF + ) + err=9 + err_exit "${msg}" +fi #------------------------------------------------------------------# # Now select all storms to be processed, that is, process every @@ -640,57 +611,52 @@ fi # then exit. #------------------------------------------------------------------# -numvitrecs=$(cat ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} | wc -l) -if [ ${numvitrecs} -eq 0 ]; then - set +x - echo " " - echo "!!! ERROR -- There are no vitals records for this time period " - echo "!!! in the UPDATED vitals file." - echo "!!! File ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} is empty." - echo "!!! Please check the dates and submit this job again...." - echo " " - set_trace - exit 8 +numvitrecs=$(wc -l "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}") +if [[ "${numvitrecs}" -eq 0 ]]; then + cat << EOF + +!!! ERROR -- There are no vitals records for this time period +!!! in the UPDATED vitals file. +!!! File ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} is empty. +!!! Please check the dates and submit this job again.... + +EOF + err=8 + err_exit fi -set +x -echo " " | tee storm_list -echo " " | tee -a storm_list -echo " " | tee -a storm_list -echo " *--------------------------------*" | tee -a storm_list -echo " | STORM SELECTION |" | tee -a storm_list -echo " *--------------------------------*" | tee -a storm_list -echo " " | tee -a storm_list -echo " Below is a list of the storms to be processed: " | tee -a storm_list -echo " " | tee -a storm_list -cat ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} | tee -a storm_list -echo " " | tee -a storm_list -set_trace - -set +u -[ -n "../$pgmout" ] && cat storm_list >> ../$pgmout -set -u +# shellcheck disable=SC2312 +cat << EOF | tee stormlist + + + +*--------------------------------* +| STORM SELECTION | +*--------------------------------* + +Below is a list of the storms to be processed: + +$(cat "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}") + +EOF + +if [[ -n "${pgmout}" ]]; then + cat storm_list >> "../${pgmout}" +fi rm storm_list -ict=1 -while [ $ict -le 15 ] -do - stormflag[${ict}]=3 - let ict=ict+1 +for ((ict = 1; ict <= 15; ict++)); do + stormflag[ict]=3 done dtg_current="${symd} ${dishh}00" -smax=$( grep "${dtg_current}" ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} | wc -l) +smax=$(grep -c "${dtg_current}" "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}") -sct=1 -while [ ${sct} -le ${smax} ] -do - stormflag[${sct}]=1 - let sct=sct+1 +for ((ict = 1; ict <= smax; ict++)); do + stormflag[sct]=1 done - #-----------------------------------------------------------------# # # ------ CUT APART INPUT GRIB FILES ------- @@ -711,201 +677,214 @@ done # sure to check the lbms in your fortran program after getgb). #-----------------------------------------------------------------# -set +x -echo " " -echo " -----------------------------------------" -echo " NOW CUTTING APART INPUT GRIB FILES TO " -echo " CREATE 1 BIG GRIB INPUT FILE " -echo " -----------------------------------------" -echo " " -set_trace +cat << EOF + +----------------------------------------- + NOW CUTTING APART INPUT GRIB FILES TO + CREATE 1 BIG GRIB INPUT FILE +----------------------------------------- + +EOF #grid='255 0 151 71 70000 190000 128 0000 340000 1000 1000 64' #grid='255 0 360 181 90000 0000 128 -90000 -1000 1000 1000 64' #grid='255 0 360 181 90000 0000 128 -90000 -1000 1000 1000 0' -regflag=$(grep NHC ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} | wc -l) +regflag=$(grep -c NHC "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}") # ---------------------------- # Process NGM, if selected # ---------------------------- -if [ ${model} -eq 5 ]; then - - grid='255 0 151 71 70000 190000 128 0000 340000 1000 1000 64' - - if [ ${regflag} = 'n' ]; then - set +x - echo " " - echo " *******************************************************************" - echo " !!! NGM model has been selected, but there are no storms in the" - echo " !!! TC Vitals file that are from NHC. Therefore, unless you have" - echo " !!! entered your own auxiliary TC vitals file that has a storm " - echo " !!! within the NGM domain, the tracker will exit after reading " - echo " !!! in the analysis data." - echo " *******************************************************************" - echo " " - set_trace - fi - - if [ -s ${vdir}/ngmlatlon.pgrb.${symd}${dishh} ]; then - rm ${vdir}/ngmlatlon.pgrb.${symd}${dishh} - fi - - for fhour in ${fcsthrsngm} - do - - if [ ! -s ${ngmdir}/${ngmgfile}${fhour} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! NGM File missing: ${ngmdir}/${ngmgfile}${fhour}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - set_trace - continue - fi - if [ -s $TMPDIR/tmpixfile ]; then rm $TMPDIR/tmpixfile; fi - ${GRBINDEX:?} ${ngmdir}/${ngmgfile}${fhour} $TMPDIR/tmpixfile - x1=$TMPDIR/tmpixfile - - set +x - echo " " - echo " Extracting NGM GRIB data for forecast hour = $fhour" - echo " " - set_trace - - g1=${ngmdir}/${ngmgfile}${fhour} - - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 33 100 850' $g1 $x1 $TMPDIR/ngmllu850.grb.f${fhour}; rcc1=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 33 100 700' $g1 $x1 $TMPDIR/ngmllu700.grb.f${fhour}; rcc2=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 33 100 500' $g1 $x1 $TMPDIR/ngmllu500.grb.f${fhour}; rcc3=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 33 105 10' $g1 $x1 $TMPDIR/ngmllu10m.grb.f${fhour}; rcc4=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 41 100 850' $g1 $x1 $TMPDIR/ngmllav850.grb.f${fhour}; rcc5=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 41 100 700' $g1 $x1 $TMPDIR/ngmllav700.grb.f${fhour}; rcc6=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 7 100 850' $g1 $x1 $TMPDIR/ngmllz850.grb.f${fhour}; rcc7=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 7 100 700' $g1 $x1 $TMPDIR/ngmllz700.grb.f${fhour}; rcc8=$? - ${COPYGB:?} -g"$grid" -k'2*-1 104 -1 2 102 0' $g1 $x1 $TMPDIR/ngmllmslp.grb.f${fhour}; rcc9=$? - - if [ $rcc1 -eq 134 -o $rcc2 -eq 134 -o $rcc3 -eq 134 -o $rcc4 -eq 134 -o $rcc5 -eq 134 -o \ - $rcc6 -eq 134 -o $rcc7 -eq 134 -o $rcc8 -eq 134 -o $rcc9 -eq 134 ]; then - set +x - echo " " - echo "!!! ERROR using $COPYGB to interpolate ngm data. We will stop execution because" - echo "!!! some variables may have been copied okay, while some obviously have not, " - echo "!!! and that could lead to unreliable results from the tracker. Check to make" - echo "!!! sure you've allocated enough memory for this job (error 134 using $COPYGB is " - echo "!!! typically due to using more memory than you've allocated). Exiting....." - echo " " - set_trace - exit 8 +if [[ "${model}" -eq 5 ]]; then + + grid='255 0 151 71 70000 190000 128 0000 340000 1000 1000 64' + + if [[ "${regflag}" == 'n' ]]; then + cat << EOF + +******************************************************************* +!!! NGM model has been selected, but there are no storms in the +!!! TC Vitals file that are from NHC. Therefore, unless you have +!!! entered your own auxiliary TC vitals file that has a storm +!!! within the NGM domain, the tracker will exit after reading +!!! in the analysis data. +******************************************************************* + +EOF fi - cat $TMPDIR/ngmllu850.grb.f${fhour} $TMPDIR/ngmllu700.grb.f${fhour} \ - $TMPDIR/ngmllu500.grb.f${fhour} $TMPDIR/ngmllz850.grb.f${fhour} \ - $TMPDIR/ngmllz700.grb.f${fhour} $TMPDIR/ngmllmslp.grb.f${fhour} \ - $TMPDIR/ngmllav850.grb.f${fhour} $TMPDIR/ngmllav700.grb.f${fhour} \ - $TMPDIR/ngmllu10m.grb.f${fhour} \ - >>${vdir}/ngmlatlon.pgrb.${symd}${dishh} + rm -f "${vdir}/ngmlatlon.pgrb.${symd}${dishh}" - done + for fhour in ${fcsthrsngm}; do - ${GRBINDEX:?} ${vdir}/ngmlatlon.pgrb.${symd}${dishh} ${vdir}/ngmlatlon.pgrb.ix.${symd}${dishh} - gribfile=${vdir}/ngmlatlon.pgrb.${symd}${dishh} - ixfile=${vdir}/ngmlatlon.pgrb.ix.${symd}${dishh} + if [[ ! -s "${ngmdir}/${ngmgfile}${fhour}" ]]; then + cat << EOF -fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! NGM File missing: ${ngmdir}/${ngmgfile}${fhour} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +EOF + continue + fi + rm -f "${TMPDIR}/tmpixfile" + ${GRBINDEX:?} "${ngmdir}/${ngmgfile}${fhour}" "${TMPDIR}/tmpixfile" + x1="${TMPDIR}/tmpixfile" + + cat << EOF +Extracting NGM GRIB data for forecast hour = ${fhour} + +EOF + + g1="${ngmdir}/${ngmgfile}${fhour}" + + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 33 100 850' "${g1}" "${x1}" "${TMPDIR}/ngmllu850.grb.f${fhour}" + rcc1=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 33 100 700' "${g1}" "${x1}" "${TMPDIR}/ngmllu700.grb.f${fhour}" + rcc2=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 33 100 500' "${g1}" "${x1}" "${TMPDIR}/ngmllu500.grb.f${fhour}" + rcc3=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 33 105 10' "${g1}" "${x1}" "${TMPDIR}/ngmllu10m.grb.f${fhour}" + rcc4=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 41 100 850' "${g1}" "${x1}" "${TMPDIR}/ngmllav850.grb.f${fhour}" + rcc5=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 41 100 700' "${g1}" "${x1}" "${TMPDIR}/ngmllav700.grb.f${fhour}" + rcc6=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 7 100 850' "${g1}" "${x1}" "${TMPDIR}/ngmllz850.grb.f${fhour}" + rcc7=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 7 100 700' "${g1}" "${x1}" "${TMPDIR}/ngmllz700.grb.f${fhour}" + rcc8=$? + ${COPYGB:?} -g"${grid}" -k'2*-1 104 -1 2 102 0' "${g1}" "${x1}" "${TMPDIR}/ngmllmslp.grb.f${fhour}" + rcc9=$? + + if [[ ${rcc1} -eq 134 || ${rcc2} -eq 134 || ${rcc3} -eq 134 || ${rcc4} -eq 134 || ${rcc5} -eq 134 || + ${rcc6} -eq 134 || ${rcc7} -eq 134 || ${rcc8} -eq 134 || ${rcc9} -eq 134 ]]; then + msg=$( + cat << EOF + +!!! FATAL ERROR using ${COPYGB} to interpolate ngm data. We will stop execution because +!!! some variables may have been copied okay, while some obviously have not, +!!! and that could lead to unreliable results from the tracker. Check to make +!!! sure you've allocated enough memory for this job (error 134 using ${COPYGB} is +!!! typically due to using more memory than you've allocated). Exiting..... + +EOF + ) + err=8 + err_exit "${msg}" + fi + + cat "${TMPDIR}/ngmllu850.grb.f${fhour}" "${TMPDIR}/ngmllu700.grb.f${fhour}" \ + "${TMPDIR}/ngmllu500.grb.f${fhour}" "${TMPDIR}/ngmllz850.grb.f${fhour}" \ + "${TMPDIR}/ngmllz700.grb.f${fhour}" "${TMPDIR}/ngmllmslp.grb.f${fhour}" \ + "${TMPDIR}/ngmllav850.grb.f${fhour}" "${TMPDIR}/ngmllav700.grb.f${fhour}" \ + "${TMPDIR}/ngmllu10m.grb.f${fhour}" \ + >> "${vdir}/ngmlatlon.pgrb.${symd}${dishh}" + + done + + ${GRBINDEX:?} "${vdir}/ngmlatlon.pgrb.${symd}${dishh}" "${vdir}/ngmlatlon.pgrb.ix.${symd}${dishh}" + gribfile="${vdir}/ngmlatlon.pgrb.${symd}${dishh}" + ixfile="${vdir}/ngmlatlon.pgrb.ix.${symd}${dishh}" + +fi # ---------------------------------- # Process Early NAM, if selected # ---------------------------------- -if [ ${model} -eq 6 ]; then - - grid='255 0 301 141 70000 190000 128 0000 340000 500 500 64' - - if [ ${regflag} = 'n' ]; then - set +x - echo " " - echo " *******************************************************************" - echo " !!! NAM model has been selected, but there are no storms in the" - echo " !!! TC Vitals file that are from NHC. Therefore, unless you have" - echo " !!! entered your own auxiliary TC vitals file that has a storm " - echo " !!! within the NAM domain, the tracker will exit after reading " - echo " !!! in the analysis data." - echo " *******************************************************************" - echo " " - set_trace - fi - - if [ -s ${vdir}/namlatlon.pgrb.${symd}${dishh} ]; then - rm ${vdir}/namlatlon.pgrb.${symd}${dishh} - fi - - for fhour in ${fcsthrsnam} - do - - if [ ! -s ${namdir}/${namgfile}${fhour}.tm00 ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! Early NAM File missing: ${namdir}/${namgfile}${fhour}.tm00" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - set_trace - continue - fi - if [ -s $TMPDIR/tmpixfile ]; then rm $TMPDIR/tmpixfile; fi - ${GRBINDEX:?} ${namdir}/${namgfile}${fhour}.tm00 $TMPDIR/tmpixfile - x1=$TMPDIR/tmpixfile - - set +x - echo " " - echo " Extracting Early NAM GRIB data for forecast hour = $fhour" - echo " " - set_trace - - g1=${namdir}/${namgfile}${fhour}.tm00 - - if [ -s $TMPDIR/namlatlon.pgrb ]; then rm $TMPDIR/namlatlon.pgrb; fi - ${COPYGB:?} -g"$grid" -k'4*-1 33 100 850' $g1 $x1 $TMPDIR/namllu850.grb.f${fhour}; rcc1=$? - ${COPYGB:?} -g"$grid" -k'4*-1 33 100 700' $g1 $x1 $TMPDIR/namllu700.grb.f${fhour}; rcc2=$? - ${COPYGB:?} -g"$grid" -k'4*-1 33 100 500' $g1 $x1 $TMPDIR/namllu500.grb.f${fhour}; rcc3=$? - ${COPYGB:?} -g"$grid" -k'4*-1 33 105 10' $g1 $x1 $TMPDIR/namllu10m.grb.f${fhour}; rcc4=$? - ${COPYGB:?} -g"$grid" -k'4*-1 41 100 850' $g1 $x1 $TMPDIR/namllav850.grb.f${fhour}; rcc5=$? - ${COPYGB:?} -g"$grid" -k'4*-1 41 100 700' $g1 $x1 $TMPDIR/namllav700.grb.f${fhour}; rcc6=$? - ${COPYGB:?} -g"$grid" -k'4*-1 7 100 850' $g1 $x1 $TMPDIR/namllz850.grb.f${fhour}; rcc7=$? - ${COPYGB:?} -g"$grid" -k'4*-1 7 100 700' $g1 $x1 $TMPDIR/namllz700.grb.f${fhour}; rcc8=$? - ${COPYGB:?} -g"$grid" -k'4*-1 2 102 0' $g1 $x1 $TMPDIR/namllmslp.grb.f${fhour}; rcc9=$? - - if [ $rcc1 -eq 134 -o $rcc2 -eq 134 -o $rcc3 -eq 134 -o $rcc4 -eq 134 -o $rcc5 -eq 134 -o \ - $rcc6 -eq 134 -o $rcc7 -eq 134 -o $rcc8 -eq 134 -o $rcc9 -eq 134 ]; then - set +x - echo " " - echo "!!! ERROR using $COPYGB to interpolate nam data. We will stop execution because" - echo "!!! some variables may have been copied okay, while some obviously have not, " - echo "!!! and that could lead to unreliable results from the tracker. Check to make" - echo "!!! sure you've allocated enough memory for this job (error 134 using $COPYGB is " - echo "!!! typically due to using more memory than you've allocated). Exiting....." - echo " " - set_trace - exit 8 +if [[ "${model}" -eq 6 ]]; then + + grid='255 0 301 141 70000 190000 128 0000 340000 500 500 64' + + if [[ "${regflag}" == 'n' ]]; then + cat << EOF + +******************************************************************* +!!! NAM model has been selected, but there are no storms in the +!!! TC Vitals file that are from NHC. Therefore, unless you have +!!! entered your own auxiliary TC vitals file that has a storm +!!! within the NAM domain, the tracker will exit after reading +!!! in the analysis data. +******************************************************************* + +EOF fi - cat $TMPDIR/namllu850.grb.f${fhour} $TMPDIR/namllu700.grb.f${fhour} \ - $TMPDIR/namllu500.grb.f${fhour} $TMPDIR/namllz850.grb.f${fhour} \ - $TMPDIR/namllz700.grb.f${fhour} $TMPDIR/namllmslp.grb.f${fhour} \ - $TMPDIR/namllav850.grb.f${fhour} $TMPDIR/namllav700.grb.f${fhour} \ - $TMPDIR/namllu10m.grb.f${fhour} \ - >>${vdir}/namlatlon.pgrb.${symd}${dishh} + rm -f "${vdir}/namlatlon.pgrb.${symd}${dishh}" - done + for fhour in ${fcsthrsnam}; do + if [[ ! -s "${namdir}/${namgfile}${fhour}.tm00" ]]; then + cat << EOF - ${GRBINDEX:?} ${vdir}/namlatlon.pgrb.${symd}${dishh} ${vdir}/namlatlon.pgrb.ix.${symd}${dishh} - gribfile=${vdir}/namlatlon.pgrb.${symd}${dishh} - ixfile=${vdir}/namlatlon.pgrb.ix.${symd}${dishh} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! Early NAM File missing: ${namdir}/${namgfile}${fhour}.tm00 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +EOF + continue + fi + rm -f "${TMPDIR}/tmpixfile" + ${GRBINDEX:?} "${namdir}/${namgfile}${fhour}.tm00" "${TMPDIR}/tmpixfile" + x1="${TMPDIR}/tmpixfile" -fi + cat << EOF + +Extracting Early NAM GRIB data for forecast hour = ${fhour} + +EOF + g1="${namdir}/${namgfile}${fhour}.tm00" + + rm -f "${TMPDIR}/namlatlon.pgrb" + ${COPYGB:?} -g"${grid}" -k'4*-1 33 100 850' "${g1}" "${x1}" "${TMPDIR}/namllu850.grb.f${fhour}" + rcc1=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 33 100 700' "${g1}" "${x1}" "${TMPDIR}/namllu700.grb.f${fhour}" + rcc2=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 33 100 500' "${g1}" "${x1}" "${TMPDIR}/namllu500.grb.f${fhour}" + rcc3=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 33 105 10' "${g1}" "${x1}" "${TMPDIR}/namllu10m.grb.f${fhour}" + rcc4=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 41 100 850' "${g1}" "${x1}" "${TMPDIR}/namllav850.grb.f${fhour}" + rcc5=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 41 100 700' "${g1}" "${x1}" "${TMPDIR}/namllav700.grb.f${fhour}" + rcc6=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 7 100 850' "${g1}" "${x1}" "${TMPDIR}/namllz850.grb.f${fhour}" + rcc7=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 7 100 700' "${g1}" "${x1}" "${TMPDIR}/namllz700.grb.f${fhour}" + rcc8=$? + ${COPYGB:?} -g"${grid}" -k'4*-1 2 102 0' "${g1}" "${x1}" "${TMPDIR}/namllmslp.grb.f${fhour}" + rcc9=$? + + if [[ "${rcc1}" -eq 134 || "${rcc2}" -eq 134 || "${rcc3}" -eq 134 || "${rcc4}" -eq 134 || "${rcc5}" -eq 134 || + "${rcc6}" -eq 134 || "${rcc7}" -eq 134 || "${rcc8}" -eq 134 || "${rcc9}" -eq 134 ]]; then + cat << EOF + +!!! FATAL ERROR using ${COPYGB} to interpolate nam data. We will stop execution because +!!! some variables may have been copied okay, while some obviously have not, +!!! and that could lead to unreliable results from the tracker. Check to make +!!! sure you've allocated enough memory for this job (error 134 using ${COPYGB} is +!!! typically due to using more memory than you've allocated). Exiting..... + +EOF + err=8 + err_exit + fi + + cat "${TMPDIR}/namllu850.grb.f${fhour}" "${TMPDIR}/namllu700.grb.f${fhour}" \ + "${TMPDIR}/namllu500.grb.f${fhour}" "${TMPDIR}/namllz850.grb.f${fhour}" \ + "${TMPDIR}/namllz700.grb.f${fhour}" "${TMPDIR}/namllmslp.grb.f${fhour}" \ + "${TMPDIR}/namllav850.grb.f${fhour}" "${TMPDIR}/namllav700.grb.f${fhour}" \ + "${TMPDIR}/namllu10m.grb.f${fhour}" \ + >> "${vdir}/namlatlon.pgrb.${symd}${dishh}" + + done + + ${GRBINDEX:?} "${vdir}/namlatlon.pgrb.${symd}${dishh}" "${vdir}/namlatlon.pgrb.ix.${symd}${dishh}" + gribfile="${vdir}/namlatlon.pgrb.${symd}${dishh}" + ixfile="${vdir}/namlatlon.pgrb.ix.${symd}${dishh}" + +fi # ------------------------------ # Process ECMWF, if selected @@ -924,643 +903,575 @@ fi # be taken out, and the data should then be processed as the other normal # full-coverage global models (ukmet, mrf, gfs, NAVGEM) currently are. -if [ ${model} -eq 4 ]; then - - if [ ! -s ${ecmwfdir}/${ecmwfgfile} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! ECMWF GRIB or Index File missing from directory: ${ecmwfdir}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " !!! Due to missing ECMWF file, execution is ending...." - echo " " - set_trace - exit 8 - fi - - ${GRBINDEX:?} ${ecmwfdir}/${ecmwfgfile} $TMPDIR/${ecmwfgfile}.ix - x1=$TMPDIR/${ecmwfgfile}.ix - - if [ -s ${vdir}/ecmwf.bufzone.grb.${symd}${dishh} ]; then - rm ${vdir}/ecmwf.bufzone.grb.${symd}${dishh} - fi - if [ -s ${vdir}/ecmwf.bufzone.ix.${symd}${dishh} ]; then - rm ${vdir}/ecmwf.bufzone.ix.${symd}${dishh} - fi - - g1=${ecmwfdir}/${ecmwfgfile} - ecgrid='255 0 144 33 40000 0000 128 -40000 357500 2500 2500 64' - ${COPYGB:?} -g"$ecgrid" $g1 $x1 ${vdir}/ecmwf.bufzone.grb.${symd}${dishh} - ${GRBINDEX:?} ${vdir}/ecmwf.bufzone.grb.${symd}${dishh} ${vdir}/ecmwf.bufzone.ix.${symd}${dishh} - gribfile=${vdir}/ecmwf.bufzone.grb.${symd}${dishh} - ixfile=${vdir}/ecmwf.bufzone.ix.${symd}${dishh} +if [[ "${model}" -eq 4 ]]; then + if [[ ! -s "${ecmwfdir}/${ecmwfgfile}" ]]; then + msg=$( + cat << EOF -fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! ECMWF GRIB or Index File missing from directory: ${ecmwfdir} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +!!! Due to missing ECMWF file, execution is ending.... + +EOF + ) + err=8 + err_exit "${msg}" + fi + + ${GRBINDEX:?} "${ecmwfdir}/${ecmwfgfile}" "${TMPDIR}/${ecmwfgfile}.ix" + x1="${TMPDIR}/${ecmwfgfile}.ix" + rm -f "${vdir}/ecmwf.bufzone.grb.${symd}${dishh}" + rm -f "${vdir}/ecmwf.bufzone.ix.${symd}${dishh}" + + g1="${ecmwfdir}/${ecmwfgfile}" + ecgrid='255 0 144 33 40000 0000 128 -40000 357500 2500 2500 64' + ${COPYGB:?} -g"${ecgrid}" "${g1}" "${x1}" "${vdir}/ecmwf.bufzone.grb.${symd}${dishh}" + ${GRBINDEX:?} "${vdir}/ecmwf.bufzone.grb.${symd}${dishh}" "${vdir}/ecmwf.bufzone.ix.${symd}${dishh}" + gribfile="${vdir}/ecmwf.bufzone.grb.${symd}${dishh}" + ixfile="${vdir}/ecmwf.bufzone.ix.${symd}${dishh}" + +fi # ------------------------------ # Process GFS, if selected # ------------------------------ -if [ ${model} -eq 1 ]; then +if [[ "${model}" -eq 1 ]]; then - if [ -s ${vdir}/gfsgribfile.${symd}${dishh} ]; then - rm ${vdir}/gfsgribfile.${symd}${dishh} - fi + rm -f "${vdir}/gfsgribfile.${symd}${dishh}" - for fhour in ${fcsthrsgfs} - do + for fhour in ${fcsthrsgfs}; do + if [[ ! -s "${gfsdir}/${gfsgfile}${fhour}" ]]; then + cat << EOF - if [ ! -s ${gfsdir}/${gfsgfile}${fhour} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! GFS File missing: ${gfsdir}/${gfsgfile}${fhour}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - set_trace - continue - fi - - gfile=${gfsdir}/${gfsgfile}${fhour} - ${WGRIB:?} -s $gfile >$TMPDIR/gfs.ix - - for parm in ${wgrib_parmlist} - do - case ${parm} in - "SurfaceU") - grep "UGRD:10 m " $TMPDIR/gfs.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gfsgribfile.${symd}${dishh} ;; - "SurfaceV") - grep "VGRD:10 m " $TMPDIR/gfs.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gfsgribfile.${symd}${dishh} ;; - *) - grep "${parm}" $TMPDIR/gfs.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gfsgribfile.${symd}${dishh} ;; - esac +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! GFS File missing: ${gfsdir}/${gfsgfile}${fhour} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +EOF + continue + fi + + gfile="${gfsdir}/${gfsgfile}${fhour}" + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/gfs.ix" + + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:10 m" ;; + "SurfaceV") parm="VGRD:10 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/gfs.ix" | ${WGRIB:?} -s "${gfile}" -i -grib -append \ + -o "${vdir}/gfsgribfile.${symd}${dishh}" + done done - done - - ${GRBINDEX:?} ${vdir}/gfsgribfile.${symd}${dishh} ${vdir}/gfsixfile.${symd}${dishh} - gribfile=${vdir}/gfsgribfile.${symd}${dishh} - ixfile=${vdir}/gfsixfile.${symd}${dishh} + ${GRBINDEX:?} "${vdir}/gfsgribfile.${symd}${dishh}" "${vdir}/gfsixfile.${symd}${dishh}" + gribfile="${vdir}/gfsgribfile.${symd}${dishh}" + ixfile="${vdir}/gfsixfile.${symd}${dishh}" fi - # ------------------------------ # Process GDAS, if selected # ------------------------------ -if [ ${model} -eq 8 ]; then +if [[ "${model}" -eq 8 ]]; then - export nest_type="fixed" - export trkrebd=360.0 - export trkrwbd=0.0 - export trkrnbd=85.0 - export trkrsbd=-85.0 - rundescr="xxxx" - atcfdescr="xxxx" + export nest_type="fixed" + export trkrebd=360.0 + export trkrwbd=0.0 + export trkrnbd=85.0 + export trkrsbd=-85.0 + rundescr="xxxx" + atcfdescr="xxxx" - if [ -s ${vdir}/gdasgribfile.${symd}${dishh} ]; then - rm ${vdir}/gdasgribfile.${symd}${dishh} - fi + rm -f "${vdir}/gdasgribfile.${symd}${dishh}" - if [ ${gribver} -eq 1 ]; then + if [[ "${gribver}" -eq 1 ]]; then - # Use GRIB1 input data + # Use GRIB1 input data - for fhr in $( seq -6 $BKGFREQ 3 ); do - if [ $fhr -lt 0 ]; then - fpref=pgm$(expr $fhr \* -1) - elif [ $fhr -eq 0 ]; then - fpref=pges - elif [ $fhr -gt 0 ]; then - fpref=pgp$fhr - fi - gfile=$DATA/${fpref}prep + for ((fhr = -6; fhr <= 3; fhr += BKGFREQ)); do + if [[ "${fhr}" -lt 0 ]]; then + fpref="pgm$((-fhr))" + elif [[ "${fhr}" -eq 0 ]]; then + fpref=pges + elif [[ "${fhr}" -gt 0 ]]; then + fpref="pgp${fhr}" + fi + gfile="${DATA}/${fpref}prep" - if [ ! -s $gfile ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! gdas File missing: $gfile" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set_trace - continue - fi + if [[ ! -s "${gfile}" ]]; then + cat << EOF - ${WGRIB:?} -s $gfile >$TMPDIR/gdas.ix +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! gdas File missing: ${gfile} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - for parm in ${wgrib_parmlist} - do +EOF + continue + fi - case ${parm} in - "SurfaceU") - grep "UGRD:10 m " $TMPDIR/gdas.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gdasgribfile.${symd}${dishh} ;; - "SurfaceV") - grep "VGRD:10 m " $TMPDIR/gdas.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gdasgribfile.${symd}${dishh} ;; - *) - grep "${parm}" $TMPDIR/gdas.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/gdasgribfile.${symd}${dishh} ;; - esac + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/gdas.ix" - done + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:10 m" ;; + "SurfaceV") parm="VGRD:10 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/gdas.ix" | ${WGRIB:?} -s "${gfile}" -i -grib -append \ + -o "${vdir}/gdasgribfile.${symd}${dishh}" + done - done + done - else + else - # Use GRIB2 input data.... + # Use GRIB2 input data.... + for ((fhr = -6; fhr <= 3; fhr += BKGFREQ)); do + if [[ "${fhr}" -lt 0 ]]; then + fhour="0$((-fhr))" + fpref=pgm$((-fhr)) + elif [[ "${fhr}" -eq 0 ]]; then + fhour=00 + fpref=pges + elif [[ "${fhr}" -gt 0 ]]; then + fhour="0${fhr}" + fpref="pgp${fhr}" + fi + gfile="${DATA}/${fpref}prep" + + if [[ ! -s "${gfile}" ]]; then + cat << EOF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! gdas File missing: ${gfile} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - for fhr in $( seq -6 $BKGFREQ 3 ); do - if [ $fhr -lt 0 ]; then - fhour=0$(expr $fhr \* -1) - fpref=pgm$(expr $fhr \* -1) - elif [ $fhr -eq 0 ]; then - fhour=00 - fpref=pges - elif [ $fhr -gt 0 ]; then - fhour=0$fhr - fpref=pgp$fhr - fi - gfile=$DATA/${fpref}prep +EOF + continue + fi - if [ ! -s $gfile ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! gdas File missing: $gfile" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set_trace - continue - fi - - ${WGRIB2:?} -s $gfile >$TMPDIR/gdas.ix - - for parm in ${wgrib_parmlist} - do - case ${parm} in - "SurfaceU") - grep "UGRD:10 m " $TMPDIR/gdas.ix | ${WGRIB2:?} -i $gfile -append -grib \ - ${vdir}/gdasgribfile.${symd}${dishh} ;; - "SurfaceV") - grep "VGRD:10 m " $TMPDIR/gdas.ix | ${WGRIB2:?} -i $gfile -append -grib \ - ${vdir}/gdasgribfile.${symd}${dishh} ;; - *) - grep "${parm}" $TMPDIR/gdas.ix | ${WGRIB2:?} -i $gfile -append -grib \ - ${vdir}/gdasgribfile.${symd}${dishh} ;; - esac - done + ${WGRIB2:?} -s "${gfile}" > "${TMPDIR}/gdas.ix" - done + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:10 m" ;; + "SurfaceV") parm="VGRD:10 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/gdas.ix" | ${WGRIB2:?} -i "${gfile}" -append -grib \ + "${vdir}/gdasgribfile.${symd}${dishh}" + done - fi + done - if [ ${gribver} -eq 1 ]; then - ${GRBINDEX:?} ${vdir}/gdasgribfile.${symd}${dishh} ${vdir}/gdasixfile.${symd}${dishh} - else - ${GRB2INDEX:?} ${vdir}/gdasgribfile.${symd}${dishh} ${vdir}/gdasixfile.${symd}${dishh} - fi + fi - gribfile=${vdir}/gdasgribfile.${symd}${dishh} - ixfile=${vdir}/gdasixfile.${symd}${dishh} + if [[ "${gribver}" -eq 1 ]]; then + ${GRBINDEX:?} "${vdir}/gdasgribfile.${symd}${dishh}" "${vdir}/gdasixfile.${symd}${dishh}" + else + ${GRB2INDEX:?} "${vdir}/gdasgribfile.${symd}${dishh}" "${vdir}/gdasixfile.${symd}${dishh}" + fi + + gribfile="${vdir}/gdasgribfile.${symd}${dishh}" + ixfile="${vdir}/gdasixfile.${symd}${dishh}" fi + # ------------------------------ # Process MRF, if selected # ------------------------------ -if [ ${model} -eq 2 ]; then +if [[ "${model}" -eq 2 ]]; then - if [ -s ${vdir}/mrfgribfile.${symd}${dishh} ]; then - rm ${vdir}/mrfgribfile.${symd}${dishh} - fi + rm -f "${vdir}/mrfgribfile.${symd}${dishh}" - for fhour in ${fcsthrsmrf} - do + for fhour in ${fcsthrsmrf}; do + if [[ ! -s "${mrfdir}/${mrfgfile}${fhour}" ]]; then + cat << EOF - if [ ! -s ${mrfdir}/${mrfgfile}${fhour} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! MRF File missing: ${mrfdir}/${mrfgfile}${fhour}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set_trace - continue - fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! MRF File missing: ${mrfdir}/${mrfgfile}${fhour} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - gfile=${mrfdir}/${mrfgfile}${fhour} - ${WGRIB:?} -s $gfile >$TMPDIR/mrf.ix - - for parm in ${wgrib_parmlist} - do - - case ${parm} in - "SurfaceU") - grep "UGRD:10 m " $TMPDIR/mrf.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/mrfgribfile.${symd}${dishh} ;; - "SurfaceV") - grep "VGRD:10 m " $TMPDIR/mrf.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/mrfgribfile.${symd}${dishh} ;; - *) - grep "${parm}" $TMPDIR/mrf.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/mrfgribfile.${symd}${dishh} ;; - esac +EOF + continue + fi + + gfile="${mrfdir}/${mrfgfile}${fhour}" + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/mrf.ix" + + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:10 m" ;; + "SurfaceV") parm="VGRD:10 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/mrf.ix" | ${WGRIB:?} -s "${gfile}" -i -grib -append \ + -o "${vdir}/mrfgribfile.${symd}${dishh}" + done done - done - - ${GRBINDEX:?} ${vdir}/mrfgribfile.${symd}${dishh} ${vdir}/mrfixfile.${symd}${dishh} - gribfile=${vdir}/mrfgribfile.${symd}${dishh} - ixfile=${vdir}/mrfixfile.${symd}${dishh} + ${GRBINDEX:?} "${vdir}/mrfgribfile.${symd}${dishh}" "${vdir}/mrfixfile.${symd}${dishh}" + gribfile="${vdir}/mrfgribfile.${symd}${dishh}" + ixfile="${vdir}/mrfixfile.${symd}${dishh}" fi - # ------------------------------ # Process UKMET, if selected # ------------------------------ -if [ ${model} -eq 3 ]; then +if [[ "${model}" -eq 3 ]]; then - if [ -s ${vdir}/ukmetgribfile.${symd}${dishh} ]; then - rm ${vdir}/ukmetgribfile.${symd}${dishh} - fi + rm -f "${vdir}/ukmetgribfile.${symd}${dishh}" - wgrib_parmlist=' HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 UGRD:sfc VGRD:sfc ABSV:850 ABSV:700 PRMSL:MSL ' + wgrib_parmlist='HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 UGRD:sfc VGRD:sfc ABSV:850 ABSV:700 PRMSL:MSL ' - for fhour in ${fcsthrsukmet} - do + for fhour in ${fcsthrsukmet}; do + if [[ ! -s "${ukmetdir}/${ukmetgfile}${fhour}" ]]; then + cat << EOF - if [ ! -s ${ukmetdir}/${ukmetgfile}${fhour} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! UKMET File missing: ${ukmetdir}/${ukmetgfile}${fhour}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set_trace - continue - fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! UKMET File missing: ${ukmetdir}/${ukmetgfile}${fhour} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - gfile=${ukmetdir}/${ukmetgfile}${fhour} - ${WGRIB:?} -s $gfile >$TMPDIR/ukmet.ix +EOF + continue + fi - for parm in ${wgrib_parmlist} - do - grep "${parm}" $TMPDIR/ukmet.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/ukmetgribfile.${symd}${dishh} - done + gfile="${ukmetdir}/${ukmetgfile}${fhour}" + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/ukmet.ix" - done + for parm in ${wgrib_parmlist}; do + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/ukmet.ix" | ${WGRIB:?} -s "${gfile}" -i -grib -append \ + -o "${vdir}/ukmetgribfile.${symd}${dishh}" + done - ${GRBINDEX:?} ${vdir}/ukmetgribfile.${symd}${dishh} ${vdir}/ukmetixfile.${symd}${dishh} - gribfile=${vdir}/ukmetgribfile.${symd}${dishh} - ixfile=${vdir}/ukmetixfile.${symd}${dishh} + done -fi + ${GRBINDEX:?} "${vdir}/ukmetgribfile.${symd}${dishh}" "${vdir}/ukmetixfile.${symd}${dishh}" + gribfile="${vdir}/ukmetgribfile.${symd}${dishh}" + ixfile="${vdir}/ukmetixfile.${symd}${dishh}" +fi # ------------------------------ # Process NAVGEM, if selected # ------------------------------ -if [ ${model} -eq 7 ]; then - - if [ -s ${vdir}/ngpsgribfile.${symd}${dishh} ]; then - rm ${vdir}/ngpsgribfile.${symd}${dishh} - fi - - if [ ! -s ${ngpsdir}/${ngpsgfile} ]; then - set +x - echo " " - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " !!! NAVGEM File missing: ${ngpsdir}/${ngpsgfile}" - echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " !!! Due to missing NAVGEM file, execution is ending...." - echo " " - set_trace - exit 8 - fi - - gfile=${ngpsdir}/${ngpsgfile} - ${WGRIB:?} -s $gfile >$TMPDIR/ngps.ix - - for fhour in ${fcsthrsngps} - do - - if [ $fhour = '00' ]; then - vtstring=":anl:" - else - vtstring="${fhour}hr" +if [[ "${model}" -eq 7 ]]; then + + rm -f "${vdir}/ngpsgribfile.${symd}${dishh}" + + if [[ ! -s "${ngpsdir}/${ngpsgfile}" ]]; then + msg=$( + cat << EOF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! NAVGEM File missing: ${ngpsdir}/${ngpsgfile} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +!!! Due to missing NAVGEM file, execution is ending.... + +EOF + ) + err=8 + err_exit "${msg}" fi - for parm in ${wgrib_parmlist} - do - case ${parm} in - "SurfaceU") - grep "UGRD:19 m " $TMPDIR/ngps.ix | grep ${vtstring} | \ - ${WGRIB:?} -s $gfile -i -grib -append -o ${vdir}/ngpsgribfile.${symd}${dishh} ;; - "SurfaceV") - grep "VGRD:19 m " $TMPDIR/ngps.ix | grep ${vtstring} | \ - ${WGRIB:?} -s $gfile -i -grib -append -o ${vdir}/ngpsgribfile.${symd}${dishh} ;; - *) - grep "${parm}" $TMPDIR/ngps.ix | grep ${vtstring} | \ - ${WGRIB:?} -s $gfile -i -grib -append -o ${vdir}/ngpsgribfile.${symd}${dishh} ;; - esac - done + gfile="${ngpsdir}/${ngpsgfile}" + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/ngps.ix" + + for fhour in ${fcsthrsngps}; do + if [[ "${fhour}" == '00' ]]; then + vtstring=":anl:" + else + vtstring="${fhour}hr" + fi + + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:19 m" ;; + "SurfaceV") parm="VGRD:19 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/ngps.ix" | grep "${vtstring}" | + ${WGRIB:?} -s "${gfile}" -i -grib -append -o "${vdir}/ngpsgribfile.${symd}${dishh}" + done - done + done - ${GRBINDEX:?} ${vdir}/ngpsgribfile.${symd}${dishh} ${vdir}/ngpsixfile.${symd}${dishh} - gribfile=${vdir}/ngpsgribfile.${symd}${dishh} - ixfile=${vdir}/ngpsixfile.${symd}${dishh} + ${GRBINDEX:?} "${vdir}/ngpsgribfile.${symd}${dishh}" "${vdir}/ngpsixfile.${symd}${dishh}" + gribfile="${vdir}/ngpsgribfile.${symd}${dishh}" + ixfile="${vdir}/ngpsixfile.${symd}${dishh}" fi - # --------------------------------------------- # Process User-specified Model, if selected # --------------------------------------------- -if [ ${model} -eq 9 ]; then +if [[ "${model}" -eq 9 ]]; then -# We need to first check whether or not the data in the file are stored -# on a lat/lon grid or not. We do this by scanning the analysis file -# with Wesley's grib utility, and checking the value of the "Data -# Representation Type", which is stored in byte #6 in the GDS of each -# grib file. A value of 0 indicates an equidistant lat/lon grid. + # We need to first check whether or not the data in the file are stored + # on a lat/lon grid or not. We do this by scanning the analysis file + # with Wesley's grib utility, and checking the value of the "Data + # Representation Type", which is stored in byte #6 in the GDS of each + # grib file. A value of 0 indicates an equidistant lat/lon grid. - if [ -s ${vdir}/otherlatlon.pgrb.${symdh} ]; then - rm ${vdir}/otherlatlon.pgrb.${symdh} - fi + rm -f "${vdir}/otherlatlon.pgrb.${symdh}" - gridtyp=$(${WGRIB:?} -GDS10 ${otherdir}/${fnamebeg}00${fnameend} | \ - awk -FGDS10= '{print $2}' | awk '{print $6}' | sed -n 1p) + # shellcheck disable=SC2312 + gridtyp=$(${WGRIB:?} -GDS10 "${otherdir}/${fnamebeg}00${fnameend}" | + awk -FGDS10= '{print $2}' | awk '{print $6}' | sed -n 1p) - if [ ${gridtyp} -eq 0 ]; then + if [[ "${gridtyp}" -eq 0 ]]; then -# The data are already on a lat/lon grid, we do not need to -# interpolate the data, just pull out the records that we need -# using wgrib. + # The data are already on a lat/lon grid, we do not need to + # interpolate the data, just pull out the records that we need + # using wgrib. - for fhour in ${fcsthrsother} - do + for fhour in ${fcsthrsother}; do + if [[ ! -s "${otherdir}/${fnamebeg}${fhour}${fnameend}" ]]; then + cat << EOF - if [ ! -s ${otherdir}/${fnamebeg}${fhour}${fnameend} ]; then - set +x - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!! Forecast File missing: ${otherdir}/${fnamebeg}00${fnameend}" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set_trace - continue - fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! Forecast File missing: ${otherdir}/${fnamebeg}00${fnameend} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - gfile=${otherdir}/${fnamebeg}${fhour}${fnameend} - ${WGRIB:?} -s $gfile >$TMPDIR/other.ix +EOF + continue + fi - for parm in ${wgrib_parmlist} - do + gfile="${otherdir}/${fnamebeg}${fhour}${fnameend}" + ${WGRIB:?} -s "${gfile}" > "${TMPDIR}/other.ix" - case ${parm} in - "SurfaceU") - grep "UGRD:10 m " $TMPDIR/other.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/otherlatlon.pgrb.${symdh} ;; - "SurfaceV") - grep "VGRD:10 m " $TMPDIR/other.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/otherlatlon.pgrb.${symdh} ;; - *) - grep "${parm}" $TMPDIR/other.ix | ${WGRIB:?} -s $gfile -i -grib -append \ - -o ${vdir}/otherlatlon.pgrb.${symdh} ;; - esac + for parm in ${wgrib_parmlist}; do + case "${parm}" in + "SurfaceU") parm="UGRD:10 m" ;; + "SurfaceV") parm="VGRD:10 m" ;; + *) ;; + esac + # shellcheck disable=SC2312 + grep "${parm}" "${TMPDIR}/other.ix" | ${WGRIB:?} -s "${gfile}" -i -grib -append \ + -o "${vdir}/otherlatlon.pgrb.${symdh}" + done - done + done - done + else - else + # The data are on a grid that is something other than a lat/lon grid. + # Use Mark Iredell's interpolator to interpolate the data to a lat/lon + # grid and pull out the records that we need. -# The data are on a grid that is something other than a lat/lon grid. -# Use Mark Iredell's interpolator to interpolate the data to a lat/lon -# grid and pull out the records that we need. + othergrid='255 0 360 181 90000 0000 128 -90000 -1000 1000 1000 64' - othergrid='255 0 360 181 90000 0000 128 -90000 -1000 1000 1000 64' + for fhour in ${fcsthrsother}; do - for fhour in ${fcsthrsother} - do + if [[ ! -s "${otherdir}/${fnamebeg}${fhour}${fnameend}" ]]; then + cat << EOF - if [ ! -s ${otherdir}/${fnamebeg}${fhour}${fnameend} ]; then - set +x - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!! Forecast File missing: ${otherdir}/${fnamebeg}00${fnameend}" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - set +x - continue - fi - - if [ -s $TMPDIR/tmpixfile ]; then rm $TMPDIR/tmpixfile; fi - ${GRBINDEX:?} ${otherdir}/${fnamebeg}${fhour}${fnameend} $TMPDIR/tmpixfile - x1=$TMPDIR/tmpixfile - - g1=${otherdir}/${fnamebeg}${fhour}${fnameend} - - ${COPYGB:?} -g"$othergrid" -k'4*-1 33 100 850' $g1 $x1 $TMPDIR/otherllu850.grb.f${fhour}; rcc1=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 33 100 700' $g1 $x1 $TMPDIR/otherllu700.grb.f${fhour}; rcc2=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 33 100 500' $g1 $x1 $TMPDIR/otherllu500.grb.f${fhour}; rcc3=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 33 105 10' $g1 $x1 $TMPDIR/otherllu10m.grb.f${fhour}; rcc4=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 41 100 850' $g1 $x1 $TMPDIR/otherllav850.grb.f${fhour}; rcc5=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 41 100 700' $g1 $x1 $TMPDIR/otherllav700.grb.f${fhour}; rcc6=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 7 100 850' $g1 $x1 $TMPDIR/otherllz850.grb.f${fhour}; rcc7=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 7 100 700' $g1 $x1 $TMPDIR/otherllz700.grb.f${fhour}; rcc8=$? - ${COPYGB:?} -g"$othergrid" -k'4*-1 2 102 0' $g1 $x1 $TMPDIR/otherllmslp.grb.f${fhour}; rcc9=$? - - if [ $rcc1 -eq 134 -o $rcc2 -eq 134 -o $rcc3 -eq 134 -o $rcc4 -eq 134 -o $rcc5 -eq 134 -o \ - $rcc6 -eq 134 -o $rcc7 -eq 134 -o $rcc8 -eq 134 -o $rcc9 -eq 134 ]; then - set +x - echo " " - echo "!!! ERROR using $COPYGB to interpolate data. We will stop execution because" - echo "!!! some variables may have been copied okay, while some obviously have not, " - echo "!!! and that could lead to unreliable results from the tracker. Check to make" - echo "!!! sure you've allocated enough memory for this job (error 134 using $COPYGB is " - echo "!!! typically due to using more memory than you've allocated). Exiting....." - echo " " - set_trace - exit 8 - fi +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! Forecast File missing: ${otherdir}/${fnamebeg}00${fnameend} +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - cat $TMPDIR/otherllu850.grb.f${fhour} $TMPDIR/otherllu700.grb.f${fhour} \ - $TMPDIR/otherllu500.grb.f${fhour} $TMPDIR/otherllz850.grb.f${fhour} \ - $TMPDIR/otherllz700.grb.f${fhour} $TMPDIR/otherllmslp.grb.f${fhour} \ - $TMPDIR/otherllav850.grb.f${fhour} $TMPDIR/otherllav700.grb.f${fhour} \ - $TMPDIR/otherllu10m.grb.f${fhour} \ - >>${vdir}/otherlatlon.pgrb.${symdh} +EOF + continue + fi + + rm -f "${TMPDIR}/tmpixfile" + ${GRBINDEX:?} "${otherdir}/${fnamebeg}${fhour}${fnameend}" "${TMPDIR}/tmpixfile" + x1="${TMPDIR}/tmpixfile" + + g1="${otherdir}/${fnamebeg}${fhour}${fnameend}" + + ${COPYGB:?} -g"${othergrid}" -k'4*-1 33 100 850' "${g1}" "${x1}" "${TMPDIR}/otherllu850.grb.f${fhour}" + rcc1=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 33 100 700' "${g1}" "${x1}" "${TMPDIR}/otherllu700.grb.f${fhour}" + rcc2=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 33 100 500' "${g1}" "${x1}" "${TMPDIR}/otherllu500.grb.f${fhour}" + rcc3=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 33 105 10' "${g1}" "${x1}" "${TMPDIR}/otherllu10m.grb.f${fhour}" + rcc4=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 41 100 850' "${g1}" "${x1}" "${TMPDIR}/otherllav850.grb.f${fhour}" + rcc5=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 41 100 700' "${g1}" "${x1}" "${TMPDIR}/otherllav700.grb.f${fhour}" + rcc6=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 7 100 850' "${g1}" "${x1}" "${TMPDIR}/otherllz850.grb.f${fhour}" + rcc7=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 7 100 700' "${g1}" "${x1}" "${TMPDIR}/otherllz700.grb.f${fhour}" + rcc8=$? + ${COPYGB:?} -g"${othergrid}" -k'4*-1 2 102 0' "${g1}" "${x1}" "${TMPDIR}/otherllmslp.grb.f${fhour}" + rcc9=$? + + if [[ "${rcc1}" -eq 134 || "${rcc2}" -eq 134 || "${rcc3}" -eq 134 || "${rcc4}" -eq 134 || "${rcc5}" -eq 134 || + "${rcc6}" -eq 134 || "${rcc7}" -eq 134 || "${rcc8}" -eq 134 || "${rcc9}" -eq 134 ]]; then + msg=$( + cat << EOF + +!!! FATAL ERROR using ${COPYGB} to interpolate data. We will stop execution because +!!! some variables may have been copied okay, while some obviously have not, +!!! and that could lead to unreliable results from the tracker. Check to make +!!! sure you've allocated enough memory for this job (error 134 using ${COPYGB} is +!!! typically due to using more memory than you've allocated). Exiting..... - done +EOF + ) + err=8 + err_exit "${msg}" + fi - fi + cat "${TMPDIR}/otherllu850.grb.f${fhour}" "${TMPDIR}/otherllu700.grb.f${fhour}" \ + "${TMPDIR}/otherllu500.grb.f${fhour}" "${TMPDIR}/otherllz850.grb.f${fhour}" \ + "${TMPDIR}/otherllz700.grb.f${fhour}" "${TMPDIR}/otherllmslp.grb.f${fhour}" \ + "${TMPDIR}/otherllav850.grb.f${fhour}" "${TMPDIR}/otherllav700.grb.f${fhour}" \ + "${TMPDIR}/otherllu10m.grb.f${fhour}" \ + >> "${vdir}/otherlatlon.pgrb.${symdh}" - ${GRBINDEX:?} ${vdir}/otherlatlon.pgrb.${symdh} ${vdir}/otherlatlon.pgrb.ix.${symdh} - gribfile=${vdir}/otherlatlon.pgrb.${symdh} - ixfile=${vdir}/otherlatlon.pgrb.ix.${symdh} + done -fi + fi + + ${GRBINDEX:?} "${vdir}/otherlatlon.pgrb.${symdh}" "${vdir}/otherlatlon.pgrb.ix.${symdh}" + gribfile="${vdir}/otherlatlon.pgrb.${symdh}" + ixfile="${vdir}/otherlatlon.pgrb.ix.${symdh}" +fi #-------------------------------------------# # Now qsub the jobs to run the tracker # #-------------------------------------------# -ist=1 -while [ $ist -le 15 ] -do - if [ ${stormflag[${ist}]} -ne 1 ] - then - set +x; echo "Storm number $ist NOT selected for processing"; set_trace - else - set +x; echo "Storm number $ist IS selected for processing...."; set_trace - fi - let ist=ist+1 +for ((ist = 1; ist <= 15; ist++)); do + if [[ "${stormflag[ist]}" -ne 1 ]]; then + echo "Storm number ${ist} NOT selected for processing" + else + echo "Storm number ${ist} IS selected for processing...." + fi done # Load the forecast hours for this particular model into an array # that will be passed into the executable via a namelist.... -ifh=1 -while [ $ifh -le ${maxtime} ] -do - fh[${ifh}]=$( echo ${fcsthrs} | awk '{print $n}' n=$ifh) - let ifh=ifh+1 +for ((ifh = 1; ifh <= mattime; ifh++)); do + fh[ifh]=$(echo "${fcsthrs}" | awk '{print $n}' n="${ifh}") done -namelist=${vdir}/gettrk.input.${cmodel}.${symdh} -ATCFNAME=$( echo "${atcfname}" | tr '[a-z]' '[A-Z]') +namelist="${vdir}/gettrk.input.${cmodel}.${symdh}" + +export atcfymdh="${scc}${syy}${smm}${sdd}${shh}" -export atcfymdh=${scc}${syy}${smm}${sdd}${shh} contour_interval=100.0 write_vit=n want_oci=.TRUE. -echo "&datein inp%bcc=${scc},inp%byy=${syy},inp%bmm=${smm}," >${namelist} -echo " inp%bdd=${sdd},inp%bhh=${shh},inp%model=${model}," >>${namelist} -echo " inp%modtyp='${modtyp}'," >>${namelist} -echo " inp%lt_units='${lead_time_units}'," >>${namelist} -echo " inp%file_seq='${file_sequence}'," >>${namelist} -echo " inp%nesttyp='${nest_type}'/" >>${namelist} -echo "&atcfinfo atcfnum=${atcfnum},atcfname='${ATCFNAME}'," >>${namelist} -echo " atcfymdh=${atcfymdh},atcffreq=${atcffreq}/" >>${namelist} -echo "&trackerinfo trkrinfo%westbd=${trkrwbd}," >>${namelist} -echo " trkrinfo%eastbd=${trkrebd}," >>${namelist} -echo " trkrinfo%northbd=${trkrnbd}," >>${namelist} -echo " trkrinfo%southbd=${trkrsbd}," >>${namelist} -echo " trkrinfo%type='${trkrtype}'," >>${namelist} -echo " trkrinfo%mslpthresh=${MSLPTHRESH}," >>${namelist} -echo " trkrinfo%v850thresh=${V850THRESH}," >>${namelist} -echo " trkrinfo%gridtype='${modtyp}'," >>${namelist} -echo " trkrinfo%contint=${contour_interval}," >>${namelist} -echo " trkrinfo%want_oci=${want_oci}," >>${namelist} -echo " trkrinfo%out_vit='${write_vit}'," >>${namelist} -echo " trkrinfo%gribver=${gribver}," >>${namelist} -echo " trkrinfo%g2_jpdtn=${g2_jpdtn}/" >>${namelist} -echo "&phaseinfo phaseflag='${PHASEFLAG}'," >>${namelist} -echo " phasescheme='${PHASE_SCHEME}'," >>${namelist} -echo " wcore_depth=${WCORE_DEPTH}/" >>${namelist} -echo "&structinfo structflag='${STRUCTFLAG}'," >>${namelist} -echo " ikeflag='${IKEFLAG}'/" >>${namelist} -echo "&fnameinfo gmodname='${atcfname}'," >>${namelist} -echo " rundescr='${rundescr}'," >>${namelist} -echo " atcfdescr='${atcfdescr}'/" >>${namelist} -echo "&verbose verb=3/" >>${namelist} -echo "&waitinfo use_waitfor='n'," >>${namelist} -echo " wait_min_age=10," >>${namelist} -echo " wait_min_size=100," >>${namelist} -echo " wait_max_wait=1800," >>${namelist} -echo " wait_sleeptime=5," >>${namelist} -echo " per_fcst_command=''/" >>${namelist} - -pgm=$(basename $GETTX) -if [ -s $DATA/prep_step ]; then - . $DATA/prep_step -else - [ -f errfile ] && rm errfile - export XLFUNITS=0 - unset $(env | grep XLFUNIT | awk -F= '{print $1}') - - set +u - if [ -z "$XLFRTEOPTS" ]; then - export XLFRTEOPTS="unit_vars=yes" - else - export XLFRTEOPTS="${XLFRTEOPTS}:unit_vars=yes" - fi - set -u +cat << EOF > "${namelist}" +&datein inp%bcc=${scc},inp%byy=${syy},inp%bmm=${smm}, + inp%bdd=${sdd},inp%bhh=${shh},inp%model=${model}, + inp%modtyp='${modtyp}', + inp%lt_units='${lead_time_units}', + inp%file_seq='${file_sequence}', + inp%nesttyp='${nest_type}'/ +&atcfinfo atcfnum=${atcfnum},atcfname='${atcfname^^}', + atcfymdh=${atcfymdh},atcffreq=${atcffreq}/ +&trackerinfo trkrinfo%westbd=${trkrwbd}, + trkrinfo%eastbd=${trkrebd}, + trkrinfo%northbd=${trkrnbd}, + trkrinfo%southbd=${trkrsbd}, + trkrinfo%type='${trkrtype}', + trkrinfo%mslpthresh=${MSLPTHRESH}, + trkrinfo%v850thresh=${V850THRESH}, + trkrinfo%gridtype='${modtyp}', + trkrinfo%contint=${contour_interval}, + trkrinfo%want_oci=${want_oci}, + trkrinfo%out_vit='${write_vit}', + trkrinfo%gribver=${gribver}, + trkrinfo%g2_jpdtn=${g2_jpdtn}/ +&phaseinfo phaseflag='${PHASEFLAG}', + phasescheme='${PHASE_SCHEME}', + wcore_depth=${WCORE_DEPTH}/ +&structinfo structflag='${STRUCTFLAG}', + ikeflag='${IKEFLAG}'/ +&fnameinfo gmodname='${atcfname}', + rundescr='${rundescr}', + atcfdescr='${atcfdescr}'/ +&verbose verb=3/ +&waitinfo use_waitfor='n', + wait_min_age=10, + wait_min_size=100, + wait_max_wait=1800, + wait_sleeptime=5, + per_fcst_command=''/ +EOF +pgm=$(basename "${GETTX}") +if [[ -s "${DATA}/prep_step" ]]; then + source "${DATA}/prep_step" +else + rm -f errfile + export XLFUNITS=0 + # shellcheck disable=SC2046,SC2312 + unset $(env | grep XLFUNIT | awk -F= '{print $1}') + export XLFRTEOPTS="${XLFRTEOPTS:+${XLFRTEOPTS}:}unit_vars=yes" fi -touch ${vdir}/tmp.gfs.atcfunix.${symdh} +touch "${vdir}/tmp.gfs.atcfunix.${symdh}" #---------------------------------- -if [ -s fort.* ]; then - rm fort.* +rm -f fort.* + +${NLN} "${gribfile}" fort.11 +${NLN} "${vdir}/tmp.gfs.atcfunix.${symdh}" fort.14 +${NLN} "${vdir}/vitals.upd.${cmodel}.${symd}${dishh}" fort.12 +${NLN} "${ixfile}" fort.31 +${NLN} "${vdir}/trak.${cmodel}.all.${symdh}" fort.61 +${NLN} "${vdir}/trak.${cmodel}.atcf.${symdh}" fort.62 +${NLN} "${vdir}/trak.${cmodel}.radii.${symdh}" fort.63 +${NLN} "${vdir}/trak.${cmodel}.atcfunix.${symdh}" fort.64 + +if [[ "${BKGFREQ}" -eq 1 ]]; then + ${NLN} "${FIXgfs}/am/${cmodel}.tracker_leadtimes_hrly" "fort.15" +elif [[ "${BKGFREQ}" -eq 3 ]]; then + ${NLN} "${FIXgfs}/am/${cmodel}.tracker_leadtimes" "fort.15" fi -${NLN} ${gribfile} fort.11 -${NLN} ${vdir}/tmp.gfs.atcfunix.${symdh} fort.14 -${NLN} ${vdir}/vitals.upd.${cmodel}.${symd}${dishh} fort.12 -${NLN} ${ixfile} fort.31 -${NLN} ${vdir}/trak.${cmodel}.all.${symdh} fort.61 -${NLN} ${vdir}/trak.${cmodel}.atcf.${symdh} fort.62 -${NLN} ${vdir}/trak.${cmodel}.radii.${symdh} fort.63 -${NLN} ${vdir}/trak.${cmodel}.atcfunix.${symdh} fort.64 - -if [ $BKGFREQ -eq 1 ]; then - ${NLN} ${FIXgfs}/am/${cmodel}.tracker_leadtimes_hrly fort.15 -elif [ $BKGFREQ -eq 3 ]; then - ${NLN} ${FIXgfs}/am/${cmodel}.tracker_leadtimes fort.15 -fi - -##$XLF_LINKSSH -#if [ -z $XLF_LINKSSH ] ; then -###if [ -s $XLF_LINKSSH ; then $XLF_LINKSSH ; fi -#fi - -$TIMEIT ${APRNGETTX} $GETTX <${namelist} > outout 2> errfile +${TIMEIT} "${APRNGETTX}" "${GETTX}" < "${namelist}" > outout 2> errfile err=$? -###cat errfile cat errfile >> outout -cat outout > ${DATA}/model_track.out -set +u -[ -n "../$pgmout" ] && cat outout >> ../$pgmout -set -u -rm outout -set +x -echo -echo 'The foreground exit status for GETTRK is ' $err -echo -set_trace - -if [[ ${err} -gt 0 ]]; then - exit 9 +cat outout > "${DATA}/model_track.out" +if [[ -n "${pgmout}" ]]; then + cat outout >> "../${pgmout}" fi +rm outout +cat << EOF + +"The foreground exit status for GETTRK is ${err}" + +EOF -if [ -s fort.* ]; then - rm fort.* +if [[ "${err}" -gt 0 ]]; then + err=9 + err_exit fi -cpreq "${vdir}/trak.${cmodel}.all.${symdh}" "${DATA}/model_track.all" +rm -f fort.* +cpreq "${vdir}/trak.${cmodel}.all.${symdh}" "${DATA}/model_track.all" exit 0 diff --git a/ush/wave_domain_grid.sh b/ush/wave_domain_grid.sh index 753e3045d8f..7ca92790bea 100644 --- a/ush/wave_domain_grid.sh +++ b/ush/wave_domain_grid.sh @@ -10,34 +10,135 @@ ####################### process_grdID() { - grdID=$1 - case ${grdID} in - glo_10m) GRDREGION='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - glo_15mxt) GRDREGION='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_30mxt) GRDREGION='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; - glo_30m) GRDREGION='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; - glo_025) GRDREGION='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_100) GRDREGION='global' ; GRDRES=1p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_200) GRDREGION='global' ; GRDRES=2p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_500) GRDREGION='global' ; GRDRES=5p00 ; GRIDNR=255 ; MODNR=11 ;; - at_10m) GRDREGION='atlocn' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - ep_10m) GRDREGION='epacif' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - wc_10m) GRDREGION='wcoast' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - ak_10m) GRDREGION='alaska' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - aoc_9km) GRDREGION='arctic' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; - ant_9km) GRDREGION='antarc' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; - gnh_10m) GRDREGION='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - gsh_15m) GRDREGION='gsouth' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - ao_20m) GRDREGION='arctic' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; - so_20m) GRDREGION='antarc' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; - reg025) GRDREGION='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - gwes_30m) GRDREGION='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=10 ;; - *) - echo "FATAL ERROR: No grid specific wave config values exist for ${grdID}. Aborting." - exit 1 ;; - esac - grdNAME="${GRDREGION}.${GRDRES}" - echo "grdNAME=${grdNAME}" - echo "GRIDNR=${GRIDNR}" - echo "MODNR=${MODNR}" + grdID=$1 + case ${grdID} in + glo_10m) + GRDREGION='global' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + glo_15mxt) + GRDREGION='global' + GRDRES=0p25 + GRIDNR=255 + MODNR=11 + ;; + glo_30mxt) + GRDREGION='global' + GRDRES=0p50 + GRIDNR=255 + MODNR=11 + ;; + glo_30m) + GRDREGION='global' + GRDRES=0p50 + GRIDNR=255 + MODNR=11 + ;; + glo_025) + GRDREGION='global' + GRDRES=0p25 + GRIDNR=255 + MODNR=11 + ;; + glo_100) + GRDREGION='global' + GRDRES=1p00 + GRIDNR=255 + MODNR=11 + ;; + glo_200) + GRDREGION='global' + GRDRES=2p00 + GRIDNR=255 + MODNR=11 + ;; + glo_500) + GRDREGION='global' + GRDRES=5p00 + GRIDNR=255 + MODNR=11 + ;; + at_10m) + GRDREGION='atlocn' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + ep_10m) + GRDREGION='epacif' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + wc_10m) + GRDREGION='wcoast' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + ak_10m) + GRDREGION='alaska' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + aoc_9km) + GRDREGION='arctic' + GRDRES=9km + GRIDNR=255 + MODNR=11 + ;; + ant_9km) + GRDREGION='antarc' + GRDRES=9km + GRIDNR=255 + MODNR=11 + ;; + gnh_10m) + GRDREGION='global' + GRDRES=0p16 + GRIDNR=255 + MODNR=11 + ;; + gsh_15m) + GRDREGION='gsouth' + GRDRES=0p25 + GRIDNR=255 + MODNR=11 + ;; + ao_20m) + GRDREGION='arctic' + GRDRES=0p33 + GRIDNR=255 + MODNR=11 + ;; + so_20m) + GRDREGION='antarc' + GRDRES=0p33 + GRIDNR=255 + MODNR=11 + ;; + reg025) + GRDREGION='global' + GRDRES=0p25 + GRIDNR=255 + MODNR=11 + ;; + gwes_30m) + GRDREGION='global' + GRDRES=0p50 + GRIDNR=255 + MODNR=10 + ;; + *) + echo "FATAL ERROR: No grid specific wave config values exist for ${grdID}. Aborting." + exit 1 + ;; + esac + grdNAME="${GRDREGION}.${GRDRES}" + echo "grdNAME=${grdNAME}" + echo "GRIDNR=${GRIDNR}" + echo "MODNR=${MODNR}" } diff --git a/ush/wave_extractvars.sh b/ush/wave_extractvars.sh index 37551358b28..dde21a2c690 100755 --- a/ush/wave_extractvars.sh +++ b/ush/wave_extractvars.sh @@ -18,28 +18,28 @@ com_dir=${!com_varname} subdata=${1} if [[ ! -d "${subdata}" ]]; then - mkdir -p "${subdata}" + mkdir -p "${subdata}" fi -for (( nh = FHOUT_WAV_EXTRACT; nh <= FHMAX_WAV; nh = nh + FHOUT_WAV_EXTRACT )); do - fnh=$(printf "%3.3d" "${nh}") - - infile=${com_dir}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}.grib2 - new_infile=${subdata}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}_ext.grib2 - outfile=${subdata}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}.grib2 - rm -f "${outfile}" # Remove outfile if it already exists before extraction - - if [[ -f "${infile}" ]]; then # Check if input file exists before extraction - if ! cpfs "${infile}" "${new_infile}"; then - echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." - exit 1 +for ((nh = FHOUT_WAV_EXTRACT; nh <= FHMAX_WAV; nh = nh + FHOUT_WAV_EXTRACT)); do + fnh=$(printf "%3.3d" "${nh}") + + infile=${com_dir}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}.grib2 + new_infile=${subdata}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}_ext.grib2 + outfile=${subdata}/${RUN}.wave.t${cyc}z.global.${wavres}.f${fnh}.grib2 + rm -f "${outfile}" # Remove outfile if it already exists before extraction + + if [[ -f "${infile}" ]]; then # Check if input file exists before extraction + if ! cpfs "${infile}" "${new_infile}"; then + echo "FATAL ERROR: Failed to copy ${infile} to ${new_infile}." + exit 1 + fi + # shellcheck disable=SC2312 + ${WGRIB2} "${new_infile}" | grep -F -f "${varlist_wav}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" + else + echo "WARNING: ${infile} does not exist in ${com_dir}." fi - # shellcheck disable=SC2312 - ${WGRIB2} "${new_infile}" | grep -F -f "${varlist_wav}" | ${WGRIB2} -i "${new_infile}" -append -grib "${outfile}" - else - echo "WARNING: ${infile} does not exist in ${com_dir}." - fi - copy_to_comout "${outfile}" "${ARC_RFCST_PROD_WAV}" + copy_to_comout "${outfile}" "${ARC_RFCST_PROD_WAV}" done # nh exit 0 diff --git a/ush/wave_grib2_sbs.sh b/ush/wave_grib2_sbs.sh index b112248f6f8..d36b7d25632 100755 --- a/ush/wave_grib2_sbs.sh +++ b/ush/wave_grib2_sbs.sh @@ -25,7 +25,6 @@ # --------------------------------------------------------------------------- # # 0. Preparations - # Script inputs grdID=$1 GRIDNR=$2 @@ -56,8 +55,8 @@ outfile="${RUN}.t${cyc}z.${grid_region}.${grid_res}.f${FH3}.grib2" # Check if outfile exists in COM if [[ -s "${com_dir}/${outfile}" ]] && [[ -s "${com_dir}/${outfile}.idx" ]]; then - echo "File ${com_dir}/${outfile}[.idx] found, skipping generation process" - exit 0 + echo "File ${com_dir}/${outfile}[.idx] found, skipping generation process" + exit 0 fi # Copy template files to grib_DATA (required for ww3_grib.x) @@ -70,8 +69,8 @@ ${NLN} "${DATA}/mod_def.${grdID}" "./mod_def.ww3" ${NLN} "${DATA}/out_grd.${grdID}" "./out_grd.ww3" # Create the input file for the ww3_grib2 code -ngrib=1 # only one time slice -dtgrib=3600 # only one time slice +ngrib=1 # only one time slice +dtgrib=3600 # only one time slice tstart="${valid_time:0:8} ${valid_time:8:2}0000" sed -e "s/TIME/${tstart}/g" \ @@ -89,28 +88,28 @@ source prep_step "${EXECgfs}/${pgm}" > "grib2_${grid_region}_${FH3}.out" 2>&1 export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: ${pgm} returned non-zero status: ${err}; exiting!" - exit "${err}" + echo "FATAL ERROR: ${pgm} returned non-zero status: ${err}; exiting!" + exit "${err}" fi cat "grib2_${grid_region}_${FH3}.out" if [[ ! -s gribfile ]]; then - echo "FATAL ERROR: '${pgm}' failed!" - exit 2 + echo "FATAL ERROR: '${pgm}' failed!" + exit 2 fi if [[ ${fhr} -gt 0 ]]; then - ${WGRIB2} gribfile -set_date "${PDY}${cyc}" -set_ftime "${fhr} hour fcst" -grib "${outfile}" - err=$? + ${WGRIB2} gribfile -set_date "${PDY}${cyc}" -set_ftime "${fhr} hour fcst" -grib "${outfile}" + err=$? else - ${WGRIB2} gribfile -set_date "${PDY}${cyc}" -set_ftime "${fhr} hour fcst" \ - -set table_1.4 1 -set table_1.2 1 -grib "${outfile}" - err=$? + ${WGRIB2} gribfile -set_date "${PDY}${cyc}" -set_ftime "${fhr} hour fcst" \ + -set table_1.4 1 -set table_1.2 1 -grib "${outfile}" + err=$? fi if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: Error creating '${outfile}' with '${WGRIB2}'" - exit 3 + echo "FATAL ERROR: Error creating '${outfile}' with '${WGRIB2}'" + exit 3 fi # Create index @@ -118,41 +117,41 @@ ${WGRIB2} -s "${outfile}" > "${outfile}.idx" # Move grib files to COM directory if [[ -s "${outfile}" && -s "${outfile}.idx" ]]; then - cpfs "${outfile}" "${com_dir}/${outfile}" - cpfs "${outfile}.idx" "${com_dir}/${outfile}.idx" - echo "INFO: Copied ${outfile} and ${outfile}.idx from ${grib_DATA} to COM" + cpfs "${outfile}" "${com_dir}/${outfile}" + cpfs "${outfile}.idx" "${com_dir}/${outfile}.idx" + echo "INFO: Copied ${outfile} and ${outfile}.idx from ${grib_DATA} to COM" else - echo "FATAL ERROR: ${outfile} and ${outfile}.idx not found in ${grib_DATA} to copy to COM" - exit 4 + echo "FATAL ERROR: ${outfile} and ${outfile}.idx not found in ${grib_DATA} to copy to COM" + exit 4 fi # Create grib2 subgrid if this is the source grid if [[ "${grdID}" == "${WAV_SUBGRBSRC}" ]]; then - for subgrb in ${WAV_SUBGRB}; do - subgrbref=$(echo ${!subgrb} | cut -d " " -f 1-20) - subgrbnam=$(echo ${!subgrb} | cut -d " " -f 21) - subgrbres=$(echo ${!subgrb} | cut -d " " -f 22) - subfnam="${RUN}.t${cyc}z.${subgrbnam}.${subgrbres}.f${FH3}.grib2" - - ${COPYGB2} -g "${subgrbref}" -i0 -x "${outfile}" "${subfnam}" - ${WGRIB2} -s "${subfnam}" > "${subfnam}.idx" - - if [[ -s "${subfnam}" && -s "${subfnam}.idx" ]]; then - cpfs "${subfnam}" "${com_dir}/${subfnam}" - cpfs "${subfnam}.idx" "${com_dir}/${subfnam}.idx" - echo "INFO: Copied ${subfnam} and ${subfnam}.idx from ${GRIBDATA} to COM" - else - echo "FATAL ERROR: ${subfnam} and ${subfnam}.idx not found in ${grib_DATA} to copy to COM" - exit 5 - fi - done + for subgrb in ${WAV_SUBGRB}; do + subgrbref=$(echo "${!subgrb}" | cut -d " " -f 1-20) + subgrbnam=$(echo "${!subgrb}" | cut -d " " -f 21) + subgrbres=$(echo "${!subgrb}" | cut -d " " -f 22) + subfnam="${RUN}.t${cyc}z.${subgrbnam}.${subgrbres}.f${FH3}.grib2" + + ${COPYGB2} -g "${subgrbref}" -i0 -x "${outfile}" "${subfnam}" + ${WGRIB2} -s "${subfnam}" > "${subfnam}.idx" + + if [[ -s "${subfnam}" && -s "${subfnam}.idx" ]]; then + cpfs "${subfnam}" "${com_dir}/${subfnam}" + cpfs "${subfnam}.idx" "${com_dir}/${subfnam}.idx" + echo "INFO: Copied ${subfnam} and ${subfnam}.idx from ${GRIBDATA} to COM" + else + echo "FATAL ERROR: ${subfnam} and ${subfnam}.idx not found in ${grib_DATA} to copy to COM" + exit 5 + fi + done fi if [[ "${SENDDBN}" == 'YES' && "${outfile}" != *global.0p50* ]]; then - echo "INFO: Alerting GRIB file as ${outfile}" - echo "INFO: Alerting GRIB index file as ${outfile}.idx" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WAVE_GB2" "${job}" "${com_dir}/${outfile}" - "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WAVE_GB2_WIDX" "${job}" "${com_dir}/${outfile}.idx" + echo "INFO: Alerting GRIB file as ${outfile}" + echo "INFO: Alerting GRIB index file as ${outfile}.idx" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WAVE_GB2" "${job}" "${com_dir}/${outfile}" + "${DBNROOT}/bin/dbn_alert" MODEL "${RUN^^}_WAVE_GB2_WIDX" "${job}" "${com_dir}/${outfile}.idx" else - echo "INFO: ${outfile} is global.0p50 or SENDDBN is NO, no alert sent" + echo "INFO: ${outfile} is global.0p50 or SENDDBN is NO, no alert sent" fi diff --git a/ush/wave_grid_interp_sbs.sh b/ush/wave_grid_interp_sbs.sh index ed41b813610..3e4fc585687 100755 --- a/ush/wave_grid_interp_sbs.sh +++ b/ush/wave_grid_interp_sbs.sh @@ -41,18 +41,18 @@ ${NLN} "${DATA}/out_grd.${waveGRD}" "./out_grd.${waveGRD}" # Link mod_def files from DATA into interp_DATA for ID in ${waveGRD} ${grdID}; do - ${NLN} "${DATA}/mod_def.${ID}" "./mod_def.${ID}" + ${NLN} "${DATA}/mod_def.${ID}" "./mod_def.${ID}" done # Check if there is an interpolation weights file available, and copy it if so if [[ -f "${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}" ]]; then - echo "INFO: Interpolation weights found at: '${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}'" - cpreq "${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}" "./WHTGRIDINT.bin" - weights_found=1 + echo "INFO: Interpolation weights found at: '${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}'" + cpreq "${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}" "./WHTGRIDINT.bin" + weights_found=1 else - echo "WARNING: No weights file found at: '${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}'" - echo "INFO: Interpolation will create a new weights file" - weights_found=0 + echo "WARNING: No weights file found at: '${FIXgfs}/wave/ww3_gint.WHTGRIDINT.bin.${waveGRD}.${grdID}'" + echo "INFO: Interpolation will create a new weights file" + weights_found=0 fi # Create the input file for the interpolation code @@ -69,26 +69,26 @@ cat ww3_gint.inp export pgm="${NET,,}_ww3_gint.x" source prep_step echo "INFO: Executing '${pgm}'" -"${EXECgfs}/${pgm}" > grid_interp.${grdID}.out 2>&1 +"${EXECgfs}/${pgm}" > "grid_interp.${grdID}.out" 2>&1 cat "grid_interp.${grdID}.out" if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR: '${pgm}' failed!" - exit 3 + echo "FATAL ERROR: '${pgm}' failed!" + exit 3 fi if [[ ${weights_found} -eq 0 ]]; then - echo "INFO: Interpolation created a new weights file at: '${interp_DATA}/WHTGRIDINT.bin'" + echo "INFO: Interpolation created a new weights file at: '${interp_DATA}/WHTGRIDINT.bin'" fi # Link output file (interpolated output) within DATA (this program generates this file) if [[ -f "./out_grd.${grdID}" ]]; then - if [[ -f "${DATA}/out_grd.${grdID}" ]]; then - echo "FATAL ERROR: '${DATA}/out_grd.${grdID}' already exists, ABORT!" - exit 4 - else - ${NLN} "${interp_DATA}/out_grd.${grdID}" "${DATA}/out_grd.${grdID}" - fi + if [[ -f "${DATA}/out_grd.${grdID}" ]]; then + echo "FATAL ERROR: '${DATA}/out_grd.${grdID}' already exists, ABORT!" + exit 4 + else + ${NLN} "${interp_DATA}/out_grd.${grdID}" "${DATA}/out_grd.${grdID}" + fi else - echo "FATAL ERROR: '${pgm}' failed to generate output file at: '${interp_DATA}/out_grd.${grdID}'" - exit 4 + echo "FATAL ERROR: '${pgm}' failed to generate output file at: '${interp_DATA}/out_grd.${grdID}'" + exit 4 fi diff --git a/ush/wave_grid_moddef.sh b/ush/wave_grid_moddef.sh index 7cf6d3aa20b..65ee1550337 100755 --- a/ush/wave_grid_moddef.sh +++ b/ush/wave_grid_moddef.sh @@ -21,44 +21,43 @@ # 0. Preparations # 0.a Basic modes of operation - grdID=${1?Must provide grdID} +grdID=${1?Must provide grdID} - echo "INFO: Generating mod_def file for ${grdID}" +echo "INFO: Generating mod_def file for ${grdID}" - mkdir -p "moddef_${grdID}" - cd "moddef_${grdID}" || exit 2 +mkdir -p "moddef_${grdID}" +cd "moddef_${grdID}" || exit 2 # --------------------------------------------------------------------------- # # 2. Create mod_def file +rm -f "ww3_grid.inp" +${NLN} "../ww3_grid.inp.${grdID}" "ww3_grid.inp" - rm -f "ww3_grid.inp" - ${NLN} "../ww3_grid.inp.${grdID}" "ww3_grid.inp" +if [[ -f "../${grdID}.msh" ]]; then + rm -f "${grdID}.msh" + ${NLN} "../${grdID}.msh" "${grdID}.msh" +fi - if [[ -f "../${grdID}.msh" ]]; then - rm -f "${grdID}.msh" - ${NLN} "../${grdID}.msh" "${grdID}.msh" - fi +export pgm="${NET,,}_ww3_grid.x" - export pgm="${NET,,}_ww3_grid.x" +echo "INFO: Executing ${EXECgfs}/${NET,,}_ww3_grid.x" - echo "INFO: Executing ${EXECgfs}/${NET,,}_ww3_grid.x" +"${EXECgfs}/${pgm}" +export err=$? - "${EXECgfs}/${pgm}" - export err=$? - - if [[ "${err}" != '0' ]]; then +if [[ "${err}" != '0' ]]; then echo "FATAL ERROR: Error in ${pgm}" exit "${err}" - fi +fi - if [[ -f mod_def.ww3 ]];then +if [[ -f mod_def.ww3 ]]; then cpfs "mod_def.ww3" "${COMOUT_WAVE_PREP}/${RUN}.t${cyc}z.mod_def.${grdID}.bin" mv "mod_def.ww3" "../mod_def.${grdID}" - else +else echo "FATAL ERROR: Mod def file not created for ${grdID}" exit 4 - fi +fi # --------------------------------------------------------------------------- # # 3. Clean up diff --git a/ush/wave_outp_cat.sh b/ush/wave_outp_cat.sh index b4482497666..b7200516425 100755 --- a/ush/wave_outp_cat.sh +++ b/ush/wave_outp_cat.sh @@ -29,16 +29,16 @@ specdir=$3 # 0.b Check if buoy location set if [[ $# -lt 1 ]]; then - echo 'FATAL ERROR: LOCATION ID IN ww3_outp_spec.sh NOT SET ***' - exit 1 + echo 'FATAL ERROR: LOCATION ID IN ww3_outp_spec.sh NOT SET ***' + exit 1 fi # 0.c Define directories and the search path. # The tested variables should be exported by the postprocessor script. if [[ -z "${DTPNT_WAV+0}" || -z "${FHMIN_WAV+0}" || -z "${WAV_MOD_TAG+0}" || -z "${STA_DIR+0}" ]]; then - echo 'FATAL ERROR: EXPORTED VARIABLES IN ww3_outp_cat.sh NOT SET ***' - exit 3 + echo 'FATAL ERROR: EXPORTED VARIABLES IN ww3_outp_cat.sh NOT SET ***' + exit 3 fi # --------------------------------------------------------------------------- # @@ -47,53 +47,53 @@ fi echo " Generate input file for ww3_outp." if [[ "${specdir}" == "bull" ]]; then - outfile="${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.bull" - coutfile="${STA_DIR}/c${specdir}/${WAV_MOD_TAG}.${buoy}.cbull" - rm -f "${outfile}" "${coutfile}" + outfile="${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.bull" + coutfile="${STA_DIR}/c${specdir}/${WAV_MOD_TAG}.${buoy}.cbull" + rm -f "${outfile}" "${coutfile}" else - outfile="${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.spec" - rm -f "${outfile}" + outfile="${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.spec" + rm -f "${outfile}" fi fhr=${FHMIN_WAV} fhrp=${fhr} while [[ ${fhr} -le ${MAXHOUR} ]]; do - ymdh=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${fhr} hours") - if [[ "${specdir}" == "bull" ]]; then - outfilefhr="${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" - coutfilefhr="${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" - else - outfilefhr="${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" - fi - - if [[ -f "${outfilefhr}" ]]; then - if [[ "$specdir" == "bull" ]]; then - cat "${outfilefhr}" >> "${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.bull" - cat "${coutfilefhr}" >> "${STA_DIR}/c${specdir}/${WAV_MOD_TAG}.${buoy}.cbull" - rm -f "${outfilefhr}" "${coutfilefhr}" + ymdh=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${fhr} hours") + if [[ "${specdir}" == "bull" ]]; then + outfilefhr="${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" + coutfilefhr="${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" else - cat "${outfilefhr}" >> "${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.spec" - #rm -f "${outfilefhr}" + outfilefhr="${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" fi - else - echo "FATAL ERROR: OUTPUT DATA FILE FOR BUOY ${buoy} at ${ymdh} NOT FOUND" - exit 9 - fi - FHINCP=$(( DTPNT_WAV / 3600 )) - if [[ ${fhr} -eq ${fhrp} ]]; then - fhrp=$((fhr+FHINCP)) - fi - echo "${fhrp}" + if [[ -f "${outfilefhr}" ]]; then + if [[ "${specdir}" == "bull" ]]; then + cat "${outfilefhr}" >> "${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.bull" + cat "${coutfilefhr}" >> "${STA_DIR}/c${specdir}/${WAV_MOD_TAG}.${buoy}.cbull" + rm -f "${outfilefhr}" "${coutfilefhr}" + else + cat "${outfilefhr}" >> "${STA_DIR}/${specdir}/${WAV_MOD_TAG}.${buoy}.spec" + #rm -f "${outfilefhr}" + fi + else + echo "FATAL ERROR: OUTPUT DATA FILE FOR BUOY ${buoy} at ${ymdh} NOT FOUND" + exit 9 + fi + + FHINCP=$((DTPNT_WAV / 3600)) + if [[ ${fhr} -eq ${fhrp} ]]; then + fhrp=$((fhr + FHINCP)) + fi + echo "${fhrp}" - fhr=${fhrp} # no gridded output, loop with out_pnt stride + fhr=${fhrp} # no gridded output, loop with out_pnt stride done if [[ ! -f "${outfile}" ]]; then - echo "FATAL ERROR: OUTPUTFILE ${outfile} not created " - exit 2 + echo "FATAL ERROR: OUTPUTFILE ${outfile} not created " + exit 2 fi # End of ww3_outp_cat.sh ---------------------------------------------------- # diff --git a/ush/wave_outp_spec.sh b/ush/wave_outp_spec.sh index e365741809f..96bfc196d9c 100755 --- a/ush/wave_outp_spec.sh +++ b/ush/wave_outp_spec.sh @@ -31,31 +31,31 @@ workdir=$4 # 0.b Check if buoy location set if [[ $# -lt 1 ]]; then - echo 'FATAL ERROR: LOCATION ID IN wave_outp_spec.sh NOT SET' - exit 1 + echo 'FATAL ERROR: LOCATION ID IN wave_outp_spec.sh NOT SET' + exit 1 else - point=$(awk "{if (\$2 == \"${buoy}\"){print \$1; exit} }" "${DATA}/buoy_log.ww3") - if [[ -z "${point}" ]]; then - echo 'FATAL ERROR: LOCATION ID IN ww3_outp_spec.sh NOT RECOGNIZED' - exit 2 - else - printf "\n Location ID/# : %s (%s) ${buoy} (${point})\n Spectral output start time : %s" "${buoy}" "${point}" "${ymdh}" - fi + point=$(awk "{if (\$2 == \"${buoy}\"){print \$1; exit} }" "${DATA}/buoy_log.ww3") + if [[ -z "${point}" ]]; then + echo 'FATAL ERROR: LOCATION ID IN ww3_outp_spec.sh NOT RECOGNIZED' + exit 2 + else + printf "\n Location ID/# : %s (%s) ${buoy} (${point})\n Spectral output start time : %s" "${buoy}" "${point}" "${ymdh}" + fi fi # 0.c Define directories and the search path. # The tested variables should be exported by the postprocessor script. if [[ -z "${PDY+0}" || -z "${cyc+0}" || -z "${dtspec+0}" || -z "${EXECgfs+0}" || -z "${WAV_MOD_TAG+0}" || -z "${STA_DIR+0}" ]]; then - echo 'FATAL ERROR: EXPORTED VARIABLES IN ww3_outp_spec.sh NOT SET' - exit 3 + echo 'FATAL ERROR: EXPORTED VARIABLES IN ww3_outp_spec.sh NOT SET' + exit 3 fi -cd "${workdir}" +cd "${workdir}" || exit 1 rm -rf "${specdir}_${buoy}" mkdir -p "${specdir}_${buoy}" -cd "${specdir}_${buoy}" +cd "${specdir}_${buoy}" || exit 1 cat << EOF @@ -86,22 +86,22 @@ tstart="${ymdh:0:8} ${ymdh:8:2}0000" printf " Output starts at %s.\n" "${tstart}" if [[ "${specdir}" == "bull" ]]; then - truntime="${PDY} ${cyc}0000" - sed -e "s/TIME/${tstart}/g" \ - -e "s/DT/${dtspec}/g" \ - -e "s/POINT/${point}/g" \ - -e "s/REFT/${truntime}/g" \ - "${DATA}/ww3_outp_bull.inp.tmpl" > ww3_outp.inp - outfile="${buoy}.bull" - coutfile="${buoy}.cbull" + truntime="${PDY} ${cyc}0000" + sed -e "s/TIME/${tstart}/g" \ + -e "s/DT/${dtspec}/g" \ + -e "s/POINT/${point}/g" \ + -e "s/REFT/${truntime}/g" \ + "${DATA}/ww3_outp_bull.inp.tmpl" > ww3_outp.inp + outfile="${buoy}.bull" + coutfile="${buoy}.cbull" else - sed -e "s/TIME/${tstart}/g" \ - -e "s/DT/${dtspec}/g" \ - -e "s/POINT/${point}/g" \ - -e "s/ITYPE/1/g" \ - -e "s/FORMAT/F/g" \ - "${DATA}/ww3_outp_spec.inp.tmpl" > ww3_outp.inp - outfile="ww3.${tstart:2:5}${tstart:9:2}.spc" + sed -e "s/TIME/${tstart}/g" \ + -e "s/DT/${dtspec}/g" \ + -e "s/POINT/${point}/g" \ + -e "s/ITYPE/1/g" \ + -e "s/FORMAT/F/g" \ + "${DATA}/ww3_outp_spec.inp.tmpl" > ww3_outp.inp + outfile="ww3.${tstart:2:5}${tstart:9:2}.spc" fi # 2.b Run the postprocessor @@ -114,8 +114,8 @@ echo " Executing ${EXECgfs}/${pgm}" "${EXECgfs}/${pgm}" 1> "outp_${specdir}_${buoy}.out" 2>&1 export err=$? if [[ ${err} -ne 0 ]]; then - echo "FATAL ERROR : ERROR IN ${pgm} *** " - exit 4 + echo "FATAL ERROR : ERROR IN ${pgm} *** " + exit 4 fi # --------------------------------------------------------------------------- # @@ -126,31 +126,31 @@ YMDHE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${FHMAX_WAV_PNT} hours") model_start_date=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} + ${OFFSET_START_HOUR} hours") if [[ -f "${outfile}" ]]; then - if [[ "${ymdh}" == "${model_start_date}" ]]; then - if [[ "${specdir}" == "bull" ]]; then - sed '9,$d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" - sed '8,$d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" - else - cat "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" - fi - elif [[ "${ymdh}" == "${YMDHE}" ]]; then - if [[ "${specdir}" == "bull" ]]; then - sed '1,7d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" - sed '1,6d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" - else - sed -n "/^${ymdh:0:8} ${ymdh:8:2}0000$/,\$p" "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" - fi - else - if [[ "${specdir}" == "bull" ]]; then - sed '8q;d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" - sed '7q;d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" - else - sed -n "/^${ymdh:0:8} ${ymdh:8:2}0000$/,\$p" "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" - fi - fi + if [[ "${ymdh}" == "${model_start_date}" ]]; then + if [[ "${specdir}" == "bull" ]]; then + sed '9,$d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" + sed '8,$d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" + else + cat "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" + fi + elif [[ "${ymdh}" == "${YMDHE}" ]]; then + if [[ "${specdir}" == "bull" ]]; then + sed '1,7d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" + sed '1,6d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" + else + sed -n "/^${ymdh:0:8} ${ymdh:8:2}0000$/,\$p" "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" + fi + else + if [[ "${specdir}" == "bull" ]]; then + sed '8q;d' "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.bull" + sed '7q;d' "${coutfile}" >> "${STA_DIR}/c${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.cbull" + else + sed -n "/^${ymdh:0:8} ${ymdh:8:2}0000$/,\$p" "${outfile}" >> "${STA_DIR}/${specdir}fhr/${WAV_MOD_TAG}.${ymdh}.${buoy}.spec" + fi + fi else - echo "FATAL ERROR: OUTPUT DATA FILE FOR BUOY '${buoy}' NOT FOUND" - exit 5 + echo "FATAL ERROR: OUTPUT DATA FILE FOR BUOY '${buoy}' NOT FOUND" + exit 5 fi # 3.b Clean up the rest diff --git a/ush/wave_prnc_cur.sh b/ush/wave_prnc_cur.sh index cdeecc1f7c5..a52b9336dc6 100755 --- a/ush/wave_prnc_cur.sh +++ b/ush/wave_prnc_cur.sh @@ -31,10 +31,10 @@ fext='f' # Timing has to be made relative to the single 00z RTOFS cycle for that PDY -mkdir -p rtofs_${ymdh_rtofs} -cd rtofs_${ymdh_rtofs} +mkdir -p "rtofs_${ymdh_rtofs}" +cd "rtofs_${ymdh_rtofs}" || exit 1 -ncks -x -v sst,sss,layer_density "${curfile} cur_uv_${PDY}_${fext}${fh3}.nc" +ncks -x -v sst,sss,layer_density "${curfile}" "cur_uv_${PDY}_${fext}${fh3}.nc" ncks -O -a -h -x -v Layer "cur_uv_${PDY}_${fext}${fh3}.nc" "cur_temp1.nc" ncwa -h -O -a Layer cur_temp1.nc cur_temp2.nc ncrename -h -O -v MT,time -d MT,time cur_temp2.nc @@ -44,28 +44,27 @@ mv -f "cur_temp3.nc" "cur_uv_${PDY}_${fext}${fh3}_flat.nc" # Convert to regular lat lon file # If weights need to be regenerated due to CDO ver change, use: # $CDO genbil,r4320x2160 rtofs_glo_2ds_f000_3hrly_prog.nc weights.nc -cpreq ${FIXgfs}/wave/weights_rtofs_to_r4320x2160.nc ./weights.nc +cpreq "${FIXgfs}/wave/weights_rtofs_to_r4320x2160.nc" ./weights.nc # Interpolate to regular 5 min grid ${CDO} remap,r4320x2160,weights.nc "cur_uv_${PDY}_${fext}${fh3}_flat.nc" "cur_5min_01.nc" # Perform 9-point smoothing twice to make RTOFS data less noisy when # interpolating from 1/12 deg RTOFS grid to 1/6 deg wave grid -if [ "WAV_CUR_CDO_SMOOTH" = "YES" ]; then - ${CDO} -f nc -smooth9 "cur_5min_01.nc" "cur_5min_02.nc" - ${CDO} -f nc -smooth9 "cur_5min_02.nc" "cur_glo_uv_${PDY}_${fext}${fh3}_5min.nc" +if [[ "${WAV_CUR_CDO_SMOOTH}" == "YES" ]]; then + ${CDO} -f nc -smooth9 "cur_5min_01.nc" "cur_5min_02.nc" + ${CDO} -f nc -smooth9 "cur_5min_02.nc" "cur_glo_uv_${PDY}_${fext}${fh3}_5min.nc" else - mv "cur_5min_01.nc" "cur_glo_uv_${PDY}_${fext}${fh3}_5min.nc" + mv "cur_5min_01.nc" "cur_glo_uv_${PDY}_${fext}${fh3}_5min.nc" fi # Cleanup rm -f cur_temp[123].nc cur_5min_??.nc "cur_glo_uv_${PDY}_${fext}${fh3}.nc weights.nc" -if [ ${flagfirst} = "T" ] -then - sed -e "s/HDRFL/T/g" ${PARMgfs}/wave/ww3_prnc.cur.${WAVECUR_FID}.inp.tmpl > ww3_prnc.inp +if [[ "${flagfirst}" = "T" ]]; then + sed -e "s/HDRFL/T/g" "${PARMgfs}/wave/ww3_prnc.cur.${WAVECUR_FID}.inp.tmpl" > ww3_prnc.inp else - sed -e "s/HDRFL/F/g" ${PARMgfs}/wave/ww3_prnc.cur.${WAVECUR_FID}.inp.tmpl > ww3_prnc.inp + sed -e "s/HDRFL/F/g" "${PARMgfs}/wave/ww3_prnc.cur.${WAVECUR_FID}.inp.tmpl" > ww3_prnc.inp fi rm -f cur.nc @@ -75,22 +74,15 @@ ${NLN} "${DATA}/mod_def.${WAVECUR_FID}" ./mod_def.ww3 export pgm="${NET,,}_ww3_prnc.x" source prep_step -"${EXECgfs}/${pgm}" 1> prnc_${WAVECUR_FID}_${ymdh_rtofs}.out 2>&1 -export err=$?; err_chk -if [ "$err" != '0' ] -then - cat prnc_${WAVECUR_FID}_${ymdh_rtofs}.out - set $setoff - echo ' ' - echo '******************************************** ' - echo "*** WARNING: NON-FATAL ERROR IN ${pgm} *** " - echo '******************************************** ' - echo ' ' - set $seton - echo "WARNING: NON-FATAL ERROR IN ${pgm}." - exit 4 +"${EXECgfs}/${pgm}" 1> "prnc_${WAVECUR_FID}_${ymdh_rtofs}.out" 2>&1 +export err=$? +err_chk +if [[ "${err}" -ne 0 ]]; then + cat "prnc_${WAVECUR_FID}_${ymdh_rtofs}.out" + echo "WARNING: NON-FATAL ERROR IN ${pgm}." + exit 4 fi -mv -f current.ww3 ${DATA}/rtofs.${ymdh_rtofs} +mv -f current.ww3 "${DATA}/rtofs.${ymdh_rtofs}" -cd ${DATA} +cd "${DATA}" || exit 1 diff --git a/ush/wave_prnc_ice.sh b/ush/wave_prnc_ice.sh index 3812b5e8120..caeba3a0d05 100755 --- a/ush/wave_prnc_ice.sh +++ b/ush/wave_prnc_ice.sh @@ -29,100 +29,96 @@ # 0.a Basic modes of operation - rm -rf ice - mkdir ice - cd ice - ${NLN} "${DATA}/postmsg" postmsg +rm -rf ice +mkdir ice +cd ice || exit 1 +${NLN} "${DATA}/postmsg" postmsg # 0.b Define directories and the search path. # The tested variables should be exported by the postprocessor script. - set +x - cat << EOF +set +x +cat << EOF +--------------------------------+ ! Make ice fields | +--------------------------------+ - Model TAG : $WAV_MOD_TAG + Model TAG : ${WAV_MOD_TAG} Model ID : ${RUN}.wave - Ice grid ID : $WAVEICE_FID - Ice file : $WAVICEFILE + Ice grid ID : ${WAVEICE_FID} + Ice file : ${WAVICEFILE} Making ice fields. EOF - if [[ -z "${YMDH}" ]] || [[ -z "${cycle}" ]] || \ - [[ -z "${COMOUT_WAVE_PREP}" ]] || [[ -z "${FIXgfs}" ]] || [[ -z "${EXECgfs}" ]] || \ - [[ -z "${WAV_MOD_TAG}" ]] || [[ -z "${WAVEICE_FID}" ]] || [[ -z "${COMIN_OBS}" ]]; then +if [[ -z "${YMDH}" ]] || [[ -z "${cycle}" ]] || + [[ -z "${COMOUT_WAVE_PREP}" ]] || [[ -z "${FIXgfs}" ]] || [[ -z "${EXECgfs}" ]] || + [[ -z "${WAV_MOD_TAG}" ]] || [[ -z "${WAVEICE_FID}" ]] || [[ -z "${COMIN_OBS}" ]]; then echo 'ERROR: EXPORTED VARIABLES IN preprocessor NOT SET ***' exit 1 - fi +fi # 0.c Links to working directory - ${NLN} ${DATA}/mod_def.$WAVEICE_FID mod_def.ww3 +${NLN} "${DATA}/mod_def.${WAVEICE_FID}" mod_def.ww3 # --------------------------------------------------------------------------- # # 1. Get the necessary files # 1.a Copy the ice data file - file=${COMIN_OBS}/${WAVICEFILE} +file="${COMIN_OBS}/${WAVICEFILE}" - if [ -f $file ] - then - cpreq $file ice.grib - fi +if [[ -f "${file}" ]]; then + cpreq "${file}" ice.grib +fi - if [ -f ice.grib ] - then - echo " ice.grib copied ($file)." - else - echo "ERROR: NO ICE FILE $file" - exit 2 - fi +if [[ -f ice.grib ]]; then + echo " ice.grib copied (${file})." +else + msg="FATAL ERROR: NO ICE FILE ${file}" + export err=2 + err_exit "${msg}" +fi # --------------------------------------------------------------------------- # # 2. Process the GRIB packed ice file # 2.a Unpack data - echo ' Extracting data from ice.grib ...' +echo ' Extracting data from ice.grib ...' - $WGRIB2 ice.grib -netcdf icean_5m.nc 2>&1 > wgrib.out +${WGRIB2} ice.grib -netcdf icean_5m.nc wgrib.out 2>&1 - err=$? +err=$? - if [ "$err" != '0' ] - then +if [[ "${err}" -ne 0 ]]; then cat wgrib.out echo 'ERROR: FAILURE WHILE UNPACKING GRIB ICE FILE *** ' exit 3 - fi - - rm -f wgrib.out - rm -f ice.grib - rm -f ice.index +fi +rm -f wgrib.out +rm -f ice.grib +rm -f ice.index # 2.d Run through preprocessor wave_prep - printf " Run through preprocessor ...\n" +printf " Run through preprocessor ...\n" - cpreq -f ${DATA}/ww3_prnc.ice.$WAVEICE_FID.inp.tmpl ww3_prnc.inp +cpreq -f "${DATA}/ww3_prnc.ice.${WAVEICE_FID}.inp.tmpl" ww3_prnc.inp - export pgm="${NET,,}_ww3_prnc.x" - source prep_step +export pgm="${NET,,}_ww3_prnc.x" +source prep_step - "${EXECgfs}/${pgm}" 1> prnc_${WAVEICE_FID}_${cycle}.out 2>&1 - export err=$? - if [[ ${err} -ne 0 ]] - then - cat prnc_${WAVEICE_FID}_${cycle}.out - echo "ERROR: failure in ${pgm}" - exit 4 - fi +"${EXECgfs}/${pgm}" 1> "prnc_${WAVEICE_FID}_${cycle}.out" 2>&1 +export err=$? +if [[ ${err} -ne 0 ]]; then + cat "prnc_${WAVEICE_FID}_${cycle}.out" + msg="FATAL ERROR: failure in ${pgm}" + err_exit "${msg}" +fi - rm -f wave_prep.out ww3_prep.inp ice.raw mod_def.ww3 +rm -f wave_prep.out ww3_prep.inp ice.raw mod_def.ww3 # --------------------------------------------------------------------------- # # 3. Save the ice file @@ -130,17 +126,15 @@ EOF # Ice file name will have ensemble member number if WW3ATMIENS=T # and only WAV_MOD_ID if WW3ATMIENS=F # - if [ "${WW3ATMIENS}" = "T" ] - then - icefile=${WAV_MOD_TAG}.${WAVEICE_FID}.$cycle.ice - elif [ "${WW3ATMIENS}" = "F" ] - then - icefile=${RUN}.wave.${WAVEICE_FID}.$cycle.ice - fi - - echo " Saving ice.ww3 as ${COMOUT_WAVE_PREP}/${icefile}" - cpfs ice.ww3 "${COMOUT_WAVE_PREP}/${icefile}" - rm -f ice.ww3 +if [[ "${WW3ATMIENS}" == "T" ]]; then + icefile="${WAV_MOD_TAG}.${WAVEICE_FID}.${cycle}.ice" +elif [[ "${WW3ATMIENS}" == "F" ]]; then + icefile="${RUN}.wave.${WAVEICE_FID}.${cycle}.ice" +fi + +echo " Saving ice.ww3 as ${COMOUT_WAVE_PREP}/${icefile}" +cpfs ice.ww3 "${COMOUT_WAVE_PREP}/${icefile}" +rm -f ice.ww3 # --------------------------------------------------------------------------- # # 4. Clean up the directory diff --git a/ush/wave_tar.sh b/ush/wave_tar.sh index 9e278c79b02..e24def1e11f 100755 --- a/ush/wave_tar.sh +++ b/ush/wave_tar.sh @@ -27,25 +27,23 @@ # 0.a Basic modes of operation - cd "${DATA}" - echo "Making TAR FILE" - - alertName=$(echo $RUN|tr [a-z] [A-Z]) - +cd "${DATA}" || exit 1 +echo "Making TAR FILE" +export err # 0.b Check if type set - if [[ "$#" -lt '3' ]] - then - echo 'FATAL ERROR: VARIABLES IN ww3_tar.sh NOT SET' - exit 1 - else +if [[ "$#" -lt '3' ]]; then + msg='FATAL ERROR: VARIABLES IN ww3_tar.sh NOT SET' + err=1 + err_exit "${msg}" +else ID=$1 type=$2 nb=$3 - fi +fi - cat << EOF +cat << EOF +--------------------------------+ ! Make tar file | @@ -55,122 +53,120 @@ Number of files : $3 EOF - filext=$type - if [[ "$type" == "ibp" ]]; then - filext='spec' - fi - if [[ "$type" == "ibpbull" ]]; then - filext='bull' - fi - if [[ "$type" == "ibpcbull" ]]; then - filext='cbull' - fi - - rm -rf TAR_${filext}_$ID - mkdir TAR_${filext}_$ID +filext=${type} +if [[ "${type}" == "ibp" ]]; then + filext='spec' +fi +if [[ "${type}" == "ibpbull" ]]; then + filext='bull' +fi +if [[ "${type}" == "ibpcbull" ]]; then + filext='cbull' +fi + +rm -rf "TAR_${filext}_${ID}" +mkdir "TAR_${filext}_${ID}" # this directory is used only for error capturing # 0.c Define directories and the search path. # The tested variables should be exported by the postprocessor script. - if [[ -z "${COMOUT_WAVE_STATION+x}" || -z "${SENDDBN+x}" || -z "${STA_DIR+x}" ]]; then - echo 'FATAL ERROR: EXPORTED VARIABLES IN ww3_tar.sh NOT SET' - exit 2 - fi +if [[ -z "${COMOUT_WAVE_STATION+x}" || -z "${SENDDBN+x}" || -z "${STA_DIR+x}" ]]; then + msg='FATAL ERROR: EXPORTED VARIABLES IN ww3_tar.sh NOT SET' + err=2 + err_exit "${msg}" +fi # --------------------------------------------------------------------------- # # 2. Generate tar file (spectral files are compressed) - printf "\n Making tar file ..." - - countMAX=5 - tardone='no' - sleep_interval=10 - - while [[ "${tardone}" = "no" ]] - do - - nf=$(find . -maxdepth 1 -type f -name "*.$filext" | wc -l) - nbm2=$(( $nb - 2 )) - if [[ ${nf} -ge ${nbm2} ]] - then - - tar -cf "${ID}.${type}.tar" ./*."${filext}" - err=$? - - if [[ ${err} -ne 0 ]] - then - echo 'FATAL ERROR: TAR CREATION FAILED *** ' - exit 3 - fi +printf "\n Making tar file ..." + +countMAX=5 +tardone='no' +sleep_interval=10 + +while [[ "${tardone}" == "no" ]]; do + # shellcheck disable=SC2312 + nf=$(find . -maxdepth 1 -type f -name "*.${filext}" -printf '.' | wc -c) + nbm2=$((nb - 2)) + if [[ ${nf} -ge ${nbm2} ]]; then + + tar -cf "${ID}.${type}.tar" ./*."${filext}" + err=$? + + if [[ ${err} -ne 0 ]]; then + msg='FATAL ERROR: TAR CREATION FAILED *** ' + err=3 + err_exit "${msg}" + fi + + filename="${ID}.${type}.tar" + if ! wait_for_file "${filename}" "${sleep_interval}" "${countMAX}"; then + msg="FATAL ERROR: File ${filename} not found after waiting $((sleep_interval * (countMAX + 1))) secs" + err=3 + err_exit "${msg}" + fi + + if [[ -f "${ID}.${type}.tar" ]]; then + tardone='yes' + fi + fi - filename="${ID}.${type}.tar" - if ! wait_for_file "${filename}" "${sleep_interval}" "${countMAX}" ; then - echo "FATAL ERROR: File ${filename} not found after waiting $(( sleep_interval * (countMAX + 1) )) secs" - exit 3 - fi +done - if [[ -f "${ID}.${type}.tar" ]] - then - tardone='yes' - fi - fi +if [[ "${tardone}" == 'no' ]]; then + msg='FATAL ERROR: TAR CREATION FAILED *** ' + err=3 + err_exit "${msg}" +fi - done - - if [[ "${tardone}" == 'no' ]] - then - echo 'FATAL ERROR: TAR CREATION FAILED *** ' - exit 3 - fi - - if [[ "${type}" == 'spec' ]] - then - if [[ -s "${ID}.${type}.tar" ]] - then - file_name="${ID}.${type}.tar.gz" - /usr/bin/gzip -c "${ID}.${type}.tar" > "${file_name}" - err=$? - - if [[ ${err} -ne 0 ]] - then - echo 'FATAL ERROR: SPECTRAL TAR COMPRESSION FAILED *** ' - exit 4 - fi +if [[ "${type}" == 'spec' ]]; then + if [[ -s "${ID}.${type}.tar" ]]; then + file_name="${ID}.${type}.tar.gz" + /usr/bin/gzip -c "${ID}.${type}.tar" > "${file_name}" + err=$? + + if [[ ${err} -ne 0 ]]; then + msg='FATAL ERROR: SPECTRAL TAR COMPRESSION FAILED *** ' + err=4 + err_exit + fi fi - else +else file_name="${ID}.${type}.tar" - fi +fi # --------------------------------------------------------------------------- # # 3. Move data to /com - echo " Moving tar file ${file_name} to ${COMOUT_WAVE_STATION} ..." +echo " Moving tar file ${file_name} to ${COMOUT_WAVE_STATION} ..." - cpfs "${file_name}" "${COMOUT_WAVE_STATION}/." +cpfs "${file_name}" "${COMOUT_WAVE_STATION}/." - err=$? +err=$? - if [[ ${err} -ne 0 ]]; then - echo 'FATAL ERROR: TAR COPY FAILED *** ' - exit 4 - fi +if [[ ${err} -ne 0 ]]; then + msg='FATAL ERROR: TAR COPY FAILED *** ' + export err=4 + err_exit "${msg}" +fi - if [[ "${SENDDBN}" == "YES" ]]; then +if [[ "${SENDDBN}" == "YES" ]]; then echo " Alerting TAR file as ${COMOUT_WAVE_STATION}/${file_name}" - "${DBNROOT}/bin/dbn_alert MODEL" "${alertName}_WAVE_TAR" "${job}" \ - "${COMOUT_WAVE_STATION}/${file_name}" - fi + "${DBNROOT}/bin/dbn_alert MODEL" "${RUN^^}_WAVE_TAR" "${job}" \ + "${COMOUT_WAVE_STATION}/${file_name}" +fi # --------------------------------------------------------------------------- # # 4. Final clean up -cd "${DATA}" +cd "${DATA}" || exit 1 -if [[ ${KEEPDATA:-NO} == "NO" ]]; then - set -v - rm -rf ${STA_DIR}/${type} - set +v +if [[ "${KEEPDATA:-NO}" == "NO" ]]; then + set -v + rm -rf "${STA_DIR:?}/${type}" + set +v fi # End of ww3_tar.sh ----------------------------------------------------- # diff --git a/versions/fix.ver b/versions/fix.ver index fa2b4311fad..d48482e93ae 100644 --- a/versions/fix.ver +++ b/versions/fix.ver @@ -17,7 +17,7 @@ export gdas_snow_ver=20241210 export glwu_ver=20220805 export gsi_ver=20251105 export lut_ver=20220805 -export mom6_ver=20240416 +export mom6_ver=20250128 export orog_ver=20240917 export reg2grb2_ver=20220805 export sfc_climo_ver=20220805 diff --git a/versions/run.wcoss2.ver b/versions/run.wcoss2.ver index fd4db95025e..09398f4f8c0 100644 --- a/versions/run.wcoss2.ver +++ b/versions/run.wcoss2.ver @@ -43,7 +43,7 @@ export esmf_ver=8.8.0 export util_shared_ver=1.4.0 export ncdiag_ver=1.1.2 export g2tmpl_ver=1.10.2 -export crtm_ver=2.4.0.1 +export crtm_ver=2.4.0.2 export met_ver=9.1.3 export metplus_ver=3.1.1