Skip to content

Feature: EIA Natural Gas Price Retrieval for Feedstocks#719

Merged
johnjasa merged 91 commits into
NatLabRockies:developfrom
RHammond2:feature/ng-industrial-price
May 21, 2026
Merged

Feature: EIA Natural Gas Price Retrieval for Feedstocks#719
johnjasa merged 91 commits into
NatLabRockies:developfrom
RHammond2:feature/ng-industrial-price

Conversation

@RHammond2
Copy link
Copy Markdown
Collaborator

@RHammond2 RHammond2 commented May 1, 2026

Create an EIA Natural Gas API Feedstock Model

The newly created EIANaturalGasFeedstockConfig and EIANaturalGasFeedstockCostModel allow users to directly download or rely on previously downloaded EIA API data for natural gas prices for the US or any of its 50 states, for each of the available price categories. Users can use a single cost year's annual average or monthly results to create an hourly price profile to match the consumption model.

Section 1: Type of Contribution

  • Feature Enhancement
    • Framework
    • New Model
    • Updated Model
    • Tools/Utilities
    • Other (please describe):
  • Bug Fix
  • Documentation Update
  • CI Changes
  • Other (please describe):

Section 2: Draft PR Checklist

  • Open draft PR
  • Describe the feature that will be added
  • Fill out TODO list steps
  • Describe requested feedback from reviewers on draft PR
  • Complete Section 7: New Model Checklist (if applicable)

TODO:

  • The model is functionally complete, but is awaiting any amendments based on reviewer feedback.
  • Run some more local tests to ensure things work as anticipated since the model relies on external data and API keys

Type of Reviewer Feedback Requested (on Draft PR)

Any feedback is welcome from anyone who might be interested in this or impacted by it

Structural feedback: Are there any missing considerations for when this gets scaled to a national level or for prototyping purposes?

Implementation feedback: Do the naming conventions make sense?

Other feedback: Any thoughts on integrating tests relying on local data or API keys? I wasn't sure if we crossed this bridge with H2I yet or not, so held back on it.

Section 3: General PR Checklist

  • PR description thoroughly describes the new feature, bug fix, etc.
  • Added tests for new functionality or bug fixes
  • Tests pass (If not, and this is expected, please elaborate in the Section 6: Test Results)
  • Documentation
    • Docstrings are up-to-date
    • Related docs/ files are up-to-date, or added when necessary
    • Documentation has been rebuilt successfully
    • Examples have been updated (if applicable)
  • CHANGELOG.md
    • At least one complete sentence has been provided to describe the changes made in this PR
    • After the above, a hyperlink has been provided to the PR using the following format:
      "A complete thought. [PR XYZ]((https://github.com/NatLabRockies/H2Integrate/pull/XYZ)", where
      XYZ should be replaced with the actual number.

Section 4: Related Issues

N/A

Section 5: Impacted Areas of the Software

Section 5.1: New Files

  • h2integrate/feedstocks/eia_ng_price.py
    • EIANaturalGasFeedstockConfig: EIA natural gas price configuration model that will also retrieve the data upon initialization to ensure the price attribute is populated for the cost model.
    • EIANaturalGasFeedstockCostModel: EIA cost model attuned to the specifics of the configuration model.
  • h2integrate/feedstocks/test/test_eia_ng_feedstock.py: Adds tests for all the basic functionality, except for any step requiring access to the EIA data (downloaded or API).
  • h2integrate/preprocess/eia.py: provides general functionality for handling EIA natural gas API queries with an eye towards future integration of other EIA API access points.
  • h2integrate/preprocess/geospatial.py: Adds a series of US-focused reverse geocoding and state name conversion functionality with an eye towards future expansion for other geographical regions.

Section 5.2: Modified Files

  • h2integrate/core/feedstocks.py: moved to the h2integrate/feedstocks/feedstocks.py, and updated some of the docstrings and inline commentary as I was reviewing it.
  • h2integrate/feedstocks/__init__.py: Adds feedstock cost and performance models for simplified imports.
  • h2integrate/core/supported_models.py: Adds the new EIA natural gas feedstock cost model.

Section 6: Additional Supporting Information

This addition is geared towards the MPPOC model for a national scale data center modeling project, but has been made broadly applicable by allowing all the pricing data to be accessed.

Neither tests for the execution of the API retrieval nor examples have been added for this addition because it relies on either an API key or downloaded file. Please let me know if we should still provide something more than the documentation for users.

Section 7: Test Results, if applicable

Tests pass.

Section 8 (Optional): New Model Checklist

  • Model Structure:
    • Follows established naming conventions outlined in docs/developer_guide/coding_guidelines.md
    • [] Used attrs class to define the Config to load in attributes for the model
      • If applicable: inherit from BaseConfig or CostModelBaseConfig
    • Added: initialize() method, setup() method, compute() method
      • If applicable: inherit from CostModelBaseClass
  • Integration: Model has been properly integrated into H2Integrate
    • Added to supported_models.py
    • If a new commodity_type is added, update create_financial_model in h2integrate_model.py
  • Tests: Unit tests have been added for the new model
    • Pytest-style unit tests
    • Unit tests are in a "test" folder within the folder a new model was added to
    • If applicable add integration tests
  • Example: If applicable, a working example demonstrating the new model has been created
    • Input file comments
    • Run file comments
    • Example has been tested and runs successfully in test_all_examples.py
  • Documentation:
    • Write docstrings using the Google style
    • Model added to the main models list in docs/user_guide/model_overview.md
      • Model documentation page added to the appropriate docs/ section
      • <model_name>.md is added to the _toc.yml
    • Run generate_class_hierarchy.py to update the class hierarchy diagram in docs/developer_guide/class_structure.md

