Metadata-Version: 2.4
Name: gae-delta
Version: 0.1.0
Summary: GAE-Δ: Phenotype-specific gene role shifts in multi-omics data via graph autoencoder embedding differences
Author: GAE-Delta Authors
License: MIT
Project-URL: Homepage, https://github.com/zhiyongtang1998/GAE-Delta
Project-URL: Repository, https://github.com/zhiyongtang1998/GAE-Delta
Project-URL: Issues, https://github.com/zhiyongtang1998/GAE-Delta/issues
Keywords: multi-omics,graph-autoencoder,cancer-genomics,bioinformatics
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: torch>=2.0
Requires-Dist: torch-geometric>=2.4
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-learn>=1.2
Requires-Dist: pandas>=2.0
Requires-Dist: h5py>=3.8
Requires-Dist: hydra-core>=1.3
Requires-Dist: omegaconf>=2.3
Requires-Dist: tqdm
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Provides-Extra: vis
Requires-Dist: matplotlib>=3.7.0; extra == "vis"
Requires-Dist: seaborn>=0.12.0; extra == "vis"
Dynamic: license-file

<div align="center">

# 🧬 GAE-Δ

**Phenotype-Specific Gene Role Shifts in Multi-Omics Data via Graph Autoencoder Embedding Differences**

*When genes don't change expression — but change who they talk to*

[![Python 3.10+](https://img.shields.io/badge/Python-3.10+-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![PyTorch 2.x](https://img.shields.io/badge/PyTorch-2.x-EE4C2C?logo=pytorch&logoColor=white)](https://pytorch.org/)
[![PyG 2.5+](https://img.shields.io/badge/PyG-2.5+-3C2179?logo=pyg&logoColor=white)](https://pyg.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

</div>

---

## 💡 What is GAE-Δ?

Most multi-omics methods ask: *"Which genes are differentially expressed between phenotypes?"*

**GAE-Δ asks a different question:** *"Which genes change their network roles between phenotypic groups?"*

We train separate graph autoencoders on **group-specific** gene interaction networks, then compute **embedding differences** — capturing how each gene's functional context reorganizes across phenotypic conditions. This isn't about expression changes; it's about **network rewiring**.

GAE-Δ is a general framework applicable to any binary stratification of multi-omics cohorts — survival outcomes, treatment response, disease subtypes, or any clinically meaningful grouping.

<div align="center">

```
  ┌─────────────┐         ┌─────────────┐
  │   Group A    │         │   Group B    │
  │  Gene Graph  │         │  Gene Graph  │
  └──────┬──────┘         └──────┬──────┘
         │                       │
    ┌────▼────┐             ┌────▼────┐
    │  GAE    │             │  GAE    │
    │ Encoder │             │ Encoder │
    └────┬────┘             └────┬────┘
         │                       │
      z_A ∈ ℝ^d              z_B ∈ ℝ^d
         │                       │
         └──────────┬────────────┘
                    │
              Δz = z_B − z_A
                    │
              ┌─────▼─────┐
              │    KNN     │
              │  Residual  │
              └─────┬─────┘
                    │
         ε_g ∈ ℝ^d (per gene, per omics)
                    │
         ┌──────────┼──────────┐
         RNA      Meth       CNV
         │         │          │
         └─────────┼──────────┘
                   │
           s_g ∈ ℝ^(3d) (fused)
                   │
           ┌───────▼───────┐
           │ Isolation      │
           │ Forest (top-N) │
           └───────┬───────┘
                   │
           ┌───────▼───────┐
           │ Patient Embed  │
           │ + MLP → 0/1    │
           └───────────────┘
```

</div>

## 🔬 Key Features

- **Phenotype-specific graph learning** — separate GAEs for each group, capturing group-specific gene interaction topology
- **Embedding difference as biomarker** — gene-level network reorganization, not just expression fold-change
- **Multi-omics late fusion** — RNA-seq, DNA methylation, CNV integrated at the embedding-shift level
- **KNN residual correction** — removes globally smooth trends, highlights genes with atypical rewiring
- **Isolation Forest gene selection** — unsupervised anomaly detection on fused shift space
- **Cython + C++ accelerated** — performance-critical PCC computation and KNN in compiled extensions

## ⚡ Quick Start

### Prerequisites

| Dependency | Version | Required? |
|:-----------|:--------|:----------|
| Python | ≥ 3.10 | yes |
| PyTorch | ≥ 2.0 | yes |
| PyG | ≥ 2.5 | yes |
| C++ Compiler | C++17 | only to build the optional native speedups |
| CUDA | ≥ 11.8 | optional — GPU only; CPU works out of the box |

> The Cython (PCC/adjacency) and C++ (KNN) extensions are **performance optimizations only** — the package runs correctly on pure NumPy / scikit-learn fallbacks if they are not compiled.

### Build & Install

```bash
# 1. Create environment
conda env create -f environment.yml
conda activate gae-delta

# 2. Install (compiles all native extensions automatically)
pip install .
```

> **Note:** `pip install .` now builds **all** native extensions — the Cython PCC/adjacency modules and the C++ KNN extension (pybind11) — in a single step; no separate `make` is required. A C++17 compiler is needed. `make all` remains available for an in-place editable dev build.

### Run with toy data

```bash
gae-delta \
    data.hdf5_path=data/example/toy_demo.h5 \
    data.fi_network_path=data/example/toy_fi_network.txt
```

### Run with real TCGA data

```bash
gae-delta \
    data.hdf5_path=/path/to/your/cancer_data.h5 \
    data.fi_network_path=/path/to/FI_network.txt \
    n_folds=10 \
    device=auto
```

### Use as a Python library

After `pip install gae-delta`, call the framework directly from your own code:

```python
from gae_delta import (
    run_cross_validation,      # full 10-fold pipeline (Algorithm 1)
    compute_embedding_shift,   # Δz between two group embeddings
    knn_residual_correction,   # remove globally smooth trends
    fuse_multiomics_shifts,    # late-fusion of per-omics shifts
    select_shift_genes,        # Isolation-Forest gene ranking
    OutcomeGraphBuilder,       # FI-constrained group graph builder
    MultiOmicsDataset,         # HDF5 multi-omics loader
)

# End-to-end: dataset + FI network in, cross-validated result out
result = run_cross_validation(dataset, fi_edges, n_folds=10, n_top_genes=100)
print(result.summary())        # e.g. "AUC: 0.71 ± 0.05 | F1: 0.68 ± 0.06"

# …or compose the building blocks for your own analysis
shift    = compute_embedding_shift(z_good, z_poor, normalize=True)
residual = knn_residual_correction(shift, k=15)
top_idx, scores = select_shift_genes(fused_shifts, n_top=100)
```

> The public API is imported lazily, so `import gae_delta` stays fast and does
> not pull in PyTorch until you actually call a model-backed entry point.

## 📂 Project Structure

```
GAE-Delta/
├── csrc/                    # C++ KNN extension (pybind11)
├── gae_delta/
│   ├── core/
│   │   ├── graph/           # Cython PCC + FI-constrained graph builder
│   │   ├── model/           # GCN Encoder → GAE → MLP
│   │   ├── shift/           # Δz computation + KNN residual + fusion
│   │   └── selection/       # Isolation Forest gene ranking
│   ├── data/                # HDF5 loader + omics preprocessing
│   ├── pipeline/            # 5-stage pipeline + Hydra runner
│   ├── evaluation/          # 10-fold CV + metrics
│   └── configs/             # Hydra YAML configs (shipped inside the wheel)
├── data/example/            # Toy demo dataset
└── tests/
```

## 📊 Data Format

Input data must follow this HDF5 schema:

```
dataset.h5
├── rna/expression           float32  (n_patients × n_genes)
├── methylation/beta_values  float32  (n_patients × n_genes)
├── cnv/copy_ratios          float32  (n_patients × n_genes)
├── clinical/os_days         float32  (n_patients,)
├── clinical/os_status       int32    (n_patients,)    # 1=deceased
└── meta/gene_universe       str      (n_common_genes,)
```

Each group also contains `gene_symbols` and `patient_ids` arrays. See `gae_delta/data/tcga/loader.py` for the full specification.

## ⚙️ Configuration

GAE-Δ uses [Hydra](https://hydra.cc/) for configuration management. Override any parameter from the command line:

```bash
# Custom hyperparameters
gae-delta \
    model.gae.encoder.out_channels=32 \
    model.mlp.architecture.hidden_dim=128 \
    experiment.graph.pcc_threshold=0.4 \
    n_top_genes=200

# Environment variables also work
export GAE_DELTA_DATA_PATH=/data/tcga/lihc.h5
gae-delta
```

## 🧪 Testing

```bash
make test
```

## 📜 Citation

If you use GAE-Δ in your research, please cite:

```bibtex
@article{tang2026gaedelta,
  title={GAE-$\Delta$: Phenotype-Specific Gene Role Shifts in Multi-Omics
         Data via Graph Autoencoder Embedding Differences},
  author={Tang, Zhiyong and Chen, Zhe and Chen, Mengting and Ewing, Rob
          and Niranjan, Mahesan and Ennis, Sarah and Wang, Yihua},
  journal={Bioinformatics},
  year={2026},
  publisher={Oxford University Press}
}
```

## 📄 License

This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) — free to use, modify, and redistribute with attribution.
