Macenko PCA
High-performance stain matrix estimation and colour deconvolution for histology images using the Macenko PCA method, with the compute-intensive core written in Rust via PyO3.
Supported platforms: Linux and macOS only. Windows is not supported due to differences in BLAS/LAPACK / OpenBLAS builds that can cause numerical and linking inconsistencies; to ensure reproducible numerical results we build and test only on Linux and macOS.
This implements the method described in:
Macenko, M. et al. "A method for normalizing histology slides for quantitative analysis." ISBI 2009.
And was based off the implementation from HistomicsTK
Performance improvements between the HistomicsTK implementation and this one are discussed here. We saw almost a quarter of the RAM usage and up to a 7x speedup in real world examples.
Features
| Feature | Detail |
|---|---|
| Performance | Core SVD, PCA projection, and angle binning run in compiled Rust with Rayon parallelism |
| Simple API | Six functions cover the full workflow — estimate stain vectors, decompose, and reconstruct |
| NumPy native | Accepts and returns standard NumPy arrays — no special data structures required |
| Precision-aware | Pass float32 arrays to halve RAM usage — the dtype of your input controls which Rust code path runs |
| Platform support | Built with maturin for Linux and macOS (x86_64 + arm64). Windows is not supported. |
Quick Start
Installation
pip install macenko-pca
Full Workflow Example
import numpy as np
from macenko_pca import (
rgb_separate_stains_macenko_pca,
rgb_color_deconvolution,
reconstruct_rgb,
)
# Load or create an RGB image (H×W×3, values in [0, 255])
im_rgb = np.random.rand(256, 256, 3) * 255.0
# 1. Estimate the 3×3 stain matrix from the image
stain_matrix = rgb_separate_stains_macenko_pca(im_rgb)
print("Stain matrix:\n", stain_matrix)
# 2. Decompose the image into per-stain concentration channels
concentrations = rgb_color_deconvolution(im_rgb, stain_matrix)
hematoxylin = concentrations[:, :, 0]
eosin = concentrations[:, :, 1]
residual = concentrations[:, :, 2]
# 3. Modify concentrations (e.g. isolate hematoxylin only)
concentrations_h_only = concentrations.copy()
concentrations_h_only[:, :, 1] = 0.0 # zero-out eosin
concentrations_h_only[:, :, 2] = 0.0 # zero-out residual
# 4. Reconstruct back to RGB
im_hematoxylin_only = reconstruct_rgb(concentrations_h_only, stain_matrix)
Step-by-Step API
from macenko_pca import (
rgb_to_sda,
separate_stains_macenko_pca,
color_deconvolution,
reconstruct_rgb,
)
# Convert RGB to SDA (Stain Density Absorbance) space
im_sda = rgb_to_sda(im_rgb)
# Estimate stain vectors from the SDA image
stain_matrix = separate_stains_macenko_pca(im_sda)
# Decompose SDA image into stain concentrations
concentrations = color_deconvolution(im_sda, stain_matrix)
# Reconstruct RGB from (possibly modified) concentrations
im_reconstructed = reconstruct_rgb(concentrations, stain_matrix)
Half the RAM — Use float32
# Simply cast your input to float32 — the Rust backend will use f32 throughout
im_rgb_f32 = im_rgb.astype(np.float32)
stain_matrix = rgb_separate_stains_macenko_pca(im_rgb_f32) # f32
concentrations = rgb_color_deconvolution(im_rgb_f32, stain_matrix) # f32
reconstructed = reconstruct_rgb(concentrations, stain_matrix) # f32
Precision / dtype rules
The dtype of your input array controls which Rust code path is taken:
| Input dtype | Computation dtype | Notes |
|---|---|---|
float64 |
f64 | Full precision (default for plain Python floats) |
float32 |
f32 | ≈ half the RAM — recommended when full precision is unnecessary |
float16 |
f32 | Promoted to f32 (no f16 LAPACK exists) |
| integer types | f64 | Promoted to f64 for backward compatibility |
The return array's dtype always matches the computation dtype.
API Reference
Stain Matrix Estimation
rgb_separate_stains_macenko_pca(im_rgb, ...)
End-to-end: takes an RGB image (H, W, 3) and returns a (3, 3) stain matrix.
separate_stains_macenko_pca(im_sda, ...)
Lower-level: operates on an image already in SDA space.
Colour Conversion
rgb_to_sda(im_rgb, ...)
Converts an RGB image or matrix to SDA (stain-density-absorbance) space.
Colour Deconvolution (Applying Stain Vectors)
color_deconvolution(im_sda, stain_matrix)
Decomposes an SDA image into per-stain concentration channels using the inverse of the stain matrix. Each output channel i holds the concentration of stain i.
rgb_color_deconvolution(im_rgb, stain_matrix, bg_int=None)
Convenience wrapper that converts RGB → SDA → concentrations in a single call.
Reconstruction
reconstruct_rgb(concentrations, stain_matrix, bg_int=None)
Reconstructs an RGB image from stain concentrations and a stain matrix. Inverts the deconvolution: SDA = concentrations × Wᵀ, then converts SDA back to RGB. Useful for stain normalisation workflows where you modify concentration channels and then reconstruct.
See the full API documentation for parameter details.
Development Setup
Prerequisites: Python 3.9+, a Rust toolchain, and Hatch.
On Linux you also need OpenBLAS development headers (libopenblas-dev on Debian/Ubuntu). On macOS: brew install openblas pkg-config.
git clone https://github.com/LavLabInfrastructure/macenko-pca.git
cd macenko-pca
pip install maturin hatch
maturin develop --release
Optionally install pre-commit hooks:
pip install pre-commit
pre-commit install
Common Commands
Run these directly or use the provided Makefile shortcuts (e.g. make test, make lint).
| Task | Command |
|---|---|
| Build Rust extension in-place | maturin develop --release |
| Run tests | make test |
| Tests + coverage | make cov |
| Lint Python | hatch run lint:check |
| Format Python | hatch run lint:format |
| Auto-fix lint | hatch run lint:fix |
| Format + fix + lint | hatch run lint:all |
| Type check | hatch run types:check |
| Build docs | hatch run docs:build-docs |
| Serve docs | hatch run docs:serve-docs |
| Build wheel | maturin build --release |
| Clean artifacts | make clean |
| Rust lints | make cargo-clippy |
| Rust tests | make cargo-test |
Docker
# Run tests via Docker
docker build --target maturin -t macenko-pca:maturin .
docker run --rm -e HATCH_ENV=test macenko-pca:maturin cov
# Production image (just the installed wheel)
docker build --target prod -t macenko-pca:prod .
Publishing to PyPI
This project uses trusted publishing (OIDC) — no API tokens or secrets are needed. The publish.yml workflow handles everything automatically.
One-Time Setup (PyPI)
- Go to https://pypi.org/manage/account/publishing/ (logged in as a maintainer of the lavlab org).
- Click "Add a new pending publisher" and fill in:
- PyPI project name:
macenko-pca - Owner:
lavlab(the GitHub organisation) - Repository:
macenko-pca - Workflow name:
publish.yml - Environment name:
pypi
- PyPI project name:
- (Optional) Repeat on TestPyPI with environment name
testpypito enable dry-run publishes.
One-Time Setup (GitHub)
- In the repository settings, go to Environments.
- Create an environment called
pypi.- Optionally add a protection rule requiring manual approval before publishing.
- (Optional) Create an environment called
testpypifor test publishes.
How to Release
# 1. Bump the version in src/macenko_pca/__about__.py and Cargo.toml
# 2. Commit and tag
git add -A
git commit -m "release: v0.2.0"
git tag v0.2.0
git push && git push --tags
# 3. Create a GitHub Release from the tag (via the web UI or `gh` CLI)
gh release create v0.2.0 --generate-notes
Creating the release triggers publish.yml, which:
- Builds wheels on Linux (manylinux) and macOS (x86_64 + arm64). Windows builds are intentionally omitted due to platform LAPACK/BLAS inconsistencies that affect numerical reproducibility.
- Builds a source distribution.
- Publishes everything to PyPI via trusted publishing.
Testing a Publish (Without a Release)
You can manually trigger the workflow against TestPyPI:
- Go to Actions → Publish to PyPI → Run workflow.
- Select
testpypias the target. - Verify the package at https://test.pypi.org/project/macenko-pca/.
Project Structure
macenko-pca/
├── src/
│ └── macenko_pca/ # Python package source
│ ├── __init__.py # Public API & version export
│ ├── __about__.py # Version string
│ ├── deconvolution.py # Pythonic wrappers with dtype dispatch
│ └── py.typed # PEP 561 marker
├── rust/ # Rust source (compiled via PyO3 + maturin)
│ ├── lib.rs # PyO3 module entry point (f32 + f64 variants)
│ ├── float_trait.rs # MacenkoFloat supertrait (f32/f64)
│ ├── color_conversion.rs # RGB → SDA transform (generic)
│ ├── color_deconvolution.rs # SDA → concentrations, RGB reconstruction
│ ├── complement_stain_matrix.rs
│ ├── linalg.rs # SVD, magnitude, normalisation (generic)
│ ├── rgb_separate_stains_macenko_pca.rs
│ ├── separate_stains_macenko_pca.rs
│ └── utils.rs # Image ↔ matrix helpers
├── tests/
│ ├── conftest.py # Shared pytest fixtures
│ └── test_deconvolution.py # Library function tests (104 tests)
├── docs/ # MkDocs source files
├── .github/
│ ├── workflows/
│ │ ├── build.yml # CI: build wheels on every push/PR
│ │ ├── pytest.yml # CI: run tests across Python versions
│ │ ├── lint.yml # CI: ruff lint + format check
│ │ └── publish.yml # CD: publish to PyPI on release
│ └── dependabot.yml # Auto-update deps, actions, Docker, Cargo
├── Cargo.toml # Rust crate configuration
├── pyproject.toml # Python project & tool config (maturin backend)
├── Dockerfile # Multi-stage build (maturin / dev / prod)
├── Makefile # Dev shortcuts
├── mkdocs.yml # Docs config
├── .pre-commit-config.yaml # Pre-commit hooks
├── .editorconfig # Editor consistency
└── .gitignore
Design Philosophy
This project follows a library-first approach:
- All logic lives in importable modules under
src/macenko_pca/. - Heavy computation is delegated to Rust (
rust/) for maximum throughput — SVD viandarray-linalg, parallelism viarayon. All Rust functions are generic overf32/f64via theMacenkoFloattrait. - The Python layer (
deconvolution.py) detects the input array's dtype and dispatches to the appropriate typed Rust function, providing input validation and rich docstrings. - Tests call library functions directly.
This keeps your code reusable whether it's called from another package, a Jupyter notebook, or a web API.
Contributing
See CONTRIBUTING.md for development guidelines.
License
macenko-pca is distributed under the terms of the MIT license.
Metadata
Release files for macenko-pca 1.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| macenko_pca-1.0.4.tar.gz | 58.1 kB | With provenance | Details for macenko_pca-1.0.4.tar.gz |
Built distributions (wheels)
Total release size: 58.1 MB
Release files / macenko_pca-1.0.4.tar.gz
| Download URL | macenko_pca-1.0.4.tar.gz |
|---|---|
| Size | 58.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
22bcd38a69fdf341ac6b8545b94cabf6cca7f72ef838274234b200f224dd34ca
|
|
BLAKE2b-256 checksum How to use checksums |
8da5b6ada055ed1ab7bca1159507a5a6e40c109a686a499705121d331f5923e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 450.0 kB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
fe4d2be3e630a8675a403509095c28ca0decce91cfd173e215e68b3ca4a15bcc
|
|
BLAKE2b-256 checksum How to use checksums |
34368ca1056ee8530a4205462c32334aadd7e739674d171a447b96d31232f81f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | macenko_pca-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
c0384f4704f77a25f476a37101655d6eda01ef3fedad85c42b208321ec01c613
|
|
BLAKE2b-256 checksum How to use checksums |
84b08ff9c1240d1906024b287b514d06fd86e5e775300618fff42f2c74d1dba2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 450.4 kB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7d3b30aab3b17362d629a4c719d98fdcfa808ecab8580472f49772a36d0887b9
|
|
BLAKE2b-256 checksum How to use checksums |
00035f0b1d8ae83241983b4c84bddc144af8a6b5d89969e26906fda1b54fba62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | macenko_pca-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
43474209e3bb4ebeb9c39c3aa7fff629c36163e7fb44281a918bedcb6be99956
|
|
BLAKE2b-256 checksum How to use checksums |
b722e8b5053d05bef5512a0c1ce2846d826a29c6246582b2342a749b9dcb6916
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 450.6 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d5ca334456e8e6d0899ad00922f7c8a62443d03b4c636d8f79fc3be72fc1e5b3
|
|
BLAKE2b-256 checksum How to use checksums |
5076abd13d04508e9dbb5a260c330411a146442cb04b0e6e6fdd87c459627b43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | macenko_pca-1.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
21b19a8ea60dbc99c5a57c30a0fc7ed8b5862a28eaf865705046fa8e2e8479b5
|
|
BLAKE2b-256 checksum How to use checksums |
1db42c86039de136efda733dddd08db0392f47c1ef7dd8dbbbc2d51ca9212788
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 450.3 kB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d11472e936ffe59fb91ac1f665d0a82cef29e5d8d3d7b9cf539ae1e7e9bca9d3
|
|
BLAKE2b-256 checksum How to use checksums |
4d8dbf6e50580da812e51edec22faff3f609396104f80a4a5864c4c3c69ad7a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | macenko_pca-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
687ec495ced96afa3e6e63edcc20c48c1066dfb6f0ef31d58c7b0e5c18dab552
|
|
BLAKE2b-256 checksum How to use checksums |
69f90824107ccab48a173ef15d15e2158f947d2f4a93a47b1a22e0a0cbfa5d18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp310-cp310-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp310-cp310-macosx_11_0_arm64.whl |
|---|---|
| Size | 450.6 kB |
| Tags | CPython 3.10 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
822a66559d2be1c03ebde4cc02fb2f767be1a6ac2381407fe453cdd76c035f7c
|
|
BLAKE2b-256 checksum How to use checksums |
d12fc61d7865894f75f3dc3812aea56dff146424a96f3b50b464d67a2b9d6833
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | macenko_pca-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
759a34d43b214305e75a1fb50a21ee4a69f5f5eb931493e966be2b6b588628b1
|
|
BLAKE2b-256 checksum How to use checksums |
b67a7102c9f4c5ca98c79296a35bb7c5c7b0bfb6a93887bb1ed4808a5d7d177a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logRelease files / macenko_pca-1.0.4-cp39-cp39-macosx_11_0_arm64.whl
| Download URL | macenko_pca-1.0.4-cp39-cp39-macosx_11_0_arm64.whl |
|---|---|
| Size | 452.7 kB |
| Tags | CPython 3.9 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
dbbb8fd56f61fa98f103c0fd58024f6d82765443cba2717028c5baf7f6e520ef
|
|
BLAKE2b-256 checksum How to use checksums |
d03db8246a70026c7a2e0d6c966df620e7959d36f5a5d928712bf60a9513bc88
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logSecurity for macenko-pca 1.0.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 12 files in this release have been uploaded with provenance metadata.
Attestation for macenko_pca-1.0.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.