LoiLoader

class PlasmaCalcs.quantities.patterns.loi_loader.LoiLoader

Bases: VectorArithmeticLoader

Line-Of-Integration (LOI) loader, for interpolating onto a new set of coordinates,

e.g. a path (or multiple paths) through a box, then maybe integrating along the path.

Methods

__call__(var, *args[, name, item, verbose])

returns value of var from self.

angle_xy(A)

return angle between +xhat and A, in the xy plane, in radians.

angle_xy_to_hat(A)

return unit vector u, given angle [radians] between +xhat and u in the xy plane.

attach_extra_coords(arr)

attach any self.extra_coords to array arr but only if it is an xarray.DataArray or xarray.Dataset

cls_help([qstr, only, tree, modules, ...])

prints str for help with quants.

cls_var_tree(var, *[, missing_ok])

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

copy()

returns a deep copy of self.

cross_component(A, B, x, *[, yz, missing_ok])

return x component of A cross B, given A and B which have values for y and z 'component'.

cross_components_needed()

return the components vectors need in order to find all cross product components in self.component_list

cross_product(A, B, *[, components])

return cross product of vectors A and B, along dimension 'component'.

dot_product(A, B)

return dot product of vectors A and B, assuming vector components in the 'component' dimension.

get_angle_xy(var, *[, _match, _val0])

angle between +xhat and var, in the xy plane, in radians.

get_angle_xy_to_hat(var, *[, _match, _val0])

unit vector u, given angle [radians] between +xhat and u in the xy plane.

get_behavior([keys])

return value of self.behavior.

get_cross(var, *[, _match, _val0, _val1])

cross product.

get_crosscrossdotself(var, *[, _match, ...])

((A_cross_B)_cross_B)_dot_A.

get_deg2rad(var, *[, _match])

convert degrees to radians.

get_dloi()

dloi = coord spacing to use for integration as implied by self.loi.

get_dot(var, *[, _match, _val0, _val1])

dot product.

get_hat(var, *[, _match, _val0])

unit vector in the direction of var.

get_loi_cumsum_var(var, *[, _match])

loi_cumsum_var = var interpolated onto coordinates implied by self.loi,

get_los()

return self.los as an array.

get_mod(var, *[, _match, _val0])

magnitude of var.

get_mod2(var, *[, _match, _val0])

magnitude squared of var.

get_parallel(var, *[, _match, _val0, _val1])

A_par_B --> the component of A parallel to B.

get_parmod(var, *[, _match, _val0, _val1])

magnitude of the component of A parallel to B.

get_perp(var, *[, _match, _val0, _val1])

A_perp_B --> A after removing the component of A parallel to B.

get_perpmod(var, *[, _match, _val0, _val1])

magnitude of A after removing the component of A parallel to B.

get_rad2deg(var, *[, _match])

convert radians to degrees.

get_rmscomps(var, *[, _match])

root mean squared of components.

get_set_or_cached(var)

returns var if found in self.setvars or self.cache, with compatible behavior_attrs.

get_sparmod(var, *[, _match, _val0, _val1])

signed "magnitude" of the component of A parallel to B.

get_unwrapt_2pi_var(var, *[, _match])

unwrapt_{A} --> unwrapped self(A) along 't', via np.unwrap with period=2*pi.

get_var_loi(var, *[, _match])

var_loi = var interpolated onto coordinates implied by self.loi.

get_var_los(var, *[, _match])

var_los = var projected onto line of sight (as defined by self.los).

get_vars(vars, *args[, return_type, ...])

returns values of vars from self.

get_vector_N(var, *[, _match])

vector_n --> vector with n in each component.

get_xhat()

unit vector in the x direction.

get_xyz(var, *[, _match])

x, y, and/or z components of var.

get_yhat()

unit vector in the y direction.

get_zhat()

unit vector in the z direction.

has_var(var)

return whether self can load var.

help([qstr, only, tree, modules, signature, ...])

prints str for help with quants.

help_call_options([search])

prints help for kw_call_options.

help_quants_str([qstr, only, tree, modules, ...])

returns str for help with quants.

help_str([qstr, only])

returns cls.help_quants_str(qstr=qstr, only=only, **kw).

kw_call_options(*[, sorted])

returns list of kwarg names which can be used to set attrs self during self.__call__.

load_direct(var, *args, **kw)

load var "directly", from some source which is not known by the main part of PlasmaCalcs.

load_fromfile(var, *args, **kw)

load var directly from a file.

loi_cumsum(array, *[, do_interp, sort])

return array interpolated onto coordinates implied by self.loi,

loi_interp(array)

return array interpolated onto coordinates implied by self.loi.

magnitude(A, *[, squared])

return vector magnitude of A, assuming vector components along the dimension 'component'.

maintaining_attrs(*attrs, **attrs_as_flags)

returns context manager which restores attrs of self to their original values, upon exit.

match_var(var, *[, check])

match var from cls.KNOWN_VARS or cls.KNOWN_PATTERNS, or raise FormulaMissingError.

match_var_loading_dims(var, **kw_loading_dims)

return dims for loading var across.

match_var_result_dims(var, **kw_result_dims)

return dims which result of cls(var) will vary across.

match_var_result_size(var, *[, maindims])

return size (number of elements) which self(var) will have.

match_var_tree([var])

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

quant_tree([var])

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

rmscomps(A)

return root mean squared of components of A.

set_var(var, value[, behavior_attrs, ...])

set var in self.

set_var_internal(var, value, behavior_attrs)

set var in self.

take_parallel_to(B, A)

return the component of A parallel to B.

take_perp_to(B, A)

return the component of A perpendicular to B.

tree([var])

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

unset_var(var[, behavior_attrs, missing_ok])

remove var from self.setvars (but only at values stored with relevant behavior).

unset_var_internal(var, behavior_attrs[, ...])

unset var from self.setvars.

using_at_call_depth(depth, **attrs_and_values)

context manager for setting attrs_and_values but only while call_depth == depth.

using_at_next_call_depth(**attrs_and_values)

context manager for setting attrs_and_values but only while call_depth == self.call_depth + 1

using_attrs([attrs_as_dict, _unset_sentinel])

returns context manager which sets attrs of obj upon entry; restores original values upon exit.

_apply_toplevel_scale_coords(arr)

apply self.toplevel_scale_coords to arr, if nonempty, else return arr unchanged.

_battrs_for_set_var_internal(behavior_attrs)

returns behavior_attrs which will be used by set_var_internal, given these inputs.

_battrs_for_unset_var_internal(behavior_attrs)

returns behavior_attrs which will be used by unset_var_internal, given these inputs.

_call_hijacker(var, *args__None, **kw__None)

returns False or name of hijacker method to use instead of self(var) call.

_call_postprocess(result, *, var[, name, item])

postprocess result from self.__call__.

_call_postprocess_toplevel(result, *, var[, ...])

additional postprocessing for self.__call__ when call_depth=1.

_call_preprocess(result, *, var)

preprocessing during self.__call__.

_get_maybe_missing_var(var, *args[, ...])

return value of var, or None if FormulaMissingError and missing_vars 'ignore' or 'warn'.

_handle_typevar_nan(*[, errmsg])

crash with TypevarNanError if self.typevar_crash_if_nan, else return 'nan'.

_help_matches(qstr, k, v)

returns whether qstr matches k or v, and thus should be displayed during self.help(qstr).

_help_specialized_kw_call_options()

returns dict of docstrings for specialized kw call options for self.

_increment_call_depth()

context manager for incrementing call_depth.

