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
46 changes: 46 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# geniml -- Genomic Interval Machine Learning

Builds vector embeddings and ML models from genomic interval data (BED files), enabling similarity search, clustering, and classification of genomic region sets.

## Install

```
pip install geniml # base (no ML deps)
pip install geniml[ml] # torch, transformers, gensim
pip install geniml[sc] # scanpy, anndata
pip install geniml[search] # qdrant-client, fastembed
pip install geniml[all] # everything
```

## Quick start

```python
from geniml.region2vec import Region2VecExModel

model = Region2VecExModel("databio/r2v-ChIP-atlas-hg38")
vec = model.encode("peaks.bed")
```

## Submodules

- **region2vec** -- Embed BED files into vectors (Region2VecExModel)
- **scembed** -- Single-cell embeddings (wraps region2vec for AnnData)
- **search** -- Vector similarity search (BED2BED, Text2BED; HNSW/Qdrant backends)
- **bbclient** -- Download BED files from BEDbase (BBClient)
- **atacformer** -- Transformer for scATAC-seq
- **geneformer** -- Transformer for scRNA-seq
- **craft** -- Contrastive model for gene activity
- **bedspace** -- StarSpace-based BED embedding (requires external binary)
- **assess/likelihood** -- Region set overlap, distance, and likelihood stats
- **io** -- BedSet class. For single region sets, prefer `gtars.models.RegionSet`

## Dependency gating

Heavy submodules (region2vec, scembed, atacformer, etc.) are NOT imported by `import geniml`. Import them directly: `from geniml.region2vec import Region2VecExModel`. They will fail with ImportError if the matching optional dep group is not installed.

## Deprecated -- do not use

- `geniml.io.Region`, `geniml.io.RegionSet` -- use `gtars.models.Region/RegionSet`
- `geniml.region2vec.main_legacy` -- replaced by Region2VecExModel
- `geniml.text2bednn` -- use `search.Text2BEDSearchInterface`
- `geniml.nn` -- internal utilities, not public API
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ or install the latest version from the GitHub repository:
pip install git+https://github.com/databio/geniml.git
```

### To install Machine learning dependencies use this command:
### Optional dependency groups

From pypi:
```
pip install geniml[ml]
pip install geniml[ml] # torch, transformers, gensim — for embeddings and ML models
pip install geniml[sc] # scanpy, anndata — for single-cell data processing
pip install geniml[search] # qdrant-client, fastembed — for vector search
pip install geniml[all] # everything (ml + sc + search)
pip install geniml[ml,sc] # ML + single-cell (for scembed, geneformer)
```


Expand Down
12 changes: 11 additions & 1 deletion geniml/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Submodules with heavy optional dependencies (torch, scanpy, gensim)
# are NOT imported here. Import them directly:
# from geniml.region2vec import Region2VecExModel
# from geniml.scembed import ScEmbed
# Optional dependency groups:
# pip install geniml[ml] # torch, transformers, gensim — embeddings & ML models
# pip install geniml[sc] # scanpy, anndata — single-cell data processing
# pip install geniml[search] # qdrant-client, fastembed — vector search
# pip install geniml[all] # everything (ml + sc + search)

from logging import getLogger

from ._version import __version__
from ._version import __version__ # noqa: F401
from .const import PKG_NAME

_LOGGER = getLogger(PKG_NAME)
2 changes: 1 addition & 1 deletion geniml/assess/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .cli import build_subparser
from .cli import build_subparser # noqa: F401
8 changes: 4 additions & 4 deletions geniml/assess/likelihood.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ def likelihood_flexible_universe(
# likelihood of part of the genome after the last region
res += background_likelihood(
empty_start,
chr_size,
prob_start,
prob_core,
prob_end,
chr_size, # noqa: F821
prob_start, # noqa: F821
prob_core, # noqa: F821
prob_end, # noqa: F821
)
current_chrom = i[0]
done_chroms.append(current_chrom)
Expand Down
6 changes: 3 additions & 3 deletions geniml/assess/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ def check_if_uni_sorted(universe):

def check_if_uni_flexible(universe):
with open(universe) as u:
l = u.readline()
l = l.split("\t")
if len(l) < 6:
line = u.readline()
line = line.split("\t")
if len(line) < 6:
raise Exception("Universe is not flexible")


Expand Down
1 change: 0 additions & 1 deletion geniml/atacformer/modeling_atacformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@ def forward(
attention_mask_negative: Optional[torch.Tensor] = None,
return_dict: Optional[bool] = None,
) -> Union[Tuple[torch.Tensor], BaseModelOutput]:

if attention_mask_anchor is None:
attention_mask_anchor = torch.ones_like(input_ids_anchor, dtype=torch.bool)
if attention_mask_positive is None:
Expand Down
11 changes: 7 additions & 4 deletions geniml/atacformer/training_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from __future__ import annotations

import math
import subprocess
from functools import partial
from typing import List, Dict
from typing import List, Dict, TYPE_CHECKING
from collections import defaultdict

import torch
import scanpy as sc

if TYPE_CHECKING:
import scanpy as sc

import numpy as np
from torch.optim import Optimizer
Expand Down Expand Up @@ -325,8 +329,7 @@ def __init__(
):
super().__init__()
try:
from sklearn.metrics import adjusted_rand_score
from sklearn.cluster import KMeans
import sklearn # noqa: F401
except ImportError:
raise ImportError(
"scikit-learn is required for AdjustedRandIndexCallback. Please install it with `pip install scikit-learn`."
Expand Down
4 changes: 2 additions & 2 deletions geniml/bedshift/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import logmuse

from .bedshift import Bedshift
from .yaml_handler import BedshiftYAMLHandler
from .bedshift import Bedshift # noqa: F401
from .yaml_handler import BedshiftYAMLHandler # noqa: F401

__classes__ = ["Bedshift"]
__all__ = __classes__ + []
Expand Down
Loading
Loading