Metadata-Version: 2.5
Name: altar-opentargets-e2g
Version: 0.3.0
Summary: Open Targets ENCODE-rE2G binding for Altar's variant-gene link contract
Project-URL: Documentation, https://kundajelab.github.io/altar/
Author: Riya Sinha
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: altar[gcs]<0.4,>=0.3.0
Provides-Extra: build
Requires-Dist: altar[http]<0.4,>=0.3.0; extra == 'build'
Requires-Dist: duckdb>=1.0.0; extra == 'build'
Requires-Dist: pyarrow>=17.0.0; extra == 'build'
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.24; extra == 'test'
Requires-Dist: pytest>=8; extra == 'test'
Description-Content-Type: text/markdown

# altar-opentargets-e2g

This binding reads the Open Targets Platform `enhancer_to_gene` dataset: ENCODE-rE2G predictions of which genes
a regulatory element regulates, which Open Targets keeps at score ≥ 0.6. It gives the data two shapes:

- `opentargets_e2g`, an annotation source (`OpenTargetsE2GAnnotationSource`), adds Altar's variant–gene link
  columns to each variant, from a Parquet link dataset: the copy the Kundaje lab publishes, or one you own.
- `OpenTargetsE2GSource`, a `VariantGeneLinkSource`, pages the full link records from any
  `VariantGeneLinkStore` that `OpenTargetsE2GImporter` filled.

Both map an upstream row through `OpenTargetsE2GRow`, so a link carries the same gene, score, biosample and
provenance either way.

## Annotate variants from the published copy

The Kundaje lab publishes Open Targets release 26.09 (2026-09-24, GRCh38) as a link dataset
(`PUBLISHED_DATASET`):

| Location | URI |
| --- | --- |
| `gcs` (default) | `gs://kundajelab-altar/opentargets-e2g/enhancer-to-gene-26.09` |
| `hf` | `hf://datasets/altar-genomics/opentargets-e2g-26.09` ([dataset card](https://huggingface.co/datasets/altar-genomics/opentargets-e2g-26.09)) |

A run spec reads it with no options; the package depends on `altar[gcs]`, and the `hf` mirror needs `altar[hf]`:

```toml
[sources.e2g]
type = "opentargets_e2g"
```

Hugging Face limits anonymous requests, so a large cohort read with `location = "hf"` can stall; read the bucket, or
pull a copy and name it with `dataset` ([published locations](https://kundajelab.github.io/altar/guides/published-datasets/#published-locations)).

In Python:

```python
import asyncio

from altar_opentargets_e2g import OpenTargetsE2GAnnotationSource

source = OpenTargetsE2GAnnotationSource.from_options()  # the published copy
rows = asyncio.run(source.annotate(["chr7:140924700:C:T"]))  # in BRAF's promoter
rows["chr7:140924700:C:T"]["link_top_gene"]  # 'ENSG00000157764', BRAF
```

Each annotated variant gets the `org.kundajelab.altar.annotation.variant-gene-links` columns (version 1.0.0):
`link_top_gene`, `link_top_gene_symbol`, `link_top_score`, `link_gene_count`, `link_count`, and `link_genes`, a
list of every link whose element overlaps the variant, strongest first, each with its gene, score, biosample,
element and provenance. A variant with no overlapping link has no row. Open Targets gives no gene symbols, so
`link_top_gene_symbol` and `gene_symbol` are empty.

`altar pull opentargets_e2g --to <dir>` copies the published dataset, checking each file's release; name the copy
with `dataset`. `altar pull opentargets_e2g --bigquery <project.dataset.table>` loads it into BigQuery, clustered on
`chromosome, start`; name the table with `table` and a `gcp` connection. The options:

| Option | Meaning |
| --- | --- |
| `dataset` | An owned link dataset, as a path or a URI (another release built with the builder below is fine). |
| `table`, `release` | An owned BigQuery table, read through a `gcp` `connection`, and the release it holds (default `26.09`). |
| `location` | `gcs` (default) or `hf`, for the published copy. |
| `connection`, `storage_options` | How to reach a bucket. |
| `filters` | Which links to keep: `context_names` (biosample names, such as `["liver"]`), `context_ids`, `gene_ids`, `source_ids`, `methods`, `data_releases`, `minimum_score`, `maximum_score`. |
| `column_prefix`, `name` | Prefix the columns and rename the source, to sit beside another link source. |
| `genome_build` | Optional; must be `hg38`. The source serves hg38 only, so `altar run` refuses it for a cohort on another build. |
| `prioritize_predicate` | In code only: a predicate over the columns that gates `prioritized`. |

A table's release labels are checked when the source is built, and `annotate` runs one range-join query per 10,000
variants; a query over scattered variants reads most of the table, about 12–15 GB billed for 26.09 whatever the
cohort's size. `release` without a `table` is refused, since the files record their own, and an unknown option,
filter or `location` raises a `ValueError` that lists the valid ones. The identity is the contract with the
dataset's release and `hg38`; with filters, the release gains a fingerprint of them (`26.09+<hash>`).

## Build a link dataset

```console
pip install "altar-opentargets-e2g[build]"
altar-opentargets-e2g-build --input <the release's enhancer_to_gene files or directory> \
  --release 26.09 --output /scratch/opentargets-e2g-26.09
```

`--input` takes Parquet files or directories, local paths or URIs (`https://` needs the `build` extra). The
builder reads release 26.03 and later and refuses older files, whose coordinates were 32-bit and which lack
`biosampleFromSourceId` and `qualityControls`. It refuses a row scored below 0.6, since it records the threshold
as applied. It maps each row with `OpenTargetsE2GRow.from_source_mapping(...).to_evidence_record(...)`, one process
per file (`--workers`), drops a row that repeats an `intervalId` only when the whole upstream row is identical,
and stops when two rows sharing an `intervalId` differ. `write_link_dataset` then writes one row per link,
Hive-partitioned by `chromosome=`, sorted by `start`, in 32,000-row groups, with the release, `hg38` and the
dataset recorded in every footer. The output is a local directory; copy it to a bucket yourself.

## Import into a link store

```python
import asyncio
from collections.abc import Iterable, Mapping
from typing import Any

from altar.sources import InMemoryVariantGeneLinkStore
from altar_opentargets_e2g import (
    OpenTargetsE2GImportConfig,
    OpenTargetsE2GImporter,
    OpenTargetsE2GRow,
    OpenTargetsE2GSource,
)


async def import_release(upstream_rows: Iterable[Mapping[str, Any]]) -> OpenTargetsE2GSource:
    store = InMemoryVariantGeneLinkStore()
    await OpenTargetsE2GImporter(store).ingest(
        (OpenTargetsE2GRow.from_source_mapping(row) for row in upstream_rows),
        OpenTargetsE2GImportConfig(data_release="26.09", score_threshold=0.6, threshold_applied=True),
        generation_id="sha256-of-the-source-asset",
    )
    return OpenTargetsE2GSource(store)


source = asyncio.run(import_release(upstream_rows))  # the enhancer_to_gene rows, as mappings
```

The importer accepts an iterable, so large releases stream in bounded batches. `from_source_mapping()` accepts the
official camelCase `enhancer_to_gene` fields. Pass the score threshold and whether it was applied in
`OpenTargetsE2GImportConfig`; Altar keeps those semantics in every `LinkScore` rather than treating the released
table as raw predictions. The caller supplies a generation identifier for the exact extraction: partial
generations stay hidden, exact replay is idempotent, and a generation is published only after the iterable
completes. Use `VariantGeneLinkQuery.data_releases` when a store holds more than one release. See the
[Open Targets dataset documentation](https://platform-docs.opentargets.org/data-access/datasets) and the
[rE2G documentation](https://platform-docs.opentargets.org/gentropy/enhancer-to-gene).

## Data terms and citation

Open Targets Platform data is released under [CC0 1.0](https://platform-docs.opentargets.org/licence). Please
cite:

- Buniello A, et al. Open Targets Platform: facilitating therapeutic hypotheses building in drug discovery.
  *Nucleic Acids Research* 2025;53(D1):D1467–D1475. doi:10.1093/nar/gkae1128.
- Gschwind AR, et al. An encyclopedia of enhancer-gene regulatory interactions in the human genome. bioRxiv 2023.
  doi:10.1101/2023.11.09.563812. PMID 38014075.
- The ENCODE Project Consortium, and the ENCODE prediction files (`ENCFF…`) you rely on. Open Targets names each
  row's file in its `studyId` column; the link dataset keeps the row's `intervalId` as `source_record_id`.

[Cite these data](https://kundajelab.github.io/altar/integrations/evidence/#cite-these-data) lists these with the
other datasets Altar publishes.

The binding ships no data. The contract is imported from `altar`; the binding is versioned independently and
tested against Altar's conformance suites.