_loi_integration_coord()

return coord to use for integration, as implied by self.loi.

_loi_integration_dim(*[, signed])

return dimension along which to integrate, as implied by self.loi.

_loi_interp_dict()

return dict of arrays to interpolate onto, as implied by self.loi.

_pop_kw_call_options(kw)

pop all self.kw_call_options() from kw, returning dict of popped options.

_provided_val(var[, _val, _known_vals])

returns the value of var, either from _known_vals or _val.

_specialized_kw_call_options(kw)

specialize popped kw_call_options, adjusting keys and/or values as needed,

Attributes

KNOWN_PATTERNS

KNOWN_SETTERS

KNOWN_VARS

LOI_OPTIONS

LOS_OPTIONS

assign_behavior_attrs

whether to assign self.behavior values as attrs of result when calling self.

assign_behavior_attrs_max_call_depth

max call_depth at which to assign_behavior_attrs to result,

assign_behavior_attrs_skip_xr

whether to use include_xr=False if self.assign_behavior_attrs,

behavior

dict of {attr: self.attr} for attr in self.behavior_attrs.

behavior_attrs

list of attrs in self which control behavior of self.

call_depth

depth of the current call to self.

call_depth_manager

stores the value of call_depth, and helps to manage attrs dependent on call_depth value.

cls_behavior_attrs

cross

alias to cross_product

dot

alias to dot_product

enable_fromfile

bool: whether self.load_fromfile is enabled during self.load_direct.

extra_coords

dict of {coord_name: coord_value} to attach to outputs of self(var).

get

alias to __call__

known_pattern

known_setter

known_var

line_of_sight

alias to los

loi

Line Of Integration (dim, dict of arrays for interp), or "Lots Of Interpolation", if you prefer.

loi_cumsum_sort

Tells whether to sort along the integration dimension before doing cumsum in self.loi_cumsum().

loi_explicit

loi as 2-tuple of (integration axis, None or dict of arrays for interpolation).

loi_ustr

units string (e.g., 'length') for loi interped coords,

loi_ustr_explicit

loi_ustr, but returns self._loi_ustr_default if loi_ustr is UNSET

los

line of sight vector; used by self("var_los") pattern and any quantities which depend on it.

maintaining

alias to maintaining_attrs

nondim_behavior_attrs

list of attrs in self which control behavior of self, but which are NOT in self.dimensions.

set

alias to set_var

setvar

alias to set_var

setvars

VarCache of vars set via self.set_var().

toplevel_scale_coords

dict of {coord_name: coord_scaling} to apply to top-level outputs of self(var).

typevar_crash_if_nan

bool.

unset

alias to unset_var

using

alias to using_attrs

__call__(var, *args, name=UNSET, item=False, verbose=UNSET, **kw)

returns value of var from self.

result is probably an xarray.DataArray, but not guaranteed.
var: str or iterable of strs.
Name of the var(s) to load. E.g. ‘n’ for number density, or [‘n’, ‘u’] for number density & velocity.
If multiple vars: returns an xarray.Dataset of all vars, via self.get_vars.
Determine how to load each var, as follows:
- (caching) if var in self.cache, with matching self.behavior_attrs, use value from cache.
[TODO] - caching not yet implemented. May allow for better efficiency.
- (setvars) if var in self.setvars, with matching self.behavior_attrs, use value from setvars.
[TODO] - improve set_var functionality.
set_var will allow user to apply PlasmaCalcs calculations to arbitrary values,
not just values from one of the hookups. Useful for testing & quick calculations.
- (KNOWN_VARS) if var in self.KNOWN_VARS,
use the corresponding function to get it.
- (KNOWN_PATTERNS) if var matches a pattern from self.KNOWN_PATTERNS,
use the corresponding function to get it.
- (direct) attempt to load var “directly”, via self.load_direct.
load_direct will almost always end up loading values directly from a file (e.g., “data”).
This may include converting var to fromfile_var, i.e. match file naming conventions,
and/or dimensions being loaded. E.g. ‘b’ may become ‘bz’ when loading across ‘component’.
Then, check if fromfile_var in setvars and cache, returning relevant value if found.
Lastly, call self.load_fromfile(fromfile_var).
Those are checked in the order listed.
If none of those work, raise FormulaMissingError.
name: UNSET, None, or str
try to set result.name = name.
If can’t set result.name, but result.attrs exists, set result.attrs[‘name’] = name, instead.
UNSET –> use name = var.
item: bool
if True, convert result to single value (e.g., python float) via result.item().
This will cause crash if result is not a single value;
it will also cause all metadata stored in the result to be lost.
verbose: UNSET, bool, or int
set self.verbose during this call to self.
UNSET –> use self.verbose (unchanged)
kw may additionally contain any keys from self.kw_call_options().
if it does, pop those values, and temporarily set the corresponding attr.
E.g.: self(‘n’, units=’si’, fluid=1)
–> temporarily set units=’si’, fluid=1, while getting ‘n’.
See self.help_call_options() for more details.
[EFF] passes _match=re.fullmatch(pattern, var) to the getter function,
if the match is from KNOWN_PATTERNS (but not if it is from KNOWN_VARS).
misc note: if self._call_hijacker(…), instead return result from the corresponding method.
e.g. if it returns “_get_with_chunks” then return self._get_with_chunks(var, …).
Call hijacking occurs after setting behavior attrs (inside with self.using(...): block)
but before altering call depth (outside with self._increment_call_depth(): block).
_apply_toplevel_scale_coords(arr)

apply self.toplevel_scale_coords to arr, if nonempty, else return arr unchanged.

_battrs_for_set_var_internal(behavior_attrs, forall=[], *, ukey=None)

returns behavior_attrs which will be used by set_var_internal, given these inputs.

see help(self.set_var_internal) for details.
_battrs_for_unset_var_internal(behavior_attrs, forall=[], *, ukey=None)

returns behavior_attrs which will be used by unset_var_internal, given these inputs.

see help(self.unset_var_internal) for details.
_call_hijacker(var, *args__None, **kw__None)

returns False or name of hijacker method to use instead of self(var) call.

Here, just returns False, always. Subclass might override.
_call_postprocess(result, *, var, name=UNSET, item=UNSET)

postprocess result from self.__call__. Called during self.__call__.

(self.call_depth inside here will tell depth of the current call; depth=1 for top level.)
result: any value, probably an xarray.DataArray
result from self.__call__, before postprocessing.
var, name, item: UNSET or value
passed directly from self.__call__.
The implementation here does the following (subclasses might override / add to this):
(1) if self.verbose >= 4, print a message about getting var.
(2) result = self.attach_extra_coords(result).
(3) set result.name = name, or result.attrs[‘name’] = name, if possible.
(4) if self.assign_behavior_attrs at this call depth, do so now.
(5) if self.call_depth == 1, call self._call_postprocess_toplevel.
(6) if item, convert result to single value via result.item().
_call_postprocess_toplevel(result, *, var, name=UNSET, item=UNSET)

additional postprocessing for self.__call__ when call_depth=1.

called from self._call_postprocess, after doing other postprocessing, when call_depth=1.
result: any value, probably an xarray.DataArray
result from self.__call__, after other postprocessing (except item).
var, name, item: UNSET or value
passed directly from self.__call__.
Don’t need to handle these here because self._call_postprocess will handle it.
The implementation here does the following (subclasses might override / add to this):
(1) self._apply_toplevel_scale_coords (does nothing if self.toplevel_scale_coords is empty)
_call_preprocess(result, *, var)

preprocessing during self.__call__. Called during self.__call__.

(self.call_depth inside here will tell depth of the current call; depth=1 for top level.)
result: any value, probably RESULT_MISSING
result from self.__call__, before preprocessing. Usually RESULT_MISSING.
var: str
var being loaded. Passed directly from self.__call__.
The implementation here does the following (subclasses might override / add to this):
(1) if self.verbose >= 2 or DEFAULTS.DEBUG >= 7, print a message about getting var.
(2) return result, unchanged.
If the returned result is anything other than RESULT_MISSING,
self.__call__ will return it instead of loading var normally.
_get_maybe_missing_var(var, *args, missing_vars=UNSET, **kw)

return value of var, or None if FormulaMissingError and missing_vars ‘ignore’ or ‘warn’.

missing_vars: UNSET, ‘ignore’, ‘warn’, or ‘raise’
what to do if any var causes FormulaMissingError.
UNSET –> use self.missing_vars if it exists, else ‘raise’.
‘ignore’ –> return None.
‘warn’ –> return None, but also print a warning.
‘raise’ –> raise FormulaMissingError.
_handle_typevar_nan(*, errmsg='')

crash with TypevarNanError if self.typevar_crash_if_nan, else return ‘nan’.

if crashing, use error message:
errmsg + “nTo return ‘nan’ instead of crashing, set self.typevar_crash_if_nan=False.”
classmethod _help_matches(qstr, k, v)

returns whether qstr matches k or v, and thus should be displayed during self.help(qstr).

qstr: str

the str to match; from self.help(qstr)
k: varname
the varname to test for matches.
key from self.KNOWN_VARS.keys(), or key.str from self.KNOWN_PATTERNS.keys().
v: LoadableQuantity
the LoadableQuantity to test for matches.
value from self.KNOWN_VARS.values() or self.KNOWN_PATTERNS.values().
matches if any of these are true:
qstr == ‘’
qstr in k.split(‘_’) # size limitation and split(‘_’) because, e.g. during help(‘n’),
len(qstr)>=3 and qstr in k # want vars related to number density, not all vars with the letter ‘n’.
qstr in module.split(‘.’) (where, module == v.get_f_module(cls))
‘.’ in qstr and qstr in module
len(qstr)>=3 and qstr in value from module.split(‘.’)
len(qstr)>=3 and qstr in v.fname
re.fullmatch(k, qstr) # if k is a Pattern
otherwise, does not match.
_help_specialized_kw_call_options()

returns dict of docstrings for specialized kw call options for self.

The implementation here just returns an empty dict, but subclass may override.
_increment_call_depth()

context manager for incrementing call_depth.

use “with self._increment_call_depth():” inside of __call__, e.g.:

def __call__(self, *args, **kw):
with self._increment_call_depth():
# do stuff; possibly including calling self again.
Equivalent to self.call_depth_manager.increment()
_loi_integration_coord()

return coord to use for integration, as implied by self.loi.

Just like self._loi_integration_dim(), but if result ends with ‘_dim’, remove it.
E.g. if _loi_integration_dim() == ‘grid_dim’, this returns ‘grid’.
_loi_integration_dim(*, signed=False)

return dimension along which to integrate, as implied by self.loi.

Crash with InputMissingError if self.loi implies no integration.
signed: bool
whether to start with ‘-’ to imply “cumsum in reverse order” inside loi_cumsum().
E.g. ‘-z’ –> array.isel(z=slice(None,None,-1)).cumsum(‘z’).isel(z=slice(None,None,-1)
_loi_interp_dict()

return dict of arrays to interpolate onto, as implied by self.loi.

result is None if self.loi implies “no interpolation”.
Crash if invalid self.loi.
_pop_kw_call_options(kw)

pop all self.kw_call_options() from kw, returning dict of popped options.

_provided_val(var, _val=None, _known_vals={})

returns the value of var, either from _known_vals or _val.

if _val provided, return it; if ‘_{var}’ in _known_vals, return it;
if both provided, crash with InputConflictError (unless they are the same object),
else, return None.
Can use this internally to avoid redundant recalculations. (See e.g. VectorArithmeticLoader)
_specialized_kw_call_options(kw)

specialize popped kw_call_options, adjusting keys and/or values as needed,

to be suitable to pass to self.using(**kw).
kw may be edited IN PLACE.
Overriding this is discouraged, unless using property setters/getters is truly insufficient.
If overriding this method, consider also overriding self._help_specialized_kw_call_options,
to add documentation (inside self.help_call_options()) for any specialized kw call options.
self.__call__ uses this method as follows:
using=self._pop_kw_call_options(kw)
using = self._specialize_using_kw_call_options(using)
with self.using(**using):
# <– majority of self.__call__ functionality goes here.
The implementation here just returns kw, unchanged.
static angle_xy(A)

return angle between +xhat and A, in the xy plane, in radians.

A should be a DataArray (or Dataset) with x and y in ‘component’ dimension.
A can be any vector (does not need to be a unit vector, but it can be.)
[Implementation currently just returns xarray_angle_xy(A)]
static angle_xy_to_hat(A)

return unit vector u, given angle [radians] between +xhat and u in the xy plane.

Equivalent: cos(A) * xhat + sin(A) * yhat.
[Implementation currently just returns xarray_angle_xy_to_hat(A)]
property assign_behavior_attrs

whether to assign self.behavior values as attrs of result when calling self.

False –> don’t use self.behavior code architecture to assign attrs.
True –> equivalent to ‘nondefault’
‘nondefault’ –> self.behavior.assign_nondefault_attrs(result)
(for brevity, it does not assign behavior attrs with “default” value.)
‘all’ –> self.behavior.assign_attrs(result).
[EFF] only assigns attrs at call_depth >= self.assign_behavior_attrs_max_call_depth.
(default: only assigns attrs at call_depth=1, i.e. at top level.
property assign_behavior_attrs_max_call_depth

max call_depth at which to assign_behavior_attrs to result,

if self.assign_behavior_attrs indicates to assign behavior attrs.
default 1, i.e. only assign if at top level.
Use None to indicate “no max depth”.
property assign_behavior_attrs_skip_xr

whether to use include_xr=False if self.assign_behavior_attrs,

during self.behavior.assign_nondefault_attrs.
Use this if you want to assign behavior attrs EXCEPT array-valued behavior attrs.
attach_extra_coords(arr)

attach any self.extra_coords to array arr but only if it is an xarray.DataArray or xarray.Dataset

property behavior

dict of {attr: self.attr} for attr in self.behavior_attrs. Note dims are separate;

dims go in behavior.dims. E.g. Behavior({‘units’:’si’,…}, dims={‘snap’:0,…}).
property behavior_attrs

list of attrs in self which control behavior of self.

Here, returns self.cls_behavior_attrs.
Subclasses could override if any behavior attrs are not known at the class-level,
e.g. if MySubclass’s list of behavior attrs varies between instances of MySubclass.
property call_depth

depth of the current call to self. depth = number of calls to self from within self.

E.g., call_depth while calculating gyrofrequency:

# call_depth == 0, for any code run here (outside any call to self).
self(‘gyrof’)
# call_depth == 1, for any code run here (inside ‘gyrof’ call but not inside deeper calls).
q = self(‘q’)
# call_depth == 2, for code inside ‘q’ call.
mod_B = self(‘mod_B’)
# call_depth == 2, for code inside ‘mod_B’ call.
self(‘B’)
# call_depth == 3, for code inside ‘B’ call.
m = self(‘m’)
# call_depth == 2, for code inside ‘m’ call.
result = q * mod_B / m
Cannot be set directly; can only be manipulated via self.call_depth_manager.
property call_depth_manager

stores the value of call_depth, and helps to manage attrs dependent on call_depth value.

classmethod cls_help(qstr=None, only=None, *, tree=None, modules=False, signature=False, doc=True, dense=False, print=True, **kw)

prints str for help with quants. Fails for any quants which depend on present values of a cls instance.

qstr: None or str

None –> tells info about this class & how to use this function.
in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,
and describes behavior of calling help with a string.
str –> return str for help with all quants related to str.
use empty str to get help for all quants.
only: None or str
If provided, only get help for a subset of relevant quantities.
None –> get help with all quantities related to qstr.
‘VARS’ –> only get help with KNOWN_VARS.
‘PATTERNS’ –> only get help with KNOWN_PATTERNS.
‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).
‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.
if provided when qstr is None, treat qstr as ‘’ instead.
tree: None or bool
How much help to give for quantities in cls.cls_var_tree(qstr).
False –> don’t even check cls.cls_var_tree(qstr).
True –> help for all quantities in cls.cls_var_tree.
None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()
i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.
e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,
but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).
modules: bool
Whether to include modules in result.
If True, result will be grouped into sections with modules written at top.
signature: signature: bool
whether to include line with signature in help string.
e.g. “help_str(f, *, module=True, signature=True, indent=None)”
doc: doc: bool
whether to include lines with docstring in help string.
e.g. “return str for help(f).” … and all the other docs in here.
dense: bool
Whether to reduce whitespace in result.
E.g. True –> no newlines between functions. False –> one newline between functions.
print: bool
whether to print the result. If False, return the result instead of printing.
classmethod cls_var_tree(var, *, missing_ok=False)

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.
missing_ok: bool
whether to be lenient sometimes when missing details that would allow to fully determine deps.
see help(MatchedQuantity.dep_vars) for more details.
copy()

returns a deep copy of self.

[TODO] implement something less hacky than using the pickle module?
property cross

alias to cross_product

static cross_component(A, B, x, *, yz=None, missing_ok=False)

return x component of A cross B, given A and B which have values for y and z ‘component’.

x: int, str, or Component

tells component (of result) to get. if int or str, use XYZ.get(x)
A, B: xarray.DataArray
vectors to take cross product of.
must include ‘component’ dimension including coordinates y and z.
yz: None or iterable of two (int, str, or Component) objects
the other two components; (x,y,z) should form a right-handed coordinate system.
if not provided, infer from x.
missing_ok: bool, default False
whether it is okay for ‘component’ dimension to be missing y or z components, of A or B.
if True, treat any missing components as 0.
[Implementation currently just returns xarray_cross_component(A, B, x, yz=yz, …)]
cross_components_needed()

return the components vectors need in order to find all cross product components in self.component_list

e.g. if self.component == ‘x’, return (‘y’, ‘z’), because (A_cross_B)_x needs Ay, Az, By, Bz but not Ax, Bx.
static cross_product(A, B, *, components=None)

return cross product of vectors A and B, along dimension ‘component’.

If A or B missing any components, treat them as 0.
components: None or iterable of component specifiers (int, str, or Component)
tells which components to get.
None –> get all components (XYZ)
e.g., (0, ‘z’) –> get component 0 and component ‘z’, i.e. X and Z.
[Implementation currently just returns xarray_cross_product(A, B, components=components)]
property dot

alias to dot_product

static dot_product(A, B)

return dot product of vectors A and B, assuming vector components in the ‘component’ dimension.

[Implementation currently just returns xarray_dot_product(A,B)]
property enable_fromfile

bool: whether self.load_fromfile is enabled during self.load_direct.

If False, raise QuantCalcError if load_direct can’t get value without load_fromfile().
property extra_coords

dict of {coord_name: coord_value} to attach to outputs of self(var).

Useful if planning to join the output of self(var) with output from a different QuantityLoader.
E.g. self.extra_coords={‘run’: ‘run 0’} and other.extra_coords={‘run’: ‘run 1’},
then xr.concat([self(‘n’), other(‘n’)], ‘run’) gives ‘n’ from self AND other.
(this is nice if self and other have same values for dims. Otherwise, might struggle.)
property get

alias to __call__

get_angle_xy(var, *, _match=None, _val0=None, **_known_vals)

angle between +xhat and var, in the xy plane, in radians.

CAUTION: does not “unwrap”; all angles will be reported in the range -pi to pi.

See unwrapt2pi for example of unwrapping (see also: np.unwrap)
angle_xy_{A} –> atan2(Ay, Ax).
[EFF] can provide known val for A, to avoid recalculating it. (include leading underscore.)
e.g. self(‘angle_xy_E’, _E=E) –> angle between +xhat and E, using E which is already known.
get_angle_xy_to_hat(var, *, _match=None, _val0=None, **_known_vals)

unit vector u, given angle [radians] between +xhat and u in the xy plane.

angle_xy_to_hat_{A} –> cos(A) * xhat + sin(A) * yhat.
get_behavior(keys=None)

return value of self.behavior.

keys: None or iterable
if provided, only include these attrs.
from nondim_behavior_attrs, or dims.
get_cross(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

cross product. {A}_cross_{B} –> A cross B.

returned components are determined by self.component.
(see also: the get_xyz pattern. E.g., {A}_cross_{B}_x –> x component of A cross B)
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘u_cross_E’, _u=u, _E=E) –> u cross E, using u and E which are already known.
CAUTION: if providing values, include all self.cross_components_needed() components;
missing components will be assumed to be 0.
E.g. if providing u to calculate u_cross_E, but u doesn’t have x component, assumes u_x=0.
can alternatively provide _val0 for A and/or _val1 for B.
get_crosscrossdotself(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

((A_cross_B)_cross_B)_dot_A.

if vid, will internally do calculations based on vector identities instead:

(AxB)xB).A = (A.B)^2 - A^2 B^2
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘u_crosscrossdotself_B’, _u=u, _B=B) –> ((u cross B) cross B) dot u,
using u and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
if not providing cached values, will always use self.component=None internally,
because result is a dot product so it shouldn’t depend on present self.component.
get_deg2rad(var, *, _match=None)

convert degrees to radians. deg2rad_{A} –> A * pi / 180.

self(‘deg2rad_var’) == np.deg2rad(self(‘var’))
get_dloi()

dloi = coord spacing to use for integration as implied by self.loi.

E.g. if self.loi implies integration along ‘x’ then this is basically dx
(accounting for self.slices as needed; see also: self.get_maindims_dim_didx)
Result’s values use self.units; coords use self.coords_units (default==self.units).
(e.g., units=’cgs’, coord_units=’si’ –> values are in cgs, but coords are in SI.)
See also: xarray_d_grid
get_dot(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

dot product. {A}_dot_{B} –> A dot B.

if component(s) is provided, only include that component(s) during the calculation.
e.g. A_dot_B__xy –> Ax * Bx + Ay * By.
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘u_dot_E’, _u=u, _E=E) –> u dot E, using u and E which are already known.
if providing value as None, it will be treated as if value not provided.
CAUTION: Not tested when simultaneously providing components such as A_dot_B__xy.
can alternatively provide _val0 for A and/or _val1 for B.
get_hat(var, *, _match=None, _val0=None, **_known_vals)

unit vector in the direction of var. hat_{A} –> A / |A|.

