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

utilities.md

455 lines · skills/geniml/references/utilities.md at 5f2bc03

Open on GitHub

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

1# I/O, tokenization, caches, evaluation, and security
2
3Research snapshot: 2026-10-01. API claims below use official documentation,
4PyPI metadata, and the `geniml` v0.8.4 release source. Where current docs and
5release code disagree, the discrepancy is stated explicitly.
6

I/O, tokenization, caches, evaluation, and security

Research snapshot: 2026-10-01. API claims below use official documentation, PyPI metadata, and the geniml v0.8.4 release source. Where current docs and release code disagree, the discrepancy is stated explicitly.

Raw lines 1 to 6
7## Release and dependency facts
8
9`geniml==0.8.4` was released on 2026-01-14. PyPI metadata:
11- does not set `Requires-Python`;
12- classifies Python 3.10, 3.11, 3.12, 3.13, and 3.14;
13- provides `ml` and `test` extras;
14- ships a pure-Python wheel, but dependencies include native packages;
15- uses Trusted Publishing with a Sigstore provenance link to tag `v0.8.4`.
17Release files:
19```text
20geniml-0.8.4-py3-none-any.whl
21sha256 ac0fc520cde6f6461120aee6b40d3cbf20e1e3d8bdb95a3a45345724eee545b5
23geniml-0.8.4.tar.gz
24sha256 6f429c7c89d06a4c2c378e349d14b3a2d984dc441440ada38473772fce6addb1
25```
27The stable release requires `gtars>=0.2.5` without an upper bound. The
282026-10-01 synthetic CPU checks used `gtars==0.10.0`, Python 3.12,
29AnnData 0.12.19, Scanpy 1.12.4, Zarr 2.18.7, Gensim 4.4.0, Torch 2.14.1,
30PyArrow 25.0.1, NumPy 2.5.3, pandas 2.3.3, and Hugging Face Hub 2.0.0.
31They exercised Region2Vec/scEmbed training, explicit token/cell pooling,
32local bundles, CC construction, and local BED/token caches. Gtars 0.10.0 was released 2026-09-05 and requires
33Python >=3.10.
35Pin the tested stack and retain `uv.lock`; upstream transitive requirements
36are mostly lower bounds. Geniml's Zarr <3 constraint is incompatible with
37AnnData 0.13 (Zarr >=3). AnnData 0.12.19 works with the tested Zarr 2.18.7.
38The full ml extra resolves but brings additional old pinned components;
39it was resolver-checked only, unlike the selective stack above.

Release and dependency facts

geniml==0.8.4 was released on 2026-01-14. PyPI metadata:

  • does not set Requires-Python;
  • classifies Python 3.10, 3.11, 3.12, 3.13, and 3.14;
  • provides ml and test extras;
  • ships a pure-Python wheel, but dependencies include native packages;
  • uses Trusted Publishing with a Sigstore provenance link to tag v0.8.4.

Release files:

geniml-0.8.4-py3-none-any.whl
sha256 ac0fc520cde6f6461120aee6b40d3cbf20e1e3d8bdb95a3a45345724eee545b5

geniml-0.8.4.tar.gz
sha256 6f429c7c89d06a4c2c378e349d14b3a2d984dc441440ada38473772fce6addb1

The stable release requires gtars>=0.2.5 without an upper bound. The 2026-10-01 synthetic CPU checks used gtars==0.10.0, Python 3.12, AnnData 0.12.19, Scanpy 1.12.4, Zarr 2.18.7, Gensim 4.4.0, Torch 2.14.1, PyArrow 25.0.1, NumPy 2.5.3, pandas 2.3.3, and Hugging Face Hub 2.0.0. They exercised Region2Vec/scEmbed training, explicit token/cell pooling, local bundles, CC construction, and local BED/token caches. Gtars 0.10.0 was released 2026-09-05 and requires Python >=3.10.

Pin the tested stack and retain uv.lock; upstream transitive requirements are mostly lower bounds. Geniml's Zarr <3 constraint is incompatible with AnnData 0.13 (Zarr >=3). AnnData 0.12.19 works with the tested Zarr 2.18.7. The full ml extra resolves but brings additional old pinned components; it was resolver-checked only, unlike the selective stack above.

Raw lines 7 to 40
41## BED coordinates and validation
43BED is normally 0-based, half-open `[start, end)`. A valid BED3 row requires:
45- nonempty contig;
46- integer `start >= 0`;
47- integer `end > start`;
48- `end` no greater than the declared contig length;
49- values within bounded integer limits.
51Do not confuse BED with 1-based closed VCF/GFF coordinates. BED columns beyond
52BED3 have their own constraints; preserve them rather than guessing.
53BED3 carries no strand. When BED6 strand exists, preserve `+`, `-`, or `.`
54unless a documented assay conversion says otherwise.
56Assembly compatibility requires more than matching `chr` prefixes. BEDbase
57describes chromosome-name sensitivity (XS), out-of-bounds regions (OOBR), and
58sequence fit (SF) as separate criteria. Record a concrete assembly/accession
59and chromosome-sizes digest. Reject unknown alt/decoy contigs rather than
60dropping them silently.
62Run:
64```bash
65python skills/geniml/scripts/bed_validator.py \
66 --input data/peaks.bed \
67 --assembly GRCh38 \
68 --chrom-sizes refs/GRCh38.chrom.sizes
69```
71The script emits aggregate errors and a normalization plan. It never rewrites
72coordinates or performs liftover.

BED coordinates and validation

BED is normally 0-based, half-open [start, end). A valid BED3 row requires:

  • nonempty contig;
  • integer start >= 0;
  • integer end > start;
  • end no greater than the declared contig length;
  • values within bounded integer limits.

Do not confuse BED with 1-based closed VCF/GFF coordinates. BED columns beyond BED3 have their own constraints; preserve them rather than guessing. BED3 carries no strand. When BED6 strand exists, preserve +, -, or . unless a documented assay conversion says otherwise.

Assembly compatibility requires more than matching chr prefixes. BEDbase describes chromosome-name sensitivity (XS), out-of-bounds regions (OOBR), and sequence fit (SF) as separate criteria. Record a concrete assembly/accession and chromosome-sizes digest. Reject unknown alt/decoy contigs rather than dropping them silently.

Run:

python skills/geniml/scripts/bed_validator.py \
  --input data/peaks.bed \
  --assembly GRCh38 \
  --chrom-sizes refs/GRCh38.chrom.sizes

The script emits aggregate errors and a normalization plan. It never rewrites coordinates or performs liftover.

Raw lines 41 to 73
Runs code python skills/geniml/scripts/bed_validator.py :65
74## Region and RegionSet APIs

Region and RegionSet APIs

Raw lines 74 to 75
76### Gtars API for new workflows
78```python
79from gtars.models import Region, RegionSet
81region = Region("chr1", 100, 200, None)
82regions = RegionSet("data/peaks.bed")
83print(len(regions))
84regions.to_bed("work/peaks.copy.bed")
85```
87Gtars 0.10.0 requires the fourth `Region` constructor argument (`rest`),
88including `None` for BED3. It exposes operations including `sort`, `reduce`, `coverage`,
89`count_overlaps`, `jaccard`, `nearest_neighbors`, `to_bed`, `to_bed_gz`, and
90`to_bigbed`. Do not assume these operations validate assembly or coordinate
91semantics. Validate before constructing the object and after writing output.
93Official Gtars constructors can accept URLs. This skill restricts them to
94validated local regular files by default.

Gtars API for new workflows

from gtars.models import Region, RegionSet

region = Region("chr1", 100, 200, None)
regions = RegionSet("data/peaks.bed")
print(len(regions))
regions.to_bed("work/peaks.copy.bed")

Gtars 0.10.0 requires the fourth Region constructor argument (rest), including None for BED3. It exposes operations including sort, reduce, coverage, count_overlaps, jaccard, nearest_neighbors, to_bed, to_bed_gz, and to_bigbed. Do not assume these operations validate assembly or coordinate semantics. Validate before constructing the object and after writing output.

Official Gtars constructors can accept URLs. This skill restricts them to validated local regular files by default.

Raw lines 76 to 95
96### Legacy Geniml I/O
98```python
99from geniml.io import BedSet, Region, RegionSet
101region = Region("chr1", 100, 200) # third field is named stop
102regions = RegionSet("data/peaks.bed", backed=False)
103```
105`geniml.io.RegionSet(regions, backed=False)` accepts a path/URL or a list of
106legacy Regions. With `backed=True`, it streams the BED, supports iteration and
107length, and does not support indexing. Other release classes include `BedSet`,
108`Maf`, `SNP`, `TokenizedRegionSet`, and `RegionSetCollection`, though only
109`Region`, `RegionSet`, and `BedSet` are exported from `geniml.io`.
111The 0.7.0 changelog says RegionSet use switched toward Gtars. Avoid mixing
112legacy and Gtars Region objects accidentally: field names and accepted types
113differ.

Legacy Geniml I/O

from geniml.io import BedSet, Region, RegionSet

region = Region("chr1", 100, 200)  # third field is named stop
regions = RegionSet("data/peaks.bed", backed=False)

geniml.io.RegionSet(regions, backed=False) accepts a path/URL or a list of legacy Regions. With backed=True, it streams the BED, supports iteration and length, and does not support indexing. Other release classes include BedSet, Maf, SNP, TokenizedRegionSet, and RegionSetCollection, though only Region, RegionSet, and BedSet are exported from geniml.io.

The 0.7.0 changelog says RegionSet use switched toward Gtars. Avoid mixing legacy and Gtars Region objects accidentally: field names and accepted types differ.

Raw lines 96 to 114
115## Tokenization
117### Current Gtars tokenizer
119```python
120from gtars.models import RegionSet
121from gtars.tokenizers import Tokenizer
123tokenizer = Tokenizer.from_bed("refs/universe.bed")
124encoded = tokenizer(RegionSet("data/peaks.bed"))
125input_ids = encoded["input_ids"]
126```
128Gtars exposes `Tokenizer.from_config(cfg)` and
129`Tokenizer.from_pretrained(path)`. The latter can access Hugging Face and has
130no revision/cache kwargs. For authorized downloads, use the Hub client with
131an immutable revision, then `Tokenizer.from_bed` on verified local bytes.
133With Gtars 0.10.0, a two-region universe produced `len(tokenizer) == 9` because
134seven special tokens are included. Preserve:
136- universe bytes, row order, and assembly;
137- Gtars version;
138- `special_tokens_map` and every special-token ID;
139- tokenizer length;
140- token-corpus schema and checksum.
142Run the local compatibility planner:
144```bash
145python skills/geniml/scripts/tokenizer_compatibility.py \
146 --model-dir models/region2vec \
147 --universe refs/universe.bed \
148 --assembly GRCh38
149```

Current Gtars tokenizer

from gtars.models import RegionSet
from gtars.tokenizers import Tokenizer

tokenizer = Tokenizer.from_bed("refs/universe.bed")
encoded = tokenizer(RegionSet("data/peaks.bed"))
input_ids = encoded["input_ids"]

Gtars exposes Tokenizer.from_config(cfg) and Tokenizer.from_pretrained(path). The latter can access Hugging Face and has no revision/cache kwargs. For authorized downloads, use the Hub client with an immutable revision, then Tokenizer.from_bed on verified local bytes.

With Gtars 0.10.0, a two-region universe produced len(tokenizer) == 9 because seven special tokens are included. Preserve:

  • universe bytes, row order, and assembly;
  • Gtars version;
  • special_tokens_map and every special-token ID;
  • tokenizer length;
  • token-corpus schema and checksum.

Run the local compatibility planner:

python skills/geniml/scripts/tokenizer_compatibility.py \
  --model-dir models/region2vec \
  --universe refs/universe.bed \
  --assembly GRCh38
Raw lines 117 to 150
Runs code python skills/geniml/scripts/tokenizer_compatibility.py :145
151### Legacy hard tokenization
153The stable file `geniml.tokenization.main` defines:
155```python
156hard_tokenization_main(
157 src_folder,
158 dst_folder,
159 universe_file,
160 fraction=1e-9,
161 file_list=None,
162 num_workers=10,
163 bedtools_path="bedtools",
165```
167It invokes an external Bedtools executable and multiprocessing. The
168`fraction` is passed to interval intersection logic; it is **not a statistical
169p-value**. The package `geniml.tokenization.__init__` comments out its public
170exports, so `from geniml.tokenization import hard_tokenization` and the
171installed `geniml tokenize` dispatcher are unreliable in 0.8.4.
173Do not use an arbitrary `bedtools` found on `PATH`. If reproducing the legacy
174path, pin and checksum the binary, pass an explicit absolute path, validate
175argv, bound workers, use a fresh output directory, and compare synthetic
176results with the Gtars tokenizer.
178The current preferred token corpus is a bounded Parquet file with one
179list-valued `tokens` column. Upstream issue #14 proposes deprecating one
180`.gtok` file per cell.

Legacy hard tokenization

The stable file geniml.tokenization.main defines:

hard_tokenization_main(
    src_folder,
    dst_folder,
    universe_file,
    fraction=1e-9,
    file_list=None,
    num_workers=10,
    bedtools_path="bedtools",
)

It invokes an external Bedtools executable and multiprocessing. The fraction is passed to interval intersection logic; it is not a statistical p-value. The package geniml.tokenization.__init__ comments out its public exports, so from geniml.tokenization import hard_tokenization and the installed geniml tokenize dispatcher are unreliable in 0.8.4.

Do not use an arbitrary bedtools found on PATH. If reproducing the legacy path, pin and checksum the binary, pass an explicit absolute path, validate argv, bound workers, use a fresh output directory, and compare synthetic results with the Gtars tokenizer.

The current preferred token corpus is a bounded Parquet file with one list-valued tokens column. Upstream issue #14 proposes deprecating one .gtok file per cell.

Raw lines 151 to 181
182## BBClient and cache behavior
184```python
185from geniml.bbclient import BBClient
187client = BBClient(cache_folder="/absolute/project/.bbcache")
188```
190Release defaults:
192- endpoint: `BEDBASE_API` or `https://api.bedbase.org`;
193- cache root: `BBCLIENT_CACHE` or `~/.bbcache`;
194- BEDs under `bedfiles/`;
195- BED sets under `bedsets/`;
196- token cache in `tokens.zarr`.
198`load_bed`, `load_bedset`, `load_bed_tokens`, `add_bed_tokens_to_cache`,
199and corresponding `cache-*` CLI commands may use the network on a cache miss.
200`cache_tokens` itself writes local data. The S3 convenience methods
201`add_bed_to_s3` and `get_bed_from_s3` are deprecated; use a separately
202reviewed boto3/s3fs workflow for an explicitly requested cloud transfer.
204The released client and current BEDhost source agree on these read routes:
206| Operation | Request | Response contract |
207| --- | --- | --- |
208| BED file | `GET /v1/objects/bed.{bed_id}.bed_file/access/http/bytes` | File bytes; server may redirect to its object store. |
209| BEDset members | `GET /v1/bedset/{bedset_id}/bedfiles` | JSON `results`, with each member's `id`; this route declares no pagination arguments. |
210| Token cache location | `GET /v1/bed/{bed_id}/tokens/{universe_id}/info` | JSON `file_path` and `endpoint_url` for a separate S3/Zarr read; missing tokens return 404. |
212These methods send no request body or API-authentication header. Public route
213source declares no authentication dependency. No invented bearer-token setup
214or pagination loop is needed. A deployment can impose its own access policy.
215Live `openapi.json` retrieval returned HTTP 403 in this review, so this table
216is source-verified and request-mocked, not a successful production download.
218Important release behavior:
220- BED and BEDset routes use `self.bedbase_api`; token-location requests use
221 `DEFAULT_BEDBASE_API` captured at import time, ignoring the instance setting.
222 Passing a private endpoint to the constructor does not contain token requests.
223- Calls have no timeout, stream bound, or general retry handling. BEDset
224 loading reads one complete response and downloads every listed BED; bound
225 the requested collection before invoking it. Tokens can contact the separate
226 `endpoint_url` returned by metadata.
227- `BEDBASE_API` and `BBCLIENT_CACHE` defaults are read at module import time;
228 changing them afterward does not update existing defaults. Explicit cache
229 paths are preferable.
230- BEDbase identifiers are content identifiers, not automatically SHA-256
231 checksums of the compressed file. Record your own digest and validate
232 assembly/coordinates after retrieval.
234Local-oriented CLI:
236```text
237geniml bbclient seek ID --cache-folder CACHE
238geniml bbclient inspect-bedfiles --cache-folder CACHE
239geniml bbclient inspect-bedsets --cache-folder CACHE
240geniml bbclient rm ID --cache-folder CACHE
241```
243`rm` mutates cache state; confirm the exact resolved target first. Inspection
244can still expose BED IDs and local paths, so redact output in shared logs.
246Before an approved download:
2481. approve endpoint and exact IDs;
2492. set a project-scoped cache and byte quota;
2503. reject redirects to unapproved hosts where tooling permits;
2514. verify compressed and expanded size;
2525. checksum downloaded bytes;
2536. validate BED and assembly;
2547. record provenance and retrieval time.
256No bundled skill script performs BBClient or Hub downloads.

BBClient and cache behavior

from geniml.bbclient import BBClient

client = BBClient(cache_folder="/absolute/project/.bbcache")

Release defaults:

  • endpoint: BEDBASE_API or https://api.bedbase.org;
  • cache root: BBCLIENT_CACHE or ~/.bbcache;
  • BEDs under bedfiles/;
  • BED sets under bedsets/;
  • token cache in tokens.zarr.

load_bed, load_bedset, load_bed_tokens, add_bed_tokens_to_cache, and corresponding cache-* CLI commands may use the network on a cache miss. cache_tokens itself writes local data. The S3 convenience methods add_bed_to_s3 and get_bed_from_s3 are deprecated; use a separately reviewed boto3/s3fs workflow for an explicitly requested cloud transfer.

The released client and current BEDhost source agree on these read routes:

OperationRequestResponse contract
BED fileGET /v1/objects/bed.{bed_id}.bed_file/access/http/bytesFile bytes; server may redirect to its object store.
BEDset membersGET /v1/bedset/{bedset_id}/bedfilesJSON results, with each member's id; this route declares no pagination arguments.
Token cache locationGET /v1/bed/{bed_id}/tokens/{universe_id}/infoJSON file_path and endpoint_url for a separate S3/Zarr read; missing tokens return 404.

These methods send no request body or API-authentication header. Public route source declares no authentication dependency. No invented bearer-token setup or pagination loop is needed. A deployment can impose its own access policy. Live openapi.json retrieval returned HTTP 403 in this review, so this table is source-verified and request-mocked, not a successful production download.

Important release behavior:

  • BED and BEDset routes use self.bedbase_api; token-location requests use DEFAULT_BEDBASE_API captured at import time, ignoring the instance setting. Passing a private endpoint to the constructor does not contain token requests.
  • Calls have no timeout, stream bound, or general retry handling. BEDset loading reads one complete response and downloads every listed BED; bound the requested collection before invoking it. Tokens can contact the separate endpoint_url returned by metadata.
  • BEDBASE_API and BBCLIENT_CACHE defaults are read at module import time; changing them afterward does not update existing defaults. Explicit cache paths are preferable.
  • BEDbase identifiers are content identifiers, not automatically SHA-256 checksums of the compressed file. Record your own digest and validate assembly/coordinates after retrieval.

Local-oriented CLI:

geniml bbclient seek ID --cache-folder CACHE
geniml bbclient inspect-bedfiles --cache-folder CACHE
geniml bbclient inspect-bedsets --cache-folder CACHE
geniml bbclient rm ID --cache-folder CACHE

rm mutates cache state; confirm the exact resolved target first. Inspection can still expose BED IDs and local paths, so redact output in shared logs.

Before an approved download:

  1. approve endpoint and exact IDs;
  2. set a project-scoped cache and byte quota;
  3. reject redirects to unapproved hosts where tooling permits;
  4. verify compressed and expanded size;
  5. checksum downloaded bytes;
  6. validate BED and assembly;
  7. record provenance and retrieval time.

No bundled skill script performs BBClient or Hub downloads.

Raw lines 182 to 257
258## Model loading and artifact safety
260Modern local classes:
262```python
263from geniml.region2vec.main import Region2VecExModel
264from geniml.scembed.main import ScEmbed
266r2v = Region2VecExModel.from_pretrained("models/region2vec")
267sce = ScEmbed.from_pretrained("models/scembed")
268```
270These classmethods use local bundle paths. Constructors with
271`model_path="organization/model"` call Hugging Face Hub and download
272`checkpoint.pt`, `universe.bed`, and `config.yaml`. Their constructors silently
273discard revision/cache/offline kwargs; call the Hub download API directly at a
274reviewed commit for authorized downloads, then use the local classmethod.
276Geniml's loader uses `torch.load(..., weights_only=True)` and YAML
277`safe_load`. This is safer than unrestricted pickle, but artifacts can still
278cause resource exhaustion or exploit parser/native-library vulnerabilities.
279Gensim `.model`, pickle, joblib, TorchScript, shared libraries, and external
280binaries require even stronger distrust.
282Inspect without importing Torch or deserializing:
284```bash
285python skills/geniml/scripts/model_artifact_inspector.py \
286 --model-dir models/region2vec \
287 --verify-manifest models/region2vec/SHA256SUMS
288```
290The inspector reads bounded metadata formats, hashes bytes, flags risky
291extensions, rejects URLs/symlinks/traversal, and never loads model objects.

Model loading and artifact safety

Modern local classes:

from geniml.region2vec.main import Region2VecExModel
from geniml.scembed.main import ScEmbed

r2v = Region2VecExModel.from_pretrained("models/region2vec")
sce = ScEmbed.from_pretrained("models/scembed")

These classmethods use local bundle paths. Constructors with model_path="organization/model" call Hugging Face Hub and download checkpoint.pt, universe.bed, and config.yaml. Their constructors silently discard revision/cache/offline kwargs; call the Hub download API directly at a reviewed commit for authorized downloads, then use the local classmethod.

Geniml's loader uses torch.load(..., weights_only=True) and YAML safe_load. This is safer than unrestricted pickle, but artifacts can still cause resource exhaustion or exploit parser/native-library vulnerabilities. Gensim .model, pickle, joblib, TorchScript, shared libraries, and external binaries require even stronger distrust.

Inspect without importing Torch or deserializing:

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

The inspector reads bounded metadata formats, hashes bytes, flags risky extensions, rejects URLs/symlinks/traversal, and never loads model objects.

Raw lines 258 to 292
Runs code python skills/geniml/scripts/model_artifact_inspector.py :285
293## Embedding evaluation
295The `geniml eval` release CLI has:
297```text
298gdst Genome distance scaling test
299npt Neighborhood preserving test
300ctt Cluster tendency test
301rct Reconstruction test
302bin-gen Generate binary embeddings
303```
305Examples:
307```bash
308geniml eval gdst \
309 --model-path /absolute/project/model \
310 --embed-type exmodel \
311 --num-samples 10000 \
312 --seed 42
314geniml eval npt \
315 --model-path /absolute/project/model \
316 --embed-type exmodel \
317 --K 10 \
318 --num-samples 1000 \
319 --seed 42 \
320 --num-workers 4
321```
323`exmodel` selects a modern local bundle; `region2vec` selects a legacy
324Gensim model file. The modern loader and its special-token filtering were
325executed. Full CTT/RCT/GDST/NPT calculations are illustrative templates here.
326Check that every retained region vector was actually trained before a metric
327calculation; removing special vectors alone does not establish that.
329The official tutorial's `BaseEmbeddings` and `bin-gen` workflows use pickle
330for binary embedding objects. Generate them locally and never load an
331untrusted pickle. Bound samples/workers and record random seeds. Evaluate on
332patients/donors excluded from universe selection and training.
334Primary source: Zheng et al. (2024), *Methods for evaluating unsupervised
335vector representations of genomic regions*,
336doi:[10.1093/nargab/lqae086](https://doi.org/10.1093/nargab/lqae086).

Embedding evaluation

The geniml eval release CLI has:

gdst     Genome distance scaling test
npt      Neighborhood preserving test
ctt      Cluster tendency test
rct      Reconstruction test
bin-gen  Generate binary embeddings

Examples:

geniml eval gdst \
  --model-path /absolute/project/model \
  --embed-type exmodel \
  --num-samples 10000 \
  --seed 42

geniml eval npt \
  --model-path /absolute/project/model \
  --embed-type exmodel \
  --K 10 \
  --num-samples 1000 \
  --seed 42 \
  --num-workers 4

exmodel selects a modern local bundle; region2vec selects a legacy Gensim model file. The modern loader and its special-token filtering were executed. Full CTT/RCT/GDST/NPT calculations are illustrative templates here. Check that every retained region vector was actually trained before a metric calculation; removing special vectors alone does not establish that.

The official tutorial's BaseEmbeddings and bin-gen workflows use pickle for binary embedding objects. Generate them locally and never load an untrusted pickle. Bound samples/workers and record random seeds. Evaluate on patients/donors excluded from universe selection and training.

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

Raw lines 293 to 337
338## BEDshift
340The integrated Bedshift CLI is:
342```text
343geniml bedshift --help
344```
346It can use a local chromosome-length file or resolve a Refgenie genome through
347`refgenconf`. Prefer an explicit, checksummed local chromosome-sizes file to
348avoid implicit lookup/network behavior. Set a seed, output bound, and
349perturbation policy matching the null hypothesis. Validate randomized
350coordinates exactly like originals.
352Primary source: Gu et al. (2021), *Bedshift: perturbation of genomic interval
353sets*, doi:[10.1186/s13059-021-02440-w](https://doi.org/10.1186/s13059-021-02440-w).

BEDshift

The integrated Bedshift CLI is:

geniml bedshift --help

It can use a local chromosome-length file or resolve a Refgenie genome through refgenconf. Prefer an explicit, checksummed local chromosome-sizes file to avoid implicit lookup/network behavior. Set a seed, output bound, and perturbation policy matching the null hypothesis. Validate randomized coordinates exactly like originals.

Primary source: Gu et al. (2021), Bedshift: perturbation of genomic interval sets, doi:10.1186/s13059-021-02440-w.

Raw lines 338 to 354
355## Privacy and bounded reporting
357Potentially sensitive:
359- BED coordinates and filenames;
360- sample, donor, patient, treatment, diagnosis, and tissue metadata;
361- cell barcodes and rare labels;
362- embeddings that permit membership or nearest-neighbor inference;
363- local cache paths and BEDbase identifiers.
365Default reports should contain only aggregate counts, schema names, checksums,
366software versions, and redacted file IDs. Cap error examples; never dump
367entire malformed rows or metadata values. Store full provenance manifests in
368the protected project, not chat output.

Privacy and bounded reporting

Potentially sensitive:

  • BED coordinates and filenames;
  • sample, donor, patient, treatment, diagnosis, and tissue metadata;
  • cell barcodes and rare labels;
  • embeddings that permit membership or nearest-neighbor inference;
  • local cache paths and BEDbase identifiers.

Default reports should contain only aggregate counts, schema names, checksums, software versions, and redacted file IDs. Cap error examples; never dump entire malformed rows or metadata values. Store full provenance manifests in the protected project, not chat output.

Raw lines 355 to 369
370## Migration and deprecation ledger
372- 0.4.0: tokenizers renamed to `TreeTokenizer` and `AnnDataTokenizer`.
373- 0.7.0: RegionSet use moved toward Gtars and encoding changed.
374- 0.8.0: Atacformer added.
375- 0.8.1: BEDspace fixed according to the changelog.
376- 0.8.4: latest stable; release notes contain only the version bump.
377- Current Gtars API: use the unified `gtars.tokenizers.Tokenizer`.
378- `.gtok`: proposed for deprecation in upstream issue #14; prefer Parquet.
379- `embedding_size`: backward-compatible config key; use `embedding_dim`.
380- Top-level Region2Vec/scEmbed/tokenization exports shown by old docs are
381 absent/commented in the 0.8.4 wheel.
382- Official `geniml assess` examples are stale; use
383 `geniml assess-universe`.

Migration and deprecation ledger

  • 0.4.0: tokenizers renamed to TreeTokenizer and AnnDataTokenizer.
  • 0.7.0: RegionSet use moved toward Gtars and encoding changed.
  • 0.8.0: Atacformer added.
  • 0.8.1: BEDspace fixed according to the changelog.
  • 0.8.4: latest stable; release notes contain only the version bump.
  • Current Gtars API: use the unified gtars.tokenizers.Tokenizer.
  • .gtok: proposed for deprecation in upstream issue #14; prefer Parquet.
  • embedding_size: backward-compatible config key; use embedding_dim.
  • Top-level Region2Vec/scEmbed/tokenization exports shown by old docs are absent/commented in the 0.8.4 wheel.
  • Official geniml assess examples are stale; use geniml assess-universe.
Raw lines 370 to 384
385## Dated authoritative sources
387Package and source:
389- [PyPI: geniml 0.8.4](https://pypi.org/project/geniml/0.8.4/) — released
390 2026-01-14; accessed 2026-10-01.
391- [PyPI JSON: geniml 0.8.4](https://pypi.org/pypi/geniml/0.8.4/json) —
392 artifact hashes, dependencies, extras, and null `Requires-Python`; accessed
393 2026-10-01.
394- [GitHub release v0.8.4](https://github.com/databio/geniml/releases/tag/v0.8.4)
395 — commit `5e8dd14126c45d14917df74de4fb405f383afb61`; released
396 2026-01-14; accessed 2026-10-01.
397- [Geniml changelog](https://docs.bedbase.org/geniml/changelog/) — through
398 0.8.1 on the rendered page; accessed 2026-10-01.
399- [PyPI: gtars 0.10.0](https://pypi.org/project/gtars/0.10.0/) — released
400 2026-09-05; accessed 2026-10-01.
402Official API/ecosystem documentation:
404- [Geniml documentation](https://docs.bedbase.org/geniml/) — accessed
405 2026-10-01.
406- [Geniml I/O API](https://docs.bedbase.org/geniml/api-reference/io/) —
407 accessed 2026-10-01.
408- [Gtars RegionSet](https://docs.bedbase.org/gtars/regionSet) — accessed
409 2026-10-01.
410- [Gtars tokenizers](https://docs.bedbase.org/gtars/tokenizers) — accessed
411 2026-10-01.
412- [BEDbase reference-genome compatibility](https://docs.bedbase.org/bedbase/user/reference-genome-compatibility/)
413 — accessed 2026-10-01.
414- [BEDbase BBClient and caching](https://docs.bedbase.org/bedbase/user/bbclient/)
415 — accessed 2026-10-01.
416- [Geniml evaluation tutorial](https://docs.bedbase.org/geniml/tutorials/evaluation/)
417 — accessed 2026-10-01.
418- [Official citation map](https://docs.bedbase.org/citations) — accessed
419 2026-10-01.
421Primary papers:
423- [Gharavi et al. 2021, Region2Vec](https://doi.org/10.1093/bioinformatics/btab439)
424- [Gu et al. 2021, BEDshift](https://doi.org/10.1186/s13059-021-02440-w)
425- [Gharavi et al. 2024, BEDspace](https://doi.org/10.3390/bioengineering11030263)
426- [LeRoy et al. 2024, scEmbed](https://doi.org/10.1093/nargab/lqae073)
427- [Rymuza et al. 2024, consensus universes](https://doi.org/10.1093/nar/gkae685)
428- [Zheng et al. 2024, embedding evaluation](https://doi.org/10.1093/nargab/lqae086)

Dated authoritative sources

Package and source:

Official API/ecosystem documentation:

Primary papers:

Raw lines 385 to 429
430## Current source and execution boundaries
432- [Released Region2Vec implementation](https://github.com/databio/geniml/blob/v0.8.4/geniml/region2vec/main.py),
433 [export/load utilities](https://github.com/databio/geniml/blob/v0.8.4/geniml/region2vec/utils.py),
434 [scEmbed implementation](https://github.com/databio/geniml/blob/v0.8.4/geniml/scembed/main.py),
435 and [tokenization](https://github.com/databio/geniml/blob/v0.8.4/geniml/tokenization/utils.py)
436 were checked against the SHA-256-verified released wheel, not master.
437- [Released BBClient](https://github.com/databio/geniml/blob/v0.8.4/geniml/bbclient/bbclient.py)
438 and [route constants](https://github.com/databio/geniml/blob/v0.8.4/geniml/bbclient/const.py)
439 were checked with mocked requests and a local Zarr cache.
440- Current server source at commit `864eeddab6900249e05f4fc84a171890ac997877`:
441 [objects](https://github.com/databio/bedhost/blob/864eeddab6900249e05f4fc84a171890ac997877/bedhost/routers/objects_api.py),
442 [BEDsets](https://github.com/databio/bedhost/blob/864eeddab6900249e05f4fc84a171890ac997877/bedhost/routers/bedset_api.py),
443 [token metadata](https://github.com/databio/bedhost/blob/864eeddab6900249e05f4fc84a171890ac997877/bedhost/routers/bed_api.py).
444 This does not prove that production runs that commit.
445- [AnnData release notes](https://anndata.readthedocs.io/en/stable/release-notes/)
446 and [0.13.4 metadata](https://pypi.org/pypi/anndata/0.13.4/json) establish the
447 separate Zarr 3 environment boundary.
448- [Released Annotator](https://github.com/databio/geniml/blob/v0.8.4/geniml/scembed/annotation.py)
449 still uses the removed search API; [Qdrant query documentation](https://python-client.qdrant.tech/qdrant_client.qdrant_client)
450 documents `query_points`. Qdrant 1.19.1 client API was inspected locally;
451 no hosted annotation or credentialed call was executed.
452- No model weights, human cohort data, or large genomes were downloaded. No
453 StarSpace native build, HMM/ML/CCF end-to-end run, or external annotation
454 service was executed. Their source contracts are illustrative until a
455 project-specific synthetic smoke passes.

Current source and execution boundaries

Raw lines 430 to 455