Metadata-Version: 2.5
Name: ionhop
Version: 0.1.0
Summary: ss-NMR lineshape deconvolution and relaxation analysis (T1, T1_rho, T2)
Project-URL: Homepage, https://github.com/BiffoQ/ionhop
Project-URL: Documentation, https://biffoq.github.io/ionhop/
Project-URL: Repository, https://github.com/BiffoQ/ionhop.git
Project-URL: changelog, https://github.com/BiffoQ/ionhop/blob/main/CHANGELOG.md
Author-email: Abdulkadir Olatunbosun Biffo <biffokadir13@gmail.com>
License-Expression: MIT
License-File: LICENSE.md
Keywords: T1,T1_rho,T2,lineshape analysis,nmr,peak deconvolution,relaxometry,solid-state NMR,ss-NMR
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: <3.13,>=3.10
Requires-Dist: matplotlib>=3.9.0
Requires-Dist: mrsimulator==1.0
Requires-Dist: nmrglue
Requires-Dist: numpy>=1.26.0
Requires-Dist: pandas>=2.2.0
Requires-Dist: scipy
Provides-Extra: dev
Requires-Dist: black>=22.0; extra == 'dev'
Requires-Dist: codecov-cli>=0.4.1; extra == 'dev'
Requires-Dist: isort>=5.0; extra == 'dev'
Requires-Dist: mypy>=0.981; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.0.285; extra == 'dev'
Provides-Extra: docs
Requires-Dist: cairosvg>=2.7.1; extra == 'docs'
Requires-Dist: ipywidgets>=8.0.0; extra == 'docs'
Requires-Dist: mkdocs-autorefs; extra == 'docs'
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'docs'
Requires-Dist: mkdocs-jupyter; extra == 'docs'
Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'docs'
Requires-Dist: mkdocs-material>=9.4.0; extra == 'docs'
Requires-Dist: mkdocs-material[imaging]; extra == 'docs'
Requires-Dist: mkdocstrings-python<1.12.0,>=1.11.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]<0.27.0,>=0.26.0; extra == 'docs'
Requires-Dist: mknotebooks; extra == 'docs'
Requires-Dist: pillow>=10.0.0; extra == 'docs'
Requires-Dist: pymdown-extensions; extra == 'docs'
Description-Content-Type: text/markdown

# ``ionhop``: ss-NMR lineshape and relaxation analysis made easy

``ionhop`` is an open-source Python package for solid-state NMR data analysis. It merges two
previously separate tools into one install:

- **``ionhop.lineshape``** — peak deconvolution and lineshape analysis for 1D spectra
  (formerly published as [``nmrlineshapeanalyser``](https://pypi.org/project/nmrlineshapeanalyser/))
- **``ionhop.relaxometry``** — relaxation time analysis: T1, T1_rho and T2
  (formerly published as [``relaxometrynmr``](https://pypi.org/project/relaxometrynmr/))

Both modules are compatible with Bruker's NMR data; the lineshape module also accepts spectrum
data saved as CSV.

# Why ``ionhop``?

## Lineshape analysis (`ionhop.lineshape`)
  - easy and fast processing of either lineshape spectral analysis or peak deconvolution
  - works directly from processed Bruker data, e.g. `data/single_peak/10/pdata/1`
  - for the optimisation, you only need to input the peak position(s), it does the rest
  - freedom to fix or optimise position(s), amplitude, width, or eta (Gaussian/Lorentzian mixing)
    for each peak independently
  - detailed Pseudo-Voigt fit statistics saved to a txt file
  - peak deconvolution reports the percentage contribution of each peak
  - exports fit and data as CSV and the fit as a publication-quality PNG

## Relaxometry (`ionhop.relaxometry`)
  - streamlines T1, T1_rho and T2 analysis and cuts analysis time by more than 50%
  - built-in mono-, di-, tri-, and stretched-exponential models for simple to complex
    relaxation behaviour
  - automatic delay-list detection (vdlist, vplist, vclist)
  - zero-filling, 0th/1st-order phase correction, Gaussian apodisation
  - trapezoid and Simpson's-rule numerical integration for peak area
  - full-spectrum and zoomed-in views for context and detail

# Install

```bash
pip install ionhop
```

# Dependencies

```bash
nmrglue
numpy >= 1.26.0
scipy
matplotlib >= 3.9.0
pandas >= 2.2.0
mrsimulator == 1.0
```

# A Single Peak Fitting Example (`ionhop.lineshape`)

```python
from ionhop.lineshape import NMRProcessor

# create NMRProcessor object
processor = NMRProcessor()

# Load filepath: always include the trailing slash
filepath = r"../data/single_peak/10/pdata/1/"

# Load the data
processor.load_data(filepath)

# Select the region of interest
x_data, y_data = processor.select_region(512, 650)

# Normalize the data and return normalised y_axis and the corresponding x_axis
x_data, y_normalized = processor.normalize_data(x_data, y_data)

# define initial parameters for the fitting
# this example is for a single peak
# format: [x0, amplitude, width, eta, offset]
# x0 (position), amplitude, width, eta (mixing parameter), offset
# x0 has to be close to the peak position
# offset is shared across all peaks and must be in the normalized 0-1 scale
initial_params = [
    581, 0.12, 40.51, 0.89, 0.0,
]

# Specify the number of peaks to be fitted
number_of_peaks = 1

# fixed_x0 controls whether peak positions should be fixed during fitting
# False means position can vary, True means position is fixed
fixed_x0 = [False] * number_of_peaks

# fixed_eta controls whether each peak's eta (Gaussian/Lorentzian mixing) is fixed
# False means eta is fitted freely (this is the default if fixed_eta is omitted)
# True fixes it at its initial_params value
fixed_eta = [False] * number_of_peaks

# Fit the data
popt, metrics, fitted = processor.fit_peaks(
    x_data, y_normalized, initial_params, fixed_x0, fixed_eta=fixed_eta
)

# popt is the optimized parameters
# metrics is the metrics of the fitting
# fitted is the fitted curve data

# Plot and examine the results of the fitting
fig, axes, components = processor.plot_results(x_data, y_normalized, fitted, popt)

# Save the figure as a png file and the results as a csv file
processor.save_results(filepath, x_data, y_normalized, fitted, metrics, popt, components)
```

This generates a fit image and a metrics printout like:

```
Peak Fitting Results:
===================

Peak 1 (Position: 582.01 ± 0.01):
Amplitude: 0.993 ± 0.002
Width: 12.33 ± 0.03 in ppm
Width: 835.74 ± 2.36 in Hz
Eta: 1.00 ± 0.01
Offset: -0.004 ± 0.000
Gaussian Area: 0.00 ± 0.10
Lorentzian Area: 19.23 ± 0.16
Total Area: 19.23 ± 0.19
--------------------------------------------------
Peak 1 Percentage is 100.00% ± 1.39%
Overall Percentage is 100.00% ± 1.39%
```

# A Relaxometry Example (`ionhop.relaxometry`)

```python
from ionhop.relaxometry import T1Functions

t1 = T1Functions()
# see the User Guide notebooks in docs/user_guide_relaxometry for full T1, T1_rho and T2 workflows
```

Full worked examples for both modules are in the User Guide notebooks under `docs/`.

# Migrating from `nmrlineshapeanalyser` or `relaxometrynmr`

Both packages still install, but they now just depend on `ionhop` and re-export it, so existing
imports keep working:

```python
from nmrlineshapeanalyser.core import NMRProcessor   # still works
from ionhop.lineshape import NMRProcessor             # preferred
```

New code should target `ionhop` directly.

# Contact

For questions and support, please open an issue in the [GitHub repository](https://github.com/BiffoQ/ionhop).
