Skip to content

Add FMI Silam Air Quality Ingest and Wildfire Smoke Ingest#465

Open
cloneofghosts wants to merge 28 commits into
devfrom
add-silam-aqi
Open

Add FMI Silam Air Quality Ingest and Wildfire Smoke Ingest#465
cloneofghosts wants to merge 28 commits into
devfrom
add-silam-aqi

Conversation

@cloneofghosts
Copy link
Copy Markdown
Collaborator

Describe the change

Add back the scripts for FMI Silam air quality.

Type of change

  • Bugfixes to existing code
  • Breaking change
  • New API Version
  • General Improvement
  • Code quality improvements to existing code or addition of tests
  • Documentation Updates

Checklist

  • This pull request fixes issue: fixes #
  • Code builds locally. Your pull request won't be merged unless tests pass
  • Code has been formatted using ruff

@cloneofghosts cloneofghosts added the enhancement New feature or request label Dec 11, 2025
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @cloneofghosts, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request reintroduces the FMI Silam air quality ingest script, enabling the system to fetch, process, and store global air quality forecast data from the THREDDS server. It includes a robust implementation of the EPA NowCast algorithm and a comprehensive Air Quality Index (AQI) calculation utility, ensuring accurate and up-to-date air quality reporting. This enhancement significantly improves the system's capability to provide detailed air quality information.

Highlights

  • New FMI Silam Ingest Script: A new Python script, API/FMI_Silam_Local_Ingest.py, has been added to fetch, process, and store FMI SILAM global air quality forecast data from the THREDDS server into a Zarr store. This script handles various pollutants like PM2.5, PM10, O3, NO2, SO2, and CO.
  • EPA NowCast Algorithm Implementation: The API/ingest_utils.py file now includes a calculate_nowcast_concentration function, which implements the EPA NowCast algorithm. This algorithm provides a more responsive weighted average for pollutant concentrations, particularly for PM2.5 and PM10, by giving more weight to recent hours.
  • Comprehensive AQI Calculation: A new calculate_aqi function has been added to API/ingest_utils.py. This utility calculates the Air Quality Index (AQI) based on EPA standards for multiple pollutants (PM2.5, PM10, O3, NO2, SO2), utilizing linear interpolation between defined breakpoints and optionally incorporating the NowCast algorithm.
  • Dedicated Unit Tests for AQI: A new test file, tests/test_silam_aqi.py, has been introduced. It contains extensive unit tests for both the calculate_nowcast_concentration and calculate_aqi functions, covering various scenarios including steady, rising, and falling concentrations, NaN handling, breakpoint validation, and edge cases.
  • PR Template Update: A minor cleanup was performed on the pull request template, removing an outdated checklist item related to TimeMachine versioning.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/rtma-ingest-test.yml
    • .github/workflows/test.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

gemini-code-assist[bot]

This comment was marked as outdated.

cloneofghosts and others added 3 commits December 10, 2025 21:34
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

@copilot Can we update the tests to also include tests for the calculate_aqi function to make sure everything is working properly there? The breakpoints for the different concentrations are in both ingest_utils.py and the tests. Can define them as constants in a shared file so they aren't defined twice?

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 11, 2025

@cloneofghosts I've opened a new pull request, #466, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 4 commits December 11, 2025 11:24
…466)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cloneofghosts <10248058+cloneofghosts@users.noreply.github.com>
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

/gemini review

gemini-code-assist[bot]

This comment was marked as outdated.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

Just making a mental note of what is left for this:

  1. Need to check concentration units
  2. Need to check if historical data is part of the data
  3. Minor review fixes

@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

@alexander0042 Guessing this is more of a 2.10/3.0 PR? Seems like it's a bit complex to get working and I know the plan is for this to launch this month.

@cloneofghosts

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 18, 2025

