# RMNpy
Python bindings for OCTypes, SITypes, and RMNLib C libraries.

> **🚀 Setting up on a new computer?** See **[docs/development/NEW_COMPUTER_SETUP.md](docs/development/NEW_COMPUTER_SETUP.md)** for quick setup or **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** for detailed instructions.
## Overview
RMNpy provides Python access to three scientific computing C libraries:
- **OCTypes**: Objective-C style data structures and memory management
- **SITypes**: Scientific units and dimensional analysis
- **RMNLib**: High-level analysis and computation tools
## Features
- Type-safe conversion between Python and C data structures
- Scientific units and dimensional analysis
- High-performance numerical computations
- Memory-safe interface to C libraries
## Installation
### For Development (Recommended)
See **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** for complete instructions.
Quick version:
```bash
# Clone the repo with all C libraries
git clone https://github.com/pjgrandinetti/OCTypes-SITypes.git
cd OCTypes-SITypes
# Build required C libraries first
cd OCTypes && make && make install && cd ..
cd SITypes && make && make synclib && make install && cd ..
cd RMNLib && make && make synclib && make install && cd ..
# Set up Python environment
cd RMNpy
conda env create -f environment.yml
conda activate rmnpy
pip install -e .
```
### For End Users (When Available)
```bash
pip install rmnpy
```
**Platform Support:**
- ## Requirements
- **Linux/macOS**: Python 3.11-3.12
- **Windows**: Python 3.12 only (requires MSYS2 environment)
### Windows (MSYS2/Mingw-w64 Python)
To install RMNpy with C99-based Cython extensions on Windows you must use the MSYS2 MINGW64 Python runtime:
1. Install [MSYS2](https://www.msys2.org/) and open the **MSYS2 MinGW64** shell.
2. Update packages and install dependencies:
```bash
pacman -Syu # first-time update
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-python-pip \
mingw-w64-x86_64-openblas mingw-w64-x86_64-lapack \
mingw-w64-x86_64-curl mingw-w64-x86_64-make
```
3. Create and activate a virtual environment (so pip can install into it):
```bash
python -m pip install --upgrade pip virtualenv
python -m virtualenv venv
source venv/bin/activate
```
4. Install RMNpy and test extras:
```bash
pip install numpy pytest pytest-cov
pip install -e .[test]
```
5. Run your scripts or pytest from this venv; it uses MinGW-built extensions compatible with Windows.
#### Using Conda-forge MSYS2 Environment (Optional)
If you prefer managing dependencies with conda, you can provision an MSYS2 toolchain via conda-forge:
```bash
conda create -n rmnpy-win python=3.12 pip m2-msys2-runtime m2-gcc m2-gcc-fortran m2-openblas m2-lapack m2-curl m2-make virtualenv -c conda-forge
conda activate rmnpy-win
# (Optional) isolate further via virtualenv within conda env:
python -m venv venv
source venv/bin/activate
pip install -e .[test]
```
## Quick Start
```python
from rmnpy.sitypes import Scalar, Unit, Dimensionality
# === Flexible Scalar Creation ===
# Single string expressions (value + unit)
energy = Scalar("100 J") # 100 Joules
velocity = Scalar("25 m/s") # 25 meters per second
# Single numeric values (dimensionless)
ratio = Scalar(0.75) # 0.75 (dimensionless)
count = Scalar(42) # 42 (dimensionless)
impedance = Scalar(3+4j) # Complex number
# Value and unit pairs
distance = Scalar(100, "m") # 100 meters
power = Scalar(2.5, "W") # 2.5 Watts
current = Scalar(3+4j, "A") # Complex current
# Named parameters
unit_meter = Scalar(expression="m") # 1 meter
force = Scalar(value=9.8, expression="kg*m/s^2") # 9.8 Newtons
# === Scientific Calculations with Automatic Units ===
# Basic physics calculations
time = Scalar(2, "s")
speed = distance / time # Result: 50 m/s (automatic unit derivation)
acceleration = Scalar(9.8, "m/s^2")
force = Scalar(5, "kg") * acceleration # Result: 49 N (automatic units)
# Unit conversions
speed_kmh = speed.to("km/h") # Convert to km/h
speed_si = speed.to_coherent_si() # Convert to SI base units
# === Dimensional Analysis & Safety ===
# Automatic dimensional validation
try:
invalid = distance + time # Error: cannot add length + time
except RMNError:
print("Dimensional mismatch caught!")
# Complex calculations with unit tracking
kinetic_energy = 0.5 * Scalar(2, "kg") * speed**2 # Result: 2500 J
# === Unit and Dimensionality Operations ===
# Create and manipulate units
meter = Unit("m")
second = Unit("s")
velocity_unit = meter / second # Result: m/s
# Dimensional analysis
length_dim = Dimensionality.for_quantity(kSIQuantityLength)
time_dim = Dimensionality.for_quantity(kSIQuantityTime)
velocity_dim = length_dim / time_dim # Result: L/T
print(f"Speed: {speed}") # "50 m/s"
print(f"Unit: {speed.unit}") # "m/s"
print(f"Dimensionality: {speed.dimensionality}") # "L/T"
```
## Development
This package is built using Cython to provide efficient bindings to the underlying C libraries.
### Setting up the development environment
1. **Create conda environment:**
```bash
conda env create -f environment-dev.yml
conda activate rmnpy
```
2. **Sync libraries from local development:**
```bash
make synclib # Copy libraries from local ../OCTypes, ../SITypes, ../RMNLib
```
3. **Install in development mode:**
```bash
pip install -e .
```
### Building from source
```bash
git clone https://github.com/pjgrandinetti/RMNpy.git
cd RMNpy
conda env create -f environment.yml
conda activate rmnpy
make synclib # Copy libraries from local development
pip install -e .
```
### Makefile targets
- `make synclib` - Copy libraries from local ../OCTypes, ../SITypes, ../RMNLib directories
- `make download-libs` - Download libraries from GitHub releases (future feature)
- `make clean` - Remove generated C files and build artifacts
- `make clean-libs` - Remove local libraries to force re-download
- `make rebuild` - Clean libraries and rebuild Python package
- `make test` - Run the test suite
- `make status` - Check library status
See **[docs/development/DEVELOPMENT.md](docs/development/DEVELOPMENT.md)** for complete development workflows.
## Documentation
### User Documentation
- **API Documentation**: [Read the Docs](https://rmnpy.readthedocs.io) (when available)
### Development Documentation
- **[docs/development/README.md](docs/development/README.md)** - Navigation guide for all development docs
- **[docs/development/NEW_COMPUTER_SETUP.md](docs/development/NEW_COMPUTER_SETUP.md)** - Quick setup guide
- **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** - Detailed setup + troubleshooting
- **[docs/development/DEVELOPMENT.md](docs/development/DEVELOPMENT.md)** - Development workflow
- **[docs/development/RMNpy_Implementation_Plan.md](docs/development/RMNpy_Implementation_Plan.md)** - Project plan & progress
## License
See LICENSE file for details.
## Contributing
Contributions are welcome! Please see the development documentation for guidelines.
# Trigger CI after Unit test fix
Raw data
{
"_id": null,
"home_page": null,
"name": "rmnpy",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": "Philip Grandinetti <grandinetti.1@osu.edu>",
"keywords": "scientific-computing, units, dimensional-analysis, nmr, spectroscopy, physics, chemistry, c-extensions, cython",
"author": null,
"author_email": "Philip Grandinetti <grandinetti.1@osu.edu>",
"download_url": "https://files.pythonhosted.org/packages/61/2a/72f8c031405162c942dd0a295c822024d2e96fe84e5c586926a811996c41/rmnpy-0.2.0.tar.gz",
"platform": null,
"description": "# RMNpy\n\nPython bindings for OCTypes, SITypes, and RMNLib C libraries.\n\n\n\n> **\ud83d\ude80 Setting up on a new computer?** See **[docs/development/NEW_COMPUTER_SETUP.md](docs/development/NEW_COMPUTER_SETUP.md)** for quick setup or **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** for detailed instructions.\n\n## Overview\n\nRMNpy provides Python access to three scientific computing C libraries:\n\n- **OCTypes**: Objective-C style data structures and memory management\n- **SITypes**: Scientific units and dimensional analysis\n- **RMNLib**: High-level analysis and computation tools\n\n## Features\n\n- Type-safe conversion between Python and C data structures\n- Scientific units and dimensional analysis\n- High-performance numerical computations\n- Memory-safe interface to C libraries\n\n## Installation\n\n### For Development (Recommended)\n\nSee **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** for complete instructions.\n\nQuick version:\n```bash\n# Clone the repo with all C libraries\ngit clone https://github.com/pjgrandinetti/OCTypes-SITypes.git\ncd OCTypes-SITypes\n\n# Build required C libraries first\ncd OCTypes && make && make install && cd ..\ncd SITypes && make && make synclib && make install && cd ..\ncd RMNLib && make && make synclib && make install && cd ..\n\n# Set up Python environment\ncd RMNpy\nconda env create -f environment.yml\nconda activate rmnpy\npip install -e .\n```\n\n### For End Users (When Available)\n\n```bash\npip install rmnpy\n```\n\n**Platform Support:**\n- ## Requirements\n\n- **Linux/macOS**: Python 3.11-3.12\n- **Windows**: Python 3.12 only (requires MSYS2 environment)\n\n### Windows (MSYS2/Mingw-w64 Python)\n\nTo install RMNpy with C99-based Cython extensions on Windows you must use the MSYS2 MINGW64 Python runtime:\n\n1. Install [MSYS2](https://www.msys2.org/) and open the **MSYS2 MinGW64** shell.\n2. Update packages and install dependencies:\n\n ```bash\n pacman -Syu # first-time update\n pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-python-pip \\\n mingw-w64-x86_64-openblas mingw-w64-x86_64-lapack \\\n mingw-w64-x86_64-curl mingw-w64-x86_64-make\n ```\n\n3. Create and activate a virtual environment (so pip can install into it):\n\n ```bash\n python -m pip install --upgrade pip virtualenv\n python -m virtualenv venv\n source venv/bin/activate\n ```\n\n4. Install RMNpy and test extras:\n\n ```bash\n pip install numpy pytest pytest-cov\n pip install -e .[test]\n ```\n\n5. Run your scripts or pytest from this venv; it uses MinGW-built extensions compatible with Windows.\n\n#### Using Conda-forge MSYS2 Environment (Optional)\nIf you prefer managing dependencies with conda, you can provision an MSYS2 toolchain via conda-forge:\n\n```bash\nconda create -n rmnpy-win python=3.12 pip m2-msys2-runtime m2-gcc m2-gcc-fortran m2-openblas m2-lapack m2-curl m2-make virtualenv -c conda-forge\nconda activate rmnpy-win\n# (Optional) isolate further via virtualenv within conda env:\npython -m venv venv\nsource venv/bin/activate\npip install -e .[test]\n```\n\n## Quick Start\n\n```python\nfrom rmnpy.sitypes import Scalar, Unit, Dimensionality\n\n# === Flexible Scalar Creation ===\n\n# Single string expressions (value + unit)\nenergy = Scalar(\"100 J\") # 100 Joules\nvelocity = Scalar(\"25 m/s\") # 25 meters per second\n\n# Single numeric values (dimensionless)\nratio = Scalar(0.75) # 0.75 (dimensionless)\ncount = Scalar(42) # 42 (dimensionless)\nimpedance = Scalar(3+4j) # Complex number\n\n# Value and unit pairs\ndistance = Scalar(100, \"m\") # 100 meters\npower = Scalar(2.5, \"W\") # 2.5 Watts\ncurrent = Scalar(3+4j, \"A\") # Complex current\n\n# Named parameters\nunit_meter = Scalar(expression=\"m\") # 1 meter\nforce = Scalar(value=9.8, expression=\"kg*m/s^2\") # 9.8 Newtons\n\n# === Scientific Calculations with Automatic Units ===\n\n# Basic physics calculations\ntime = Scalar(2, \"s\")\nspeed = distance / time # Result: 50 m/s (automatic unit derivation)\nacceleration = Scalar(9.8, \"m/s^2\")\nforce = Scalar(5, \"kg\") * acceleration # Result: 49 N (automatic units)\n\n# Unit conversions\nspeed_kmh = speed.to(\"km/h\") # Convert to km/h\nspeed_si = speed.to_coherent_si() # Convert to SI base units\n\n# === Dimensional Analysis & Safety ===\n\n# Automatic dimensional validation\ntry:\n invalid = distance + time # Error: cannot add length + time\nexcept RMNError:\n print(\"Dimensional mismatch caught!\")\n\n# Complex calculations with unit tracking\nkinetic_energy = 0.5 * Scalar(2, \"kg\") * speed**2 # Result: 2500 J\n\n# === Unit and Dimensionality Operations ===\n\n# Create and manipulate units\nmeter = Unit(\"m\")\nsecond = Unit(\"s\")\nvelocity_unit = meter / second # Result: m/s\n\n# Dimensional analysis\nlength_dim = Dimensionality.for_quantity(kSIQuantityLength)\ntime_dim = Dimensionality.for_quantity(kSIQuantityTime)\nvelocity_dim = length_dim / time_dim # Result: L/T\n\nprint(f\"Speed: {speed}\") # \"50 m/s\"\nprint(f\"Unit: {speed.unit}\") # \"m/s\"\nprint(f\"Dimensionality: {speed.dimensionality}\") # \"L/T\"\n```\n\n## Development\n\nThis package is built using Cython to provide efficient bindings to the underlying C libraries.\n\n### Setting up the development environment\n\n1. **Create conda environment:**\n\n ```bash\n conda env create -f environment-dev.yml\n conda activate rmnpy\n ```\n\n2. **Sync libraries from local development:**\n\n ```bash\n make synclib # Copy libraries from local ../OCTypes, ../SITypes, ../RMNLib\n ```\n\n3. **Install in development mode:**\n\n ```bash\n pip install -e .\n ```\n\n### Building from source\n\n```bash\ngit clone https://github.com/pjgrandinetti/RMNpy.git\ncd RMNpy\nconda env create -f environment.yml\nconda activate rmnpy\nmake synclib # Copy libraries from local development\npip install -e .\n```\n\n### Makefile targets\n\n- `make synclib` - Copy libraries from local ../OCTypes, ../SITypes, ../RMNLib directories\n- `make download-libs` - Download libraries from GitHub releases (future feature)\n- `make clean` - Remove generated C files and build artifacts\n- `make clean-libs` - Remove local libraries to force re-download\n- `make rebuild` - Clean libraries and rebuild Python package\n- `make test` - Run the test suite\n- `make status` - Check library status\n\nSee **[docs/development/DEVELOPMENT.md](docs/development/DEVELOPMENT.md)** for complete development workflows.\n\n## Documentation\n\n### User Documentation\n\n- **API Documentation**: [Read the Docs](https://rmnpy.readthedocs.io) (when available)\n\n### Development Documentation\n\n- **[docs/development/README.md](docs/development/README.md)** - Navigation guide for all development docs\n- **[docs/development/NEW_COMPUTER_SETUP.md](docs/development/NEW_COMPUTER_SETUP.md)** - Quick setup guide\n- **[docs/development/ENVIRONMENT_SETUP.md](docs/development/ENVIRONMENT_SETUP.md)** - Detailed setup + troubleshooting\n- **[docs/development/DEVELOPMENT.md](docs/development/DEVELOPMENT.md)** - Development workflow\n- **[docs/development/RMNpy_Implementation_Plan.md](docs/development/RMNpy_Implementation_Plan.md)** - Project plan & progress\n\n## License\n\nSee LICENSE file for details.\n\n## Contributing\n\nContributions are welcome! Please see the development documentation for guidelines.\n# Trigger CI after Unit test fix\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python bindings for OCTypes, SITypes, and RMNLib C libraries for scientific computing with units and dimensional analysis",
"version": "0.2.0",
"project_urls": {
"Bug Reports": "https://github.com/pjgrandinetti/RMNpy/issues",
"CI/CD": "https://github.com/pjgrandinetti/RMNpy/actions",
"Changelog": "https://github.com/pjgrandinetti/RMNpy/blob/master/CHANGELOG.md",
"Documentation": "https://rmnpy.readthedocs.io",
"Homepage": "https://github.com/pjgrandinetti/RMNpy",
"Repository": "https://github.com/pjgrandinetti/RMNpy",
"Source Code": "https://github.com/pjgrandinetti/RMNpy"
},
"split_keywords": [
"scientific-computing",
" units",
" dimensional-analysis",
" nmr",
" spectroscopy",
" physics",
" chemistry",
" c-extensions",
" cython"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "346a39becc648155ba9561e4296385c6715399ef5541ff8f35bab3e71a1bb742",
"md5": "3d348c2a69ae6c3c548bcfe78d462a05",
"sha256": "75da12654f4188c03cb0a12e045eefd387f2fa7c1d81b02da34cad79e33d3bc1"
},
"downloads": -1,
"filename": "rmnpy-0.2.0-cp311-cp311-macosx_13_0_arm64.whl",
"has_sig": false,
"md5_digest": "3d348c2a69ae6c3c548bcfe78d462a05",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.11",
"size": 1881260,
"upload_time": "2025-08-22T17:48:15",
"upload_time_iso_8601": "2025-08-22T17:48:15.016172Z",
"url": "https://files.pythonhosted.org/packages/34/6a/39becc648155ba9561e4296385c6715399ef5541ff8f35bab3e71a1bb742/rmnpy-0.2.0-cp311-cp311-macosx_13_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a2ed6fa5d090661dfdbbdaca3a132933257449a361f23cab5f51ca87a11d7c13",
"md5": "66ee3c15776c3ccf2ad6cfecd1753941",
"sha256": "82540fe0dc016cefa744e731b471dfdfedf9a5b37b6da8e12d0b8a02cd4b1dee"
},
"downloads": -1,
"filename": "rmnpy-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "66ee3c15776c3ccf2ad6cfecd1753941",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.11",
"size": 20065827,
"upload_time": "2025-08-22T17:48:16",
"upload_time_iso_8601": "2025-08-22T17:48:16.805835Z",
"url": "https://files.pythonhosted.org/packages/a2/ed/6fa5d090661dfdbbdaca3a132933257449a361f23cab5f51ca87a11d7c13/rmnpy-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a63b15e9edfe40c1f96161282631e650f3f80993315b7a78a3e030923db190f3",
"md5": "12b8c553f4e6fd785093210aee7be3b0",
"sha256": "b7595c718aa6de17ad3133201ce4586cab2cd65ceca2dca0ce067fa46122e133"
},
"downloads": -1,
"filename": "rmnpy-0.2.0-cp312-cp312-macosx_13_0_arm64.whl",
"has_sig": false,
"md5_digest": "12b8c553f4e6fd785093210aee7be3b0",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.11",
"size": 1869464,
"upload_time": "2025-08-22T17:48:18",
"upload_time_iso_8601": "2025-08-22T17:48:18.962656Z",
"url": "https://files.pythonhosted.org/packages/a6/3b/15e9edfe40c1f96161282631e650f3f80993315b7a78a3e030923db190f3/rmnpy-0.2.0-cp312-cp312-macosx_13_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ec7dc296a8e4eed7d1b691274b18d45b79fbcfc9c1daa93035f5579f52f9d506",
"md5": "58953dba57ae6a3c7989a268670b5248",
"sha256": "4d6bcf0bf3cc816cf34ba31e75045ba7c441fdc0b3dc932891fb49bb51c86567"
},
"downloads": -1,
"filename": "rmnpy-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "58953dba57ae6a3c7989a268670b5248",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.11",
"size": 19953684,
"upload_time": "2025-08-22T17:48:20",
"upload_time_iso_8601": "2025-08-22T17:48:20.368539Z",
"url": "https://files.pythonhosted.org/packages/ec/7d/c296a8e4eed7d1b691274b18d45b79fbcfc9c1daa93035f5579f52f9d506/rmnpy-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "612a72f8c031405162c942dd0a295c822024d2e96fe84e5c586926a811996c41",
"md5": "55007f9923990a3d77cd2a29438d377c",
"sha256": "dc2b464cd60bc03a518c2ae3ed496e10d3c480da947ed7cb33c7f491ec299b81"
},
"downloads": -1,
"filename": "rmnpy-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "55007f9923990a3d77cd2a29438d377c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 1048236,
"upload_time": "2025-08-22T17:48:22",
"upload_time_iso_8601": "2025-08-22T17:48:22.740256Z",
"url": "https://files.pythonhosted.org/packages/61/2a/72f8c031405162c942dd0a295c822024d2e96fe84e5c586926a811996c41/rmnpy-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-22 17:48:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pjgrandinetti",
"github_project": "RMNpy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "build",
"specs": []
},
{
"name": "wheel",
"specs": []
},
{
"name": "Cython",
"specs": [
[
">=",
"0.29.36"
]
]
},
{
"name": "numpy",
"specs": [
[
">=",
"1.23"
]
]
},
{
"name": "numpy",
"specs": [
[
">=",
"1.26"
]
]
},
{
"name": "pytest",
"specs": []
},
{
"name": "pytest-cov",
"specs": []
},
{
"name": "sphinx",
"specs": []
},
{
"name": "sphinx-rtd-theme",
"specs": []
},
{
"name": "breathe",
"specs": []
},
{
"name": "myst-parser",
"specs": []
},
{
"name": "sphinx-copybutton",
"specs": []
}
],
"lcname": "rmnpy"
}