Liftover chains

Liftover chains convert genomic coordinates from one reference genome assembly to another, for example from hg19 to hg38. A liftover chain resource contains a UCSC chain file describing how regions of the two assemblies align. GAIn provides the LiftoverChain Python class for performing these conversions using pyliftover.

Accessing a liftover chain

A LiftoverChain object can be built from a resource ID and a repository using build_liftover_chain_from_resource_id():

import gain.grr as grr

repo = grr.build_genomic_resource_repository()
chain = grr.build_liftover_chain_from_resource_id(
    "liftover/hg19_to_hg38", repo
)

If you already have a GenomicResource object, use build_liftover_chain_from_resource() instead:

resource = repo.get_resource("liftover/hg19_to_hg38")
chain = grr.build_liftover_chain_from_resource(resource)

Both builder functions are available through gain.grr. GAIn reuses the same LiftoverChain object when a resource is requested more than once, so the returned object may already be open.

Opening and closing a liftover chain

A newly built LiftoverChain object must be opened before converting coordinates. Call open() to load the chain file. The method returns the object itself, allowing .open() to be chained to the builder. Calling open() on an already-open chain has no effect. Use is_open() to check its state.

Unlike a genomic score, a liftover chain is not a context manager and cannot be used in a with block. It has a close() method for consistency with other resource objects, but this method does not release any resources. Because repeated builds can return the same object, its state may be shared by different parts of a program.

Converting genomic coordinates

convert_coordinate() takes a chromosome name and a 1-based genomic position. It returns a tuple containing the chromosome and 1-based position in the target assembly, the target strand, and the chain score.

chain.open()
print(chain.convert_coordinate("chr1", 1_000_000))
print(chain.convert_coordinate("chr1", 5_000_000))
chain.close()
('chr1', 1064620, '+', 20851231461)
('chr1', 4939940, '+', 20851231461)

The results depend on the alignments in the chain file. If a position does not lie within any aligned block, convert_coordinate() returns None. A successfully converted position may retain the same chromosome name or numerical coordinate, so None is the indicator of an unsuccessful conversion. If a position maps to more than one target location, the method returns the first mapping.

Chromosome naming conventions

Reference assemblies may use different chromosome naming conventions, such as chr1 and 1. The optional chrom_prefix: configuration in a liftover chain resource specifies how names are adjusted before and after conversion. The variant_coordinates subsection transforms the input chromosome name before it is passed to the chain, while target_coordinates transforms the chromosome name returned by the chain.

These transformations allow callers to use the contig names expected by their input and target genomes without manually renaming them for the chain file. The configuration options, including adding or removing prefixes, are described in Genomic resources and repositories.

API

The class and the builders below are defined in the module gain.genomic_resources.liftover_chain. LiftoverChain is also exported by gain.grr, as grr.LiftoverChain. The builders are also exported by gain.grr, as grr.build_liftover_chain_from_resource_id and grr.build_liftover_chain_from_resource.

build_liftover_chain_from_resource(resource)

Build the liftover chain of a resource.

build_liftover_chain_from_resource_id(...[, grr])

Build the liftover chain of a resource, found by its id.

LiftoverChain(resource)

Convert coordinates between assemblies with a UCSC chain file.

LiftoverChain.close()

Do nothing: a chain holds no resource to release.

LiftoverChain.convert_coordinate(chrom, pos)

Lift over a genomic coordinate.

LiftoverChain.files

Return the names of the files of the resource that the chain uses.

LiftoverChain.get_schema()

Return the cerberus schema of the resource configuration.

LiftoverChain.is_open()

Return True when the chain file is read.

LiftoverChain.map_chromosome(chrom, mapping)

Rename a chromosome (contig) name.

LiftoverChain.open()

Read the chain file.

build_liftover_chain_from_resource(resource: GenomicResource) → LiftoverChain[source]

Build the liftover chain of a resource.

The chain is memoized for each resource. A second call for the same resource returns the same chain, which may already be open.

Parameters:

resource (GenomicResource) – A resource of type liftover_chain.

Returns:

The chain. It is not open until the caller calls open.

Return type:

LiftoverChain

Raises:

ValueError – If resource is None or its type is not liftover_chain.

build_liftover_chain_from_resource_id(resource_id: str, grr: GenomicResourceRepo | None = None) → LiftoverChain[source]

Build the liftover chain of a resource, found by its id.

Parameters:
  • resource_id (str) – The id of a resource of type liftover_chain.

  • grr (GenomicResourceRepo, optional) – The repository to search. The default repository is built when this is None.

Returns:

The memoized chain. It may already be open.

Return type:

LiftoverChain

Raises:
  • FileNotFoundError – If the repository has no resource with this id.

  • ValueError – If the type of the resource is not liftover_chain.

class LiftoverChain(resource: GenomicResource)[source]

Convert coordinates between assemblies with a UCSC chain file.

The class wraps a pyliftover object. Build it with build_liftover_chain_from_resource_id and call open before the first conversion.

Parameters:

resource (GenomicResource) – A resource of type liftover_chain.

Variables:
  • resource (GenomicResource) – The resource that holds the chain file.

  • config (dict) – The validated and normalized resource configuration.

  • source_genome_id (str or None) – The id from the source_genome label, or None when the label is absent or unusable.

  • target_genome_id (str or None) – The id from the target_genome label, or None when the label is absent or unusable.

Raises:

ValueError – If the type of the resource is not liftover_chain.

close() → None[source]

Do nothing: a chain holds no resource to release.

convert_coordinate(chrom: str, pos: int) → tuple[str, int, str, int] | None[source]

Lift over a genomic coordinate.

The variant_coordinates rename applies before the lift and the target_coordinates rename applies after it.

Parameters:
  • chrom (str) – The contig name in the naming of the caller.

  • pos (int) – The 1-based position.

Returns:

The target contig, the target 1-based position, the strand of the target and the chain score. None when the position is in no aligned block of the chain. When the chain maps the position to more than one target, the first one is returned.

Return type:

tuple of (str, int, str, int) or None

property files: set[str]

Return the names of the files of the resource that the chain uses.

static get_schema() → dict[str, Any][source]

Return the cerberus schema of the resource configuration.

Returns:

The schema. It has the filename key and the optional chrom_prefix block with variant_coordinates and target_coordinates.

Return type:

dict

is_open() → bool[source]

Return True when the chain file is read.

static map_chromosome(chrom: str, mapping: dict[str, str] | None) → str[source]

Rename a chromosome (contig) name.

Parameters:
  • chrom (str) – The contig name.

  • mapping (dict, optional) – A chrom_prefix entry. Its del_prefix is removed first, then its add_prefix is prepended.

Returns:

The renamed contig. The name is unchanged when mapping is None or empty.

Return type:

str

open() → LiftoverChain[source]

Read the chain file.

Returns:

This chain, so the call chains. A call on an open chain does nothing.

Return type:

LiftoverChain