returned components are determined by self.component.
(e.g. when self.component==’x’, hat_A –> A_x / |A|.)
[EFF] can provide known val for A, to avoid recalculating it. (include leading underscore.)
e.g. self(‘hat_E’, _E=E) –> E / |E|, using E which is already known.
can alternatively provide _val0 for A.
get_loi_cumsum_var(var, *, _match=None)

loi_cumsum_var = var interpolated onto coordinates implied by self.loi,

then cumulatively summed along line-of-integration dimension implied by self.loi.
Internally calls self.loi_cumsum(val); can reliably use that method instead if desired.
get_los()

return self.los as an array. (Probably xr.DataArray.)

Not necessarily unit vector(s); to guarantee magnitude==1, use self(‘hat_los’) instead.
Crash if self.los is None, or if it is ‘component’ or ‘-component’ when current_n_component() > 1.
see self.help(‘(.+)_los’), help(type(self).los), and self.LOS_OPTIONS for more details.
[EFF] note: in case of ‘component’, ‘x’, ‘y’, ‘z’, or their negative counterparts,
self(‘var_los’) pattern will not get self(‘los’) directly.
(Though, those options are implemented here for consistency.)
get_mod(var, *, _match=None, _val0=None, **_known_vals)

magnitude of var. mod_{A} –> |A|. == sqrt(A dot A) == sqrt(Ax^2 + Ay^2 + Az^2).

alias: ‘mag_{A}’ is equivalent to ‘mod_{A}’
if component(s) is provided, only include that component(s) during the calculation.
e.g. mod_A__xy –> sqrt(Ax^2 + Ay^2).
[EFF] can provide known vals for {var} to avoid recalculating it. (include leading underscore.)
e.g. self(‘mod_E’, _E=E) –> |E|, using E which is already known.
CAUTION: Not tested when simultaneously providing components such as mod_A__xy.
can alternatively provide _val0 for A.
get_mod2(var, *, _match=None, _val0=None, **_known_vals)

magnitude squared of var. mod2_{A} –> |A|^2. == A dot A == Ax^2 + Ay^2 + Az^2.

alias: ‘mag2_{A}’ is equivalent to ‘mod2_{A}’
if component(s) is provided, only include that component(s) during the calculation.
e.g. mod2_A__xy –> Ax^2 + Ay^2.
[EFF] can provide known vals for {var} to avoid recalculating it. (include leading underscore.)
e.g. self(‘mod2_E’, _E=E) –> |E|**2, using E which is already known.
CAUTION: Not tested when simultaneously providing components such as mod_A__xy.
can alternatively provide _val0 for A.
get_parallel(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

A_par_B –> the component of A parallel to B.

Equivalent to self.take_parallel_to(B, A) == (A dot Bhat) Bhat.
see also: A_dot_hat_B, which is equivalent to mod_(A_par_B)
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘E_par_B’, _E=E, _B=B) –> E par to B, using E and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
get_parmod(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

magnitude of the component of A parallel to B.

Equivalent to mod(A_par_B). Also equivalent to abs(A_dot_hat_B)
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘E_parmod_B’, _E=E, _B=B) –> |E par to B|, using E and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
get_perp(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

A_perp_B –> A after removing the component of A parallel to B.

Equivalent to self.take_perp_to(B, A) == A - (A dot Bhat) Bhat.
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘E_perp_B’, _E=E, _B=B) –> E perp to B, using E and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
get_perpmod(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

magnitude of A after removing the component of A parallel to B.

Equivalent to mod(A_perp_B).
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘E_perpmod_B’, _E=E, _B=B) –> |E perp to B|, using E and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
get_rad2deg(var, *, _match=None)

convert radians to degrees. rad2deg_{A} –> A * 180 / pi.

self(‘rad2deg_var’) == np.rad2deg(self(‘var’))
get_rmscomps(var, *, _match=None)

root mean squared of components.

E.g., rmscomps_{A} –> sqrt((Ax^2 + Ay^2 + Az^2) / 3), if A has 3 components.
get_set_or_cached(var)

returns var if found in self.setvars or self.cache, with compatible behavior_attrs.

otherwise, raise CacheNotApplicableError.
if var is found in self.setvars and has relevant, but not matching behavior_attrs,
self.load_across_dims will be used to load the value.
get_sparmod(var, *, _match=None, _val0=None, _val1=None, **_known_vals)

signed “magnitude” of the component of A parallel to B.

Equivalent to A_dot_hat_B. Also abs(A_sparmod_B) is equivalent to mod(A_par_B).
[EFF] can provide known vals for A or B, to avoid recalculating them. (include leading underscores.)
e.g. self(‘E_parmod_B’, _E=E, _B=B) –> |E par to B|, using E and B which are already known.
can alternatively provide _val0 for A and/or _val1 for B.
get_unwrapt_2pi_var(var, *, _match=None)

unwrapt_{A} –> unwrapped self(A) along ‘t’, via np.unwrap with period=2*pi.

CAUTION: result at a given snapshot can vary depending on self.snap,

(though, (result % 2*pi) will always be the same.)
E.g. self(‘unwrapt_angle_xy_E’) –> angle between +xhat and E, but unwrapped,
so e.g. if results change from just above -pi to just below -pi,
the values below -pi will actually be below -pi,
instead of being reported as 2*pi + (value just below -pi).
get_var_loi(var, *, _match=None)

var_loi = var interpolated onto coordinates implied by self.loi.

Internally calls self.loi_interp(val) to do the interpolation (if any);
can reliably use that method for same functionality as array_loi pattern, anywhere.
Like all kwarg/attrs, can set loi beforehand, or as kwarg inside the call:
self.loi = value; self(‘u_loi’) # option 1
self(‘u_loi’, loi=value) # option 2
get_var_los(var, *, _match=None)

var_los = var projected onto line of sight (as defined by self.los).

Equivalent: self(var) dot self(“hat_los”)
Equivalent: self(f’{var}_sparmod_los’)
See help(type(self).los) and self.LOS_OPTIONS for more details.
Like all kwarg/attrs, can set los beforehand, or as kwarg inside the call:
self.los = value; self(‘u_los’) # option 1
self(‘u_los’, los=value) # option 2
Internally, if doing projection, first does xarray_result_size_check(),
to prevent accidental way-too-large result (threshold =10 GB by default),
which can happen easily if self.los implies different dimensions than self(var).
get_vars(vars, *args, return_type='dataset', missing_vars=UNSET, **kw)

returns values of vars from self.

result is probably an xarray.Dataset, but not guaranteed; also depends on return_type.
Equivalent to self(vars, *args, return_type=’dataset’, **kw).
(Actually, self(vars, …) will call self.get_vars(vars, …).)
vars: iterable of strs
Names of the vars to load. [‘n’, ‘u’] for number density & velocity.
if any of these vars returns a return_type object, expand its keys,
e.g. if ‘myDSvar’ returns dataset with ‘myvar1’, ‘myvar2’,
then [‘n’, ‘myDSvar’] gives dataset with ‘n’, ‘myvar1’, ‘myvar2’.
return_type: ‘dataset’ or ‘dict’
if ‘dataset’, return result as xarray.Dataset.
the data_var names will be the same as the var names.
if ‘dict’, return result as dict of {var: value}.
missing_vars: UNSET, ‘ignore’, ‘warn’, or ‘raise’
what to do if any vars cause FormulaMissingError at any point in the error stack.
UNSET –> use self.missing_vars if it exists, else ‘raise’.
‘ignore’ –> ignore missing vars, and don’t include them in the result.
‘warn’ –> ignore missing vars, but print a warning.
‘raise’ –> raise FormulaMissingError if any vars are missing.
additional args & kwargs are passed to self(…).
get_vector_N(var, *, _match=None)

