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

Revert "ENH: allow fully automatic unit detection for derived field" #3961

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions yt/data_objects/selection_objects/data_selection_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from yt.fields.field_exceptions import NeedsGridType
from yt.funcs import fix_axis, is_sequence, iter_fields, validate_width_tuple
from yt.geometry.selection_routines import compose_selector
from yt.units import YTArray
from yt.units import YTArray, dimensions as ytdims
from yt.utilities.exceptions import (
GenerationInProgress,
YTBooleanObjectError,
Expand Down Expand Up @@ -242,27 +242,22 @@ def _generate_fields(self, fields_to_generate):
# field accesses
units = getattr(fd, "units", "")
if units == "":
sunits = ""
dimensions = 1
dimensions = ytdims.dimensionless
else:
sunits = str(
units.get_base_equivalent(self.ds.unit_system.name)
)
dimensions = units.dimensions

if fi.dimensions is None:
mylog.warning(
"Field %s was added without specifying units or dimensions, "
"auto setting units to %s",
fi.name,
sunits,
units = str(
units.get_base_equivalent(self.ds.unit_system.name)
)
elif fi.dimensions != dimensions:
if fi.dimensions != dimensions:
raise YTDimensionalityError(fi.dimensions, dimensions)
fi.units = sunits
fi.dimensions = dimensions
fi.units = units
self.field_data[field] = self.ds.arr(fd, units)

mylog.warning(
"Field %s was added without specifying units, "
"assuming units are %s",
fi.name,
units,
)
try:
fd.convert_to_units(fi.units)
except AttributeError:
Expand Down
24 changes: 17 additions & 7 deletions yt/fields/derived_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ class DerivedField:
arguments (field, data)
units : str
A plain text string encoding the unit, or a query to a unit system of
a dataset. Powers must be in Python syntax (** instead of ^). If set
to 'auto' or None (default), units will be inferred from the return value
of the field function.
a dataset. Powers must be in python syntax (** instead of ^). If set
to "auto" the units will be inferred from the units of the return
value of the field function, and the dimensions keyword must also be
set (see below).
take_log : bool
Describes whether the field should be logged
validators : list
Expand All @@ -93,7 +94,8 @@ class DerivedField:
fields or that get aliased to themselves, we can specify a different
desired output unit than the unit found on disk.
dimensions : str or object from yt.units.dimensions
The dimensions of the field, only used for error checking with units='auto'.
The dimensions of the field, only needed if units="auto" and only used
for error checking.
nodal_flag : array-like with three components
This describes how the field is centered within a cell. If nodal_flag
is [0, 0, 0], then the field is cell-centered. If any of the components
Expand Down Expand Up @@ -160,10 +162,18 @@ def __init__(

# handle units
self.units: Optional[Union[str, bytes, Unit]]
if units in (None, "auto"):
self.units = None
if units is None:
self.units = ""
elif isinstance(units, str):
self.units = units
if units.lower() == "auto":
if dimensions is None:
raise RuntimeError(
"To set units='auto', please specify the dimensions "
"of the field with dimensions=<dimensions of field>!"
)
self.units = None
else:
self.units = units
elif isinstance(units, Unit):
self.units = str(units)
elif isinstance(units, bytes):
Expand Down
16 changes: 4 additions & 12 deletions yt/fields/field_info_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,11 @@ def alias(
if units is None:
# We default to CGS here, but in principle, this can be pluggable
# as well.

# self[original_name].units may be set to `None` at this point
# to signal that units should be autoset later
oru = self[original_name].units
if oru is None:
units = None
u = Unit(self[original_name].units, registry=self.ds.unit_registry)
if u.dimensions is not dimensionless:
units = str(self.ds.unit_system[u.dimensions])
else:
u = Unit(oru, registry=self.ds.unit_registry)
if u.dimensions is not dimensionless:
units = str(self.ds.unit_system[u.dimensions])
else:
units = oru

units = self[original_name].units
self.field_aliases[alias_name] = original_name
function = TranslationFunc(original_name)
if deprecate is not None:
Expand Down
4 changes: 4 additions & 0 deletions yt/fields/tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ def density_alias(field, data):
def unitless_data(field, data):
return np.ones(data[("gas", "density")].shape)

ds.add_field(
("gas", "density_alias_no_units"), sampling_type="cell", function=density_alias
)
ds.add_field(
("gas", "density_alias_auto"),
sampling_type="cell",
Expand All @@ -337,6 +340,7 @@ def unitless_data(field, data):
units="auto",
dimensions="temperature",
)
assert_raises(YTFieldUnitError, get_data, ds, ("gas", "density_alias_no_units"))
assert_raises(YTFieldUnitError, get_data, ds, ("gas", "density_alias_wrong_units"))
assert_raises(
YTFieldUnitParseError, get_data, ds, ("gas", "density_alias_unparseable_units")
Expand Down