# Nata API design ## Plugins ```python @register_plugin([ParticleDataset, ParticleArray], name="awesome") def my_plugin(ds: Union[ParticleDataset, ParticleArray]): pass ``` --- ## Particles | Class | Output shape of `to.numpy()` or `.to_dask()` | | ----------------- | ----------------------------------------------------- | | `ParticleDataset` | 2d structured array of `[("q1", int), ("q2", float)]` | | `ParticleArray` | 1d structured array of `[("q1", int), ("q2", float)]` | | `Particle` | 0d structured array of `[("q1", int), ("q2", float)]` | | `QuantityArray` | 1d array of `int/float/...` | | `Quantity` | 0d array of `int/float/...` | ### Indexing summary: #### `ParticleDataset` indexing: pds[t1:t2] -> ParticleDataset pds[t1] -> ParticleArray pds[t1, i1:i2] -> ParticleArray pds[t1, i1:i2, ["x1", "x2"]] -> ParticleArray pds[t1, i1:i2, "x1"] -> QuantityArray pds[t1, i1:i2, ["x1"]] -> ParticleArray pds[t1, i1] -> Particle pds[t1, i1, ["x1", "x2"]] -> Particle pds[t1, i1, "x1"] -> Quantity #### `ParticleArray` indexing: arr = pds[t1] arr[i1:i2] = pds[t1, i1:i2] -> ParticleArray arr[i1:i2, ["x1", "x2"]] -> ParticleArray arr["x1"] -> QuantityArray arr[i1:i2, "x1"] -> QuantityArray arr[i1:i2, ["x1"]] -> ParticleArray arr[i1] -> Particle arr[i1, ["x1", "x2"]] -> Particle arr[i1, "x1"] -> Quantity #### `Particle` indexing: prt = arr[i1] prt["x1"] -> Quantity prt[["x1", "x2"]] -> Particle #### Example - 10 time steps - 123 particles - 3 quantities ```python pds = ParticleDataset.from_array(...) pds.shape == (10, 123) arr = pds[t0] type(arr) == ParticleArray arr.shape == (123,) prt = arr[i1] type(prt) == Particle prt.shape == (,) ``` ### Design decision for `Particles` | Property | Meaning | | ----------------- | ---------------------------------------------------------------------------- | | `name` | Short name of the particle, e.g. species. | | `label` | Descriptive name of the particle, e.g. species. | | `time` | Associated time axis for the particle data. | | `num` | Number of particles. | | `quantities` | Tuple of containing tuples of `(name, label, unit)` for particle quantities. | | `quantity_names` | Tuple of containing quantity names. | | `quantity_labels` | Tuple of containing quantity labels. | | `quantity_units` | Tuple of containing quantity units. | --- ## Grids | Class | Output shape of `.to_numpy()` or `.to_dask()` | ------------- | ------------------------------------------------------------ | `GridDataset` | (n+1)-d array, `.shape == (nt, nx, ny, ...)`, `.ndim == n+1` | `GridArray` | (n)-d array, `.shape == (nx, ny, ...)`, `.ndim == n` ### Indexing summary: #### `GridDataset` indexing: gds[t1:t2] -> GridDataset gds[t1, ...] -> GridArray, ndim == n gds[t1, i1:i2, ...] -> GridArray, ndim == n-1 gds[t1, i1:i2, j1:j2, ...] -> GridArray, ndim == n-2 #### `GridArray` indexing: arr = gds[t1] arr[i1:i2, ...] = gds[t1, i1:i2] -> GridArray, ndim == n arr[i1, ...] -> GridArray, ndim == n-1 ### Axes summary: #### `GridDataset` axes: gds.axes -> (Axis(...), Axis(...), Axis(...)) gds.axes[0].shape == (100,) gds.axes[1].shape == (100, 10) gds.axes[2].shape == (100, 5) gds.shape == (100, 10, 5) #### `GridArray` axes: arr = gds[t1] arr.axes -> (Axis(...), Axis(...)) arr.axes[0].shape == (10,) arr.axes[1].shape == (5,) arr.shape == (10, 5) --- ## Scratchpad :::danger DO NOT CONSIDER THIS FOR API ::: ```python gds.shape == (10, 50) arr = gds.streak() #-> GridArray arr.shape == (10, 50) # if moving window gds.to_static_window(v=.99, offset=100).streak() gds.shape == (10, 50) A(x, t) A(x=2, t) gds.func(const="x", val=2) ``` GridDataset.from_path("*", tempral_axis="time") GridDataset.from_path("*", tempral_axis="iteration") GridDataset.from_path("*", tempral_axis="iteration").axes[0]._data *= (ndump * dt) foo = ParticleDataset.from_path("*", time_prop="abc") foo.time.name == "abc" bar = GridDataset.from_path("*", time_prop="abc") bar.time.name == "abc" bar.time -> bar.axes[0] baz = bar[t0] -> GridArray baz.time -> Axis, 0d --- **May the fourth be with you** | Class | Output shape of `.to_numpy()` or `.to_dask()` | | ----------------- | ----------------------------------------------------- | | `ParticleDataset` | 2d structured array of `[("q1", int), ("q2", float)]` | | `ParticleArray` | 1d structured array of `[("q1", int), ("q2", float)]` | | `Particle` | 0d structured array of `[("q1", int), ("q2", float)]` | | `Quantity` | 0d array of `int/float/...` | | `QuantityArray` | 1d array of `int/float/...` | | Class | Output shape of `.to_numpy()` or `.to_dask()` | | ----------------- | --------------------------------------------- | | `ParticleDataset` | 2d/3d array of `int/float/...` | | `ParticleArray` | 1d/2d array of `int/float/...` | | `QuantityArray` | 1d array of `int/float/...` | ```python prt = ParticleArray.from_array(...) prt[quant_idx, particle_idx] prt[quant_idx, :] -> QuantityArray prt[quant_idx, :].ndim == 1 prt[:, particle_idx] -> ParticleArray prt[:, particle_idx].ndim == 2 ``` ```python # init with array with shape == (2, 3) # ^----- number of quantities # ^-------- number of particles prt = ParticleArray.from_array( [[1, 2, 3], [3, 4, 5]], quantity_names=("x1", "x2", "x3") ) assert prt.ndim == 2 assert prt.shape == (2, 3) assert prt.number == 2 assert prt.quantity_names == ("x1", "x2", "x3") assert prt.quantity_labels == ("unlabeled", "unlabeled", "unlabeled") assert prt.quantity_units == ("", "", "") # init with array with shape == (6,) # ^-------- number of particles prt = ParticleArray.from_array([1, 2, 3, 3, 4, 5]) assert prt.ndim == 1 assert prt.shape == (6,) assert prt.number == 6 assert prt.quantity_names == () assert prt.quantity_labels == () assert prt.quantity_units == () # init with array with just a number prt = ParticleArray.from_array(1) assert prt.ndim == 0 assert prt.shape == () assert prt.number == 1 assert prt.quantity_names == () assert prt.quantity_labels == () assert prt.quantity_units == () # init with array with empty tuple (a.k.a. no particles) prt = ParticleArray.from_array(()) assert prt.ndim == 1 assert prt.shape == (0,) assert prt.number == 0 assert prt.quantity_names == () assert prt.quantity_labels == () assert prt.quantity_units == () ```
{"metaMigratedAt":"2023-06-15T22:58:17.438Z","metaMigratedFrom":"Content","title":"Nata API design","breaks":true,"contributors":"[{\"id\":\"54197f01-0ce8-491e-a753-e36658126153\",\"add\":6227,\"del\":1286},{\"id\":\"b75f5995-0a30-4f2d-8aba-2b5f77658f75\",\"add\":7575,\"del\":5108},{\"id\":null,\"add\":153,\"del\":0}]"}
    210 views