@RHammond2 RHammond2 requested review from cfrontin and johnjasa May 1, 2026 00:38
@RHammond2 RHammond2 added enhancement New feature or request nationwide sweeps Functionality needed to enable nationwide sweeps (potentially ported from NEDsim) labels May 1, 2026
@RHammond2 RHammond2 changed the base branch from main to develop May 1, 2026 15:08
Comment thread h2integrate/feedstocks/feedstocks.py Outdated
Comment thread h2integrate/feedstocks/feedstocks.py
@RHammond2 RHammond2 requested review from johnjasa and removed request for johnjasa May 19, 2026 00:21
Copy link
Copy Markdown
Collaborator

@elenya-grant elenya-grant left a comment

Choose a reason for hiding this comment

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

Thanks for making these changes! I had a few suggestions to using plant_config['sites'] because each key under sites is a user-defined site name. I think it'd be good to test the feedstock cost model using a plant config from one of the examples!

Comment thread h2integrate/core/h2integrate_model.py
Comment thread h2integrate/feedstocks/feedstocks.py
Comment thread h2integrate/feedstocks/feedstocks.py
Comment thread h2integrate/feedstocks/eia_ng_price.py Outdated
Comment thread h2integrate/preprocess/geospatial.py
Comment thread h2integrate/feedstocks/test/test_eia_ng_feedstock.py
@elenya-grant
Copy link
Copy Markdown
Collaborator

One other thought - since price is an openmdao input for the feedstock cost model, we should maybe throw a user warning if they change it.

I'm thinking like the following thing in the compute() statement

def compute(self, inputs, outputs):
   if not np.isclose(inputs["price"], self.config.price, rtol=1e-6):
      warnings.warn("price has changed from EIA price", UserWarnings)
   super().compute(inputs, outputs)

@RHammond2
Copy link
Copy Markdown
Collaborator Author

One other thought - since price is an openmdao input for the feedstock cost model, we should maybe throw a user warning if they change it.

Should this be a warning or an error? In theory this class should be relying on the EIA natural gas pricing data either through an API query or loading existing data, so it would seem counterproductive to override it.

@johnjasa
Copy link
Copy Markdown
Collaborator

One other thought - since price is an openmdao input for the feedstock cost model, we should maybe throw a user warning if they change it.

Should this be a warning or an error? In theory this class should be relying on the EIA natural gas pricing data either through an API query or loading existing data, so it would seem counterproductive to override it.

I think it should be a warning if we do anything here. The use case would be if somebody has the EIA nat gas price coming in, then maybe does a parameter sweep on price with the same base config files, we'd want to warn them. I don't think the warning is strictly necessary but I do think Elenya's suggestion is a user-friendly reminder, so probably worth adding imo.

@RHammond2
Copy link
Copy Markdown
Collaborator Author

One other thought - since price is an openmdao input for the feedstock cost model, we should maybe throw a user warning if they change it.

Should this be a warning or an error? In theory this class should be relying on the EIA natural gas pricing data either through an API query or loading existing data, so it would seem counterproductive to override it.

I think it should be a warning if we do anything here. The use case would be if somebody has the EIA nat gas price coming in, then maybe does a parameter sweep on price with the same base config files, we'd want to warn them. I don't think the warning is strictly necessary but I do think Elenya's suggestion is a user-friendly reminder, so probably worth adding imo.

Thanks for the explanation, I'll add it as a warning.

@RHammond2 RHammond2 requested review from johnjasa and removed request for johnjasa May 20, 2026 21:12
Copy link
Copy Markdown
Collaborator

@elenya-grant elenya-grant left a comment

Choose a reason for hiding this comment

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

Thanks for making these changes! Looks good to me! Very cool new functionality! Thanks for adding this in!

Copy link
Copy Markdown
Collaborator

@johnjasa johnjasa left a comment

Choose a reason for hiding this comment

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

Thanks for this, Rob! I briefly tried it locally and appreciate the added capabilities. I like that it's either a preprocessing step or a feedstock model; very flexible. Hope this is useful for your work, I know it will be for others!

Comment thread h2integrate/feedstocks/test/test_eia_ng_feedstock.py
@johnjasa johnjasa enabled auto-merge (squash) May 21, 2026 22:14
@johnjasa johnjasa merged commit 4250dd2 into NatLabRockies:develop May 21, 2026
12 checks passed
@RHammond2 RHammond2 deleted the feature/ng-industrial-price branch May 22, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request nationwide sweeps Functionality needed to enable nationwide sweeps (potentially ported from NEDsim) ready for review This PR is ready for input from folks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants