Skip to content

Conversation

@jiaruidong2017
Copy link
Contributor

@jiaruidong2017 jiaruidong2017 commented Dec 27, 2025

Description

This PR adds an entry to enable assimilation of the GHCN snow observations for reanalysis. This PR also includes functionality to preprocess the GHCN snow observations for global snow analysis.

This PR depends NOAA-EMC/GDASApp#2019; #4388; NOAA-EMC/GDASApp#2027
Resolves NOAA-EMC/GDASApp#2018

This PR merged the PR #4387 which enables to read and process the input IMS snow cover data in either ascii or netCDF format.
Resolves NOAA-EMC/GDASApp#2022

Type of change

  • New feature (adds functionality)

Change characteristics

How has this been tested?

I conducted cycled experiments with DO_JEDISNOWDA=YES. These runs also require GHCN snow observations.

  • Cycled test on Ursa

Checklist

  • Any dependent changes have been merged and published
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have documented my code, including function, input, and output descriptions
  • My changes generate no new warnings
  • New and existing tests pass with my changes
  • This change is covered by an existing CI test or a new one has been added
  • Any new scripts have been added to the .github/CODEOWNERS file with owners
  • I have made corresponding changes to the system documentation if necessary

Copy link
Contributor

@ClaraDraper-NOAA ClaraDraper-NOAA left a comment

Choose a reason for hiding this comment

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

For both IMS and GHCN, the snow_analysis task will continue without failing if there's a problem with the input data.

If there's a problem in prepare_[dataset], it reports a warning and continues. The snow_analysis will also continue if it doesn't find the expected file. I'd prefer that the code exits (or perhaps has a config option to force exit?) to let us know that there was a problem with the file. @CoryMartin-NOAA ?

@CoryMartin-NOAA
Copy link
Contributor

@ClaraDraper-NOAA we can make an option that will fail instead of warn, but except in rare circumstances, operational requirements will make it so that the code needs to run to completion if input data is missing. Assimilating no snow obs that cycle is 10000x preferred to the GFS not starting in a timely manner.

@ClaraDraper-NOAA
Copy link
Contributor

@ClaraDraper-NOAA we can make an option that will fail instead of warn, but except in rare circumstances, operational requirements will make it so that the code needs to run to completion if input data is missing. Assimilating no snow obs that cycle is 10000x preferred to the GFS not starting in a timely manner.

thanks @CoryMartin-NOAA . @jiaruidong2017 Can you please make an option for GHCN and IMS to switch between warning and failing if the obs are missing. It should be controlled by an input flag, with the default being to throw a warning.

@jiaruidong2017
Copy link
Contributor Author

jiaruidong2017 commented Dec 31, 2025

@ClaraDraper-NOAA we can make an option that will fail instead of warn, but except in rare circumstances, operational requirements will make it so that the code needs to run to completion if input data is missing. Assimilating no snow obs that cycle is 10000x preferred to the GFS not starting in a timely manner.

thanks @CoryMartin-NOAA . @jiaruidong2017 Can you please make an option for GHCN and IMS to switch between warning and failing if the obs are missing. It should be controlled by an input flag, with the default being to throw a warning.

If the GHCN data is missing, the GHCN preprocessing (prepare_GHCN()) will not run as shown below.

        # if 00z, do GHCN preprocessing
        _ghcn_file = os.path.join(self.task_config.COMIN_OBS, f'{self.task_config.OPREFIX}ghcn_snow.csv')
        logger.info(f"Checking for GHCN csv file: {_ghcn_file}")
        if self.task_config.cyc == 0 and os.path.exists(_ghcn_file):
            _DO_GHCN = True
        else:
            _DO_GHCN = False

Therefore, the warning in prepare_GHCN() is unnecessary because this condition will never occur in practice. It can be safely removed. What do you think?

        if not os.path.isfile(csv_file):
            logger.warning(f"WARNING: GHCN obs file not found.")
            return

If we still decide to keep the logic that allows the code to exit when the GHCN data is missing, then this check should be implemented during the initialize() step as shown below:

        # if 00z, do GHCN preprocessing
        _DO_GHCN = False
        if self.task_config.cyc == 0:
            if os.path.exists(_ghcn_file):
                _DO_GHCN = True
            else:
                if _fail_on_missing:
                    raise FileNotFoundError(
                        f"GHCN obs file required but not found: {_ghcn_file}"
                    )
                else:
                    logger.warning(f"GHCN obs file missing: {_ghcn_file}")
        else:
            logger.info("Not 00z cycle — Skipping GHCN preprocessing.")

Any suggestions?

@CoryMartin-NOAA
Copy link
Contributor

