Skip to content

Commit 9689ae2

Browse files
Confromity Update
1 parent b1b6742 commit 9689ae2

77 files changed

Lines changed: 5365 additions & 11896 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- [customics package refactor complete](project_state.md) — v0.1.0 PyPI-ready, bc_multiomics env, 54 passing tests
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: customics package refactor complete
3+
description: CustOmics was refactored from a research repo into a proper PyPI-ready package named customics (v0.1.0)
4+
type: project
5+
---
6+
7+
The repo was fully refactored from a research-only codebase into an installable `customics` package (v0.1.0).
8+
9+
**Why:** User wants to publish to PyPI.
10+
11+
**What was done:**
12+
- New layout: `src/customics/` package with `__init__.py` in every sub-package
13+
- `pyproject.toml` with `setuptools.build_meta` backend, Python ≥ 3.9
14+
- Active conda env for this project: `bc_multiomics`
15+
- Run tests with: `conda run -n bc_multiomics python -m pytest tests/`
16+
17+
**Key bugs fixed:**
18+
- B1: `list``nn.ModuleList` for autoencoders (fixes `state_dict()`)
19+
- B2: `eval()``_ACTIVATIONS` dict in `SurvivalNet`
20+
- B3: `classification_loss` arg order corrected (`y_pred, y_true`)
21+
- B4: `FullyConnectedLayer` now honours the passed `norm_layer`
22+
- B5: Broken `evaluate_latent()` removed; `evaluate()` unified
23+
- OHE fitted on integer-encoded labels (not strings) in `fit()`
24+
25+
**How to apply:** When working on this repo, install in editable mode in bc_multiomics and run pytest to verify.

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.9", "3.11"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install package and dev dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install -e ".[dev]"
28+
29+
- name: Run tests
30+
run: pytest --tb=short -q
31+
32+
- name: Check package imports
33+
run: python -c "import customics; print(customics.__version__)"

