# MAF track

**TL;DR:** a `MafTrack` (with a `LinearMafDisplay`) shows a multiple alignment
of several species against a reference, one row per species with a coverage
summary on top. JBrowse reads three formats (BigMaf, tabix MAF, bgzipped TAF).
Supply the species with a `samples` array, an `nhLocation` Newick tree, or both.

A MAF track shows a multiple alignment of several species against a reference
genome: one row per aligned species, with a coverage summary on top. JBrowse
reads three formats, all configured as a `MafTrack` with a `LinearMafDisplay`.
For what the track looks like once loaded, see the
[MAF track user guide](https://jbrowse.org/jb2-staging/docs/user_guides/maf_track).

## Adapters

<!-- FILE_TYPES maf START -->

<!-- prettier-ignore -->
| Format | Adapter | Track type | Notes |
| --- | --- | --- | --- |
| BigMaf | [](https://jbrowse.org/jb2-staging/docs/config/bigmafadapter) | [](https://jbrowse.org/jb2-staging/docs/config/maftrack) |  |
| Indexed MAF (bgzip + .tai) | [](https://jbrowse.org/jb2-staging/docs/config/bgzipmafadapter) | [](https://jbrowse.org/jb2-staging/docs/config/maftrack) | A published whole-genome multiple alignment, read by locus |
| MAF (tabix) | [](https://jbrowse.org/jb2-staging/docs/config/maftabixadapter) | [](https://jbrowse.org/jb2-staging/docs/config/maftrack) |  |
| TAF (bgzipped Taffy) | [](https://jbrowse.org/jb2-staging/docs/config/bgziptaffyadapter) | [](https://jbrowse.org/jb2-staging/docs/config/maftrack) |  |

<!-- FILE_TYPES maf END -->

Provide the aligned species as one of the following (see
[below](#the-samples-array)):

- a `samples` array, in track order
- an `nhLocation` Newick tree, which both supplies the species and orders/labels
  the rows as a dendrogram
- both

Example using the tabix-indexed BED form (the UCSC ce11 26-way, ordered by its
phylogenetic tree). `MafTabixAdapter` takes the
[`uri` shorthand](https://jbrowse.org/jb2-staging/docs/config_guides/file_types#the-uri-shorthand), resolving
the sibling `.tbi`, plus an `nhUri` for the tree:

```json addtrack
{
  "type": "MafTrack",
  "trackId": "ce11.26way",
  "name": "UCSC 26-way multiple alignment",
  "assemblyNames": ["ce11"],
  "adapter": {
    "type": "MafTabixAdapter",
    "uri": "https://jbrowse.org/demos/ce/ce11.26way.bed.gz",
    "nhUri": "https://hgdownload.soe.ucsc.edu/goldenPath/ce11/multiz26way/ce11.26way.nh"
  }
}
```

`BigMafAdapter` is the one MAF adapter with no `uri` shorthand: it takes a
`bigBedLocation`, as in the 470-way example below, and may also carry the two
optional sub-adapters.

## The samples array

A [`samples`](https://jbrowse.org/jb2-staging/docs/config/maftabixadapter/#slot-samples) entry is either a bare
id string or an object. The id is the token matched against the MAF's `src`
column, haplotype suffix included, so a `hg38.chr1` row matches the sample
`hg38`. The object form adds:

- **`label`** — the sidebar label, for an id that is not itself readable.
- **`color`** — the row's color.
- **`assemblyName`** — the assembly this species' own genome is loaded as, which
  makes its rows navigable: right-clicking a drag selection then offers
  [that row's locus in the species' own coordinates](https://jbrowse.org/jb2-staging/docs/user_guides/maf_track#jumping-to-a-species-own-genome).
  Rows of a sample that leaves it unset are not offered. It has to be written
  out: ids are UCSC db names in some alignments, scientific names in others
  (which map to several assemblies) and lab-internal ids in others still, so a
  name lookup can land on the wrong genome and report coordinates that are
  silently wrong.
- **`assemblyConfigLocation`** — the config to load `assemblyName` out of when
  the session does not already have it. Omit it when the assembly is already in
  the config the user opened. A site hosting many genomes keeps one config per
  genome, so an alignment's species usually are not present in that config;
  JBrowse fetches just the named assembly from here at click time, which keeps a
  26-way or 470-way navigable. It is a `UriLocation`, so a relative uri resolves
  against the declaring config rather than against the page.

**A tree and a `samples` array compose**, which is how a tree-ordered alignment
also gets navigable rows. With an `nhLocation`/`nhUri` the tree's leaf names are
the sample set and the row order, and `samples` becomes an override table
matched by id; a leaf with no matching entry keeps its own name as its label.

This track has one row pointing at an assembly the config already holds, one
loading its assembly from a sibling config on click, and one plain row that is
not navigable:

```json addtrack
{
  "type": "MafTrack",
  "trackId": "volvox_maf_navigable",
  "name": "MAF multiple alignment (navigable rows)",
  "assemblyNames": ["volvox"],
  "adapter": {
    "type": "MafTabixAdapter",
    "uri": "volvox.maf.bed.gz",
    "samples": [
      { "id": "volvox", "label": "volvox", "assemblyName": "volvox" },
      {
        "id": "simvolvox",
        "label": "simvolvox",
        "assemblyName": "simvolvox",
        "assemblyConfigLocation": {
          "uri": "config_maf_nav_targets.json",
          "locationType": "UriLocation"
        }
      },
      { "id": "microvolvox", "label": "microvolvox" }
    ]
  }
}
```

The hosted
[`config_maf_navigation.json`](https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config_maf_navigation.json)
is the runnable version of that config, also reachable from the no-config
screen.

## Producing the tabix BED from a MAF

`MafTabixAdapter` reads a BED whose sixth column packs every row of an alignment
block as comma-separated `src:start:size:strand:srcSize:seq`, with the first
three columns giving that block's interval on the reference.
[maf2bed](https://github.com/cmdcolin/maf2bed) writes it. It takes the assembly
to use as the reference, so a `hg38.chr1` row becomes a `chr1` line and every
other species rides in column 6:

```bash
cargo install maf2bed

export LC_ALL=C  # sort and tabix have to agree on collation
maf2bed hg38 < file.maf | sort -k1,1 -k2,2n | bgzip > file.bed.gz
tabix -p bed file.bed.gz
```

It streams, so a whole-genome MAF costs no more memory than a small one, and it
reads from a pipe (`pigz -dc file.maf.gz | maf2bed hg38 | ...`). Without a Rust
toolchain,
[`maf2bed.pl`](https://github.com/GMOD/jbrowse-plugin-mafviewer/blob/master/bin/maf2bed.pl)
is the same conversion in Perl and its output is interchangeable.

Every block has to be rooted on the assembly you name, which a MAF from
`hal2maf --refGenome <name>` or from UCSC already is. A MAF whose blocks are
rooted on different genomes, as `pggb -M` produces, needs re-rooting first; see
[](https://jbrowse.org/jb2-staging/docs/tutorials/pangenome_ecoli#whole-genome-alignment-maf-projection).

## Sub-adapters: summary and CDS frames

Two optional sub-adapters hang off the MAF **adapter**, alongside the main
location:

- **`summaryAdapter`**: the zoom-out tier, described in its own section
  [below](#the-zoom-out-tier). Either a UCSC `bigMafSummary` (a `BigBedAdapter`
  over `bigMafSummary.bb`) or a `BedTabixAdapter` over the summary
  [maf2bed](https://github.com/cmdcolin/maf2bed) writes.
- **`annotationAdapter`**: a UCSC `mafFrames` file (a `BigBedAdapter` over
  `multiz<N>wayFrames.bb`) carrying each gene's CDS reading frame projected
  through the alignment, one record per (species, region), keyed by `src`
  species. It enables the "Show CDS frames" overlay and the "Codon changes
  (amino acids)" row coloring, neither on by default. When the file carries a
  record for the reference `src`, the reference row shows its own gene structure
  too.

## The zoom-out tier

Every MAF format packs each block's species sequences together, so a zoomed-out
query downloads them all: on a deep alignment a single screen can be tens of
megabytes. JBrowse blocks that with a "requested too much data" prompt, which
means a track with no `summaryAdapter` has no zoom-out view — only the prompt.

The `summaryAdapter` slot points at a second, much smaller file holding one row
per species per aligned region, with a score but **no sequence**. Where it is
configured, zooming out past the force-load threshold swaps the per-base rows
for per-species presence bars read from that file instead of blocking.

For a **BigMaf** track, UCSC ships one alongside the alignment:

```json
"summaryAdapter": {
  "type": "BigBedAdapter",
  "bigBedLocation": { "uri": "https://example.com/multiz470waySummary.bb" }
}
```

For the other three, `maf2bed --summary` writes one in the same pass that
converts the alignment, so it costs no extra scan of the MAF:

```bash
export LC_ALL=C

maf2bed hg38 --summary summary.bed < file.maf \
  | sort -k1,1 -k2,2n | bgzip > file.bed.gz
tabix -p bed file.bed.gz

sort -k1,1 -k2,2n summary.bed | bgzip > summary.bed.gz
tabix -p bed summary.bed.gz
```

`--summary` needs maf2bed v0.6.0 or newer. Versions before that read only the
first argument and ignore the rest, so the command above exits 0 and writes only
the alignment BED; check that `summary.bed` exists before wiring the slot.

Its `#` header names the columns, so the sub-adapter needs no `columnNames`:

```json addtrack
{
  "type": "MafTrack",
  "trackId": "multiz_with_summary",
  "name": "Multiz alignment (with zoom-out tier)",
  "assemblyNames": ["hg38"],
  "adapter": {
    "type": "MafTabixAdapter",
    "uri": "https://example.com/multiz.bed.gz",
    "samples": ["hg38", "panTro6", "mm39"],
    "summaryAdapter": {
      "type": "BedTabixAdapter",
      "bedGzLocation": { "uri": "https://example.com/multiz.summary.bed.gz" },
      "index": {
        "location": { "uri": "https://example.com/multiz.summary.bed.gz.tbi" }
      }
    }
  }
}
```

The bars are shaded by the summary's score, and hovering one reports it as a
number alongside the species and the aligned block. The two producers put
different metrics there — UCSC a normalized alignment score, `maf2bed` percent
identity to the reference — but both are 0..1 and both shade the same way, so
the tooltip labels it as the file's `score` rather than as either. Both are
distinct from the conservation band, which is computed from the alignment itself
and needs no file.

`BgzipMafAdapter` and `BgzipTaffyAdapter` take the same slot, and the same
`maf2bed --summary` BED serves them. Their `.tai` index seeks within an
alignment, so a read costs what is on screen rather than what the blocks happen
to span. That bounds the span a read covers, not the number of rows, and a read
costs both. On a deep alignment an index moves the zoom-out ceiling; the summary
file removes it. Each slot doc quotes the bytes per base measured for that
format on HPRC's published alignment:
[`BgzipMafAdapter`](https://jbrowse.org/jb2-staging/docs/config/bgzipmafadapter/#slot-summaryadapter),
[`BgzipTaffyAdapter`](https://jbrowse.org/jb2-staging/docs/config/bgziptaffyadapter/#slot-summaryadapter).

## Display options

The conservation band, the identity plots (heatmap / X-Y plot),
source-chromosome coloring, and the inversion (strand-flip) overlay are all
derived from the alignment with no extra configuration, picked from the track
menu. The [user guide](https://jbrowse.org/jb2-staging/docs/user_guides/maf_track) covers what each one shows.

## A larger example: the human 470-way

These features work at genome scale. The UCSC hg38 **470-way multiz** (the
Zoonomia mammals and more) is a `BigMafAdapter` over `multiz470way.bigMaf`, with
its `multiz470waySummary.bb` (zoom-out) and `multiz470wayFrames.bb` (CDS frames
/ codon view): the same three pieces as the smaller examples, pointed at the
UCSC downloads.

```json
{
  "type": "MafTrack",
  "trackId": "multiz470way",
  "name": "Multiz 470-way",
  "assemblyNames": ["hg38"],
  "adapter": {
    "type": "BigMafAdapter",
    "bigBedLocation": {
      "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/multiz470way/multiz470way.bigMaf"
    },
    "summaryAdapter": {
      "type": "BigBedAdapter",
      "bigBedLocation": {
        "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/multiz470way/multiz470waySummary.bb"
      }
    },
    "annotationAdapter": {
      "type": "BigBedAdapter",
      "bigBedLocation": {
        "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/multiz470way/multiz470wayFrames.bb"
      }
    }
  }
}
```

A subtree filter (from the track menu) narrows the hundreds of species to a
focused set for detailed reading; see the
[user guide](https://jbrowse.org/jb2-staging/docs/user_guides/maf_track) for how the large alignment renders.

## See also

- [](https://jbrowse.org/jb2-staging/docs/user_guides/maf_track)
- [Synteny track config](https://jbrowse.org/jb2-staging/docs/config_guides/synteny_track)
- [](https://jbrowse.org/jb2-staging/docs/config_guides/file_types)

