Skip to content

SPH derived fields require using ds.add_field #5306

@chrishavlin

Description

@chrishavlin

When you attempt to add an SPH derived field as a new global field, it is not identified as an SPH field:

import yt 

def _Ha_cloudy(field, data):
    return 2*data['PartType0','Density']


yt.add_field(
    name=("PartType0", "my_density"),
    function=_Ha_cloudy,
    sampling_type="particle",
)

ds = yt.load_sample("snapshot_033")
print(ds.field_info[('PartType0', 'my_density')].is_sph_field) # False

And any operations that should work for SPH fields fail (e.g., projection plots) despite ds._sph_ptypes containing PartType0.

If you define the new field just for the dataset, it is correctly identified as an SPH field:

import yt 

ds = yt.load_sample("snapshot_033")

def _Ha_cloudy(field, data):
    return 2*data['PartType0','Density']

ds.add_field(
    name=("PartType0", "my_density"),
    function=_Ha_cloudy,
    sampling_type="particle",
)
print(ds.field_info[('PartType0', 'my_density')].is_sph_field) # True

and everything works as usual.

I find this behavior confusing... and it's not obvious from the docs on whether this is the intended behavior.

Any thoughts on whether this a bug or just an undocumented behavior (that should be documented)?

From a quick look at the code, I'm guessing the issue arises because the DerivedField.ds is set to None for global fields so is_sph_field will always return False for global fields:

@property
def is_sph_field(self):
if self.sampling_type == "cell":
return False
is_sph_field = False
if self.is_alias:
name = self.alias_name
else:
name = self.name
if hasattr(self.ds, "_sph_ptypes"):
is_sph_field |= name[0] in (self.ds._sph_ptypes + ("gas",))
return is_sph_field

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions