# plasma_plots.gvec

*module*

Read GVEC's evaluation Datasets in plasma-plots' conventions.

`GVEC <https://gvec.readthedocs.io>`_ evaluates an equilibrium into ``xarray`` Datasets
(``state.evaluate(...)``, ``state.evaluate_sfl(...)``, ``gvec.Evaluations``) with the dimensions
``rad``, ``pol``, ``tor``, the flux coordinates ``rho``, ``theta``, ``zeta`` (or the Boozer angles
``theta_B``, ``zeta_B``, or the PEST angle ``theta_P``) over them, vectors along ``xyz``, the
position as the variable ``pos`` and LaTeX ``symbol`` attributes. [`from_gvec()`][plasma_plots.gvec.from_gvec] returns the
same data the way the rest of plasma-plots reads it:

* the dimensions are the flux coordinates themselves: ``rho``, ``theta``/``theta_B``/``theta_P``
  and ``zeta``/``zeta_B``, so ``rho=0.5`` or ``zeta=0`` selects and ``x="zeta"`` draws;
* ``pos`` becomes the physical coordinates ``X``, ``Y``, ``Z`` of every variable (for
  ``coords="physical"``, 3-D views and the vector calculus on the mapped domain), and ``X1``,
  ``X2`` (GVEC's reference coordinates, ``R`` and ``Z`` for the cylindrical map), ``theta_P`` and
  the logical angles of a Boozer or PEST grid become coordinates as well;
* ``xyz`` becomes ``component``;
* each ``symbol`` becomes a ``label`` (``$\iota$``), which plots use for axes and color bars;
* the angles get a ``period`` attribute (2π, and 2π/nfp toroidally), from which the mode
  spectra take their periods and full-torus mode numbers, and the ``coordinate_lines`` overlay
  its lines;
* GVEC's quadrature weights (``rad_weight``, ``pol_weight``, ``tor_weight``) become
  ``rho_weight``, ``theta_weight``, ``zeta_weight``, which integrals use. GVEC's toroidal weight
  counts every field period; ``zeta_weight`` is divided by nfp, so that an integral covers the
  sampled grid (one field period) as on every other grid: multiply by nfp for the device;
* the number of field periods (``N_FP``) is the ``nfp`` attribute of the Dataset and of every
  variable.

The ``.plasma`` accessor applies [`from_gvec()`][plasma_plots.gvec.from_gvec] by itself to GVEC data, so
``ev.mod_B.plasma.plot.slice(x="zeta", y="theta", rho=1.0)`` needs no call. Call it once on the
whole Dataset to attach the geometry to every variable first: a single variable such as
``ev.mod_B`` doesn't carry ``pos``. GVEC itself is not needed.

**Examples**

```pycon
>>> import plasma_plots
>>> ev = plasma_plots.from_gvec(
...     state.evaluate(
...         "mod_B", "pos", "iota", "N_FP", rho=11, theta=32, zeta=24
...     )
... )
>>> ev.mod_B.plasma.plot.slice(
...     coords="physical",
...     plane="RZ",
...     zeta=0.0,
...     overlays={"coordinate_lines": {"rho": 5, "theta": 8}},
... )
>>> ev.iota.plasma.plot.lineout(rationals=4)
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L1-L1)

## plasma_plots.gvec.AXES

*attribute* · *module attribute*

```python
AXES = {'rad': ('rho'), 'pol': ('theta_B', 'theta_P', 'theta'), 'tor': ('zeta_B', 'zeta')}
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L57-L61)

## plasma_plots.gvec.GRID_VARIABLES

*attribute* · *module attribute*

```python
GRID_VARIABLES = ('X1', 'X2', 'theta_P', 'theta', 'zeta', 'theta_B', 'zeta_B')
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L63-L63)

## plasma_plots.gvec.GVEC_DIMS

*attribute* · *module attribute*

```python
GVEC_DIMS = ('rad', 'pol', 'tor')
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L55-L55)

## plasma_plots.gvec.POLOIDAL

*attribute* · *module attribute*

```python
POLOIDAL = ('theta', 'theta_B', 'theta_P')
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L64-L64)

## plasma_plots.gvec.TOROIDAL

*attribute* · *module attribute*

```python
TOROIDAL = ('zeta', 'zeta_B')
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L65-L65)

## plasma_plots.gvec.from_gvec

*function*

```python
def from_gvec(data: xr.DataArray | xr.Dataset, *, nfp: int | None = None) -> xr.DataArray | xr.Dataset
```

Return GVEC evaluations in plasma-plots' conventions; see [`plasma_plots.gvec`][plasma_plots.gvec].

Data that is not in GVEC's layout (see [`is_gvec()`][plasma_plots.gvec.is_gvec]) comes back with only the steps that
apply, so calling it twice is harmless.

**Parameters**

- `data` (`xarray.Dataset or xarray.DataArray`) — A Dataset from ``state.evaluate(...)``, ``state.evaluate_sfl(...)`` or ``gvec.Evaluations`` (also after ``to_netcdf`` and ``open_dataset``), or one of its variables.
- `nfp` (`int`) (default: `None`) — The number of field periods. Default: the ``N_FP`` variable (evaluate ``"N_FP"`` with the rest), else an ``nfp`` attribute, else from a toroidal grid that spans one field period uniformly (GVEC's default grid); without one, the toroidal angle gets no ``period``.

**Returns**

- (`xarray.Dataset or xarray.DataArray`) — The same data, of the same type, with the dimensions ``rho``, ``theta``/``theta_B``/ ``theta_P``, ``zeta``/``zeta_B`` and ``component``, the coordinates ``X``, ``Y``, ``Z`` (from ``pos``), ``X1``, ``X2``, labels from the ``symbol`` attributes, the angles' ``period`` and the ``nfp`` attribute.

**Examples**

```pycon
>>> ev = from_gvec(
...     state.evaluate("mod_B", "pos", "N_FP", rho=11, theta=32, zeta=24)
... )
>>> ev.mod_B.plasma.plot.panels(
...     sweep="zeta", coords="physical", plane="RZ", nrows=1, ncols=3
... )
>>> boozer = from_gvec(
...     state.evaluate_sfl(
...         "mod_B", "pos", rho=[0.5], theta=32, zeta=24, sfl="boozer"
...     )
... )
>>> boozer.mod_B.plasma.plot.slice(x="zeta_B", y="theta_B", rho=0.5)
```

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L122-L225)

## plasma_plots.gvec.is_gvec

*function*

```python
def is_gvec(data: xr.DataArray | xr.Dataset) -> bool
```

Whether ``data`` is still in GVEC's layout.

That is a ``rad``, ``pol`` or ``tor`` dimension with one of GVEC's flux coordinates on it.

**Parameters**

- `data` (`xarray.DataArray or xarray.Dataset`) — The data.

**Returns**

- (`bool`) — ``True`` for GVEC's evaluations (before [`from_gvec()`][plasma_plots.gvec.from_gvec]), ``False`` otherwise.

[View source](https://github.com/max-models/plasma-plots/blob/devel/src/plasma_plots/gvec.py#L77-L97)
