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 str
- name 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 str
- name of this dimension, in plural form. E.g. ‘fluids’.None –> use str(name)+’s’.
- value_error_type: None or type
- type for cls.dimension_value_error. E.g. FluidValueErrorNone –> use DimensionValueError
- key_error_type: None or type
- type for cls.dimension_key_error. E.g. FluidKeyErrorNone –> use DimensionKeyError
Note 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 DimensionValueList
- current 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 DimensionValueList
- all 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.
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.
_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 str
- plural form of name. If None, use str(name)+’s’. (Only used if name is not None)
- value_error_type: None or type
- if provided, set cls.dimension_value_error = value_error_type
- key_error_type: None or type
- if 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.
- _dim_method(dim_methods={'_as_single_{dim}': '_as_single', '_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}_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.
- 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.v
- if 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 bool
- whether 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: bool
- whether 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.v
- if 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 False
- if 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 True
- whether to restore original self.v after iteration.
- enumerate: bool, default False
- whether 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 True
- whether 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 False
- whether 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.DataArray
- array 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 value
- if 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 False
- whether to remove this dimension from arr.coords for arr in result.
- as_dict: bool, default False
- if True, return dict of {dim value: array value at this dim} instead.
- squeeze: bool, default True
- if False, always return list (with length==1 if not self.is_iterable()),unless as_dict=True. (Ignore squeeze if as_dict.)
- item: bool
- if 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 dimension
- take 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 False
- whether to remove this dimension from arr.coords for arr in result.
- as_dict: bool, default False
- if True, return dict of {dim value: array value at this dim} instead of list.
- item: bool
- if 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_UNSET
- upon 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.