Skip to content

Allow units to have multiple physical types #11202

Description

@namurphy

Description

The physical_type attribute for UnitBase instances currently returns a string that describes what a particular unit measures:

>>> import astropy.units as u
>>> (u.barn * u.Mpc).physical_type
'volume'

However, sometimes a set of units corresponds to multiple physical types. For example, a 1 Pa ≡ 1 J · m-3, so a pascal can represent both pressure and energy density. In addition, a kessel run can be retconned from distance to time.

Units to physical type is not a one-to-one mapping. Each set of units can map to multiple physical types. Each physical type should usually map to one set of units, though there can be some exceptions to this (for example, the temperature_energy equivalency that lets eV represent energy as well as temperature).

I propose that we enable each unit to correspond to multiple physical types instead of limiting them to a single physical type. This would change backward compatibility.

Draft design and brainstorm for the API

A possibility would be to create a PhysicalType class. Instances of PhysicalType could be created for each set of units and become the physical_type attribute, and contain a collection of all of the possible physical types that each set of units could have.

Essential behavior of physical_type attribute

I'd like to allow the following behavior.

>>> import astropy.units as u
>>> u.Pa.physical_type 
"pressure, energy density"
>>> u.Pa.physical_type  # not sure if this should be a list or str
["pressure", "energy density"]
>>> u.Pa.physical_type == "pressure"
True
>>> u.Pa.physical_type == "energy_density"
True

The last two lines would require defining PhysicalType.__eq__ to be able to handle multiple physical types (e.g., by making sure "pressure" or "energy" is in the collection of physical types).

Handling equivalencies

The physical type will also depend on which equivalencies are enabled.

>>> u.eV.physical_type == "temperature"
False
>>> u.set_enabled_equivalencies(u.temperature_energy())
>>> u.eV.physical_type == "temperature"
True

Allowing users to specify the physical type for units or quantities

It would also be helpful for users to be able to specify the physical type in more detail. I'm not sure if this would be best done for units or quantities, and I have a feeling this could be more difficult to implement. A possible API for the unit approach would be:

>>> specific_pressure_unit = create_unit_with_specific_physical_type(u.Pa, physical_type="pressure")
>>> specific_pressure_unit.physical_type = "pressure"
>>> specific_pressure_unit.physical_type == "energy density"
False
>>> u.Pa.physical_type == "energy density"  # we don't want to change the physical type of the original unit
True

For a Quantity instance, this could be something like

>>> pressure = u.Quantity(1.0, u.Pa, physical_type="pressure")
>>> pressure.physical_type == "pressure"
True
>>> pressure.physical_type == "energy density"
False

It appears that Quantity does not have a physical_type attribute so this would be particularly new.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions