Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,24 @@ on: [pull_request, push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
- uses: conda-incubator/setup-miniconda@v3
with:
python-version: ${{ matrix.python }}

- uses: julia-actions/setup-julia@v2
with:
version: '1.10'

- uses: julia-actions/cache@v2
environment-file: environment.yml
auto-activate-base: false
miniforge-version: latest
use-mamba: true

- name: Install MAGEMin_C
run: julia -e 'using Pkg; Pkg.add("MAGEMin_C")'
shell: bash -l {0}
run: phasetools-julia-setup --install

- name: Install phasetools
run: python -m pip install -e .
- name: Verify environment
shell: bash -l {0}
run: phasetools-julia-setup --check

- name: Run tests
shell: bash -l {0}
run: python -m unittest discover tests -v
14 changes: 12 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@

## Quick start

**Conda / mamba (Linux & CI):**
```bash
mamba env create -f environment.yml
conda activate phasetools
phasetools-julia-setup --install
phasetools-julia-setup --check
```

**pip + juliaup (cross-platform, incl. macOS):**
```bash
python -m pip install -e .
phasetools-julia-setup --check # verify Julia + MAGEMin_C
phasetools-julia-setup --install # install MAGEMin_C in Julia
phasetools-julia-setup --check # verify Julia + MAGEMin_C
python3 -m unittest discover tests # run all tests (mock-based, no Julia needed)
```

Expand Down Expand Up @@ -282,9 +291,10 @@ The `ox.count("O")` bug undercounts oxygen, inflating the6-O scale factor by ~60
- Files: `test_redox_logic.py`, `test_site_occupancy.py`, `test_fe_basis.py`, `test_fractionation.py`, `test_iron_oxide_conversions.py`, `test_solvus_instances.py`, `test_lmo_fix.py`.
- New public functions must be documented in the **directory's README.md** (e.g., `calculators/README.md`, `core/README.md`) **and** the package structure above must be updated.

## Requirements (from `setup.py`)
## Requirements (from `pyproject.toml`)

`pandas`, `numpy`, `matplotlib`, `scipy`, `molmass`, `juliacall`. Python ≥ 3.10.
Extras: `[jupyter]` (jupyterlab, ipykernel, nbconvert), `[dev]` (ruff).

## Tutorials

Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,29 @@

## 📦 Installation

### 1. Python Package
Install `phasetools` in editable mode from the repository root:
### 1. Conda / mamba (Linux & CI)

```bash
python -m pip install -e .
mamba env create -f environment.yml
conda activate phasetools
phasetools-julia-setup --install
phasetools-julia-setup --check
```

### 2. Julia Environment Setup
`phasetools` requires Julia and the `MAGEMin_C` package. Use the built-in helper to check your environment:
*Note: On macOS (especially Apple Silicon), conda-forge's `julia` package is unavailable — use the pip + juliaup path below instead.*

### 2. pip + juliaup (cross-platform, incl. macOS)

```bash
python -m pip install -e .
phasetools-julia-setup --check
phasetools-julia-setup --install
```

If `MAGEMin_C` is missing, install it automatically:
To also install Jupyter (for tutorials) and dev tooling (ruff):

```bash
phasetools-julia-setup --install
python -m pip install -e ".[jupyter,dev]"
```

*Note: If Julia is not installed on your system, please download it from [julialang.org](https://julialang.org/downloads/).*
Expand Down
11 changes: 7 additions & 4 deletions Tutorials/Garnet/1-Functionality_overview.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
"metadata": {},
"outputs": [],
"source": [
"from phasetools import MAGEMinGarnetCalculator\n",
"import juliacall\n",
"import matplotlib.pyplot as plt"
"import matplotlib.pyplot as plt\n",
"\n",
"from phasetools import MAGEMinGarnetCalculator"
]
},
{
Expand Down Expand Up @@ -207,6 +207,7 @@
"outputs": [],
"source": [
"from phasetools.utils import create_PTt_path\n",
"\n",
"P = [5., 6., 7., 8., 9., 10.] # kbar\n",
"T = [500., 600., 700., 800., 900., 1000.] # °C\n",
"t = [1., 2., 3., 4., 5., 6.] # Myr\n",
Expand Down Expand Up @@ -290,7 +291,9 @@
"metadata": {},
"outputs": [],
"source": [
"from juliacall import Main as jl, convert as jlconvert\n",
"from juliacall import Main as jl\n",
"from juliacall import convert as jlconvert\n",
"\n",
"rm_j = jlconvert(jl.Vector[jl.String], ['chl'])\n",
"rmp_MM = MAGEMin_C.remove_phases(rm_j, 'mp')"
]
Expand Down
14 changes: 7 additions & 7 deletions Tutorials/Garnet/2-Overlapping_isopleths.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from phasetools import PhasePTEstimator\n",
"from phasetools.utils import *\n",
"import phasetools\n",
"import os\n",
"\n",
"from juliacall import Main as jl, convert as jlconvert"
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"from phasetools import PhasePTEstimator\n",
"from phasetools.utils import *"
]
},
{
Expand Down Expand Up @@ -122,6 +121,7 @@
"outputs": [],
"source": [
"from phasetools import MAGEMinGarnetCalculator\n",
"\n",
"garnet_calculator = MAGEMinGarnetCalculator(db=db, dataset=636)\n",
"garnet_calculator.setup_bulk_composition(Xoxides, X, sys_in=sys_in)\n",
"\n",
Expand Down
9 changes: 3 additions & 6 deletions Tutorials/Garnet/3-Garnet_cpx_thermometry.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,10 @@
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"from phasetools import MAGEMinPTGridCalculator\n",
"\n",
"from phasetools import MAGEMin_C\n",
"from juliacall import Main as jl, convert as jlconvert"
"from phasetools import MAGEMinPTGridCalculator"
]
},
{
Expand Down Expand Up @@ -569,7 +566,7 @@
"source": [
"from phasetools.core.phase_properties import get_phase_fe_split\n",
"\n",
"for i in range(0, 5):\n",
"for i in range(5):\n",
" i0 = int(np.flatnonzero(valid)[i]) # first valid grid point\n",
" o0 = out[i0]\n",
" cpx_split = get_phase_fe_split(o0, cpx)\n",
Expand Down
7 changes: 3 additions & 4 deletions Tutorials/General/1-Getting_started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import juliacall\n",
"from juliacall import Main as jl, convert as jlconvert\n",
"import phasetools\n",
"from juliacall import Main as jl\n",
"from juliacall import convert as jlconvert\n",
"\n",
"from phasetools import MAGEMin_C"
]
},
Expand Down
6 changes: 4 additions & 2 deletions Tutorials/General/2-Determining_fractions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
"outputs": [],
"source": [
"import numpy as np\n",
"import juliacall\n",
"from juliacall import Main as jl, convert as jlconvert\n",
"\n",
"import phasetools\n",
"from phasetools import MAGEMin_C"
]
Expand Down Expand Up @@ -103,6 +102,7 @@
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"plt.plot(temp, liq_frac_vals, c='k', ls=':')\n",
"plt.scatter(liquidus_T, 1, marker='x', c='red', label='Liquidus')\n",
"plt.scatter(solidus_T, 0, marker='x', c='green', label='Solidus')\n",
Expand Down Expand Up @@ -192,6 +192,7 @@
"source": [
"from scipy.optimize import root_scalar\n",
"\n",
"\n",
"def melt_fraction(T):\n",
" out = MAGEMin_C.single_point_minimization(P, T, data)\n",
" return phasetools.phase_frac(phase=\"liq\", MAGEMinOutput=out, sys_in='mol')\n",
Expand Down Expand Up @@ -241,6 +242,7 @@
"outputs": [],
"source": [
"from phasetools import PhaseFunctions\n",
"\n",
"phaseFunctions = PhaseFunctions(db=db, dataset=636)\n",
"phaseFunctions.setup_bulk_composition(list(out.oxides), list(out.bulk), sys_in='mol')"
]
Expand Down
5 changes: 2 additions & 3 deletions Tutorials/General/3-Lunar_Magma_Ocean.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from phasetools.models.magma_ocean import MagmaOcean\n",
"import sys"
"\n",
"from phasetools.models.magma_ocean import MagmaOcean"
]
},
{
Expand Down
10 changes: 10 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: phasetools
channels:
- conda-forge
- nodefaults
dependencies:
- python=3.11
- julia
- pip
- pip:
- -e ".[jupyter,dev]"
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "phasetools"
version = "0.1.0"
description = "A python package to perform MAGEMin calculations in python"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.10"
authors = [{ name = "Ben Knight", email = "ben.knight@curtin.edu.au" }]
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Scientific/Engineering",
"Natural Language :: English",
]
dependencies = [
"pandas>=1.0.0",
"numpy>=1.18.0",
"matplotlib>=3.0.0",
"scipy>=1.4.0",
"molmass>=2024.0.0",
"juliacall>=0.9",
]

[project.optional-dependencies]
jupyter = ["jupyterlab", "ipykernel", "nbconvert"]
dev = ["ruff"]

[project.scripts]
phasetools-julia-setup = "phasetools.julia_setup:main"

[tool.setuptools.packages.find]
where = ["src"]

[tool.ruff]
extend-exclude = ["Tutorials"]
38 changes: 0 additions & 38 deletions setup.py

This file was deleted.

Loading
Loading