@jiaruidong2017 your last snippet makes sense to me, raise a FileNotFound error if the file is missing and we want it to not continue when missing

@ClaraDraper-NOAA
Copy link
Contributor

Thanks @jiaruidong2017. I like your last solution too. can you please add it for IMS as well?

@jiaruidong2017
Copy link
Contributor Author

Thanks @CoryMartin-NOAA @ClaraDraper-NOAA I will add it for both GHCN and IMS.

CoryMartin-NOAA added a commit to NOAA-EMC/GDASApp that referenced this pull request Jan 2, 2026
# Description
This PR adds a `ghcn_snod2ioda.py` script to processes the GHCN data in
csv format to IODA-format files for snow DA in the global-workflow.

# Companion PRs
This PR depends NOAA-EMC/jcb-gdas#220,
NOAA-EMC/DA-utils#53, and
NOAA-EMC/global-workflow#4388
This PR contributes NOAA-EMC/global-workflow#4386

# Issues
Resolves #2018 

# Automated CI tests to run in Global Workflow
<!-- Which Global Workflow CI tests are required to adequately test this
PR? -->
- [ ] atm_jjob <!-- JEDI atm single cycle DA !-->
- [ ] C96C48_ufs_hybatmDA <!-- JEDI atm cycled DA !-->
- [ ] C96C48_hybatmsnowDA <!-- JEDI snow cycled DA !-->
- [ ] C96_gcafs_cycled <!-- JEDI aerosol cycled DA !-->
- [ ] C48mx500_3DVarAOWCDA <!-- JEDI low-res marine 3DVar cycled DA !-->
- [ ] C48mx500_hybAOWCDA <!-- JEDI marine hybrid envar cycled DA !-->
- [ ] C96C48_ufsgsi_hybatmDA <!-- JEDI atm Var with GSI EnKF cycled DA
!-->
- [ ] C96C48_hybatmDA <!-- GSI atm cycled DA !-->

---------

Co-authored-by: Cory Martin <[email protected]>
@jiaruidong2017
Copy link
Contributor Author

Thank you @RussTreadon-NOAA As you suggested, I update the config.esnowanl.j2 to include the required parameters settings for snow ensemble analysis.

@DavidHuber-NOAA
Copy link
Contributor

Launching CI on C6.

@emcbot emcbot added CI-Gaeac6-Ready **CM use only** PR is ready for CI testing on Gaea C6 CI-Gaeac6-Building **Bot use only** CI testing is cloning/building on Gaea C6 CI-Gaeac6-Running **Bot use only** CI testing on Gaea C6 for this PR is in-progress and removed CI-Gaeac6-Ready **CM use only** PR is ready for CI testing on Gaea C6 CI-Gaeac6-Building **Bot use only** CI testing is cloning/building on Gaea C6 labels Jan 6, 2026
@emcbot
Copy link

emcbot commented Jan 6, 2026

C96C48_hybatmsnowDA FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96C48_hybatmsnowDA_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96C48_hybatmsnowDA_bc6c2927-6829/logs/2021122018/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot emcbot added CI-Gaeac6-Failed **Bot use only** CI testing on Gaea C6 for this PR has failed and removed CI-Gaeac6-Running **Bot use only** CI testing on Gaea C6 for this PR is in-progress labels Jan 6, 2026
@emcbot
Copy link

emcbot commented Jan 6, 2026

C48mx500_hybAOWCDA FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C48mx500_hybAOWCDA_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C48mx500_hybAOWCDA_bc6c2927-6829/logs/2021032500/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot
Copy link

emcbot commented Jan 6, 2026

C96C48_hybatmDA FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96C48_hybatmDA_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96C48_hybatmDA_bc6c2927-6829/logs/2021122100/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot
Copy link

emcbot commented Jan 6, 2026

C96_atm3DVar FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96_atm3DVar_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96_atm3DVar_bc6c2927-6829/logs/2021122100/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot
Copy link

emcbot commented Jan 6, 2026

C48mx500_3DVarAOWCDA FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C48mx500_3DVarAOWCDA_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C48mx500_3DVarAOWCDA_bc6c2927-6829/logs/2021032500/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@CoryMartin-NOAA
Copy link
Contributor

@DavidHuber-NOAA I think we are going to have to just accept that this PR has broken stats and the other has broken snow and merge both in and I will fix ASAP any issues that were missed. Apologies but it's from juggling too many pieces in the syncing of PRs between repos.

@jiaruidong2017
Copy link
Contributor Author

I think the gdas_anlstat issue can be fixed by @CoryMartin-NOAA's PR #4401

@jiaruidong2017
Copy link
Contributor Author

