Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate unit of measurement handling #137

Closed
jarq6c opened this issue Sep 28, 2021 · 3 comments · Fixed by #196
Closed

Investigate unit of measurement handling #137

jarq6c opened this issue Sep 28, 2021 · 3 comments · Fixed by #196
Assignees
Labels
enhancement New feature or request

Comments

@jarq6c
Copy link
Collaborator

jarq6c commented Sep 28, 2021

HT currently has no formal unit of measurement handling. We may be able to incorporate a library like Pint to deal with this.

https://pint.readthedocs.io/en/stable/

@jarq6c jarq6c added the enhancement New feature or request label Sep 28, 2021
@jarq6c jarq6c self-assigned this Sep 28, 2021
@jarq6c
Copy link
Collaborator Author

jarq6c commented Oct 29, 2021

This issue is related to #113

@jarq6c
Copy link
Collaborator Author

jarq6c commented Oct 29, 2021

Parking this example here:

from hydrotools.nwis_client.iv import IVDataService
import numpy as np
import pint

def convert(values, from_units, to_units):
    """Convert scientific units of values.
    
    Parameters
    ==========
    values: npt.ArrayLike
        Values to convert
    from_units: pint.UnitRegistry.Quantity compatible object
        Original units of values.
    to_units: pint.UnitRegistry.Quantity compatible object
        Desired conversion units.
        
    Returns
    =======
    result: npt.ArrayLike
        Same shape as values containing converted values.
    """
    # Setup registry
    u = pint.UnitRegistry()

    # Pint Array
    quantities = u.Quantity(np.asarray(values), from_units)

    # Convert units
    return quantities.to(to_units).magnitude

def main():
    # Setup client
    client = IVDataService(value_time_label="value_time")

    # Retrieve some data
    df = client.get(
        sites="01013500",
        startDT="20211001T00:00",
        endDT="20211002T00:00"
    )

    # Convert to cubic meters per second
    df["value"] = convert(df["value"], "ft^3/s", "m^3/s")
    df["measurement_unit"] = "m^3/s"

    # Look at the data
    print(df.head())

if __name__ == "__main__":
    main()

Output

           value_time variable_name usgs_site_code measurement_unit      value qualifiers series
0 2021-10-01 00:00:00    streamflow       01013500            m^3/s  16.112286      ['P']      0
1 2021-10-01 00:15:00    streamflow       01013500            m^3/s  16.112286      ['P']      0
2 2021-10-01 00:30:00    streamflow       01013500            m^3/s  16.112286      ['P']      0
3 2021-10-01 00:45:00    streamflow       01013500            m^3/s  16.112286      ['P']      0
4 2021-10-01 01:00:00    streamflow       01013500            m^3/s  16.112286      ['P']      0

@jarq6c
Copy link
Collaborator Author

jarq6c commented Oct 29, 2021

Minimal example to compute discharge per unit area (AKA total runoff)

# Set up registry
u = pint.UnitRegistry()

# Parameters
catchment_area = u.Quantity(25.0, "miles^2").to("ft^2")
period = u.Quantity(15.0, "minutes").to("s")
discharge = u.Quantity(500.0, "ft^3/s")

# Compute discharge per unit area
discharge_per_unit_area = discharge * period / catchment_area

# Display in inches
print(discharge_per_unit_area.to("inches"))

Output

0.007747933884297518 inch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant