<h1>
    <img src="https://gitlab.com/Sevans7/plasmacalcs/-/raw/main/logo/logo.png" alt="PlasmaCalcs" height=100px>
</h1>

PlasmaCalcs provides a consistent interface (in Python) for plasma calculations from any inputs.

If you use Python to analyze any data related to plasma physics, then this package is for you!

Online docs available at https://plasmacalcs.readthedocs.io

Overview, examples, guides, and installation instructions below!


# Overview

**Plasma physics contains a myriad of quantities, mathematical operations, and potential data sources.**
- _Quantities_ include:
    electric and magnetic field,
    mass,
    charge,
    density,
    velocity,
    temperature,
    collision frequency,
    magnetization parameter,
    debye length,
    collisional mean free path,
    thermal speed,
    zeroth-order values such as equilibrium temperatures,
    elemental abunances,
    and many more.
- _Operations_ include:
    spatial and temporal derivatives,
    vector magnitude,
    cross products and dot products,
    Fourier transforms,
    and interpolation from lookup tables.
- _Data sources_ include:
    observations from spacecraft or telescopes;
    outputs from various types of simulators, including kinetic codes (e.g., [EPPIC](https://iopscience.iop.org/article/10.3847/2041-8213/ab75bc)),
    multifluid codes (e.g., [Ebysus](https://iopscience.iop.org/article/10.3847/1538-4357/ababa3)),
    and single-fluid radiative magnetohydrodynamic (MHD) codes (e.g., [Bifrost](https://www.aanda.org/articles/aa/full_html/2011/07/aa16520-11/aa16520-11.html), [MURAM](https://www.aanda.org/articles/aa/abs/2005/01/aa1507/aa1507.html));
    and any arbitrary dataset (e.g., an artificially-constructed grid of relevant physical parameters).

**Complicating matters further, quantities often have different dimensionality across different data sources.**
    For example, magnetic field is constant in EPPIC, but varies in time and space in Bifrost, which may provide 2D or 3D values.
    Also, EPPIC number density varies from species to species, while single-fluid codes like Bifrost instead track the "averaged" single-fluid number density.

**PlasmaCalcs helps to manage all of this complexity.**
This package
    provides a consistent interface for loading data from any kind of input,
    has many different available calculations relevant to plasma physics,
    supports well-labeled multidimensional arrays via [xarray](https://xarray.dev/),
    features many convenient capabilities for data manipulation and exploration,
    and contains well-documented custom-built help systems.
PlasmaCalcs also features useful plotting tools for exploring multi-dimensional data, including a simple interface to create animations:

```python
import PlasmaCalcs as pc
ec = pc.EppicCalculator.from_here(u_t=1)
ec('n').pc.subplots(row='fluid', cmap='plasma').ani()
```
![(number density movie example)](https://gitlab.com/Sevans7/plasmacalcs-assets/-/raw/main/readme_assets/eppic_2a__n__snapstep=4_fps=20.gif)

This shows number density of each species across the EPPIC simulation (from values stored in the current working directory).
The data ([available online](https://doi.org/10.5281/zenodo.13935288)) in this example animation comes from a [simulation of a plasma instability](https://doi.org/10.3847/1538-4357/adcd70) with electrons, H+, and C+. Note that the plotted data varies across 4 dimensions: x, y, time, and species!

**The animation here shows just a hint of what PlasmaCalcs can do.**
PlasmaCalcs also
    has many available quantities and operations (e.g., `ec('fft_n')` takes the Fourier transform),
    and provides a consistent interface for any inputs (e.g., the code to analyze Ebysus outputs looks similar but uses `pc.EbysusCalculator` instead).
See below for more examples and guides to help you get started!


# Examples and Guides

- [getting-started_eppic.ipynb](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/getting-started_eppic.ipynb) is a good place for anyone to get started. Even though some details are specific to eppic, most of it is generic enough to be useful to everyone. Estimated time: 5 mins.

- [getting-started_from_dataset.ipynb](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/getting-started_from_dataset.ipynb) provides all the necessary details to work with _any_ data you have, even if there's no associated hookup inside the PlasmaCalcs code yet! Estimated time: 10 mins.

- [slicing_tutorial.ipynb](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/slicing_tutorial.ipynb) showcases options for indexing and slicing data, before or after doing computations, including some extra convenient special methods implemented in PlasmaCalcs. Estimated time: 3 mins.

- [personalizing_your_PlasmaCalculator_example.ipynb](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/personalizing_your_PlasmaCalculator_example.ipynb) shows how to add new known quantities and further customize your PlasmaCalculator, by making a subclass! Estimated time: 2 mins.

- [tfbi_theory_example.ipynb](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/tfbi_theory_example.ipynb) shows some examples of solving the Thermal Farley-Buneman Instability theory, via the [tfbi\_theory](https://pypi.org/project/tfbi_theory) package. That package solves the theory itself, but PlasmaCalcs loads all the relevant inputs and helps with analyzing the results. Estimated time: 2-3 mins.

- Interested in adding a new hookup? The [dev_guide_new_hookup.pdf](https://gitlab.com/Sevans7/plasmacalcs/-/blob/main/examples/dev_guide_new_hookup.pdf) is a good place to start. Also, try to follow the implementation pattern of existing hookups, and feel free to reach out to PlasmaCalcs developers to ask for help!


# Installation

You can install the [latest release](https://pypi.org/project/PlasmaCalcs/) via:
```bash
pip install plasmacalcs
```

Or, you can install directly from git:
```bash
cd directory_where_you_want_this_code_to_be_installed
git clone https://gitlab.com/Sevans7/plasmacalcs
cd PlasmaCalcs  # into the directory where the pyproject.toml can be found.
pip install -e .   # you can drop the "-e" if you will never edit PlasmaCalcs.
```

You also might want to install with most optional dependencies:
```bash
# if installing the latest release:
pip install "plasmacalcs[most]"
# OR, if installing directly from git (replace "pip install -e ." above):
pip install -e ".[most]"
```
Using `[most]` includes most optional dependencies. Also consider `[all_fast]` which additionally includes packages with a small userbase (e.g. less than 100 users), and `[all]` which additionally includes packages with a long installation time (e.g. more than a few seconds).


# Contributing
Happy to accept contributions.
At this stage in development, the easiest way to contribute is to ask for permission to push commits directly to this repo.
Long-term contributors can push directly to `main`.
New contributors will be asked to make a new branch, then submit a merge request.

If making a new branch sounds scary, or if you're not super familiar with git, consider [GitHub Desktop](https://github.com/apps/desktop); it helps make git way more intuitive and less painful to use.

Note there are tests in the tests folder; if you are able to add any tests which test new or existing PlasmaCalcs code, please do! They run automatically whenever someone commits to this repo.

# License
Licensed under the MIT License; see also: LICENSE

# Citing PlasmaCalcs
If PlasmaCalcs supported any of the work in your publication, please cite it. Citation details are available on the [zenodo repository](https://doi.org/10.5281/zenodo.18381499) (scroll to Export section then export BiBTeX, or go to Citation section for other formats). It is sufficient to put in the acknowledgements section a statement like: `This work utilized the PlasmaCalcs package (citation).`

# Project status
Actively developing & using this project.
