archaeopteryx 3.11.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,7 @@ config key live and shows the exact config JSON to copy into your own
37
37
  * [Nucleotide alignment (600 columns)](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=alignment_nt)
38
38
  * [Genome alignment (150 × 30,000 columns)](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=genome_alignment)
39
39
  * [Sequence alignment](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=alignment)
40
+ * [Sequence logo (the motif changes by clade)](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=sequence_logo)
40
41
  * [Influenza HA (annotated)](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=influenza)
41
42
  * [Dinosaur time tree](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=dinosaur)
42
43
  * [Ammonite time tree (fossil ranges)](https://cmzmasek.github.io/archaeopteryx-js/demo.html?tree=ammonite)
@@ -315,6 +316,25 @@ describe the MAD rooting only. A shared view remembers a MAD root. A phyloXML
315
316
  download keeps them as `<confidence type="MAD">`, as the desktop writes them;
316
317
  a Newick or Nexus download never puts one where a support value goes.
317
318
 
319
+ A tip is written under its **name**; where it has none, under its taxonomy
320
+ (code, then scientific, then common name), then its sequence's name, symbol or
321
+ gene name, then its sequence **accession**, and only if it has none of those
322
+ under a `node<N>` placeholder numbering it by position among the tips. Each
323
+ step is tried in turn, so a taxonomy element that is present but empty does
324
+ not stop the search. An unlabeled *internal* node stays unlabeled — a
325
+ placeholder there would invent a name for an ancestor. Newick and Nexus use
326
+ the one chain, so a tree saved in both formats names its tips identically, and
327
+ it is the desktop Archaeopteryx's chain, compared byte for byte.
328
+
329
+ Newick and Nexus have **one** support slot per branch and no place to name
330
+ what kind of support it is, so a branch carrying several confidences is
331
+ written with the first that is not a MAD value, exactly as the desktop writes
332
+ it, and a `bootstrap` read back from such a file is typed `unknown`. phyloXML
333
+ keeps every one of them, typed. Everything else survives a trip through
334
+ either format unchanged — names, branch lengths (including zero-length and
335
+ negative branches) and aligned sequences — in both directions, which the test
336
+ suite pins as two standing round trips.
337
+
318
338
  1. Tria, F.D.K., Landan, G., Dagan, T. (2017). Phylogenetic rooting using
319
339
  minimal ancestor deviation. *Nature Ecology & Evolution*, 1, 0193.
320
340
  <https://www.nature.com/articles/s41559-017-0193>
@@ -455,7 +475,9 @@ desktop's Unicode entry: it stays with the text field there, as it should.
455
475
  A view is what you made of a tree with the panel: the layout and display
456
476
  type, which labels show, the colour and shape fields, both searches, the
457
477
  clade you switched to, the clades you collapsed, the font, node and branch
458
- sizes, the rotation, the tracks. On the demo pages it rides in the URL's
478
+ sizes, the rotation, and the tracks — which track is shown, the heat map's
479
+ column order (including one you arranged by hand) and whether the alignment
480
+ is summarised as a logo. On the demo pages it rides in the URL's
459
481
  `#` hash and follows every change, so the address bar is always a link to
460
482
  what is on screen: copy it (**Copy link to this view** in the toolbar) and
461
483
  the recipient opens the same tree in the same view. Opening your own file
@@ -472,7 +494,9 @@ as the page does.
472
494
  Embedders get the same four pieces: the handle's `getViewState()` and
473
495
  `applyViewState(state)`, the config's `view` (open straight into one) and
474
496
  `onViewChange(state, encoded)` (called when it changes), and
475
- `archaeopteryx.encodeViewState()` / `decodeViewState()` for the hash form,
497
+ `archaeopteryx.encodeViewState()` / `decodeViewState()` for the hash form
498
+ (every key the state can hold survives the hash — a test reads `getViewState`
499
+ and fails on any key the codec does not know),
476
500
  which reads like
477
501
  `layout=circular&colorBy=tax:common_name&show=name,external&font=9&collapsed=12,44&a=HUMAN&af=Any+Text&am=contains`.
478
502
  Nodes are named by their launch-time preorder index, so a view belongs to
@@ -530,10 +554,39 @@ checkbox under Display Data toggles the whole track.
530
554
  To find a motif, pick **Molecular Sequence** in a search box: it matches the
531
555
  residues as written, gap characters included, as the desktop does.
532
556
 
557
+ **Sequence Logo** (the checkbox under **Alignment**) replaces the conservation
558
+ bar with a **logo**: every column a stack of letters, as tall as that column's
559
+ information content in bits and shared out by residue frequency, most frequent
560
+ on top — the display the MEME Suite and WebLogo draw. A conserved column is one
561
+ tall letter, a variable one a short pile, and the caption gives the scale
562
+ (0 to 2 bits for nucleotides, 0 to 4.3 for amino acids).
563
+
564
+ It summarises **the tips currently on screen**, so entering a clade gives that
565
+ clade's motif rather than the file's, and the caption names how many tips that
566
+ is (`n = 12`). Two consequences worth knowing: gaps are not a letter —
567
+ frequencies are taken over the residues present, and the stack is then scaled
568
+ by the column's occupancy, so a column held up by two sequences out of fifty
569
+ draws short rather than perfectly conserved; and there is **no small-sample
570
+ correction**, because entering a three-tip clade is a normal thing to do and
571
+ Schneider's correction would subtract more than the maximum and leave the
572
+ column blank. Read `n` and judge.
573
+
533
574
  Alignments arrive with the tree: as phyloXML `<mol_seq is_aligned="true">`
534
575
  elements, or in a **Nexus** file whose characters matrix accompanies its tree.
535
576
  The **Nexus** entry in the Download menu writes the current tree *and* its
536
- alignment back into one Nexus file (Taxa, Characters and Trees blocks).
577
+ alignment back into one Nexus file (Taxa, Characters and Trees blocks), in the
578
+ same bytes the desktop Archaeopteryx writes: a row per taxon rather than per
579
+ sequence, so a tip carrying no sequence gets a row of the missing symbol `?`
580
+ and the matrix still covers every taxon the file declares. Reading it back,
581
+ such a row is absence of data and not a sequence of question marks. Residues
582
+ from a Nexus matrix are normalised as the desktop normalises them — raised to
583
+ upper case, `.` read as a gap, and anything outside the declared alphabet read
584
+ as the unspecified residue, `X` for protein and `N` for nucleotides, so the
585
+ missing symbol `?` arrives as `X` or `N`. A phyloXML `<mol_seq>` is kept
586
+ exactly as written, by both programs. Sequences
587
+ of *unequal* length are not an alignment and cannot form a character matrix,
588
+ so they are not written at all — the file says so in a bracketed comment
589
+ rather than padding them into an alignment that does not exist.
537
590
 
538
591
  ## Heat maps
539
592
 
@@ -999,11 +1052,14 @@ plus Search, and folds the ones that are adjustments to make later: Zoom,
999
1052
  Sizes and the domain controls. Whatever you open or close is then remembered, for the
1000
1053
  page and across reloads, so a panel you have arranged stays arranged, even
1001
1054
  when you switch to another tree. In a short window it also keeps itself to one
1002
- screen: opening a section folds the one you opened longest ago, but only while
1003
- the panel would not otherwise fit — on a tall screen nothing is ever folded for
1004
- you. Anything that puts something into a folded section opens it, so jumping to
1005
- the search box (⌘F / Ctrl+F), revealing Search B, or a tool reporting its
1006
- result as search hits all unfold Search. A host with little room to give can
1055
+ screen: opening a section folds the one you opened longest ago, and dragging
1056
+ the window (or the element it sits in) shorter does the same — but only while
1057
+ the panel would not otherwise fit, never past the last section left open, and
1058
+ never at all on a tall screen. Growing the window back leaves the folds where
1059
+ they are: what is open is your choice, and only running out of room overrules
1060
+ it. Anything that puts something into a folded section opens it, so jumping to
1061
+ the search box (⌘F / Ctrl+F) or a tool reporting its result as search hits
1062
+ unfolds Search. A host with little room to give can
1007
1063
  also start the whole panel tighter and narrower with
1008
1064
  [`panelDensity: 'compact'`](#configuration), or collapsed to its header bar
1009
1065
  with `collapseControlPanel`.
@@ -1041,6 +1097,7 @@ copy-pastable JSON.
1041
1097
  | `layout` | `'rectangular'` | The starting layout: `'rectangular'`, `'circular'`, or `'unrooted'`. |
1042
1098
  | `ladderizeTree` | `true` | Ladderize the tree on load: at each node, the larger clade first (any number of children, so a polytomy sorts too). |
1043
1099
  | `showMsa` | tree-derived | Open with the alignment track shown. Default: on when the tree carries an aligned `mol_seq`, off otherwise — an explicit `true`/`false` overrides that. |
1100
+ | `showMsaLogo` | `false` | Open with the alignment summarised as a sequence logo instead of a conservation bar: each column a stack of letters as tall as its information content, over the tips currently on screen. Only drawn while the alignment track is shown. |
1044
1101
  | `showHeatmap` | `false` | Open with the heat map shown. Offered whenever the tree carries two or more numeric per-tip fields, but off unless asked for: almost any annotated tree has such fields, so turning it on by itself would be an opinion about the tree rather than a service. |
1045
1102
  | `heatmapColumnOrder` | tree-derived | How the heat map's columns are ordered: `'document'` (as the file lists them), `'clustered'` (Euclidean), `'clustered-presence'` (Bray–Curtis), `'alphabetical'`, `'frequency'`. The clustered modes also draw the dendrogram. Default: a **clustered** order, with the distance chosen from the values — Bray–Curtis where the matrix has zeros to ignore and nothing negative, Euclidean otherwise. An explicit value always wins and is never re-derived. |
1046
1103
  | `heatmapManualOrder` | `null` | The heat map's columns in your own order, as an array of property refs (`['meta:recA', 'meta:gyrA', …]`). Only read while `heatmapColumnOrder` is `'manual'`. A ref the tree has not got is ignored, and a column the list does not name follows the ones it does. |
@@ -1710,14 +1767,38 @@ readout (`forester.msaResidueInfo`, `msaUngappedPosition`) names the residue
1710
1767
 
1711
1768
  Navigation: a lazily-created bar fixed at the viewport bottom — first / page
1712
1769
  back / slider / page forward / last, a jump-to-column box (1-based, matching
1713
- the hover readout) and a live "column N – M of total" — plus wheel-over-track
1770
+ the hover readout) and a live "column N M of total" — plus wheel-over-track
1714
1771
  at a tenth of a screen per notch. Every route lands in one `msaScrollTo()`,
1715
1772
  which clamps and redraws; the tree never moves. A faint dashed guide runs
1716
1773
  from each tip's label (or its node, when labels are hidden) across to that
1717
1774
  tip's row, so a row reads back to its sequence without counting.
1718
1775
 
1719
- The conservation bar, consensus row and column ruler are a **floating strip**
1720
- (see the time axes below); the residue rows stay with their tips.
1776
+ **The sequence logo** (`showMsaLogo`, `forester.msaLogo`) replaces the
1777
+ conservation bar and the consensus row rather than joining them: a stack's
1778
+ height *is* the column's conservation and its top letter *is* the consensus,
1779
+ so all three would say one thing three times. Per column the model returns
1780
+ `bits` = `log₂K − H` over the non-gap residues, `occupancy` = non-gap / rows,
1781
+ `height` = `bits × occupancy`, and the letters most frequent first (ties
1782
+ alphabetical, so a figure reproduces). Rows are the **displayed** tips over
1783
+ the visible window, which is what makes entering a clade re-read the summary.
1784
+ **No small-sample correction**: Schneider's `e_n = (K−1)/(2 ln2 · n)` is for a
1785
+ motif sampled from many sequences, and at n = 3 for protein it exceeds the
1786
+ 4.32-bit maximum, so a perfectly conserved column of a small clade would draw
1787
+ nothing — the caption names `n` instead.
1788
+
1789
+ Each letter is scaled to fill its slice: `sy = hpx / (ascent + descent)` of
1790
+ **that glyph's** ink box, measured once per character off a canvas, with the
1791
+ baseline placed at `y − descent × sy` so the ink lands inside the slice.
1792
+ Measured off one glyph instead, Q and G hung their descenders through the
1793
+ ruler. Note that an SVG `<text>`'s `getBoundingClientRect` is the *font's*
1794
+ layout box, not the ink, so it cannot check this — `test_trees/msa_logo.html`
1795
+ compares letters and order through the DOM and the ink itself is measured from
1796
+ rendered pixels.
1797
+
1798
+ The conservation bar or logo, the consensus row and the column ruler are a
1799
+ **floating strip** (see the time axes below); the residue rows stay with their
1800
+ tips. The strip's height follows what it holds (`msaBottomReserve()`), and the
1801
+ bottom reserve the fit allows for follows that.
1721
1802
 
1722
1803
  ### The heat map
1723
1804
 
@@ -98,6 +98,10 @@ export interface ArchaeopteryxConfig {
98
98
  heatmapManualOrder?: string[] | null;
99
99
  showHeatmap?: boolean;
100
100
  showMsa?: boolean;
101
+ /** Summarize the alignment as a sequence logo instead of a conservation
102
+ * bar: each column a stack of letters as tall as its information content,
103
+ * over the tips currently on screen. Only drawn with the track shown. */
104
+ showMsaLogo?: boolean;
101
105
  showSupportDots?: boolean;
102
106
  showTimeAxis?: boolean;
103
107
  supportDotMinimum?: number;
@@ -150,6 +154,8 @@ export interface ViewState {
150
154
  rotation?: number;
151
155
  horizontalLabels?: boolean;
152
156
  msa?: boolean;
157
+ /** The alignment summarized as a sequence logo. */
158
+ msaLogo?: boolean;
153
159
  heatmap?: boolean;
154
160
  heatmapOrder?: 'document' | 'clustered' | 'clustered-presence' | 'alphabetical' | 'frequency' | 'manual';
155
161
  heatmapManual?: string[];