xarray_interp_inverse
- PlasmaCalcs.tools.xarray_tools.xarray_sci.xarray_interp_inverse(array, interpto=None, output=None, *, promote_dims_if_needed=True, assume_sorted=None, assume_sorted_values=None, method=None, kw_interp=None, **interpto_as_kw)
interpolate a DataArray but using the array values as one of the interpolation variables;
the result is the array of the unused interpolation coordinate.Example: if array has dims {‘x’, ‘y’} and name ‘T’, and interpto specifies ‘x’ and ‘T’,then result will be a DataArray with dims {‘x’, ‘T’} and values for ‘y’.Special case: if interpto specifications are single values,the result will be scalar along that key instead of a dimension,e.g. if interpto[‘x’] = 7 (as a opposed to a 1D array like [1,2,3]),then result would have coordinate ‘x’=7 but not have an ‘x’ dimension.See below for even more examples.[EFF] note: inefficient if choosing many values along vars other than array.name.each result value along those vars corresponds to its own interp call.The internal steps are roughly:(1) array.interp(all interpto vars except array.name)(2) array.assign_coords({array.name: array})(3) for each index along all interpto vars except array.name:tmp = array.isel(index).interp({array.name: interpto[array.name]})result[index] = tmp[output var][TODO] still need to implement step 3 for 3D+ arrays instead of only 2D or less.array: xarray.DataArraymust have non-None array.name.interpto: None or dictdictionary of {var: value or array of values} to interpolate to.Keys must correspond to array.name, and coords for all except 1 dim of array.None –> provide interpto dict as kwargs to this function.Note: the array of values for [TODO]output: None or strname for the result variable.None –> use the key from array.dims which is missing from interpto (after xarray_ensure_dims).promote_dims_if_needed: boolwhether to promote non-dimension coords to dimensions.if False, raise DimensionKeyError if any relevant coord is not already a dimension.assume_sorted: None or boolwhether to assume_sorted during step (1),i.e. during the initial interp for all interpto vars except array.nameNone –> assume_sorted if xarray_is_sorted.True –> assume_sorted without checking. CAUTION: only do this if you’re 100% sure!False –> don’t assume sorted. May be noticeably slower for large arrays.assume_sorted_values: None or boolwhether to assume_sorted during step (3),i.e. during the interp using array.name as a coordinate.None –> assume_sorted if xarray_is_sorted. check at each index in step 3;if False multiple times in a row, stop checking and just assume False.True –> assume_sorted without checking. CAUTION: only do this if you’re 100% sure!False –> don’t assume sorted. May be noticeably slower for large arrays.method: None or strmethod to pass to xarray.interp for all interpolations.if None, use xarray.interp method default.kw_interp: None or dictif provided, pass these kwargs to all calls of xarray.interp.These will eventually go to the internal interpolator method e.g. from scipy.interpto_as_kw: optionally, provide interpto dict as kwargs to this function.— More Examples —# This array should make it easier to understand, follow, and predict results:tt = pc.xrrange(5, ‘tens’)oo = pc.xrrange(10, ‘ones’)arr = (10 * tt + oo).rename(‘n’)# arr looks like: [[0, 10, …, 40], [1, 11, …, 41], …, [9, 19, …, 49]].pc.xarray_interp_inverse(arr, tens=1, n=17) == 7arr.pc.interp_inverse(tens=1, n=17) == 7 # more convenient syntax thanks to pcAccessor.# more exact matches:arr.pc.interp_inverse(tens=2, n=23) == 3 # n=23, tens=2 –> ones=3arr.pc.interp_inverse(n=20, tens=2) == 0 # n=20, tens=2 –> ones=0arr.pc.interp_inverse(n=18, ones=8) == 1 # n=18, ones=8 –> tens=1arr.pc.interp_inverse(n=29, ones=9) == 2 # n=29, ones=9 –> tens=2# inexact matches:arr.pc.interp_inverse(n=15, ones=0) == 1.5 # ones=0 –> tens needs 0.5arr.pc.interp_inverse(n=27, ones=3) == 2.4arr.pc.interp_inverse(n=23.5, tens=2) == 3.5arr.pc.interp_inverse(n=27, tens=2.5) == 2# unreachable array values (n) gives nanarr.pc.interp_inverse(n=27, tens=3) –> NaN # ones can’t compensate# out of bounds input coords (ones or tens) raises DimensionValueError (regardless of n)arr.pc.interp_inverse(n=27, ones=10) –> crash with DimensionValueErrorarr.pc.interp_inverse(n=11, ones=-1) –> crash with DimensionValueError# coords can be arrays (output will be an xarray; shown here as a list.)arr.pc.interp_inverse(ones=[7, 2], n=27)–> xr.DataArray([2.0, 2.5], name=’tens’, dims=[‘ones’], coords=dict(ones=[7, 2], n=27))arr.pc.interp_inverse(tens=[2,3], n=27)–> xr.DataArray([7.0, nan], name=’ones’, dims=[‘tens’], coords=dict(tens=[2, 3], n=27))# arr.name var can be an array:arr.pc.interp_inverse(ones=5, n=[20, 25, 30, 36])–> xr.DataArray([1.5, 2, 2.5, 3.1], name=’tens’, dims=[‘n’],coords=dict(ones=5, n=[20, 25, 30, 36]))# both can be arrays:arr.pc.interp_inverse(ones=[0, 7, 9], n=[27, 29])–> xr.DataArray([[2.7, 2.9], [2.0, 2.2], [1.8, 2.0]], name=’tens’, dims=[‘ones’, ‘n’],coords=dict(ones=[0, 7, 9], n=[27, 29]))# inputs can also be well-labeled; relevant info will be maintained:ones = xr.DataArray([7, 2], name=’customname’, dims=[‘x’], coords=dict(x=[100, 200]))arr.pc.interp_inverse(ones=ones, n=27)–> xr.DataArray([2.0, 2.5], name=’tens’, dims=[‘x’],coords=dict(ones=(‘x’, [7, 2]), n=27, x=[100, 200]))