Skip to content
Merged
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
7 changes: 0 additions & 7 deletions .flake8

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
run: ruff format --check .

- name: mypy
run: mypy .
run: mypy ./src

# ---- Tests ----
- name: Run tests
Expand Down
159 changes: 1 addition & 158 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,158 +1 @@
# template-python-lib

A minimal, modern **Python library template** designed to jumpstart your project with best practices and tooling.

---

## 🚀 Quick start: using this template

### 1. Create a new repository
- Via GitHub UI:
Click **Use this template** → create `my-awesome-lib`
- Or via CLI:
```bash
gh repo create your-org/my-awesome-lib --template JaLuka98/template-python-lib --public
```

### 2. Clone your new repo and enter it
```bash
git clone https://github.com/your-org/my-awesome-lib.git
cd my-awesome-lib
```

### 3. Apply required customisations
Before you start developing, update the following items in your new project:

| Item | Where to change | Notes |
|-----------------------------|-----------------------------------------------------|-------------------------------------------------|
| Package name | `src/template_python_lib/` → `src/your_package/` | Rename the directory and update all references |
| Import paths | All source and test files | Replace `template_python_lib` with your package |
| Package metadata | `pyproject.toml`, `setup.cfg` | Update name, author, description, etc. |
| Version | `pyproject.toml`, `setup.cfg` | Optionally set initial version |
| License | `pyproject.toml`, `setup.cfg`, LICENSE | Choose and update license as needed |
| README | `README.md` | Update project name and description |
| Documentation | `docs/` | Update Sphinx config and docstrings |

### 4. Set up your environment
Set up the necessary packages in an environment of your choice:
```bash
<activate_your_environment>
pip install -e .[dev]
```

### 5. Run tests to verify setup
```bash
pytest
```

---

## 📂 Project structure

```plaintext
.
├── src/
│ └── template_python_lib/ # Your package source code
├── tests/ # Test suite
├── docs/ # Sphinx documentation source
├── .github/workflows/ # GitHub Actions CI workflows
├── .pre-commit-config.yaml # Pre-commit hooks configuration
├── pyproject.toml # Build system and tool configurations
├── setup.cfg # Package metadata and settings
├── requirements-dev.txt # Development dependencies
└── README.md # This file
```

---

## 🛠️ Local development

- Use the `src` layout to avoid import conflicts.
- Install dev dependencies with `pip install -e .[dev]`.
- Run tests with `pytest`.
- Type-check your code with `mypy`.
- Lint your code with `ruff`.

---

## 🎨 Linting & formatting

- **Ruff** handles linting and formatting checks.
- Run lint checks manually with:
```bash
ruff check src tests
```

---

## 🔧 Pre-commit hooks

- Pre-commit hooks run automatically before each commit to catch issues early.
- Set up pre-commit by running:
```bash
pre-commit install
```
- Hooks include:
- Ruff linting
- Adding trailing whitespaces

---

## 📦 Versioning

