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
100 changes: 100 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Bug Report
description: Report a problem to help us improve
title: "[BUG] <short description>"
labels: [bug]
body:
- type: markdown
attributes:
value: |
**Thank you for taking the time to report a bug! Please fill out the form below.**

- type: textarea
id: bug-description
attributes:
label: Describe the Bug
description: A clear and concise description of what the bug is.
placeholder: What happened?
validations:
required: true

- type: checkboxes
id: reproduce-checklist
attributes:
label: To Reproduce
description: Please check all that apply.
options:
- label: I have provided step-by-step instructions below
- label: I have attached or linked the file that caused the issue (if applicable)
- label: I have pasted the exact command used

- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to Reproduce
description: Please provide step-by-step instructions.
placeholder: |
1.
2.
3.
validations:
required: true

- type: input
id: file-link
attributes:
label: File link (if applicable)
description: Paste a link to the file that caused the issue, if possible.
placeholder: https://...

- type: input
id: command-used
attributes:
label: Command used
description: Paste the exact command that failed.
placeholder: playnano ...

- type: textarea
id: expected-behaviour
attributes:
label: Expected Behaviour
description: What did you expect to happen?
placeholder: I expected...
validations:
required: true

- type: checkboxes
id: screenshots
attributes:
label: Screenshots
description: Attach screenshots if applicable.
options:
- label: I have attached screenshots
- type: textarea
id: screenshots-area
attributes:
label: Screenshot details
description: Paste or drag screenshots here.

- type: dropdown
id: environment-type
attributes:
label: Environment type
description: Select your operating system.
options:
- Windows
- macOS
- Linux
- Other

- type: textarea
id: environment-details
attributes:
label: Environment details
description: Run `playnano env-info` and paste the output here.
placeholder: Paste output here

- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Add any other context about the problem here.
73 changes: 73 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
name: Feature Request
description: Suggest a new feature or improvement
title: "[Feature] <short description>"
labels: [enhancement]

body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest a feature! Please fill out the form below to help us understand your idea.

- type: input
id: summary
attributes:
label: Feature Summary
description: Provide a short, clear summary of the feature you'd like to see.
placeholder: e.g., Add support for XYZ file format
validations:
required: true

- type: textarea
id: problem
attributes:
label: What problem does this feature solve?
description: Describe the problem or limitation you're experiencing that this feature would address.
placeholder: I often run into...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: How would you like this feature to work? Be as specific as possible.
placeholder: I'd like it to...
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: Have you tried other solutions or workarounds? What were they?
placeholder: I've tried...
validations:
required: false

- type: dropdown
id: priority
attributes:
label: Priority
description: How important is this feature to you?
options:
- Low - Nice to have
- Medium - Would improve usability
- High - Blocking or critical for my workflow
validations:
required: true
- type: checkboxes
id: context
attributes:
label: Additional Context
description: Check any that apply.
options:
- label: I am willing to help implement this feature
- label: I can provide example data or use cases
- label: This feature is related to a bug I reported
- type: textarea
id: extra
attributes:
label: Anything else?
description: Add any other context, links, or screenshots here.
placeholder: Related issues, references, mockups, etc.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:

- name: Run tests with coverage
run: |
pytest --maxfail=1 --disable-warnings -q --cov=pnanolocz_lib --cov-report=xml --cov-report=term
pytest --maxfail=1 --disable-warnings -q --cov=pnanolocz --cov-report=xml --cov-report=term

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dist/
build/
.eggs/
*.egg
dist/

# Version file
_version.py
Expand Down
198 changes: 198 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<!-- markdownlint-disable MD033 MD024-->
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---

## [Unreleased]

---

## [0.1.0] - 2026-03-02

### Changed

- **Major project restructure**:

- Renamed package from `pnanolocz_lib` → `pnanolocz`.
- Updated source directory structure to `src/pnanolocz/`.
- Updated all import references and entry points.

### Added

- Initial public packaging setup for PyPI using `setuptools` + `setuptools_scm`.
- Comprehensive project metadata, classifiers, dependencies, and dev tools.
- Version writing via `src/pnanolocz/_version.py`.
- Entry point integration for `playnano` filters.

---

## [0.0.4] - 2026-03-02

### Added

- (none)

### Changed

- Updated project metadata: corrected author name to "Daniel E. Rollins".
- Standardised suppression of polynomial fitting warnings using
`RuntimeWarning` and rank-related filters, replacing direct `RankWarning`
references across leveling modules.
- Improved consistency in author attribution within `thresholder.py`.

### Fixed

- Eliminated dependency on `numpy.polynomial.polyutils.RankWarning` to avoid
type-checking issues and NumPy internals.

### Infrastructure

- `.markdownlint.yaml` now ignores `LICENSE` and `LICENSE.md`.
- `.pre-commit-config.yaml` now excludes the `build/` directory from Black.

## [0.0.3] - 2026-01-14

### Summary