vector_n –> vector with n in each component. E.g. vector_0 –> vector with components (0,0,0).

result components determined by self.component.
get_xhat()

unit vector in the x direction.

result components determined by self.component, e.g. xhat_x == 1; xhat_y == 0.
get_xyz(var, *, _match=None)

x, y, and/or z components of var.

get_yhat()

unit vector in the y direction.

result components determined by self.component, e.g. yhat_x == 0; yhat_y == 1.
get_zhat()

unit vector in the z direction.

result components determined by self.component, e.g. zhat_x == 0; zhat_z == 1.
has_var(var)

return whether self can load var. True if self.match_var(var) is found, else False.

Subclasses might override, to include checks for whether var can be loaded from data.
[TODO] also check if var in self.cache or self.setvars.
help(qstr=None, only=None, *, tree=None, modules=False, signature=False, doc=True, dense=False, print=True)

prints str for help with quants.

qstr: None or str

None –> tells info about this class & how to use this function.
in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,
and describes behavior of calling help with a string.
str –> return str for help with all quants related to str.
use empty str to get help for all quants.
only: None or str
If provided, only get help for a subset of relevant quantities.
None –> get help with all quantities related to qstr.
‘VARS’ –> only get help with KNOWN_VARS.
‘PATTERNS’ –> only get help with KNOWN_PATTERNS.
‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).
‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.
if provided when qstr is None, treat qstr as ‘’ instead.
tree: None or bool
How much help to give for quantities in cls.cls_var_tree(qstr).
False –> don’t even check cls.cls_var_tree(qstr).
True –> help for all quantities in cls.cls_var_tree.
None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()
i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.
e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,
but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).
modules: bool
Whether to include modules in result.
If True, result will be grouped into sections with modules written at top.
signature: signature: bool
whether to include line with signature in help string.
e.g. “help_str(f, *, module=True, signature=True, indent=None)”
doc: doc: bool
whether to include lines with docstring in help string.
e.g. “return str for help(f).” … and all the other docs in here.
dense: bool
Whether to reduce whitespace in result.
E.g. True –> no newlines between functions. False –> one newline between functions.
help_call_options(search=None)

prints help for kw_call_options.

if search is provided, only print help for keys containing search.
classmethod help_quants_str(qstr=None, only=None, *, tree=None, modules=True, signature=False, doc=True, dense=False, _instance=None)

returns str for help with quants.

qstr: None or str

None –> tells info about this class & how to use this function.
in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,
and describes behavior of calling help with a string.
str –> return str for help with all quants related to str.
use empty str to get help for all quants.
only: None or str
If provided, only get help for a subset of relevant quantities.
None –> get help with all quantities related to qstr.
‘VARS’ –> only get help with KNOWN_VARS.
‘PATTERNS’ –> only get help with KNOWN_PATTERNS.
‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).
‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.
if provided when qstr is None, treat qstr as ‘’ instead.
tree: None or bool
How much help to give for quantities in cls.cls_var_tree(qstr).
False –> don’t even check cls.cls_var_tree(qstr).
True –> help for all quantities in cls.cls_var_tree.
None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()
i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.
e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,
but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).
modules: bool
Whether to include modules in result.
If True, result will be grouped into sections with modules written at top.
signature: signature: bool
whether to include line with signature in help string.
e.g. “help_str(f, *, module=True, signature=True, indent=None)”
doc: doc: bool
whether to include lines with docstring in help string.
e.g. “return str for help(f).” … and all the other docs in here.
dense: bool
Whether to reduce whitespace in result.
E.g. True –> no newlines between functions. False –> one newline between functions.
_instance: None or QuantityLoader instance
if provided, use _instance.match_var_tree() instead of cls.cls_var_tree().
classmethod help_str(qstr=None, only=None, **kw)

returns cls.help_quants_str(qstr=qstr, only=only, **kw).

cls.help() calls help_str.
subclasses might overwrite help_str, but probably won’t touch help_quants_str.
kw_call_options(*, sorted=True)

returns list of kwarg names which can be used to set attrs self during self.__call__.

(see self.__call__ for more details).
Here, returns list(self.behavior_attrs) + list(self._extra_kw_for_quantity_loader_call)
property line_of_sight

alias to los

load_direct(var, *args, **kw)

load var “directly”, from some source which is not known by the main part of PlasmaCalcs.

The implementation here just returns self.load_fromfile() (or crashes if not self.enable_fromfile),
but subclasses may override to include more checks. (see DirectLoader)
(Here also sets self._load_direct_used_override = None to indicate no override was used,
i.e. result is from load_fromfile, not from something like setvars nor cache.)
return the result (probably a numpy array, but not guaranteed).
load_fromfile(var, *args, **kw)

load var directly from a file. Other methods should usually use load_direct, instead.

the implementation here just raises LoadingNotImplementedError;
subclasses should implement this method in order to load any values from files.
property loi

Line Of Integration (dim, dict of arrays for interp), or “Lots Of Interpolation”, if you prefer.

Used by self(“var_loi”) pattern (for the interpolation) and any quantities which integrate along a line.
([TODO] move the integrate-along-a-line patterns here, e.g. from mhd_radiative_loader.)
Can be any of the following:
None –> no integrate-along-a-line (those methods will crash), and no interpolation.
self(“var_loi”) == self(“var”).
dict –> no integrate-along-a-line (those methods will crash), but can interpolate onto these arrays.
self(“var_loi”) == self(“var”).interp(**self.loi)
str –> special option (e.g. ‘los’ for “use behavior implied by self.los”)
see self.LOI_OPTIONS for all special options.
2-tuple –> (integration instructions, interpolation instructions)
integration instructions can be None (as above) or str telling dim to integrate along.
Note: if dim ends with ‘_dim’, assumes dim[:-4] tells coord values,
e.g. x_dim implies integration along ‘x_dim’ but dx comes from ‘x’ coord,
which is a useful pattern if ‘x’ coord depends on multiple dims.
Note: if dim starts with ‘-’, assumes loi_cumsum should be evaluated in reverse order.
Physically, this can affect things like optical depth.
interpolation instructions can be None (as above) or dict (as above).
(To supply kwargs to the interpolator, provide them in the dict.
E.g.: dict(x=array(…), y=array(…), assume_sorted=True).
Or, for clarity: dict(coords=(x=array(…), y=array(…)), assume_sorted=True).)
loi_cumsum(array, *, do_interp=True, sort=UNSET)

return array interpolated onto coordinates implied by self.loi,

then cumulatively summed along line-of-integration dimension implied by self.loi.
Cumulative sum is in forward order by default, but if loi integration dim starts with ‘-‘,
instead reverse order, then cumsum, then reverse again to restore original order.
do_interp: bool
whether to do the interpolation step (if any) implied by self.loi.
(disable if providing array which is already the result of loi_interp().)
sort: UNSET, bool, ‘ascending’, or ‘descending’
if UNSET, use sort = self.loi_cumsum_sort
Tells whether to sort along the integration dimension before doing cumsum in self.loi_cumsum().
(If sorting changes order, will not restore original order after cumsum operation,
so operations relying on xarray coord matching would still work,
but underlying data order will be different between result and original array.)
True or ‘ascending’ –> sort in ascending order.
‘descending’ –> sort in descending order.
False –> do not sort.
This check occurs before any reversing implied by self.loi.
Example: self.loi_explicit[0] == ‘-z’, loi_cumsum_sort=True
–> array.sortby(‘z’).isel(z=slice(None,None,-1)).cumsum(‘z’).isel(z=slice(None,None,-1))
See help(type(self).loi) for more details.
property loi_cumsum_sort