CHANGELOG.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Changelog
2+
3+
All notable changes to `customics` are documented here.
4+
5+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) — versioning follows [Semantic Versioning](https://semver.org/).
6+
7+
---
8+
9+
## [0.1.0] — 2026-04-21
10+
11+
First PyPI-ready release. The package was refactored from the original research
12+
codebase with full packaging, typing, testing, and documentation.
13+
14+
### Added
15+
- `pyproject.toml` — installable via `pip install customics`
16+
- Proper `src/customics/` package layout with `__init__.py` in every sub-package
17+
- `__version__ = "0.1.0"` version string
18+
- `customics` CLI entry point (`python -m customics` or `customics` command)
19+
- `customics.exceptions` module: `CustOmicsError`, `DataValidationError`,
20+
`ModelNotFittedError`, `ConfigurationError`
21+
- Type hints on all public methods and class signatures
22+
- `logging` integration throughout (replaces all `print()` calls)
23+
- Input validation in `CustOMICS.__init__` and `fit()` with descriptive errors
24+
- `CustOMICS.predict()` — dedicated classification prediction method
25+
- `CustOMICS.source_names` attribute for explicit source-to-index mapping
26+
- `CustOMICS._get_central_representation()` — always uses the central VAE for
27+
inference regardless of training phase
28+
- `customics.visualization` module: `plot_loss`, `plot_representation`,
29+
`plot_survival_stratification` (extracted from the monolithic model class)
30+
- `customics.explain.shap` module (replaces `ex_vae/shap_vae.py`)
31+
- `MultiOmicsDataset.get_samples()` method
32+
- Complete NumPy-style docstrings with `Parameters`, `Returns`, `Raises`, and
33+
`Examples` sections throughout
34+
- Full test suite: unit tests for losses, metrics, dataset, encoders, model;
35+
integration tests for fit → evaluate → save/load
36+
- GitHub Actions CI workflow (Python 3.9 and 3.11)
37+
- `CHANGELOG.md` and `CONTRIBUTING.md`
38+
- Updated `README.md` with installation, quick start, API table, and data-format
39+
documentation
40+
41+
### Fixed
42+
- **[B1]** `self.autoencoders`, `self.lt_encoders`, `self.lt_decoders` were plain
43+
Python `list` objects — replaced with `nn.ModuleList` so `state_dict()`,
44+
`load_state_dict()`, and `to(device)` work correctly
45+
- **[B2]** `eval('nn.{}()'.format(activation))` in `SurvivalNet` — replaced with
46+
a safe dictionary dispatch (`_ACTIVATIONS` map)
47+
- **[B3]** `classification_loss` argument order was inverted (`y_true`/`y_pred`
48+
swapped relative to call sites) — corrected signature and docstring
49+
- **[B4]** `FullyConnectedLayer` silently overwrote the passed `norm_layer`
50+
argument with `nn.BatchNorm1d` — fixed to honour the caller's choice
51+
- **[B5]** `evaluate_latent()` called `svc_model.predict_proba()` without
52+
arguments — removed the broken method; `evaluate()` now correctly handles both
53+
tasks
54+
55+
### Changed
56+
- Package name standardised to lowercase `customics` throughout
57+
- All `from src.xxx import` statements updated to `from customics.xxx import`
58+
- `Decoder` and `ProbabilisticDecoder` now reverse `hidden_dim` internally,
59+
mirroring the encoder ordering
60+
- `fit()` now returns `self` for method chaining
61+
- `CustOMICS.stratify()` and `CustOMICS.plot_*` are thin wrappers that delegate
62+
to `customics.visualization`
63+
- `src/tools/prepare_dataset.py` and `src/tools/core_utils.py` removed (tightly
64+
coupled to internal TCGA paths; not library code)
65+
- `src/debug/print_layer.py` removed (unused)
66+
- `src/config/samples.txt` dependency removed from `utils.py`
67+
68+
### Deprecated
69+
- `evaluate_latent()` — removed (was broken; use `evaluate()` instead)

CONTRIBUTING.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Contributing to customics
2+
3+
Thank you for your interest in contributing!
4+
5+
---
6+
7+
## Development Setup
8+
9+
```bash
10+
git clone https://github.com/HakimBenkirane/CustOmics.git
11+
cd CustOmics
12+
pip install -e ".[dev]"
13+
```
14+
15+
This installs the package in editable mode together with `pytest` and `pytest-cov`.
16+
17+
---
18+
19+
## Running Tests
20+
21+
```bash
22+
pytest # run all tests
23+
pytest tests/unit/ # unit tests only
24+
pytest tests/integration/ # integration tests only
25+
pytest --cov=customics # with coverage report
26+
```
27+
28+
All tests use synthetic data and run on CPU — no GPU or external files required.
29+
30+
---
31+
32+
## Code Conventions
33+
34+
- **Imports** — all internal imports use `from customics.xxx import yyy` (never `from src.xxx`).
35+
- **Type hints** — add them to every public function and class signature.
36+
- **Docstrings** — NumPy style with `Parameters`, `Returns`, and `Raises` sections.
37+
Add a short `Examples` block for public-facing methods.
38+
- **Logging** — use `logger = logging.getLogger(__name__)` instead of `print()`.
39+
- **No `eval()`** — use dict dispatch for dynamic object construction (see `_ACTIVATIONS` in `tasks/survival.py`).
40+
- **`nn.ModuleList`** — use it (not plain `list`) for collections of `nn.Module` objects.
41+
42+
---
43+
44+
## Submitting Changes
45+
46+
1. Fork the repository and create a branch off `main`.
47+
2. Make your changes, add tests for new behaviour, and ensure the full test suite passes.
48+
3. Open a pull request against `main` with a clear description of what changed and why.
49+
50+
---
51+
52+
## Reporting Issues
53+
54+
Please open an issue at [github.com/HakimBenkirane/CustOmics/issues](https://github.com/HakimBenkirane/CustOmics/issues) and include:
55+
- A minimal reproducible example
56+
- Your Python and PyTorch versions
57+
- The full traceback if applicable

0 commit comments

Comments
 (0)