import inspect
import numpy as np
import yt.frontends as frontends_module
from yt.config import ytcfg
from yt.fields.derived_field import NullFunc
from yt.frontends.api import _frontends
from yt.frontends.stream.fields import StreamFieldInfo
from yt.funcs import obj_length
from yt.testing import fake_random_ds
from yt.units import dimensions
from yt.units.yt_array import Unit
from yt.utilities.cosmology import Cosmology
fields, units = [], []
for fname, (code_units, _aliases, _dn) in StreamFieldInfo.known_other_fields:
fields.append(("gas", fname))
units.append(code_units)
base_ds = fake_random_ds(4, fields=fields, units=units)
base_ds.index
base_ds.cosmological_simulation = 1
base_ds.cosmology = Cosmology()
ytcfg["yt", "internals", "within_testing"] = True
np.seterr(all="ignore")
def _strip_ftype(field):
if not isinstance(field, tuple):
return field
elif field[0] == "all":
return field
return field[1]
np.random.seed(int(0x4D3D3D3))
units = [base_ds._get_field_info(f).units for f in fields]
fields = [_strip_ftype(f) for f in fields]
ds = fake_random_ds(16, fields=fields, units=units, particles=1)
ds.parameters["HydroMethod"] = "streaming"
ds.parameters["EOSType"] = 1.0
ds.parameters["EOSSoundSpeed"] = 1.0
ds.conversion_factors["Time"] = 1.0
ds.conversion_factors.update({f: 1.0 for f in fields})
ds.gamma = 5.0 / 3.0
ds.current_redshift = 0.0001
ds.cosmological_simulation = 1
ds.hubble_constant = 0.7
ds.omega_matter = 0.27
ds.omega_lambda = 0.73
ds.cosmology = Cosmology(
hubble_constant=ds.hubble_constant,
omega_matter=ds.omega_matter,
omega_lambda=ds.omega_lambda,
unit_registry=ds.unit_registry,
)
for my_unit in ["m", "pc", "AU", "au"]:
new_unit = f"{my_unit}cm"
my_u = Unit(my_unit, registry=ds.unit_registry)
ds.unit_registry.add(
new_unit,
my_u.base_value,
dimensions.length,
"\\rm{%s}/(1+z)" % my_unit,
prefixable=True,
)
header = r"""
.. _field-list:
Field List
==========
This is a list of many of the fields available in yt. We have attempted to
include most of the fields that are accessible through the plugin system, as
well as the fields that are known by the frontends, however it is possible to
generate many more permutations, particularly through vector operations. For
more information about the fields framework, see :ref:`fields`.
Some fields are recognized by specific frontends only. These are typically
fields like density and temperature that have their own names and units in
the different frontend datasets. Often, these fields are aliased to their
yt-named counterpart fields (typically 'gas' fieldtypes). For example, in
the ``FLASH`` frontend, the ``dens`` field (i.e. ``(flash, dens)``) is aliased
to the gas field density (i.e. ``(gas, density)``), similarly ``(flash, velx)``
is aliased to ``(gas, velocity_x)``, and so on. In what follows, if a field
is aliased it will be noted.
Try using the ``ds.field_list`` and ``ds.derived_field_list`` to view the
native and derived fields available for your dataset respectively. For example
to display the native fields in alphabetical order:
.. notebook-cell::
import yt
ds = yt.load("Enzo_64/DD0043/data0043")
for i in sorted(ds.field_list):
print(i)
To figure out out what all of the field types here mean, see
:ref:`known-field-types`.
.. contents:: Table of Contents
:depth: 1
:local:
:backlinks: none
.. _yt-fields:
Universal Fields
----------------
"""
footer = """
Index of Fields
---------------
.. contents::
:depth: 3
:backlinks: none
"""
print(header)
seen = []
def fix_units(units, in_cgs=False):
unit_object = Unit(units, registry=ds.unit_registry)
if in_cgs:
unit_object = unit_object.get_cgs_equivalent()
latex = unit_object.latex_representation()
return latex.replace(r"\ ", "~")
def print_all_fields(fl):
for fn in sorted(fl):
df = fl[fn]
f = df._function
s = f"{df.name}"
print(s)
print("^" * len(s))
print()
if obj_length(df.units) > 0:
if df.name[1] in [
"particle_position",
"particle_position_x",
"particle_position_y",
"particle_position_z",
"entropy",
"kT",
"metallicity",
"dx",
"dy",
"dz",
"cell_volume",
"x",
"y",
"z",
]:
print(f" * Units: :math:`{fix_units(df.units)}`")
else:
print(f" * Units: :math:`{fix_units(df.units, in_cgs=True)}`")
print(f" * Sampling Method: {df.sampling_type}")
print()
print("**Field Source**")
print()
if f == NullFunc:
print("No source available.")
print()
continue
else:
print(".. code-block:: python")
print()
for line in inspect.getsource(f).split("\n"):
print(" " + line)
print()
ds.index
print_all_fields(ds.field_info)
class FieldInfo:
"""a simple container to hold the information about fields"""
def __init__(self, ftype, field, ptype):
name = field[0]
self.units = ""
u = field[1][0]
if len(u) > 0:
self.units = r":math:`\mathrm{%s}`" % fix_units(u)
a = [f"``{f}``" for f in field[1][1] if f]
self.aliases = " ".join(a)
self.dname = ""
if field[1][2] is not None:
self.dname = f":math:`{field[1][2]}`"
if ftype != "particle_type":
ftype = f"'{ftype}'"
self.name = f"({ftype}, '{name}')"
self.ptype = ptype
current_frontends = [f for f in _frontends if f not in ["stream"]]
for frontend in current_frontends:
this_f = getattr(frontends_module, frontend)
field_info_names = [fi for fi in dir(this_f) if "FieldInfo" in fi]
dataset_names = [dset for dset in dir(this_f) if "Dataset" in dset]
if frontend == "gadget":
dataset_names = ["GadgetDataset"]
field_info_names = ["GadgetFieldInfo"]
elif frontend == "boxlib":
field_info_names = []
for d in dataset_names:
if "Maestro" in d:
field_info_names.append("MaestroFieldInfo")
elif "Castro" in d:
field_info_names.append("CastroFieldInfo")
else:
field_info_names.append("BoxlibFieldInfo")
elif frontend == "chombo":
field_info_names = [
f for f in field_info_names if "1D" not in f and "2D" not in f
]
for dset_name, fi_name in zip(dataset_names, field_info_names):
fi = getattr(this_f, fi_name)
nfields = 0
if hasattr(fi, "known_other_fields"):
known_other_fields = fi.known_other_fields
nfields += len(known_other_fields)
else:
known_other_fields = []
if hasattr(fi, "known_particle_fields"):
known_particle_fields = fi.known_particle_fields
if "Tipsy" in fi_name:
known_particle_fields += tuple(fi.aux_particle_fields.values())
nfields += len(known_particle_fields)
else:
known_particle_fields = []
if nfields > 0:
print(f".. _{dset_name.replace('Dataset', '')}_specific_fields:\n")
h = f"{dset_name.replace('Dataset', '')}-Specific Fields"
print(h)
print("-" * len(h) + "\n")
field_stuff = []
for field in known_other_fields:
field_stuff.append(FieldInfo(frontend, field, False))
for field in known_particle_fields:
if frontend in ["sph", "halo_catalogs", "sdf"]:
field_stuff.append(FieldInfo("particle_type", field, True))
else:
field_stuff.append(FieldInfo("io", field, True))
len_name = 10
len_units = 5
len_aliases = 7
len_part = 9
len_disp = 12
for f in field_stuff:
len_name = max(len_name, len(f.name))
len_aliases = max(len_aliases, len(f.aliases))
len_units = max(len_units, len(f.units))
len_disp = max(len_disp, len(f.dname))
fstr = "{nm:{nw}} {un:{uw}} {al:{aw}} {pt:{pw}} {dp:{dw}}"
header = fstr.format(
nm="field name",
nw=len_name,
un="units",
uw=len_units,
al="aliases",
aw=len_aliases,
pt="particle?",
pw=len_part,
dp="display name",
dw=len_disp,
)
div = fstr.format(
nm="=" * len_name,
nw=len_name,
un="=" * len_units,
uw=len_units,
al="=" * len_aliases,
aw=len_aliases,
pt="=" * len_part,
pw=len_part,
dp="=" * len_disp,
dw=len_disp,
)
print(div)
print(header)
print(div)
for f in field_stuff:
print(
fstr.format(
nm=f.name,
nw=len_name,
un=f.units,
uw=len_units,
al=f.aliases,
aw=len_aliases,
pt=f.ptype,
pw=len_part,
dp=f.dname,
dw=len_disp,
)
)
print(div)
print("")
print(footer)