Thanks @CoryMartin-NOAA

@emcbot
Copy link

emcbot commented Jan 6, 2026

C96_gcafs_cycled FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96_gcafs_cycled_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96_gcafs_cycled_bc6c2927-6829/logs/2021122018/gcdas_anlstat.log

View Error Logs: (gcdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot
Copy link

emcbot commented Jan 6, 2026

C96C48mx500_S2SW_cyc_gfs FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96C48mx500_S2SW_cyc_gfs_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96C48mx500_S2SW_cyc_gfs_bc6c2927-6829/logs/2021122018/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@emcbot
Copy link

emcbot commented Jan 6, 2026

C96C48_hybatmsoilDA FAILED on Gaeac6 (pipeline ID: 6829)

In directory: /gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/EXPDIR/C96C48_hybatmsoilDA_bc6c2927-6829

Error Log Files:


/gpfs/f6/drsa-precip3/world-shared/global/CI/GITLAB/pr_cases_4386_bc6c2927_6829/RUNTESTS/COMROOT/C96C48_hybatmsoilDA_bc6c2927-6829/logs/2022051512/gdas_anlstat.log

View Error Logs: (gdas_anlstat.log)

This failure was detected automatically by global-workflow's CI/CD Pipeline

@DavidHuber-NOAA
Copy link
Contributor

Closing as this has been merged into #4401.

DavidNew-NOAA pushed a commit to NOAA-EMC/GDASApp that referenced this pull request Jan 16, 2026
# Description
This PR adds a `ghcn_snod2ioda.py` script to processes the GHCN data in
csv format to IODA-format files for snow DA in the global-workflow.

# Companion PRs
This PR depends NOAA-EMC/jcb-gdas#220,
NOAA-EMC/DA-utils#53, and
NOAA-EMC/global-workflow#4388
This PR contributes NOAA-EMC/global-workflow#4386

# Issues
Resolves #2018 

# Automated CI tests to run in Global Workflow
<!-- Which Global Workflow CI tests are required to adequately test this
PR? -->
- [ ] atm_jjob <!-- JEDI atm single cycle DA !-->
- [ ] C96C48_ufs_hybatmDA <!-- JEDI atm cycled DA !-->
- [ ] C96C48_hybatmsnowDA <!-- JEDI snow cycled DA !-->
- [ ] C96_gcafs_cycled <!-- JEDI aerosol cycled DA !-->
- [ ] C48mx500_3DVarAOWCDA <!-- JEDI low-res marine 3DVar cycled DA !-->
- [ ] C48mx500_hybAOWCDA <!-- JEDI marine hybrid envar cycled DA !-->
- [ ] C96C48_ufsgsi_hybatmDA <!-- JEDI atm Var with GSI EnKF cycled DA
!-->
- [ ] C96C48_hybatmDA <!-- GSI atm cycled DA !-->

---------

Co-authored-by: Cory Martin <[email protected]>
DavidNew-NOAA pushed a commit to NOAA-EMC/GDASApp that referenced this pull request Jan 16, 2026
# Description

This PR updates the `da-utils` commit hash to include the required
utilities.

This PR also addresses Copilot comments in `ghcn_snod2ioda.py`. In
particular, it fixes the use of AttrData and DimDict as mutable
module-level dictionaries, which is error-prone—especially since DimDict
is modified within the class. These structures are now handled in a
safer, more maintainable way.

This PR is a supplementary update to PR #2019 and contributes to
NOAA-EMC/global-workflow#4386

# Issues

Resolves #2018 

# Automated CI tests to run in Global Workflow
<!-- Which Global Workflow CI tests are required to adequately test this
PR? -->
- [ ] atm_jjob <!-- JEDI atm single cycle DA !-->
- [ ] C96C48_ufs_hybatmDA <!-- JEDI atm cycled DA !-->
- [ ] C96C48_hybatmsnowDA <!-- JEDI snow cycled DA !-->
- [ ] C96_gcafs_cycled <!-- JEDI aerosol cycled DA !-->
- [ ] C48mx500_3DVarAOWCDA <!-- JEDI low-res marine 3DVar cycled DA !-->
- [ ] C48mx500_hybAOWCDA <!-- JEDI marine hybrid envar cycled DA !-->
- [ ] C96C48_ufsgsi_hybatmDA <!-- JEDI atm Var with GSI EnKF cycled DA
!-->
- [ ] C96C48_hybatmDA <!-- GSI atm cycled DA !-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI-Gaeac6-Failed **Bot use only** CI testing on Gaea C6 for this PR has failed JEDI Feature development to support JEDI-based DA

Projects

None yet

6 participants