Metadata-Version: 2.4
Name: curvature-mapping-method
Version: 0.1.0
Summary: A NumPy implementation of the Curvature Mapping Method for projected magnetic curvature and Lorentz-force mapping.
Author: Mengke Zhao, Guang-Xing Li, Keping Qiu
License-Expression: MIT
Project-URL: Homepage, https://github.com/meng-ke/curvature-mapping-method
Project-URL: Repository, https://github.com/meng-ke/curvature-mapping-method
Project-URL: Issues, https://github.com/meng-ke/curvature-mapping-method/issues
Project-URL: Paper, https://arxiv.org/abs/2408.09690
Project-URL: ADS, https://ui.adsabs.harvard.edu/abs/2024arXiv240809690Z
Keywords: astronomy,astrophysics,magnetic field,polarization,Lorentz force,curvature mapping
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23
Provides-Extra: notebook
Requires-Dist: astropy>=5; extra == "notebook"
Requires-Dist: jupyter>=1; extra == "notebook"
Requires-Dist: matplotlib>=3.6; extra == "notebook"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Provides-Extra: dev
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Dynamic: license-file

# Curvature Mapping Method

[![CI](https://github.com/meng-ke/curvature-mapping-method/actions/workflows/ci.yml/badge.svg)](https://github.com/meng-ke/curvature-mapping-method/actions/workflows/ci.yml)

A small Python package for calculating the projected magnetic-field curvature orientation and magnitude from a two-dimensional magnetic-field position-angle map. When a total magnetic-field strength is supplied, the package also calculates the Lorentz-force proxy implemented in the original script.

This repository implements and cites:

> Zhao, M., Li, G.-X., & Qiu, K. (2024), **Curvature Mapping Method: Mapping Lorentz Force in Orion A**, arXiv:2408.09690, ADS bibcode: `2024arXiv240809690Z`.

## Repository layout

```text
curvature-mapping-method/
├── pyproject.toml
├── README.md
├── LICENSE
├── CITATION.cff
├── CITATION.bib
├── CHANGELOG.md
├── CONTRIBUTING.md
├── src/
│   ├── Curvature_mapping_method.py  # Backward-compatible module name
│   └── curvature_mapping_method/
│       ├── __init__.py
│       ├── core.py
│       └── py.typed
├── tests/
├── legacy/
│   └── Curvature_mapping_method_original.py  # Original supplied script
├── examples/
│   └── example.ipynb       # Reproducible usage example
└── data/
    ├── OMC-1-bandC.fits     # Example observational data
    └── README.md            # Data provenance and usage notes
```

The `legacy/` directory preserves the original supplied script. The installed package uses the implementation in `src/curvature_mapping_method/core.py`, which adds packaging, validation, array broadcasting, type information, and documentation while preserving the original default numerical normalization.

Repository-level files under `data/` are intentionally excluded from the wheel by default. This prevents large observational data files from being uploaded to PyPI accidentally, while still allowing the files to remain in the GitHub repository for use by `examples/example.ipynb`.

## Installation

### Install directly from GitHub

After the repository has been uploaded to GitHub:

```bash
python -m pip install "git+https://github.com/meng-ke/curvature-mapping-method.git"
```

To install a specific tag, such as `v0.1.0`:

```bash
python -m pip install "git+https://github.com/meng-ke/curvature-mapping-method.git@v0.1.0"
```

### Install from PyPI

After the package has been published to PyPI:

```bash
python -m pip install curvature-mapping-method
```

### Local editable installation

```bash
git clone https://github.com/meng-ke/curvature-mapping-method.git
cd curvature-mapping-method
python -m pip install -e ".[dev,notebook]"
```

## Quick start

```python
import numpy as np
from curvature_mapping_method import compute_curvature_mapping

# Magnetic-field position-angle map in radians, shape (ny, nx).
pa = np.zeros((100, 100), dtype=float)

# Curvature only. Here pixelsize is measured in pc per pixel.
curvature_angle, curvature = compute_curvature_mapping(
    pa,
    pixelsize=0.01,
    Btot="auto",
    nn=3,
)

# Lorentz-force proxy. Btot is measured in gauss and may be either
# a scalar or an array that can be broadcast to the shape of pa.
force_angle, force_proxy = compute_curvature_mapping(
    pa,
    pixelsize=0.01,
    Btot=5.0e-4,
    nn=3,
    omega=1.0,
)
```

The original module name remains available for compatibility with existing notebooks:

```python
from Curvature_mapping_method import compute_curvature_mapping
```

## API

### `compute_curvature_mapping(PAxy, pixelsize="auto", Btot="auto", nn=3, omega=1.0)`

#### Parameters

- `PAxy`: Two-dimensional magnetic-field position-angle array in radians.
- `pixelsize`: Physical size represented by one pixel, in parsecs. Use `"auto"` only when requesting curvature in inverse pixels.
- `Btot`: Total magnetic-field strength in gauss. It may be a scalar or an array broadcastable to `PAxy`. Use `"auto"` to calculate curvature without a force proxy.
- `nn`: Grid spacing in pixels passed to `numpy.gradient`. The default value of `3` preserves the behavior of the original supplied script.
- `omega`: Optional multiplicative calibration factor. The default value of `1.0` preserves the original result.

#### Returns

`compute_curvature_mapping` returns `(curvature_angle, value)`:

- `curvature_angle` is the curvature-vector orientation in radians over the full `[-pi, pi]` range.
- When `Btot="auto"`, `value` is the curvature magnitude:
  - in `pc^-1` when `pixelsize` is numeric;
  - in `pixel^-1` when `pixelsize="auto"`.
- When `Btot` is supplied, `value` follows the Gaussian-cgs normalization used by the original script:

```text
omega * Btot**2 / (8*pi) * curvature
```

Under this convention, the result is expressed in `dyn cm^-3`. Record the adopted normalization and the calibration value of `omega` explicitly in any scientific analysis. The associated paper presents the CMM physical formulation and its simulation-calibrated correction factor; users should ensure that the software settings match their intended scientific convention.

## Coordinate and angle conventions

The input array is interpreted as an image with shape `(ny, nx)`. NumPy gradients are evaluated along the y and x axes, respectively. The magnetic unit-vector components are defined as

```text
bx = cos(PAxy)
by = sin(PAxy)
```

The returned curvature orientation is calculated with `arctan2(curvature_y, curvature_x)`. Because magnetic polarization orientations have a 180-degree ambiguity, verify that the position-angle convention used by the input data is consistent with the coordinate system of the analysis.

## Missing data and masks

The function uses NumPy finite-difference gradients. `NaN` values therefore propagate into neighboring gradient pixels. Before calling the function, apply the appropriate polarization signal-to-noise selection, observational mask, and boundary treatment. Reapply the same scientific mask to the outputs.

## Example notebook and data

1. Open `examples/example.ipynb`.
2. Keep its input data under the repository-level `data/` directory.
3. Resolve the repository root before constructing data paths. For example:

```python
from pathlib import Path

repo_root = Path.cwd().parent if Path.cwd().name == "examples" else Path.cwd()
data_dir = repo_root / "data"
```

4. Install the notebook dependencies with:

```bash
python -m pip install -e ".[notebook]"
```

For a public release, document the provenance, units, license, and citation for every data product in `data/README.md`. Large data files may be better hosted in an archival data repository and downloaded by the notebook, rather than stored directly in Git.

## Testing and building

Run the test suite and lint checks:

```bash
python -m pip install -e ".[dev,notebook]"
python -m pytest
python -m ruff check .
```

Build and validate the source distribution and wheel:

```bash
python -m pip install build twine
python -m build
python -m twine check dist/*
```

Successful builds are written to `dist/`.

## Continuous integration

The repository includes `.github/workflows/ci.yml`. On pushes and pull requests, GitHub Actions tests the package with supported Python versions and validates the built distributions.

## Publishing to PyPI with GitHub Actions

The repository includes `.github/workflows/publish.yml`. When a GitHub Release is published, the workflow builds the package and uploads it through PyPI Trusted Publishing.

1. Create the project on PyPI, or configure a pending trusted publisher.
2. In the PyPI trusted-publisher settings, enter the GitHub owner, repository name, and workflow filename `publish.yml`.
3. Create a Git tag such as `v0.1.0`, then publish a GitHub Release for that tag.
4. The workflow will build and publish the files under `dist/`.

Before each release, update:

- `version` in `pyproject.toml`;
- `__version__` in `src/curvature_mapping_method/__init__.py`;
- `CHANGELOG.md`.

## Citation

When using this package, cite both the associated paper and the software release. The repository includes `CITATION.cff` and `CITATION.bib`. GitHub recognizes `CITATION.cff` and displays a **Cite this repository** control automatically.

```bibtex
@article{Zhao2024CMM,
  author        = {Zhao, Mengke and Li, Guang-Xing and Qiu, Keping},
  title         = {Curvature Mapping Method: Mapping Lorentz Force in Orion A},
  year          = {2024},
  journal       = {arXiv e-prints},
  eid           = {arXiv:2408.09690},
  archivePrefix = {arXiv},
  eprint        = {2408.09690},
  primaryClass  = {astro-ph.GA},
  adsnote       = {ADS bibcode: 2024arXiv240809690Z}
}
```

## License

This repository currently uses the MIT License. Before public release, confirm that all authors and rights holders approve this license. If a different license is required, update both `LICENSE` and the license metadata in `pyproject.toml`.