This release moves the Python NanoLocz implementation from being functionally similar to the MATLAB reference to being
**algorithmically aligned**. It standardizes mask semantics, improves numerical parity, completes several automated
routines, and clarifies public API behavior. These changes significantly improve reproducibility, validation, and ease
of extension.

### Breaking Changes

- **Minimum Python version** is now **3.11** (3.10 support removed).
- **Thresholding & mask polarity**:
- New public API: `apply_thresholder(img, method, limits=None, invert=False)`.
- All thresholders now return **boolean exclusion masks** (`True = excluded`).
- Removes prior NaN-mask and mixed-polarity behavior.
- **Leveling functions now expect exclusion masks**:
- Leveling internally converts exclusion ↔ validity masks.
- Fitting uses **NaN-outside** semantics.
- **MATLAB behavioral alignment changes**:
- `level_line` only runs the *column* stage when `polyy > 0`.
- `med_line` interprets `polyx` as a **gain** when `polyx > 0`, matching MATLAB.

### Added / Improved

#### Mask Semantics (All Modules)

- Unified boolean exclusion masks across thresholding and leveling.
- Introduced `_validity_mask` to convert public exclusion masks to internal validity masks.
- All fits and summaries use NaN-outside semantics while preserving excluded pixels.

#### Core Leveling (`level.py`)

- Polynomial fits now use **1‑based indices** and **population standard deviation (`ddof=0`)**,
matching MATLAB `polyfit(..., mu)`.
- Reworked methods (`plane`, `line`, `med_line`, `med_line_y`, `smed_line`, `mean_plane`, `log_y`) for:
- alignment with MATLAB gating rules,
- explicit low-sample fallbacks,
- validity-mask‑only fitting.
- Guarantees: `background = input - leveled` under consistent semantics.

#### Automated Routines (`level_auto.py`)

- Implemented:
- `multi-plane-edges`
- `multi-plane-otsu`
- Restored missing histogram passes after plane leveling.
- Added anisotropy‑gated one‑off `med_line` preconditioning.
- MATLAB‑style Gaussian histogram (`gauss1`) fitting:
- `gauss_fit`, `gauss_peaks`, `gauss_holes`
- Adaptive bounds computed **per frame** (documented MATLAB deviation).

#### Thresholding (`thresholder.py`)

- New dispatcher: `apply_thresholder` (returns exclusion masks).
- Expanded & clarified methods (e.g., histogram, selection, otsu, edge masks, skel masks).
- Added advanced methods:
- `line_step` (PELT change‑point)
- `adaptive` (Sobel + morphology + inclusive gating)

#### Region‑Weighted Leveling (`level_weighted.py`)

- Region detection uses **8‑connectivity** and **min area = floor(1% of H×W)** (MATLAB rule).
- Weights ≤2% are zeroed (not renormalized), matching MATLAB.
- Evaluations use **1‑based coordinate grids**.
- Expanded documentation and edge‑case behavior notes.

#### Documentation

- Added `CITATION.cff` for formal citation.
- Updated README with:
- Python 3.11+ requirement,
- new APIs,
- improved examples.
- Updated example notebook accordingly.

#### Tooling & CI

- CI now tests Python **3.11, 3.12, 3.13**.
- Pinned `scikit-image >= 0.26, < 0.27` for stability.
- Improved pre‑commit configuration and ignore rules.
- Standardized tooling (Black, Ruff, Mypy) to **py311**.

#### Tests & Resources

- Added `tests/conftest.py` with NPZ loader fixture.
- Added AFM resource data under `tests/resources/`.

### Migration Notes

#### Thresholding

Before:

```python
mask = thresholder(img, method="otsu") # mixed polarity, NaN masks
```

After:

```python
mask_excl = apply_thresholder(img, method="otsu") # True = excluded
valid = ~mask_excl
```

#### Leveling

Before:

```python
leveled = apply_level_weighted(img, 1, 1, method="line", mask=valid_mask)
```

After:

```python
leveled = apply_level_weighted(img, 1, 1, method="line", mask=mask_excl)
```

#### Automated Routines

```python
out = apply_level_auto(stack, routine="multi-plane-otsu")
```

### CI Note

To ensure setuptools-scm sees tags:

```yaml
- uses: actions/checkout@v4
with:
fetch-depth: 0
```

---

[Unreleased]: https://github.com/derollins/Python-Nanolocz-Library/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/derollins/Python-Nanolocz-Library/releases/tag/v0.1.0
[0.0.4]: https://github.com/derollins/Python-Nanolocz-Library/releases/tag/v0.0.4
[0.0.3]: https://github.com/derollins/Python-Nanolocz-Library/releases/tag/v0.0.3
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type: software
authors:
- given-names: Daniel E
family-names: Rollins
email: d.e.rollins@leed.ac.uk
email: d.e.rollins@leeds.ac.uk
affiliation: University of Leeds
- given-names: George R
family-names: Heath
Expand Down
Loading