Dimension
- class PlasmaCalcs.dimensions.dimension_tools.dimension.Dimension(v=None, values=UNSET, *, on_set_v=None, **kw_super)
Bases:
objecta single dimension, representing a current value AND a list of all possible values.
when creating a subclass, provide:
name: None or strname of this dimension. E.g. ‘fluid’.None –> this will not be a useable dimension.(use None if creating a subclass which is intended to be subclassed again)plural: None or strname of this dimension, in plural form. E.g. ‘fluids’.None –> use str(name)+’s’.value_error_type: None or typetype for cls.dimension_value_error. E.g. FluidValueErrorNone –> use DimensionValueErrorkey_error_type: None or typetype for cls.dimension_key_error. E.g. FluidKeyErrorNone –> use DimensionKeyErrorNote that docstrings for DIM_METHODS will be formatted using these names,via docstring.format(dim=name, dims=plural), if name is provided.when creating an instance (possibly an instance of a subclass), can provide:v: None, DimensionValue, or DimensionValueListcurrent value of this dimension. Might be multiple values.None –> use self.values instead.note: when setting self.v = value, will attempt to match value(s) from self.values if possible:if value is None, set self.v = None.else, if self.values exists (and is not None), attempt self.v = self.values.get(v).By default (if the previous cases fail or don’t hold), sets self.v = value.values: UNSET, None, or DimensionValueListall possible values of this dimension.UNSET (or, del self.values) –> raise an AttributeError when trying to access.None –> disables the AttributeError, but also disables the “smart” behavior of self.v,where setting self.v tries to match value(s) from self.values.on_set_v: None or callable of 1 argument.if not None, call self.on_set_v(value) immediately after doing self.v = value.— Example —class FluidDimension(Dimension, name=’fluid’):pass # no special methods for this example@FluidDimension.setup_haver # setup FluidHaver by attaching various relevant properties & methods.class FluidHaver(DimensionHaver, dimension=’fluid’):pass # no special methods for this exampleafter the lines above, FluidHaver will “have” a fluid dimension, e.g.:- fluid_haver.fluid_dim –> FluidDimension instance associated with this fluid_haver instance- fluid_haver.fluid –> fluid_haver.fluid_dim.v- fluid_haver.fluids –> fluid_haver.fluid_dim.values- fluid_haver.current_n_fluid –> fluid_haver.fluid_dim.current_n- fluid_haver.iter_fluids –> fluid_haver.fluid_dim.iter_values- fluid_haver.take_fluid –> fluid_haver.fluid_dim.takewhere fluid_haver is an instance of FluidHaver.Note that FluidHaver has those attributes as well but they are properties or methods, e.g.:FluidHaver.fluid = property(lambda self: self.fluid_dim.v) # roughly.FluidHaver.iter_fluids = property(lambda self: self.fluid_dim.iter_values) # roughly.For a complete list of all methods which will be attached, see Dimension.setup_haver and DIM_METHODS.Methods
__init_subclass__(*[, name, plural, ...])setup cls based on provided name and plural.
__repr__()return repr for an instance of this class.
array_equals(other)return whether self.v == other (which is assumed to be a numpy array or xarray.DataArray).
assign_coord(array[, value, overwrite, ...])returns array.assign_coords(dict({cls.name}=self.v)).
assign_coord_along(array, dim[, value])assign value as coords along the indicated dimension.
return number of values currently represented by self.v
enumerate(*[, restore])iterate through self.v.
enumerate_values(*[, restore])iterate through self.values, seting self.v and yielding (i, v) for each v in self.values.
get_type(*[, check_all])get type of single value in self.v.
is_iterable(*[, min_length])return whether self.v represents multiple values.
iter(*[, restore, enumerate])iterate through self.v.
iter_partition(partition, *[, restore])iterate through self.values.
iter_values(*[, restore, enumerate])iterate through self.values.
join_along(arrays[, labels])return arrays joined along the {cls.name} dimension.
list()return self.v, but guaranteed to be a list.
maintaining(*attrs, **attrs_as_flags)returns context manager which restores attrs of self to their original values, upon exit.
setup_haver(haver_cls)setup haver_cls, so that it "has" this dimension,
take(array[, value, drop_labels, as_dict, ...])take the array at array.{cls.name} == self.v (or at value, if provided).
take_along(array[, at, i, drop_labels, ...])return a list of the array value for each {cls.name} in array.
using([attrs_as_dict, _unset_sentinel])returns context manager which sets attrs of obj upon entry; restores original values upon exit.
_as_single([val])return the single value at self.v, or self.v corresponding to val if provided.
_assert_array_equals(other)raise DimensionValueError unless self.array_equals(other),
_dim_method([dim_methods])return decorator(f) which returns f after putting {fmtname: f.__name__} into dim_methods
_get_first([val])return first value from self.v, or self.v corresponding to val if provided.
Attributes
DIM_METHODSwhether this dimension is currently being loaded across, via self.load_across().
namepluralcurrent value in self.
all possible values of this dimension.
- classmethod __init_subclass__(*, name=None, plural=None, value_error_type=None, key_error_type=None, **kw_super)
setup cls based on provided name and plural.
name: None or str
if provided, does the following:- sets cls.name- sets cls.plural- replace DIM_METHODS keys with key.format(dim=name, dims=plural).plural: None or strplural form of name. If None, use str(name)+’s’. (Only used if name is not None)value_error_type: None or typeif provided, set cls.dimension_value_error = value_error_typekey_error_type: None or typeif provided, set cls.dimension_key_error = key_error_type
- __repr__()
return repr for an instance of this class.
- _as_single(val=None)
return the single value at self.v, or self.v corresponding to val if provided.
If result is not a single value, raise DimensionValueError.
- _assert_array_equals(other)
raise DimensionValueError unless self.array_equals(other),
i.e. unless self.v == other (which is assumed to be a numpy array or xarray.DataArray).
- _dim_method(dim_methods={'_as_single_{dim}': '_as_single', '_assert_{dim}_array_equals': '_assert_array_equals', '_get_first_{dim}': '_get_first', 'assign_{dim}_along': 'assign_coord_along', 'assign_{dim}_coord': 'assign_coord', 'current_n_{dim}': 'current_n', 'enumerate_{dims}': 'enumerate_values', 'enumerate_{dim}': 'enumerate', 'iter_{dims}': 'iter_values', 'iter_{dims}_partition': 'iter_partition', 'iter_{dim}': 'iter', 'join_{dims}': 'join_along', 'take_{dims}': 'take_along', 'take_{dim}': 'take', '{dim}_array_equals': 'array_equals', '{dim}_is_iterable': 'is_iterable', '{dim}_list': 'list', '{dim}_type': 'get_type'})
return decorator(f) which returns f after putting {fmtname: f.__name__} into dim_methods
- _get_first(val=None)
return first value from self.v, or self.v corresponding to val if provided.
If iterable, return self.v[0], else return self.v.
- array_equals(other)
return whether self.v == other (which is assumed to be a numpy array or xarray.DataArray).
return False if other.size != self.current_n().Else, if not self.is_iterable(), compare to other.item().Else, compare elementwise: np.all(other==self.v), or return False if other.ndim >=2.
- assign_coord(array, value=UNSET, *, overwrite=None, expand_if_iterable=False)
returns array.assign_coords(dict({cls.name}=self.v)).
if not self.is_iterable(), raise DimensionalityError, unless expand_if_iterable=True.value: UNSET, or value to use instead of self.vif provided, temporarily set self.v = value, then restore it afterwards.This means value can be “shorthand” for actual values,e.g. value = 0 –> self.v = self.values.get(0).overwrite: None or boolwhether to overwrite an existing value for this coord in array.(note - array will never be altered here; only the result might be altered.)If this coord already in array.coords, behavior depends on overwrite:None –> crash with DimensionKeyError.True –> overwrite this coord.False –> return array, unchanged.expand_if_iterable: boolwhether to expand_dims if self.is_iterable(),e.g. array.expand_dims(dict({cls.name}=self.v))
- assign_coord_along(array, dim, value=UNSET, **kw_assign_coords)
assign value as coords along the indicated dimension.
Equivalent to array.assign_coords({self.name: (dim, value)})requires self.is_iterable() else raises DimensionValueError.value: UNSET, or value to use instead of self.vif provided, temporarily set self.v = value, then restore it afterwards.
- current_n()
return number of values currently represented by self.v
0 if None, else len(self.v) if possible, else 1.
- dimension_key_error
alias of
DimensionKeyError
- dimension_value_error
alias of
DimensionValueError
- enumerate(*, restore=True)
iterate through self.v. sets self.v and yields (i, v), for each value in self.v when iteration began.
i corresponds to position of value in original self.v (not necessarily self.values).Equivalent to self.iter(restore=restore, enumerate=True).
- enumerate_values(*, restore=True)
iterate through self.values, seting self.v and yielding (i, v) for each v in self.values.
Equivalent to self.iter_values(restore=restore, enumerate=True).
- get_type(*, check_all=False)
get type of single value in self.v.
check_all: bool, default Falseif True, check all values in self.v to ensure they are all the same type.
- is_iterable(*, min_length=None)
return whether self.v represents multiple values.
False if self.v represents only one value.if min_length is provided, return bool((result) and (len(self.v) >= min_length)).
- iter(*, restore=True, enumerate=False)
iterate through self.v. sets AND yields self.v, for each value in self.v when iteration began.
Note the difference between this method and iter_values;
this method uses self.v when called, to determine which values to iterate through,while iter_values instead uses self.values to determine which values to iterate through.if self.v is not iterable, yield self.v once and do not change its value.restore: bool, default Truewhether to restore original self.v after iteration.enumerate: bool, default Falsewhether to yield indices too, i.e. (i, v) instead of just v.if True, indices correspond to position of value in the original self.v (not necessarily self.values!)
- iter_partition(partition, *, restore=True)
iterate through self.values. setting self.v=vlist, yielding (partkey, self.v) from partition.items()
partition: dict-like of {partkey: vlist}use to partition values into groups.Note: iter_partition doesn’t return vlist directly, but instead sets self.v = vlist,then returns self.v. If vlist is a list of v-specifiers, the actual v will be returned.E.g. if vlist = [0,3,4], result has self.values.get([0,3,4]), not [0,3,4].restore: bool, default Truewhether to restore original self.v after iteration.E.g. partition = {‘a’: [‘v0’, ‘v1’, ‘v4’], ‘b’: [‘v2’, ‘v3’], ‘c’: [‘v5’]}–> yields (‘a’, [‘v0’, ‘v1’, ‘v4’]), then (‘b’, [‘v2’, ‘v3’]), then (‘c’, [‘v5’]),setting self.v=[‘v0’, ‘v1’, ‘v4’], then self.v=[‘v2’, ‘v3’], then self.v=[‘v5’].
- iter_values(*, restore=True, enumerate=False)
iterate through self.values. sets AND yields self.v, for each value in self.values.
restore: bool, default True
whether to restore original self.v after iteration.enumerate: bool, default Falsewhether to yield indices too, i.e. (i, v) instead of just v.if True, indices correspond to position of value in self.values.
- classmethod join_along(arrays, labels=None, **kw__join_along_dimension)
return arrays joined along the {cls.name} dimension.
if labels is provided, set result[{cls.name}] = labels.
- list()
return self.v, but guaranteed to be a list.
if self.v is iterable, return self.v, unchanged;else, return [self.v].
- property loading
whether this dimension is currently being loaded across, via self.load_across().
- maintaining(*attrs, **attrs_as_flags)
returns context manager which restores attrs of self to their original values, upon exit.
E.g. maintaining_attrs(obj, ‘attr1’, ‘attr2’, attr3=True, attr4=False)–> will restore upon exit, original values of obj.attr1, attr2, and attr3, but not attr4.
- classmethod setup_haver(haver_cls)
setup haver_cls, so that it “has” this dimension,
in the sense that the following are defined (replacing “fluid” with cls.name):- h = haver_cls- plural = cls.plural- h.fluid_dim_cls = cls- h.fluid_dim = alias to the instance of cls associated with an instance of h- h.fluid = alias to h.fluid_dim.v- h.{plural} = alias to h.fluid_dim.values- h._loading_fluid = alias to h.fluid_dim.loading- for (key, method) in cls.DIM_METHODS.items():# assert that h.{key} doesn’t exist yet, then define:h.{key} = alias to h.fluid_dim.{method}# (e.g., h.assign_snap_coord = alias to h.snap_dim.assign_coord)Also, call haver_cls.__setup_haver__(cls) if it exists.returns haver_cls, so that this function may be used as a class decorator.
- take(array, value=UNSET, *, drop_labels=False, as_dict=False, squeeze=True, item=False, **kw__take_along)
take the array at array.{cls.name} == self.v (or at value, if provided).
if self.is_iterable(), return [array at array.{cls.name}==val for val in self.v].otherwise, return a single array: array at array.{cls.name}==self.v.array: xarray.DataArrayarray to take from.E.g., self.v==’e’, cls.name==’fluid’, array has coord ‘fluid’ with one value equal to ‘e’–> take(array) gives array value at fluid==’e’.value: UNSET or valueif provided, temporarily set self.v = value, then restore it afterwards.This means value can be “shorthand” for actual values,e.g. value = 0 –> self.v = self.values.get(0)value = None –> self.v = None, so self.v gives self.values.See help(type(self).v) for more info.drop_labels: bool, default Falsewhether to remove this dimension from arr.coords for arr in result.as_dict: bool, default Falseif True, return dict of {dim value: array value at this dim} instead.squeeze: bool, default Trueif False, always return list (with length==1 if not self.is_iterable()),unless as_dict=True. (Ignore squeeze if as_dict.)item: boolif True, convert arrays to single values via array.item().
- classmethod take_along(array, at=None, *, i=None, drop_labels=False, as_dict=False, item=False, **kw__take_along_dimension)
return a list of the array value for each {cls.name} in array.
array: xarray.DataArray
array to take from.E.g., array with coords fluid [‘e’, ‘H+’, ‘C+’], cls.name==’fluid’–> take_along(array) gives [array value for ‘e’, value for ‘H+’, value for ‘C+’].at: None or list-like of values in this dimensiontake at these values. None –> use values from array.coords[this dimension]i: None or indices(if provided) take only at these indices; use isel.drop_labels: bool, default Falsewhether to remove this dimension from arr.coords for arr in result.as_dict: bool, default Falseif True, return dict of {dim value: array value at this dim} instead of list.item: boolif True, convert arrays to single values via array.item().additional kwargs go to tools.take_along_dimension
- using(attrs_as_dict={}, _unset_sentinel=ATTR_UNSET, **attrs_and_values)
returns context manager which sets attrs of obj upon entry; restores original values upon exit.
_unset_sentinel: any value, default ATTR_UNSETupon entry, delete any attrs with value _unset_sentinel (compared via ‘is’).E.g. using_attrs(obj, _unset_sentinel=None, x=None) –> del obj.x upon entry.
- property v
current value in self.
Getting self.v:Return self._v if it exists (and is not None), else return self.values.Setting self.v = value:Attempt to match value from self.values if possible:if value is None, set self.v = Noneif value is a DimensionSpecialValueSpecifier, call value.value_to_set(self).else, if self.values exists (and is not None), attempt self.v = self.values.get(value).By default (if the previous cases fail or don’t hold), sets self.v = value.Afterwards, call self.on_set_v(value), if self.on_set_v is not None.
- property values
all possible values of this dimension.
If values does not exist, raise an AttributeError with a helpful message.(the message is most helpful at “high level”, when using DimensionHaver,so it uses the dimension’s name instead of ‘v’ and ‘values’.)If you want to avoid using DimensionValueList (at the cost of not using its smart behavior..)you can use self.values=None, to disable that error message.You can del self.values to re-enable that error message.(del self.values will do nothing if self.values doesn’t exist, as opposed to crashing.)Settings self.values will also reset self.v to None afterwards.