Tells whether to sort along the integration dimension before doing cumsum in self.loi_cumsum().

(If sorting changes order, will not restore original order after cumsum operation,
so operations relying on xarray coord matching would still work,
but underlying data order will be different between result and original array.)
True or ‘ascending’ –> sort in ascending order.
‘descending’ –> sort in descending order.
False –> do not sort.
This check occurs before any reversing implied by self.loi.
Example: self.loi_explicit[0] == ‘-z’, loi_cumsum_sort=True
–> array.sortby(‘z’).isel(z=slice(None,None,-1)).cumsum(‘z’).isel(z=slice(None,None,-1))
property loi_explicit

loi as 2-tuple of (integration axis, None or dict of arrays for interpolation).

Getting loi_explicit will crash if no implied integration axis.
If integration axis starts with ‘-’, it implies loi_cumsum() in reverse order.
e.g. ‘-x’ is just like ‘x’ but any loi cumsums will be in reverse.
Physically, this can affect quantities like optical depth.
loi_interp(array)

return array interpolated onto coordinates implied by self.loi.

See help(type(self).loi) for more details.
Returns array unchanged if self.loi implies no interpolation.
property loi_ustr

units string (e.g., ‘length’) for loi interped coords,

in case self.units != self.coords_units, and loi not just along a maindim.
Probably want to use ‘length’, but ‘length’ not assumed by LoiLoader,
because maindims can technically represent anything, not just physical length.
Subclass can alter default value used by editing _LOI_USTR_DEFAULT.
(So, if subclass knows maindims and loi are lengths, it should set _LOI_USTR_DEFAULT=’length’)
UNSET –> internally uses self._loi_ustr_default (default in LoiLoader: None. Subclass may override.)
None –> if any units ambiguity (e.g. when getting dloi), crash.
str –> use this string to get unit conversion factors as needed.
e.g., umul = self.u(self.loi_ustr, units=self.units, convert_from=self.coords_units_explicit)
dloi = xarray_d_grid(interped, xc) * umul # (when loi not in maindims)
property loi_ustr_explicit

loi_ustr, but returns self._loi_ustr_default if loi_ustr is UNSET

property los

line of sight vector; used by self(“var_los”) pattern and any quantities which depend on it. Can be:

None –> var_los will crash,
str –> must be one of a few special strings (e.g. ‘x’ for XHAT, ‘-x’ for -XHAT);
see self.LOS_OPTIONS for all special options.
array –> xr.DataArray with ‘component’ dim representing line-of-sight vector(s).
(Does not need to have magnitude 1; var_los will convert to unit vectors as needed.)
To get array, use self(‘los’) (instead of something like self.los_explicit).
static magnitude(A, *, squared=False)

return vector magnitude of A, assuming vector components along the dimension ‘component’.

squared: bool, default False
if True, return |A|**2 instead of |A|.
[EFF] to get |A|**2, when |A| is not needed,
magnitude(A, squared=True) is more efficient than magnitude(A)**2
property maintaining

alias to maintaining_attrs

maintaining_attrs(*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 match_var(var, *, check=['KNOWN_VARS', 'KNOWN_PATTERNS'])

match var from cls.KNOWN_VARS or cls.KNOWN_PATTERNS, or raise FormulaMissingError.

returns result=MatchedQuantity(var, loadable, _match=_match) where:

loadable is the LoadableQuantity associated with this var,
_match is:
None, if var in cls.KNOWN_VARS;
re.fullmatch(pattern, var), if var matches any pattern in cls.KNOWN_PATTERNS.
if var matches multiple patterns, only the first matching pattern is used.
Uses MatchedVar if match from KNOWN_VARS, MatchedPattern if from KNOWN_PATTERNS.
(note that both MatchedVar and MatchedPattern subclass MatchedQuantity.)
check: str or list of str from [‘KNOWN_VARS’, ‘KNOWN_PATTERNS’]
where to check for matches. Default is to check KNOWN_VARS and KNOWN_PATTERNS.
E.g. to only check KNOWN_PATTERNS, use check=[‘KNOWN_PATTERNS’].
loadable and _match can be retrieved via result.loadable and result._match.
match_var_loading_dims(var, **kw_loading_dims)

return dims for loading var across.

Result will probably vary across these dims (but not guaranteed, if any dependency uses reduces_dims.)
These are all Dimension dims, not maindims. (E.g. ‘fluid’ and ‘snap’, but not ‘x’, ‘y’, ‘z’).
Equivalent: self.match_var_tree(var).loading_dims(**kw_loading_dims)
match_var_result_dims(var, **kw_result_dims)

return dims which result of cls(var) will vary across.

These are all Dimension dims, not maindims. (E.g. ‘fluid’ and ‘snap’, but not ‘x’, ‘y’, ‘z’).
Equivalent: cls.match_var_tree(var).result_dims(**kw_result_dims)
match_var_result_size(var, *, maindims=True, **kw_result_dims)

return size (number of elements) which self(var) will have.

(Efficient; doesn’t actually get self(var).)
Depends on current values of relevant dims. (E.g., self.fluid, not self.fluids)
maindims: bool
if True, include maindims_shape when calculating size.
match_var_tree(var=UNSET, **kw_quant_tree_from_quantity_loader)

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.
var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).
See also: type(self).cls_var_tree, for the classmethod version of this function.
Most of the time it is possible to get tree without any details from self,
but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.
additional kwargs will be passed to QuantTree.from_quantity_loader(…),
which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
matched_pattern_cls

alias of MatchedPattern

matched_var_cls

alias of MatchedVar

property nondim_behavior_attrs

list of attrs in self which control behavior of self, but which are NOT in self.dimensions.

quant_tree(var=UNSET, **kw_quant_tree_from_quantity_loader)

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.
var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).
See also: type(self).cls_var_tree, for the classmethod version of this function.
Most of the time it is possible to get tree without any details from self,
but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.
additional kwargs will be passed to QuantTree.from_quantity_loader(…),
which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
quant_tree_cls

alias of QuantTree

static rmscomps(A)

return root mean squared of components of A.

E.g., rmscomps(A) –> sqrt((Ax^2 + Ay^2 + Az^2) / 3), if A has 3 components.
property set

alias to set_var

set_var(var, value, behavior_attrs=None, forall=[], *, ukey=None, forced=False, **kw_using)

set var in self. When later doing self(var) to get var, return the set value,