- Uses **CalVer** (Calendar Versioning) format: `YYYY.MM.PATCH` (e.g., `2025.09.0`).
- Version is managed with [bump-my-version](https://github.com/callowayproject/bump-my-version).
- Bump versions with:
```bash
bump-my-version patch
```
or with the dedicated GitHub action.

---

## 📚 Documentation

- Documentation is built with **Sphinx**.
- Source files are in the `docs/` directory.
- Ready for hosting on Read the Docs.
- Build docs locally with:
```bash
cd docs
make html
```

---

## ⚙️ Continuous Integration (CI)

- GitHub Actions workflows automate:
- Linting and type-checking.
- Running tests on multiple Python versions.
- Ensures code quality and consistency on every push and pull request.

---

## 🤔 Rationale

This template aims to provide a minimal yet modern starting point for Python libraries, incorporating:

- Best practices like the `src` layout to avoid import pitfalls.
- Automated tooling for testing, linting, formatting, and type checking.
- Pre-commit hooks to maintain code quality from the start.
- Clear versioning strategy with CalVer.
- Documentation setup ready for expansion and publishing.

---

## 🤝 Contributing

Contributions are welcome! Please:

- Follow the existing code style and conventions.
- Run tests and linting before submitting PRs.
- Use the pre-commit hooks to catch issues early.
- Update this README as needed.

---

Thank you for using this template — happy coding!
# NPKit
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
import sys
import importlib

project = "template-python-lib"
project = "NPKit"
try:
__version__ = importlib.import_module("template_python_lib").__version__
__version__ = importlib.import_module("npkit").__version__
except Exception:
__version__ = "0.0.0"
sys.path.insert(0, os.path.abspath("../../src"))

project = "template-python-lib"
project = "NPKit"
copyright = "2025, Jan Lukas Späh"
author = "Jan Lukas Späh"
release = __version__
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.. CPax documentation master file, created by
.. NPkit documentation master file, created by
sphinx-quickstart on Mon Mar 31 23:52:35 2025.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

CPax documentation
NPKit documentation
==================

Add your content using ``reStructuredText`` syntax. See the
Expand Down
60 changes: 60 additions & 0 deletions examples/minimal_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import numpy as np
from npkit import (
Observable,
ObservableSet,
GaussianModel,
GaussianLikelihood,
)
from npkit import build_belt, invert_belt
import matplotlib.pyplot as plt
from npkit.plot import plot_belt

# Model: two observables
obs = ObservableSet(
[
Observable("xsec1", lambda p: 100 + 10 * p["C"] ** 2),
]
)

V = np.array([100])

model = GaussianModel(obs=obs, covariance=V)

# Observed data (example)
y_obs = 100
# data = Combination(names=obs.names, values=y_obs, covariance=V)


def like_builder():
return GaussianLikelihood(obs, y_obs, V)


start = {"C": 0.0}
# bounds = {"C": (-1e6, 1e6)}
bounds = None
rng = np.random.default_rng(123)

# Build a 68% belt
grid = np.linspace(-2, 2, 51)
belt = build_belt(
param="C",
model=model,
like_builder=like_builder,
grid=grid,
n_toys=3000,
alpha=1 - 0.6827,
rng=rng,
start=start,
bounds=bounds,
)

print(belt)

# Invert for observed interval
interval = invert_belt(belt, like_builder=like_builder, start=start, bounds=bounds)
print("Neyman CI:", interval)

# Visualize the Neyman belt
ax = plot_belt(belt)
ax.set_title("Neyman Belt Visualization")
plt.show()
52 changes: 52 additions & 0 deletions examples/multiple_observable_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import numpy as np
from npkit import (
Observable,
ObservableSet,
Combination,
GaussianModel,
GaussianLikelihood,
)
from npkit import build_belt, invert_belt

# Model: two observables
obs = ObservableSet(
[
Observable("xsec1", lambda p: 1.0 + 0.4 * p["C"]),
Observable("xsec2", lambda p: 0.8 - 0.2 * p["C"]),
]
)

V = np.array([[0.04**2, 0.5 * 0.04 * 0.05], [0.5 * 0.04 * 0.05, 0.05**2]])

model = GaussianModel(obs=obs, covariance=V)

# Observed data (example)
y_obs = np.array([1.05, 0.78])
data = Combination(names=obs.names, values=y_obs, covariance=V)


def like_builder():
return GaussianLikelihood(obs, y_obs, V)


start = {"C": 0.0}
bounds = {"C": (-2.0, 2.0)}
rng = np.random.default_rng(123)

# Build a 68% belt
grid = np.linspace(-2, 2, 161)
belt = build_belt(
param="C",
model=model,
like_builder=like_builder,
grid=grid,
n_toys=1000,
alpha=1 - 0.6827,
rng=rng,
start=start,
bounds=bounds,
)

# Invert for observed interval
interval = invert_belt(belt, like_builder=like_builder, start=start, bounds=bounds)
print("Neyman CI:", interval)
18 changes: 0 additions & 18 deletions examples/root_finding_example.py

This file was deleted.

28 changes: 22 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ requires = ["setuptools>=65.5", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "template-python-lib"
name = "NPKit"
version = "2025.09.0"
description = "template-python-lib: A template repository for modern python packages."
description = "NPKit: Toolkit for frequentist interpretations and inference."
authors = [
{ name = "Jan Lukas Späh", email = "[email protected]" }
]
Expand All @@ -19,7 +19,7 @@ classifiers = [
]

dependencies = [
"numpy>=2.0",
"numpy>=2.0", "scipy>=1.16"
]

[project.optional-dependencies]
Expand All @@ -28,12 +28,28 @@ dev = ["bump-my-version>=1.2", "ruff>=0.6", "pre-commit>=3.8", "mypy>=1.11"]
docs = ["sphinx>=7", "sphinx-rtd-theme", "sphinx-autodoc-typehints", "sphinx-autoapi", "myst-parser"]

[project.urls]
Homepage = "https://github.com/JaLuka98/template-python-lib"
Issues = "https://github.com/JaLuka98/template-python-lib/issues"
Source = "https://github.com/JaLuka98/template-python-lib"
Homepage = "https://github.com/JaLuka98/NPKit"
Issues = "https://github.com/JaLuka98/NPKit/issues"
Source = "https://github.com/JaLuka98/NPKit"

[tool.setuptools]
package-dir = {"" = "src"}

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

[tool.mypy]
python_version = "3.12"
strict = true
exclude = ["^docs/", "^examples/"]

warn_unused_ignores = true
warn_redundant_casts = true
warn_unreachable = true

[[tool.mypy.overrides]]
module = [
"scipy.*",
"matplotlib.*",
]
ignore_missing_imports = true
Loading