Skill Tracer
Skills › Scientific Agent Skills › geniml › region2vec.md

region2vec.md

316 lines · skills/geniml/references/region2vec.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Region2Vec
2
3Verified against `geniml==0.8.4` release source and the official BEDbase
4documentation on 2026-10-01.
5

Region2Vec

Verified against geniml==0.8.4 release source and the official BEDbase documentation on 2026-10-01.

Raw lines 1 to 5
6## What the method does
7
8Region2Vec learns vectors for genomic regions from region co-occurrence within
9interval sets. The primary paper describes randomizing regions within each set
10to create word2vec-like contexts, then pooling region vectors to represent
11sets. Treat learned proximity as a property of the training corpus and
12universe, not as proof of a biological mechanism.
14Primary method source: Gharavi et al. (2021), *Embeddings of genomic region sets
15capture rich biological associations in low dimensions*,
16doi:[10.1093/bioinformatics/btab439](https://doi.org/10.1093/bioinformatics/btab439).

What the method does

Region2Vec learns vectors for genomic regions from region co-occurrence within interval sets. The primary paper describes randomizing regions within each set to create word2vec-like contexts, then pooling region vectors to represent sets. Treat learned proximity as a property of the training corpus and universe, not as proof of a biological mechanism.

Primary method source: Gharavi et al. (2021), Embeddings of genomic region sets capture rich biological associations in low dimensions, doi:10.1093/bioinformatics/btab439.

Raw lines 6 to 17
18## Stable 0.8.4 API reality
20Use concrete module paths:
22```python
23from geniml.region2vec.main import Region2VecExModel
24from geniml.region2vec.utils import Region2VecDataset
25from gtars.tokenizers import Tokenizer
26```
28The release's `geniml.region2vec.__init__` does not export
29`Region2VecExModel` or the legacy `region2vec` function. Consequently,
30`from geniml.region2vec import region2vec` and the installed
31`geniml region2vec ...` dispatch path are not reliable in 0.8.4. The old
32function still exists at `geniml.region2vec.main_legacy.region2vec`, but use it
33only to reproduce an existing workflow after a pinned smoke test.

Stable 0.8.4 API reality

Use concrete module paths:

from geniml.region2vec.main import Region2VecExModel
from geniml.region2vec.utils import Region2VecDataset
from gtars.tokenizers import Tokenizer

The release's geniml.region2vec.__init__ does not export Region2VecExModel or the legacy region2vec function. Consequently, from geniml.region2vec import region2vec and the installed geniml region2vec ... dispatch path are not reliable in 0.8.4. The old function still exists at geniml.region2vec.main_legacy.region2vec, but use it only to reproduce an existing workflow after a pinned smoke test.

Raw lines 18 to 34
Starts an agent dispatch :31
35## Universe and tokenizer contract
37Create the tokenizer from a validated local BED universe:
39```python
40from gtars.tokenizers import Tokenizer
42tokenizer = Tokenizer.from_bed("refs/universe.bed")
43```
45With verified `gtars==0.10.0`:
47- universe regions receive stable IDs in file order;
48- seven special tokens are added (`unk`, `pad`, `mask`, `cls`, `eos`, `bos`,
49 and `sep`);
50- `len(tokenizer)` is universe row count plus special tokens;
51- `tokenizer(region_set)["input_ids"]` returns integer IDs.
53Compatibility requires the exact universe bytes/order, assembly, contig policy,
54Gtars version, special-token map/IDs, and tokenization behavior. Re-sorting a
55universe changes IDs even when the interval set is mathematically identical.
56Never infer compatibility from a shared filename such as `hg38.bed`.
58Before tokenizing:
601. Validate BED as 0-based half-open intervals.
612. Confirm a single assembly with a checksummed chromosome-sizes file.
623. Resolve `chr1`/`1`, alt-contig, mitochondrial, and strand policies.
634. Split by patient/donor before learning or evaluating representations.
645. Record the universe SHA-256 and row count.
66Run:
68```bash
69python skills/geniml/scripts/bed_validator.py \
70 --input refs/universe.bed \
71 --assembly GRCh38 \
72 --chrom-sizes refs/GRCh38.chrom.sizes
73```

Universe and tokenizer contract

Create the tokenizer from a validated local BED universe:

from gtars.tokenizers import Tokenizer

tokenizer = Tokenizer.from_bed("refs/universe.bed")

With verified gtars==0.10.0:

  • universe regions receive stable IDs in file order;
  • seven special tokens are added (unk, pad, mask, cls, eos, bos, and sep);
  • len(tokenizer) is universe row count plus special tokens;
  • tokenizer(region_set)["input_ids"] returns integer IDs.

Compatibility requires the exact universe bytes/order, assembly, contig policy, Gtars version, special-token map/IDs, and tokenization behavior. Re-sorting a universe changes IDs even when the interval set is mathematically identical. Never infer compatibility from a shared filename such as hg38.bed.

Before tokenizing:

  1. Validate BED as 0-based half-open intervals.
  2. Confirm a single assembly with a checksummed chromosome-sizes file.
  3. Resolve chr1/1, alt-contig, mitochondrial, and strand policies.
  4. Split by patient/donor before learning or evaluating representations.
  5. Record the universe SHA-256 and row count.

Run:

python skills/geniml/scripts/bed_validator.py \
  --input refs/universe.bed \
  --assembly GRCh38 \
  --chrom-sizes refs/GRCh38.chrom.sizes
Raw lines 35 to 74
Runs code python skills/geniml/scripts/bed_validator.py :69
75## Prepare the token corpus
77`Region2VecDataset` reads a Parquet file with one list-valued column named
78`tokens`; each row is one BED document, sample, or cell. IDs must come from the
79same tokenizer that initializes the model.
81```python
82import pyarrow as pa
83import pyarrow.parquet as pq
84from gtars.models import RegionSet
86documents = []
87for local_bed in validated_local_beds:
88 ids = tokenizer(RegionSet(local_bed))["input_ids"]
89 documents.append(ids)
91table = pa.table({"tokens": pa.array(documents, type=pa.list_(pa.int32()))})
92pq.write_table(table, "work/tokens.parquet")
93```
95This example assumes `validated_local_beds` came from a bounded, local
96manifest. Do not discover arbitrary directory contents, follow symlinks, or
97log sample filenames. Ensure every token is an integer in
98`[0, len(tokenizer))`. Empty or unusually short documents need an explicit
99policy; do not silently discard them after splitting.
101`Region2VecDataset(path, shuffle=True, convert_to_str=False)` loads the full
102Parquet `tokens` column into memory. Bound rows and total tokens before
103construction. `shuffle=True` mutates each document order when accessed; record
104the training seed, but do not assume every library/thread schedule is bitwise
105deterministic.

Prepare the token corpus

Region2VecDataset reads a Parquet file with one list-valued column named tokens; each row is one BED document, sample, or cell. IDs must come from the same tokenizer that initializes the model.

import pyarrow as pa
import pyarrow.parquet as pq
from gtars.models import RegionSet

documents = []
for local_bed in validated_local_beds:
    ids = tokenizer(RegionSet(local_bed))["input_ids"]
    documents.append(ids)

table = pa.table({"tokens": pa.array(documents, type=pa.list_(pa.int32()))})
pq.write_table(table, "work/tokens.parquet")

This example assumes validated_local_beds came from a bounded, local manifest. Do not discover arbitrary directory contents, follow symlinks, or log sample filenames. Ensure every token is an integer in [0, len(tokenizer)). Empty or unusually short documents need an explicit policy; do not silently discard them after splitting.

Region2VecDataset(path, shuffle=True, convert_to_str=False) loads the full Parquet tokens column into memory. Bound rows and total tokens before construction. shuffle=True mutates each document order when accessed; record the training seed, but do not assume every library/thread schedule is bitwise deterministic.

Raw lines 75 to 106
107## Train the modern model
109```python
110from geniml.region2vec.main import Region2VecExModel
111from geniml.region2vec.utils import Region2VecDataset
113dataset = Region2VecDataset("work/tokens.parquet", shuffle=True, convert_to_str=True)
114model = Region2VecExModel(
115 tokenizer=tokenizer,
116 embedding_dim=100,
117 pooling_method="mean",
118 device="cpu",
120model.train(
121 dataset,
122 window_size=5,
123 epochs=10,
124 min_count=10,
125 num_cpus=4,
126 seed=42,
128```
130The recipe was executed with a tiny synthetic corpus on the pinned CPU stack.
131Seed Python's `random` before dataset iteration and Torch before model
132construction as well as passing Gensim's `seed`: `shuffle=True` uses Python's
133global RNG. `convert_to_str=True` makes vocabulary keys explicit strings.
135Current source defaults are not fully consistent across legacy and modern
136modules. Pass every material setting explicitly. `train` uses Gensim
137Word2Vec, then copies learned weights into a Torch embedding matrix.
138`load_from_checkpoint` and per-epoch Gensim `.model` files deserialize Gensim
139artifacts; load only artifacts you created or independently trust.
141Suggested run record:
143- Geniml, Gtars, Python, Torch, Gensim, NumPy, and PyArrow versions;
144- lockfile digest and platform;
145- universe/checkpoint/config/token-corpus/manifest SHA-256;
146- assembly, coordinate and contig contracts;
147- vocabulary and special-token sizes;
148- embedding dimension, window, epochs, `min_count`, workers, seed, shuffling,
149 pooling, and device;
150- train/validation/test grouping and excluded documents.
152Generate a bounded plan first:
154```bash
155python skills/geniml/scripts/embedding_plan.py \
156 --mode region2vec \
157 --data work/tokens.parquet \
158 --universe refs/universe.bed \
159 --output-dir work/region2vec \
160 --assembly GRCh38 \
161 --embedding-dim 100 --epochs 10 --workers 4 --seed 42
162```

Train the modern model

from geniml.region2vec.main import Region2VecExModel
from geniml.region2vec.utils import Region2VecDataset

dataset = Region2VecDataset("work/tokens.parquet", shuffle=True, convert_to_str=True)
model = Region2VecExModel(
    tokenizer=tokenizer,
    embedding_dim=100,
    pooling_method="mean",
    device="cpu",
)
model.train(
    dataset,
    window_size=5,
    epochs=10,
    min_count=10,
    num_cpus=4,
    seed=42,
)

The recipe was executed with a tiny synthetic corpus on the pinned CPU stack. Seed Python's random before dataset iteration and Torch before model construction as well as passing Gensim's seed: shuffle=True uses Python's global RNG. convert_to_str=True makes vocabulary keys explicit strings.

Current source defaults are not fully consistent across legacy and modern modules. Pass every material setting explicitly. train uses Gensim Word2Vec, then copies learned weights into a Torch embedding matrix. load_from_checkpoint and per-epoch Gensim .model files deserialize Gensim artifacts; load only artifacts you created or independently trust.

Suggested run record:

  • Geniml, Gtars, Python, Torch, Gensim, NumPy, and PyArrow versions;
  • lockfile digest and platform;
  • universe/checkpoint/config/token-corpus/manifest SHA-256;
  • assembly, coordinate and contig contracts;
  • vocabulary and special-token sizes;
  • embedding dimension, window, epochs, min_count, workers, seed, shuffling, pooling, and device;
  • train/validation/test grouping and excluded documents.

Generate a bounded plan first:

python skills/geniml/scripts/embedding_plan.py \
  --mode region2vec \
  --data work/tokens.parquet \
  --universe refs/universe.bed \
  --output-dir work/region2vec \
  --assembly GRCh38 \
  --embedding-dim 100 --epochs 10 --workers 4 --seed 42
Raw lines 107 to 163
Runs code python skills/geniml/scripts/embedding_plan.py :155
164## Export and inspect artifacts
166The 0.8.4 constants are:
168- `checkpoint.pt`
169- `config.yaml`
170- `universe.bed`
172The config uses `vocab_size` and `embedding_dim`; `embedding_size` is accepted
173only for backward compatibility and is marked for future deprecation.
175Important release-source caveat: `model.export(path)` calls
176`export_region2vec_model`, which writes the Torch checkpoint and YAML config
177but does **not** write the tokenizer's universe or the pooling method, despite
178the API docstring. A model initialized with max pooling reloads as mean pooling
179unless `pooling_method` is added to `config.yaml`.
180Copy the exact validated universe into the bundle yourself, without changing
181row order, then create a checksum manifest.
183```python
184from pathlib import Path
185import shutil
186import yaml
188bundle = Path("models/region2vec")
189model.export(str(bundle))
190shutil.copyfile("refs/universe.bed", bundle / "universe.bed")
191config_path = bundle / "config.yaml"
192config = yaml.safe_load(config_path.read_text())
193config["pooling_method"] = model.pooling_method
194config_path.write_text(yaml.safe_dump(config))
195```
197Do not overwrite an existing bundle without preserving its prior manifest.
198Inspect without deserialization:
200```bash
201python skills/geniml/scripts/model_artifact_inspector.py \
202 --model-dir models/region2vec
204python skills/geniml/scripts/tokenizer_compatibility.py \
205 --model-dir models/region2vec \
206 --universe refs/universe.bed \
207 --assembly GRCh38
208```
210The checkpoint is a `.pt` file. Geniml's local loader uses
211`torch.load(..., weights_only=True)`, which reduces but does not eliminate
212untrusted-artifact risks such as resource exhaustion, parser defects, or
213native-library vulnerabilities. Never use `torch.load`, Gensim load, pickle,
214or joblib merely to inspect metadata.

Export and inspect artifacts

The 0.8.4 constants are:

  • checkpoint.pt
  • config.yaml
  • universe.bed

The config uses vocab_size and embedding_dim; embedding_size is accepted only for backward compatibility and is marked for future deprecation.

Important release-source caveat: model.export(path) calls export_region2vec_model, which writes the Torch checkpoint and YAML config but does not write the tokenizer's universe or the pooling method, despite the API docstring. A model initialized with max pooling reloads as mean pooling unless pooling_method is added to config.yaml. Copy the exact validated universe into the bundle yourself, without changing row order, then create a checksum manifest.

from pathlib import Path
import shutil
import yaml

bundle = Path("models/region2vec")
model.export(str(bundle))
shutil.copyfile("refs/universe.bed", bundle / "universe.bed")
config_path = bundle / "config.yaml"
config = yaml.safe_load(config_path.read_text())
config["pooling_method"] = model.pooling_method
config_path.write_text(yaml.safe_dump(config))

Do not overwrite an existing bundle without preserving its prior manifest. Inspect without deserialization:

python skills/geniml/scripts/model_artifact_inspector.py \
  --model-dir models/region2vec

python skills/geniml/scripts/tokenizer_compatibility.py \
  --model-dir models/region2vec \
  --universe refs/universe.bed \
  --assembly GRCh38

The checkpoint is a .pt file. Geniml's local loader uses torch.load(..., weights_only=True), which reduces but does not eliminate untrusted-artifact risks such as resource exhaustion, parser defects, or native-library vulnerabilities. Never use torch.load, Gensim load, pickle, or joblib merely to inspect metadata.

Raw lines 164 to 215
Runs code python skills/geniml/scripts/model_artifact_inspector.py :201
Runs code python skills/geniml/scripts/tokenizer_compatibility.py :204
216## Load only after verification
218Local bundle:
220```python
221from geniml.region2vec.main import Region2VecExModel
223model = Region2VecExModel.from_pretrained("models/region2vec")
224```
226Despite its name, this classmethod joins local filenames and makes no Hub
227request. In contrast:
229```python
230model = Region2VecExModel(model_path="organization/model")
231```
233calls `huggingface_hub.hf_hub_download` for the checkpoint, universe, and
234config, but **does not forward constructor kwargs** such as `revision`,
235`cache_dir`, or `local_files_only`. For an authorized download, call
236`hf_hub_download(repo_id=..., filename=..., revision=REVIEWED_COMMIT,
237local_dir=...)` directly for each expected file, verify the resulting hashes,
238then use the local classmethod. This download recipe is source-verified;
239no public weights were fetched in this review.
241The loader constructs the tokenizer from `universe.bed`, reads `config.yaml`
242with YAML `safe_load`, creates a model of `vocab_size × embedding_dim`, and
243loads checkpoint weights. A checksum match is necessary but not sufficient:
244also compare assembly, special tokens, shape, pooling, and software versions.

Load only after verification

Local bundle:

from geniml.region2vec.main import Region2VecExModel

model = Region2VecExModel.from_pretrained("models/region2vec")

Despite its name, this classmethod joins local filenames and makes no Hub request. In contrast:

model = Region2VecExModel(model_path="organization/model")

calls huggingface_hub.hf_hub_download for the checkpoint, universe, and config, but does not forward constructor kwargs such as revision, cache_dir, or local_files_only. For an authorized download, call hf_hub_download(repo_id=..., filename=..., revision=REVIEWED_COMMIT, local_dir=...) directly for each expected file, verify the resulting hashes, then use the local classmethod. This download recipe is source-verified; no public weights were fetched in this review.

The loader constructs the tokenizer from universe.bed, reads config.yaml with YAML safe_load, creates a model of vocab_size × embedding_dim, and loads checkpoint weights. A checksum match is necessary but not sufficient: also compare assembly, special tokens, shape, pooling, and software versions.

Raw lines 216 to 245
246## Encode intervals and sets
248`Region2VecExModel.encode` accepts a local BED path, a Region, a sequence of
249regions, `geniml.io.RegionSet`, or `gtars.models.RegionSet`.
251```python
252vectors = model.encode(
253 "data/query.bed",
254 pooling="mean",
255 batch_size=64,
257```
259The method tokenizes each input region, projects its token IDs, and applies
260mean or max pooling. It returns one vector per input region. It does not
261validate assembly or repair malformed intervals. Validate first, and report
262aggregate shapes/statistics rather than raw genomic coordinates. Empty input
263raises rather than returning an empty matrix; unmatched regions get the `unk`
264embedding, which is usually untrained. Reject or explicitly flag these cases.
265The wrapper's `device` argument records a target but does not move its model
266or inference tensors; the verified recipe is CPU-only.

Encode intervals and sets

Region2VecExModel.encode accepts a local BED path, a Region, a sequence of regions, geniml.io.RegionSet, or gtars.models.RegionSet.

vectors = model.encode(
    "data/query.bed",
    pooling="mean",
    batch_size=64,
)

The method tokenizes each input region, projects its token IDs, and applies mean or max pooling. It returns one vector per input region. It does not validate assembly or repair malformed intervals. Validate first, and report aggregate shapes/statistics rather than raw genomic coordinates. Empty input raises rather than returning an empty matrix; unmatched regions get the unk embedding, which is usually untrained. Reject or explicitly flag these cases. The wrapper's device argument records a target but does not move its model or inference tensors; the verified recipe is CPU-only.

Raw lines 246 to 267
268## Evaluate without leakage
270Geniml's `eval` module implements the paper's:
272- CTT: cluster tendency;
273- RCT: preservation of training-occurrence information;
274- GDST: relation between genomic and embedding distance;
275- NPT: preservation of genomic neighborhoods.
277Source-backed CLI:
279```text
280geniml eval ctt --model-path MODEL --embed-type exmodel
281geniml eval gdst --model-path MODEL --embed-type exmodel
282geniml eval npt --model-path MODEL --embed-type exmodel --K 10
283geniml eval rct --model-path MODEL --embed-type exmodel \
284 --bin-path BINARY_EMBEDDINGS
285```
287For the modern directory bundle above, use `--embed-type exmodel`.
288`region2vec` means a legacy Gensim model file, not a Geniml bundle directory.
289The exmodel loader was executed and correctly excluded all seven special
290vectors. It does not exclude low-frequency untrained region vectors; audit
291those separately. These metric commands are parser-checked templates;
292large-cohort metric estimation was not executed.
294`rct` also requires binary embeddings from the same tokenized corpus. The
295official tutorial and `eval bin-gen` write pickle; treat that format as trusted
296local output only and never load a third-party pickle. Hold out independent
297patients/donors before universe selection, hyperparameter tuning, training, and
298metric selection. Report all metrics and baselines rather than selecting a
299single favorable score.
301Primary evaluation source: Zheng et al. (2024), *Methods for evaluating
302unsupervised vector representations of genomic regions*,
303doi:[10.1093/nargab/lqae086](https://doi.org/10.1093/nargab/lqae086).

Evaluate without leakage

Geniml's eval module implements the paper's:

  • CTT: cluster tendency;
  • RCT: preservation of training-occurrence information;
  • GDST: relation between genomic and embedding distance;
  • NPT: preservation of genomic neighborhoods.

Source-backed CLI:

geniml eval ctt --model-path MODEL --embed-type exmodel
geniml eval gdst --model-path MODEL --embed-type exmodel
geniml eval npt --model-path MODEL --embed-type exmodel --K 10
geniml eval rct --model-path MODEL --embed-type exmodel \
  --bin-path BINARY_EMBEDDINGS

For the modern directory bundle above, use --embed-type exmodel. region2vec means a legacy Gensim model file, not a Geniml bundle directory. The exmodel loader was executed and correctly excluded all seven special vectors. It does not exclude low-frequency untrained region vectors; audit those separately. These metric commands are parser-checked templates; large-cohort metric estimation was not executed.

rct also requires binary embeddings from the same tokenized corpus. The official tutorial and eval bin-gen write pickle; treat that format as trusted local output only and never load a third-party pickle. Hold out independent patients/donors before universe selection, hyperparameter tuning, training, and metric selection. Report all metrics and baselines rather than selecting a single favorable score.

Primary evaluation source: Zheng et al. (2024), Methods for evaluating unsupervised vector representations of genomic regions, doi:10.1093/nargab/lqae086.

Raw lines 268 to 304
305## Official sources
307- [PyPI geniml 0.8.4](https://pypi.org/project/geniml/0.8.4/) (released
308 2026-01-14; accessed 2026-10-01)
309- [v0.8.4 release source](https://github.com/databio/geniml/tree/v0.8.4)
310 (commit `5e8dd14126c45d14917df74de4fb405f383afb61`; accessed 2026-10-01)
311- [Official Region2Vec tutorial](https://docs.bedbase.org/geniml/tutorials/region2vec/)
312 (undated; accessed 2026-10-01; contains legacy imports)
313- [Official evaluation tutorial](https://docs.bedbase.org/geniml/tutorials/evaluation/)
314 (undated; accessed 2026-10-01)
315- [Gtars tokenizer documentation](https://docs.bedbase.org/gtars/tokenizers)
316 (undated; accessed 2026-10-01)

Official sources

Raw lines 305 to 316