but only if self.behavior is compatible with the relevant parts of self.behavior when var was set.
This function will use, if it exists:
self.KNOWN_SETTERS[var](self, value, behavior_attrs, forall=forall)
Otherwise, calls:
self.set_var_internal(var, value, self.behavior_attrs, forall=forall)
var: str
the var to set in self.
value: number, xarray, iterable or 1D array, array with shape matching self.maindims_shape.
the value to set var to.
number –> set var to this number.
xarray –> set var to this xarray.
[TODO](not yet implemented) iterable or 1D array –> set var to these values along dim=’testing’.
[TODO](not yet implemented) array with shape matching self.maindims_shape –> set var to this array.
behavior_attrs: None or list
tells which attrs from self control behavior of the set var.
The set var will only be retrieved when behavior_attrs of self are compatible.
E.g. set_var(‘n’, [‘fluid’, ‘snap’]) –> saves ‘n’ in cache with current fluid & snap.
Will only load ‘n’ if self.fluid and self.snap == cached fluid and snap for ‘n’.
if var in self.KNOWN_SETTERS, cannot provide behavior_attrs here.
else, use self.behavior_attrs if None.
forall: list of strings
if provided, tells which attrs of self do NOT control the behavior of the set var.
E.g. forall=[‘snap’] –> ‘snap’ will NOT be included in behavior_attrs.
(anything in behavior_attrs AND forall will be removed from the final behavior_attrs)
ukey: None or str
if provided, tells string to give to UnitsManager when converting value’s units.
When ukey is known, setting value in any unit system will enable to read it in all unit systems.
E.g. set_var(‘n’, 1e10, …, ukey=’n’, units=’si’)
–> self(‘n’, units=’raw’) == self(‘n’, units=’si’) * self.u(‘u’, ‘raw’, convert_from=’si’)
if not provided, value will be associated with current unit system;
attempted to read value in any other unit system will not used the cached value set here.
E.g. set_var(‘u’, 1e10, …, units=’si’) # ukey not provided
–> self(‘u’, units=’raw’) –> uses self’s other logic for getting ‘u’, not from setvars.
note: if provided, ‘units’ will be added to behavior_attrs if not already in there.
forced: bool, default True
handles the case where self.KNOWN_SETTERS[var] doesn’t exist. In that case…
True –> set var in self, anyway.
False –> crash; raise FormulaMissingError
additional kwargs, if provided, go to self.using(**kw) during the operation.
returns list of set quantities.
set_var_internal(var, value, behavior_attrs, forall=[], *, ukey=None)

set var in self. KNOWN_SETTERS functions may wish to use this method.

(KNOWN_SETTERS functions should NOT use self.set_var, to avoid recursion issue.)
This function has the internal logic for self.set_var;
set_var calls set_var_internal when self.KNOWN_SETTERS[var] not provided.
var: str
the var to set in self.
value: number, xarray, iterable or 1D array, array with shape matching self.maindims_shape.
the value to set var to. See help(self.set_var) for more info.
behavior_attrs: list of strings
the behavior attrs relevant to setting this var;
getting var only gives value when current behavior attrs values are compatible with the cached ones.
forall: list of strings
if provided, tells which behavior attrs do NOT control the behavior of the set var.
e.g. behavior_attrs=[‘snap’, ‘fluid’], forall=[‘snap’] –> use [‘fluid’], only.
ukey: None or str
if provided, tells string to give to UnitsManager when converting value’s units;
when ukey is provided, can retrieve value in any unit system (probably ‘si’ or ‘raw’).
when ukey not provided, if ‘units’ in used behavior attrs, can only retrieve value in that unit system.
property setvar

alias to set_var

property setvars

VarCache of vars set via self.set_var(). Returns these values when appropriate,

i.e. whenever self.behavior is compatible with the behavior in the cache.
To empty the cache, use self.setvars.clear() to empty the cache.
static take_parallel_to(B, A)

return the component of A parallel to B. Equivalent: (A dot Bhat) Bhat.

Note that B is the first argument.
[Implementation currently just returns xarray_take_parallel_to(B,A)]
static take_perp_to(B, A)

return the component of A perpendicular to B. Equivalent: A - (A dot Bhat) Bhat.

Note that B is the first argument.
[Implementation currently just returns xarray_take_perp_to(B,A)]
property toplevel_scale_coords

dict of {coord_name: coord_scaling} to apply to top-level outputs of self(var).

(Never applies to internal calls of self(var), only applies at self.call_depth==1.)
Useful if making plots and want to scale coords by some factor.
E.g., self.toplevel_scale_coords = {‘t’: 1000} to convert s to ms.
CAUTION: coord units labels will remain unaffected.
tree(var=UNSET, **kw_quant_tree_from_quantity_loader)

return QuantTree of MatchedQuantity objects from matching var and all dependencies,

using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.
var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).
See also: type(self).cls_var_tree, for the classmethod version of this function.
Most of the time it is possible to get tree without any details from self,
but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.
additional kwargs will be passed to QuantTree.from_quantity_loader(…),
which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
property typevar_crash_if_nan

bool. whether to crash methods if typevar output would be ‘nan’.

False –> return NaN when typevar gives ‘nan’, instead of crashing.
“typevar” here refers to any var used for checking which formula to use, from various options,
e.g. ‘ntype’ in MhdMultifluidLoader or ‘ionfrac_type’ in MhdIonizationLoader.
The relevant methods can check if self.typevar_crash_if_nan before returning a ‘nan’ result.
property unset

alias to unset_var

unset_var(var, behavior_attrs=[], *, missing_ok=True, **kw_using)

remove var from self.setvars (but only at values stored with relevant behavior).

[TODO] define rules for which vars unset which other vars…
e.g. for eppic right now, set_var(‘n’) sets ‘den’ but not ‘n’;
unset_var(‘n’) unsets nothing… but should probably alias to unset_var(‘den’).
behavior_attrs: list of strings
only remove cached values where self.behavior matches cached behavior for these attrs.
if empty, remove all cached values for var, regardless of associated behavior.
missing_ok: bool
whether it is okay for there to be zero matching cached values for var.
raise CacheNotApplicableError if missing_ok=False when there are no matching cached values.
additional kwargs, if provided, go to self.using(**kw) during the operation.
return list of CachedQuantity objects which were removed from self.setvars.
unset_var_internal(var, behavior_attrs, forall=[], *, ukey=None, missing_ok=True)

unset var from self.setvars.

KNOWN_SETTERS functions may wish to use this method, to unset dependent values.
E.g. if u depends on n, and n is changed, may wish to unset the value of u.
behavior_attrs: list of strings
the behavior attrs relevant to setting this var.
forall: list of strings
if provided, tells which behavior attrs to ignore when unsetting the var.
ukey: None or string
if provided, ignore ‘units’ behavior attr when unsetting the var
(due to assuming that ukey was provided when setting the var,
hence that the set var could be retrieved in any units system)
missing_ok: bool
whether it is okay for there to be zero matching cached values for var.
raise CacheNotApplicableError if missing_ok=False when there are no matching cached values.
return list of CachedQuantity objects which were removed from self.setvars.
property using

alias to using_attrs

using_at_call_depth(depth, **attrs_and_values)

context manager for setting attrs_and_values but only while call_depth == depth.

E.g.:

with self.using_at_call_depth(3, verbose=3):
self(‘sgyrof’)
# while self.call_depth == 3 inside of this ‘with’ block, uses self.verbose=3.
# but everywhere else, uses original value of verbose.
# assuming originally verbose=False (or unset), this example will print:
| | (call_depth=2) get var=’q’
| | (call_depth=2) get var=’mod_B’
| | (call_depth=2) get var=’m’
# compare this to simply using self.verbose=3, which would print:
| (call_depth=1) get var=’sgyrof’
| | (call_depth=2) get var=’q’
| | (call_depth=2) get var=’mod_B’
| | | (call_depth=3) get var=’B_dot_B’
| | | | (call_depth=4) get var=’B_xyz’
| | | | | (call_depth=5) get var=’B’
| | (call_depth=2) get var=’m’
Equivalent to self.call_depth_manager.using_obj_attrs_at(depth, **attrs_and_values)
using_at_next_call_depth(**attrs_and_values)

context manager for setting attrs_and_values but only while call_depth == self.call_depth + 1

Equivalent to self.using_at_call_depth(self.call_depth + 1, **attrs_and_values).

(Also equivalent to self.call_depth_manager.using_obj_attrs_at_next(**attrs_and_values).)
using_attrs(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.