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
65 changes: 65 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Bug Report
description: Something is broken or producing incorrect results.
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug. Please fill in as much detail as possible.

- type: textarea
id: description
attributes:
label: Description
description: A clear and concise description of the bug.
validations:
required: true

- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Minimal steps or code snippet to reproduce the issue.
placeholder: |
1. Config used (paste relevant TOML section)
2. Command run
3. Error / unexpected output
validations:
required: true

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

- type: textarea
id: environment
attributes:
label: Environment
description: |
Run `python -m ftnet.helper.collect_env` and paste the output here.
render: shell
validations:
required: true

- type: dropdown
id: dataset
attributes:
label: Dataset
options:
- SODA
- MFN
- SCUT-Seg
- Cityscapes Thermal
- Other / N/A
validations:
required: false

- type: textarea
id: additional
attributes:
label: Additional context
description: Logs, screenshots, or anything else that might help.
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Feature Request
description: Suggest a new feature, dataset, or improvement.
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for suggesting an improvement! Please describe your idea clearly.

- type: textarea
id: problem
attributes:
label: Problem / motivation
description: What problem does this solve? What is the current limitation?
validations:
required: true

- type: textarea
id: solution
attributes:
label: Proposed solution
description: Describe the feature or change you'd like to see.
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Any alternative approaches you have considered or tried.

- type: dropdown
id: area
attributes:
label: Area
multiple: true
options:
- New dataset support
- Model architecture
- Training / optimisation
- Inference / deployment
- Documentation
- CI / tooling
- Other
validations:
required: true
31 changes: 31 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Summary

<!-- 1-3 bullet points describing what this PR does -->

-

## Motivation

<!-- Why is this change needed? Link to a related issue if applicable. Closes #... -->

## Changes

<!-- List the key files / components changed and why -->

-

## Testing

<!-- Describe how you tested this change -->

- [ ] New unit tests added in `tests/`
- [ ] Existing tests pass (`poetry run pytest`)
- [ ] Pre-commit hooks pass (`poetry run pre-commit run --all-files`)

## Checklist

- [ ] PR targets `develop` (not `main`)
- [ ] Type hints added/updated for any new public functions
- [ ] Docstrings added/updated (Google style)
- [ ] Config changes reflected in `ftnet/cfg/cfg_dataclasses.py` with sensible defaults
- [ ] No `print()` statements — using `logger` instead
97 changes: 97 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: CI

on:
push:
branches: [develop, main]
pull_request:
branches: [develop, main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
name: Lint & Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install ruff
run: pip install ruff==0.4.4

- name: Run ruff lint
run: ruff check .

- name: Run ruff format check
run: ruff format --check .

type-check:
name: Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install dependencies
run: pip install mypy==1.10.0 pydantic types-toml types-tqdm types-seaborn

- name: Run mypy
run: mypy ftnet --ignore-missing-imports

test:
name: Tests (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true

- name: Cache virtualenv
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
restore-keys: |
venv-${{ runner.os }}-${{ matrix.python-version }}-

- name: Install dependencies (CPU torch)
run: |
poetry config installer.max-workers 10
poetry install --no-interaction --with dev -E cpu 2>/dev/null || \
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu && \
poetry install --no-interaction --with dev --no-root && \
pip install -e .

- name: Run tests
run: poetry run pytest tests/ -v --cov=ftnet --cov-report=xml --cov-report=term-missing

- name: Upload coverage
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.10'
with:
file: ./coverage.xml
fail_ci_if_error: false
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ repos:
#- mdformat-black
- mdformat_frontmatter

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
hooks:
- id: mypy
additional_dependencies: [pydantic, torch, types-toml, types-tqdm, types-seaborn]
args: [--ignore-missing-imports]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
Expand Down
132 changes: 132 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Contributing to FTNet

Thank you for your interest in contributing! This document covers how to set up your development environment, the branch strategy, code standards, and how to submit changes.

## Table of Contents

- [Branch Strategy](#branch-strategy)
- [Development Setup](#development-setup)
- [Code Standards](#code-standards)
- [Running Tests](#running-tests)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [Reporting Issues](#reporting-issues)

---

## Branch Strategy

| Branch | Purpose |
|--------|---------|
| `main` | Stable, published results matching the IEEE Access paper |
| `develop` | Active development — all PRs target this branch |

**All pull requests must target `develop`, not `main`.**

`main` is only updated via a release PR from `develop` when a new stable milestone is reached.

---

## Development Setup

### Prerequisites

- Python 3.10+
- [Poetry](https://python-poetry.org/docs/#installation)
- Git

### Install

```bash
git clone https://github.com/shreyaskamathkm/FTNet.git
cd FTNet
git checkout develop

# Install all dependencies including dev tools
poetry install --with dev

# Install pre-commit hooks
poetry run pre-commit install
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `FTNET_PRETRAINED_DIR` | `<repo_root>/pretrained_models` | Override path for pretrained backbone weights |

---

## Code Standards

This project uses [Ruff](https://docs.astral.sh/ruff/) for linting and formatting, and [mypy](https://mypy.readthedocs.io/) for static type checking. These are enforced automatically via pre-commit hooks.

### Manual checks

```bash
# Lint
poetry run ruff check .

# Format
poetry run ruff format .

# Type check
poetry run mypy ftnet --ignore-missing-imports
```

### Key conventions

- **Type hints** are required on all public functions and methods.
- **Docstrings** follow Google style (Args / Returns sections).
- **Logging** — use `logger = logging.getLogger(__name__)` instead of `print()`.
- **Config changes** — all new parameters must be added to the appropriate Pydantic dataclass in `ftnet/cfg/cfg_dataclasses.py` with a sensible default.

---

## Running Tests

```bash
# Run all tests
poetry run pytest

# Run with coverage report
poetry run pytest --cov=ftnet --cov-report=term-missing

# Run a specific test file
poetry run pytest tests/test_loss.py -v
```

Tests live in the `tests/` directory and mirror the `ftnet/` package structure.

---

## Submitting a Pull Request

1. **Branch** off `develop`:
```bash
git checkout develop
git pull
git checkout -b feat/your-feature-name
```

2. **Make your changes** and write tests for any new functionality.

3. **Ensure all checks pass** locally before opening a PR:
```bash
poetry run pre-commit run --all-files
poetry run pytest
```

4. **Open a PR** against `develop` (not `main`). Fill in the pull request template.

5. A maintainer will review your PR. Please respond to review comments promptly.

---

## Reporting Issues

Use the GitHub issue templates:

- **Bug report** — for incorrect behaviour, crashes, or wrong results.
- **Feature request** — for new dataset support, model variants, or tooling improvements.

Please include your OS, Python version, GPU/CUDA version, and a minimal reproducible example where applicable.
3 changes: 2 additions & 1 deletion ftnet/cfg/cfg_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def validate_all_fields_at_the_same_time(cls, field_values):
and not field_values.task.train_only
):
raise ValueError(
"When train only mode is on, please update the dataset name to cityscapes_thermal_combine"
"Dataset 'cityscapes_thermal_combine' requires train_only=True. "
"Please set task.train_only = true in your config."
)
return field_values
Loading
Loading