Metadata-Version: 2.2
Name: emout
Version: 1.3.4
Summary: Emses output manager
Author-email: Nkzono99 <j-nakazono@stu.kobe-u.ac.jp>
Maintainer-email: Nkzono99 <j-nakazono@stu.kobe-u.ac.jp>
License: MIT License
        
        Copyright (c) 2020 Nkzono99
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Repository, https://github.com/Nkzono99/emout.git
Keywords: Visualization,Simulation,EMSES
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: matplotlib
Requires-Dist: h5py
Requires-Dist: f90nml
Requires-Dist: scipy
Requires-Dist: pandas

# emout

A Python library for parsing and visualizing output files generated by [EMSES](https://github.com/Nkzono99/MPIEMSES3D) simulations.

- **Documentation:** [https://nkzono99.github.io/emout/](https://nkzono99.github.io/emout/)

## Installation

```bash
pip install emout
```

## Example

- [Visualization of simulation results for lunar surface charging](https://nbviewer.org/github/Nkzono99/examples/blob/main/examples/emout/example.ipynb)

## Overview

When you run EMSES simulations, the results (e.g., potentials, densities, currents) are output in `.h5` files, and a parameter file (`plasma.inp`) contains the simulation settings. **emout** helps you:

1. **Load and handle** these outputs easily in Python.
2. **Access simulation parameters** from `plasma.inp`.
3. **Plot scalar/vector fields** for quick data visualization.
4. **Create animations** to see how data evolve over time.
5. **Convert units** between EMSES internal units and SI units.
6. **Combine multi-run outputs** for continued or appended simulations.
7. **Apply data masking** to filter data regions of interest.
8. **(Experimental) Solve Poisson’s equation** directly from charge distributions for 3D potentials.

Below, you will find usage examples that assume the following directory structure:

```
.
└── output_dir
    ├── plasma.inp
    ├── phisp00_0000.h5
    ├── nd1p00_0000.h5
    ├── nd2p00_0000.h5
    ├── j1x00_0000.h5
    ├── j1y00_0000.h5
    ...
    └── bz00_0000.h5
```

---

## Usage

### Loading Data

```python
import emout

# Initialize Emout with the path to the output directory
data = emout.Emout('output_dir')

# Access arrays by their variable names (derived from EMSES filename)
data.phisp   # Data from phisp00_0000.h5
len(data.phisp)   # Number of time steps
data.phisp[0].shape

data.j1x
data.bz
data.j1xy  # Vector data from "j1x00_0000.h5" + "j1y00_0000.h5"

# Data created by "relocating" ex00_0000.h5
data.rex

# Access data as a pandas DataFrame
data.icur
data.pbody
```

---

### Retrieving the Parameter File (plasma.inp)

```python
# The namelist is parsed into a dictionary-like structure
data.inp
data.inp['tmgrid']['nx']  # Access via group name and parameter name
data.inp['nx']            # Group name can be omitted if not ambiguous
data.inp.tmgrid.nx        # Access like object attributes
data.inp.nx               # Still valid
```

---

### Plotting Data

```python
x, y, z = 32, 32, 100

# Basic 2D plot (xy-plane at z=100 for the last timestep)
data.phisp[-1, z, :, :].plot()

# Line plot along z-axis at x=32, y=32
data.phisp[-1, :, y, x].plot()

# Plot using SI units
data.phisp[-1, z, :, :].plot(use_si=True)  # Default is True

# Show or save plot
data.phisp[-1, z, :, :].plot(show=True)
data.phisp[-1, z, :, :].plot(savefilename='phisp.png')

# Plot vector field as a streamline
data.j1xy[-1, z, :, :].plot()
```

---

### Creating Animations

```python
# Create a time-series animation along the first axis (time = 0)
x, y, z = 32, 32, 100
data.phisp[:, z, :, :].gifplot()

# Specify a different axis (default is axis=0)
data.phisp[:, z, :, :].gifplot(axis=0)

# Save animation as a GIF
data.phisp[:, z, :, :].gifplot(action='save', filename='phisp.gif')

# Display the animation inline in a Jupyter notebook
data.phisp[:, z, :, :].gifplot(action='to_html')

# Combining multiple frames for a single animation
updater0 = data.phisp[:, z, :, :].gifplot(action='frames', mode='cmap')
updater1 = data.phisp[:, z, :, :].build_frame_updater(mode='cont')
updater2 = data.nd1p[:, z, :, :].build_frame_updater(mode='cmap', vmin=1e-3, vmax=20, norm='log')
updater3 = data.nd2p[:, z, :, :].build_frame_updater(mode='cmap', vmin=1e-3, vmax=20, norm='log')
updater4 = data.j2xy[:, z, :, :].build_frame_updater(mode='stream')

layout = [
    [
        [updater0, updater1],
        [updater2],
        [updater3, updater4]
    ]
]
animator = updater0.to_animator(layout=layout)
animator.plot(action='to_html')  # or 'save', 'show', etc.
```

---

### Working with Units

> **Note**  
> EMSES → SI conversion is supported only when the first line of `plasma.inp` includes something like:
> ```text
> !!key dx=[0.5],to_c=[10000.0]
> ```
> where `dx` is the grid spacing [m], and `to_c` is the (normalized) speed of light used internally by EMSES.

```python
# Converting between physical (SI) and EMSES units
data.unit.v.trans(1)    # Convert 1 m/s to EMSES velocity unit
data.unit.v.reverse(1)  # Convert 1 EMSES velocity unit to m/s

# Access converted data in SI units
phisp_volt = data.phisp[-1, :, :, :].val_si       # Potential in volts [V]
j1z_A_per_m2 = data.j1z[-1, :, :, :].val_si       # Current density [A/m^2]
nd1p_per_cc = data.nd1p[-1, :, :, :].val_si       # Number density [1/cm^3]
```

---

### Handling Appended Simulation Outputs

If your simulation continues and creates new directories:

```python
import emout

# Merge multiple output directories into one Emout object
data = emout.Emout('output_dir', append_directories=['output_dir_2', 'output_dir_3'])

# Same as above if 'ad="auto"' is specified (detects appended outputs automatically)
data = emout.Emout('output_dir', ad='auto')
```

---

### Data Masking

```python
# Mask values below the average
data.phisp[1].masked(lambda phi: phi < phi.mean())

# Equivalent manual approach
phi = data.phisp[1].copy()
phi[phi < phi.mean()] = float('nan')
```

---

### Solving Poisson’s Equation (Experimental)

You can solve Poisson’s equation from 3D charge distributions using `emout.poisson` (depends on `scipy`):

```python
import numpy as np
import scipy.constants as cn
from emout import Emout, poisson

data = Emout('output_dir')
dx = data.inp.dx  # [m] Grid spacing
rho = data.rho[-1].val_si  # [C/m^3] Charge distribution
btypes = ["pdn"[i] for i in data.inp.mtd_vbnd]  # Boundary conditions

# Solve Poisson’s equation for potential
phisp = poisson(rho, dx=dx, btypes=btypes, epsilon_0=cn.epsilon_0)

# Compare with EMSES potential
np.allclose(phisp, data.phisp[-1])  # Should be True (within numerical tolerance)
```

---

Feel free to explore the documentation for more details and advanced usage:

[emout Documentation](https://nkzono99.github.io/emout/)

Happy analyzing!