@cloneofghosts I've opened a new pull request, #478, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 4 commits December 18, 2025 16:58
…tests for air quality ingest (#478)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cloneofghosts <10248058+cloneofghosts@users.noreply.github.com>
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new ingest script for FMI Silam air quality data, which is a great addition. The implementation is well-structured, with new modules for constants, conversion utilities, and AQI calculation logic. The inclusion of a comprehensive test suite (test_silam_aqi.py) is particularly commendable, as it covers unit tests, integration tests, and edge cases for the new complex logic.

My review focuses on improving maintainability and adhering to the project's style guide. I've pointed out several instances of variable names that don't follow the snake_case convention. I've also identified opportunities to reduce code duplication by refactoring repetitive blocks into helper functions, particularly for creating placeholder data arrays and for handling file output. Additionally, I've suggested using os.path.join for constructing file paths to ensure cross-platform compatibility.

Overall, this is a solid contribution. Addressing the feedback will make the new code even more robust and easier to maintain.

Comment thread API/FMI_Silam_Local_Ingest.py Outdated
Comment thread API/FMI_Silam_Local_Ingest.py
Comment thread API/FMI_Silam_Local_Ingest.py Outdated
Comment thread API/FMI_Silam_Local_Ingest.py Outdated
Comment thread API/FMI_Silam_Local_Ingest.py
Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 30, 2025

@cloneofghosts I've opened a new pull request, #493, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cloneofghosts <10248058+cloneofghosts@users.noreply.github.com>
@cloneofghosts cloneofghosts changed the title Add FMI Silam Air Quality Ingest Add FMI Silam Air Quality Ingest and Wildfire Smoke Ingest Dec 30, 2025
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces two new data ingest scripts for FMI Silam air quality and IS4FIRES wildfire smoke data. It also adds the necessary utility functions for AQI calculation, data conversion, and corresponding constants and tests. The changes are well-structured, and the addition of tests is particularly valuable.

My review focuses on improving adherence to the project's style guide, particularly regarding naming conventions, import order, and the use of type hints. I've also identified opportunities to improve code maintainability by using os.path.join for path construction and refactoring duplicated code blocks. The new utility functions are solid, but could be enhanced with type hints for better clarity and static analysis.

Comment thread API/FMI_IS4FIRES_Local_Ingest.py
Comment thread API/FMI_IS4FIRES_Local_Ingest.py
Comment thread API/FMI_IS4FIRES_Local_Ingest.py Outdated
Comment thread API/FMI_IS4FIRES_Local_Ingest.py
Comment thread API/FMI_Silam_Local_Ingest.py
Comment thread API/ingest_utils.py Outdated
Comment thread API/ingest_utils.py Outdated
Comment thread API/silam_conversion.py
Comment thread tests/test_silam_aqi.py
Comment thread tests/test_silam_aqi.py Outdated
cloneofghosts and others added 2 commits January 7, 2026 15:10
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

cloneofghosts commented Jan 8, 2026

@copilot Ingest tests started failing with this error:

def convert_vmr_to_concentration(vmr, air_density, molar_mass):
    """
    Convert volume mixing ratio (VMR) to mass concentration in µg/m³.

    Args:
        vmr: Volume mixing ratio in mole/mole (mole pollutant per mole air)
        air_density: Air density in kg/m³
        molar_mass: Molar mass of the pollutant in kg/mole

    Returns:
        Concentration in µg/m³

    Formula:
        concentration (µg/m³) = VMR (mole/mole) * air_density (kg/m³) *
                                (molar_mass_pollutant / molar_mass_air) * KG_M3_TO_UG_M3

    Note: SILAM's vmr_*_gas variables are true volume mixing ratios (mole/mole),
    as confirmed by the SILAM metadata (units: mole/mole, silam_amount_unit: mole).
    The conversion requires both the pollutant's molecular weight and air's molecular weight.
    """
    # Volume mixing ratio conversion to mass concentration
    # VMR is mole_pollutant/mole_air
    # mass_concentration = VMR * (air_density / molar_mass_air) * molar_mass_pollutant
   return vmr * air_density * (molar_mass / MOLAR_MASS_AIR) * KG_M3_TO_UG_M3
                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  TypeError: unsupported operand type(s) for /: 'tuple' and 'float'

API/silam_conversion.py:42: TypeError
=========================== short test summary info ============================
FAILED tests/test_silam_aqi.py::TestVMRConversion::test_vmr_conversion_different_gases - TypeError: unsupported operand type(s) for /: 'tuple' and 'float'

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 8, 2026

@cloneofghosts I've opened a new pull request, #509, to work on those changes. Once the pull request is ready, I'll request review from you.

…509)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cloneofghosts <10248058+cloneofghosts@users.noreply.github.com>
@cloneofghosts cloneofghosts enabled auto-merge (squash) January 21, 2026 15:21
@cloneofghosts cloneofghosts moved this from Todo to In Progress in PirateWeather API Jan 21, 2026
@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

@alexander0042 Like the other PR am curious on what the timeline is to get this merged in since this has been in progress for a while now.

@cloneofghosts
Copy link
Copy Markdown
Collaborator Author

@copilot Could we add ingest for this AQI model as well? https://www.nco.ncep.noaa.gov/pmb/products/aqm/

It updates at 06Z and 12Z and we can ingest hourly PM2.5 and Ozone and as for AQI - how would it work with SILAM AQI calculations? This data should be used where available but the SILAM ingest is storing AQI as a parameter and while we could take the maximum if SILAM PM2.5 is higher then the AQM model the maximum may not make sense.

Do we need to do the AQI calculations in the API instead and how would that work since all parameters are averages?

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 24, 2026

@cloneofghosts I've opened a new pull request, #588, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits March 24, 2026 13:41
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cloneofghosts <10248058+cloneofghosts@users.noreply.github.com>
Co-authored-by: Kev <cloneofghosts@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: normal

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants