# `PlMultiSequenceAlignment`

The name of the component is usually shortened to MSA.

For the design, see
https://www.figma.com/design/pndFzfW2eqdIWfA8IoraMg/%F0%9F%A7%AC-MSA?t=LRoRiHQhyga7Ndzx-0.

## Structure

### PlMultiSequenceAlignment

Defined in `PlMultiSequenceAlignment.vue`.

This component is a "wrapper" that takes supplied data, runs data fetchers from
`data.ts` and draws `<MultiSequenceAlignmentView />`. It also draws a
`<Toolbar />` and is responsible for loading and error states.

The inputs are:

- `pFrame`
- `sequenceColumnPredicate`: predicate function by which the component filters
  the columns to find only the sequence columns
- `selection`: `PlSelectionModel` that is returned from GraphMaker,
  PlAgDataTable or potentially some other component, indicates which rows should
  be selected from the columns
- `modelValue`: a storage for MSA settings

The settings for MSA are derived from `modelValue`, filling the `undefined` gaps
with default settings (defined in `settings.ts`).

### MultiSequenceAlignmentView

Defined in `MultiSequenceAlignmentView.vue`.

This is the presentational part, where most of the rendering is happening. It's
meant to have as little logic as possible to prevent the out-of-sync states. The
rendering is optimized to be as much monospace text-only as possible, with
[highlighting](#highlighting-color-scheme) implemented as a background image. A
lot of the rendering relies on the specific dimensions of the font. Gaps between
letters are implemented with `letter-spacing`.

### Data

Defined in `data.ts`.

This is MSA data fetcher that is split between 4 Vue composables:

- `useSequenceColumnsOptions`
- `useLabelColumnsOptions`
- `useMarkupColumnsOptions`
- `useMultipleAlignmentData`

First 3 composable are very similar. They take a list of columns from
`pFrameDriver.listColumns(pFrame)` and return all the options that would be
reasonable for the user to be able to choose from.

`useSequenceColumnsOptions` and `useLabelColumnsOptions` specifically also
return a list of default options that are preselected for the user.

`useMultipleAlignmentData` does the actual computation. It runs
`pFrameDriver.calculateTableData`, `multiSequenceAlignment`, highlighting and
returns data in this format:

- `sequences`: list of sequences rows, aligned and concatenated with a single
  whitespace (`["<r0c0> <r0c1>", "<r1c0> <r1c1>", ...]`; "r"—row, "c"—column);
  every row is the same length
- `sequenceNames`: list of sequence names, should match the names of the options
  in a dropdown, which user selected
- `labelRows`: list of lists of labels,
  (`[["<r0l0>", "<r0l1>", ...], ["<r1l0>", "<r1l1>", ...]]`, "r"—row, "l"—label)
- `residueCounts`: see [Residue counts](#residue-counts)
- `highlightImage`: optional, see [Highlighting](#highlighting-color-scheme)
- `exceedsLimit`: see [Row limit](#row-limit)

Most of the data generated by it is in the format that is useful for
`<MultiSequenceAlignmentView />`.

### Highlighting (Color Scheme)

There are two ways to colorize the MSA output. Both output a
[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that is an SVG
file which is later scaled up to fit the table layout. Current implementation
uses <path> tags to group multiple runs of the same color. The viewbox is
doubled in one of the directions to use SVG strokes without resorting to
fractional positions.

There's also an option to not colorize the output at all.

#### Chemical properties

Defined in `chemical-properties.ts`.

This is an implementation of Clustal X color scheme. See
https://www.jalview.org/help/html/colourSchemes/clustal.html and
https://www.rbvi.ucsf.edu/chimera/1.2065/docs/ContributedSoftware/multalignviewer/cxcolor.html
for reference.

#### Markup

Defined in `markup.ts`.

This color scheme highlights the parts of sequences that have a special meaning.
Markup format looks like `<id_0>:<start_0>+<length_0>|<id_1>:<start_1>|...`,
where `start` and `length` are encoded as base-36 numbers. `length` is optional,
and is 1 by default. Markup entries can overlap, although right now it's not
really handled in the UI. IDs bear no special meaning, and can be used in the UI
directly, or the labels can be looked up in the
`pl7.app/sequence/annotation/mapping` annotation of the markup column.

For example, a string `1:P+A|2:1G+7|3:2O+D` encodes this markup:

| id | start | length |
| -- | ----- | ------ |
| 1  | 25    | 10     |
| 2  | 52    | 7      |
| 3  | 96    | 13     |

Note that the markup itself is for an original sequence, not an aligned one. So
it needs to be adjusted for an aligned sequence (see function
`markupAlignedSequence`).

### Alignment

Defined in `multi-sequence-alignment.ts`.

To run the actual alignment, MSA component uses
(kalign)[https://github.com/TimoLassmann/kalign]. It is used as a WASM binary
through a (Web
Worker)[https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker].
Currently, the source is (biowasm)[https://biowasm.com/cdn/v3/kalign/3.3.1],
which we repackaged to work bundled and without a CDN.

The worker is reused between multiple calls. The results are cached by input
sequences and alignment params.

### Widgets

#### Consensus

Defined in `Consensus.vue`.

This widget visualizes the most used residue in a column using `miplots4`'s
`discrete` plot with a `bar` layer.

#### SeqLogo

Defined in `SeqLogo.vue`.

For reference, see https://ivanek.github.io/seqLogo/articles/seqLogo.html. This
is rendered using `miplots4`'s `discrete` plot with a `logo` layer.

#### Legend

Defined in `Legend.vue`.

Legend for a selected color scheme.

### Toolbar

Defined in `Toolbar.vue`.

Displays the current (settings)[#settings]. Updates to settings are applied to
model, from which the settings are re-derived afterwards.

### Residue counts

Defined in `residue-counts.ts`.

Supplemental data for [chemical properties](#chemical-properties) color scheme,
[Consensus](#consensus) and [SeqLogo](#seqlogo) widgets. Simply counts how many
times each residue was used in a column.

### Settings

Defined in `settings.ts`.

Derived from the `PlMultiSequenceAlignmentModel`, providing defaults for
`undefined` fields in a model.

- `sequenceColumnIds`: defines which sequence columns should be displayed
- `labelColumnIds`: defines which label columns should be displayed
- `colorScheme`: defined which [Color scheme](#highlighting-color-scheme) should
  be used for output highlighting
- `widgets`: defines which [Widgets](#widgets) to display
- `alignmentParams`: params that are used for [kalign](#alignment); currently
  `gpo`, `gpe` and `tgpe`

Technically, `sequenceColumnIds` and `labelColumnIds` shouldn't be optional, but
they are implemented as such because the defaults are fetched when the
`PlMultiSequenceAlignment` component renders.

### Migrations

Defined in `migrations.ts`.

Defines migrations to run for the MSA model before anything is rendered. Useful
when model format is changed and to upgrade an empty model to one with a
version. Also, the simplest way to reset all the MSA settings would be to set
the model to `{}` and run migrations.

### `useMiPlots.ts`

A helper to import `miplots4` dependency dynamically to avoid blowing up the
bundle. Probably should be moved outside this component at some point.

## Notes

### Row limit

There's an agreed upon limit of 1,000 rows, over which the alignment won't be
run. This limit is artificial, but it prevents a user from running a computation
that might be too heavy, especially given that at the moment there's no way to
terminate the alignment process.

This limit is imposed on `useMultipleAlignmentData`
/`pFrameDriver.calculateTableData` level.
