Files
obikmer/doc/usage/phylo/index.html
T
Eric Coissac caf59b5658 Update documentation for CLI command renames and new commands
Renames the reindex command to convert across all usage guides and navigation menus. Adds documentation for the newly introduced name-tree command. Updates flag references, such as replacing --metric with --distance in pack and phylo modules, and adjusts MkDocs configuration to match the revised structure. All changes are strictly limited to documentation and configuration files.
2026-08-28 23:06:05 +02:00

2245 lines
58 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="prev" href="../annotate/">
<link rel="next" href="../unitig/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>phylo - obikmer — User Guide</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#phylo" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="obikmer — User Guide" class="md-header__button md-logo" aria-label="obikmer — User Guide" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
obikmer — User Guide
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
phylo
</span>
</div>
</div>
</div>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="obikmer — User Guide" class="md-nav__button md-logo" aria-label="obikmer — User Guide" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
obikmer — User Guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../installation/" class="md-nav__link">
<span class="md-ellipsis">
Installation
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Theory
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Theory
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../theory/kmers_and_superkmers/" class="md-nav__link">
<span class="md-ellipsis">
Kmers and super-kmers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../theory/encoding/" class="md-nav__link">
<span class="md-ellipsis">
DNA encoding
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../theory/entropy_filter/" class="md-nav__link">
<span class="md-ellipsis">
Low-complexity kmer filter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../theory/minimizer_selection/" class="md-nav__link">
<span class="md-ellipsis">
Minimizer selection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../theory/indexing_architecture/" class="md-nav__link">
<span class="md-ellipsis">
Partitioning and indexing architecture
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Usage
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Usage
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../superkmer/" class="md-nav__link">
<span class="md-ellipsis">
superkmer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../index_command/" class="md-nav__link">
<span class="md-ellipsis">
index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../merge/" class="md-nav__link">
<span class="md-ellipsis">
merge
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../filter/" class="md-nav__link">
<span class="md-ellipsis">
filter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../select/" class="md-nav__link">
<span class="md-ellipsis">
select
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../query/" class="md-nav__link">
<span class="md-ellipsis">
query
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dump/" class="md-nav__link">
<span class="md-ellipsis">
dump
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../annotate/" class="md-nav__link">
<span class="md-ellipsis">
annotate
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
phylo
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
phylo
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#arguments" class="md-nav__link">
<span class="md-ellipsis">
Arguments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#distance-matrix-distance" class="md-nav__link">
<span class="md-ellipsis">
Distance matrix (--distance)
</span>
</a>
<nav class="md-nav" aria-label="Distance matrix (--distance)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#whole-index-metrics" class="md-nav__link">
<span class="md-ellipsis">
Whole-index metrics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#snp-corrections" class="md-nav__link">
<span class="md-ellipsis">
snp-* corrections
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#output" class="md-nav__link">
<span class="md-ellipsis">
Output
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#-exclude-genome-min-shared-family" class="md-nav__link">
<span class="md-ellipsis">
--exclude-genome, --min-shared-family
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#central-position-snp-model" class="md-nav__link">
<span class="md-ellipsis">
Central-position SNP model
</span>
</a>
<nav class="md-nav" aria-label="Central-position SNP model">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#-sibling-stats" class="md-nav__link">
<span class="md-ellipsis">
--sibling-stats
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#family-overlap" class="md-nav__link">
<span class="md-ellipsis">
Family Overlap
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#-pseudo-alignment" class="md-nav__link">
<span class="md-ellipsis">
--pseudo-alignment
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#sampling-at-scale-subsample-shannon-entropy" class="md-nav__link">
<span class="md-ellipsis">
Sampling at scale: --subsample, --shannon, --entropy
</span>
</a>
<nav class="md-nav" aria-label="Sampling at scale: --subsample, --shannon, --entropy">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#-shannon-measuring-how-informative-a-family-is" class="md-nav__link">
<span class="md-ellipsis">
--shannon: measuring how informative a family is
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#-entropy-mu-entropy-sd-sigma-biasing-the-sample-toward-informative-families" class="md-nav__link">
<span class="md-ellipsis">
--entropy MU / --entropy-sd SIGMA: biasing the sample toward informative families
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#sankoff-calibration-and-phylogenetic-exports" class="md-nav__link">
<span class="md-ellipsis">
Sankoff calibration and phylogenetic exports
</span>
</a>
<nav class="md-nav" aria-label="Sankoff calibration and phylogenetic exports">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#the-16-state-model" class="md-nav__link">
<span class="md-ellipsis">
The 16-state model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#exports" class="md-nav__link">
<span class="md-ellipsis">
Exports
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#output-files" class="md-nav__link">
<span class="md-ellipsis">
Output files
</span>
</a>
<nav class="md-nav" aria-label="Output files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#distance-matrix" class="md-nav__link">
<span class="md-ellipsis">
Distance matrix
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#central-position-snp-model_1" class="md-nav__link">
<span class="md-ellipsis">
Central-position SNP model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sankoff-calibration-and-exports" class="md-nav__link">
<span class="md-ellipsis">
Sankoff calibration and exports
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rare-states-and-iqtree-min-freq" class="md-nav__link">
<span class="md-ellipsis">
Rare states and --iqtree-min-freq
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../unitig/" class="md-nav__link">
<span class="md-ellipsis">
unitig
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../estimate/" class="md-nav__link">
<span class="md-ellipsis">
estimate
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../convert/" class="md-nav__link">
<span class="md-ellipsis">
convert
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../utils/" class="md-nav__link">
<span class="md-ellipsis">
utils
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pack/" class="md-nav__link">
<span class="md-ellipsis">
pack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../predicates/" class="md-nav__link">
<span class="md-ellipsis">
Predicates and taxonomy paths
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Formats
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Formats
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../formats/index_layout/" class="md-nav__link">
<span class="md-ellipsis">
Index construction and on-disk layout
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../architecture/" class="md-nav__link">
<span class="md-ellipsis">
Architecture notes
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#arguments" class="md-nav__link">
<span class="md-ellipsis">
Arguments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#distance-matrix-distance" class="md-nav__link">
<span class="md-ellipsis">
Distance matrix (--distance)
</span>
</a>
<nav class="md-nav" aria-label="Distance matrix (--distance)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#whole-index-metrics" class="md-nav__link">
<span class="md-ellipsis">
Whole-index metrics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#snp-corrections" class="md-nav__link">
<span class="md-ellipsis">
snp-* corrections
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#output" class="md-nav__link">
<span class="md-ellipsis">
Output
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#-exclude-genome-min-shared-family" class="md-nav__link">
<span class="md-ellipsis">
--exclude-genome, --min-shared-family
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#central-position-snp-model" class="md-nav__link">
<span class="md-ellipsis">
Central-position SNP model
</span>
</a>
<nav class="md-nav" aria-label="Central-position SNP model">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#-sibling-stats" class="md-nav__link">
<span class="md-ellipsis">
--sibling-stats
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#family-overlap" class="md-nav__link">
<span class="md-ellipsis">
Family Overlap
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#-pseudo-alignment" class="md-nav__link">
<span class="md-ellipsis">
--pseudo-alignment
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#sampling-at-scale-subsample-shannon-entropy" class="md-nav__link">
<span class="md-ellipsis">
Sampling at scale: --subsample, --shannon, --entropy
</span>
</a>
<nav class="md-nav" aria-label="Sampling at scale: --subsample, --shannon, --entropy">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#-shannon-measuring-how-informative-a-family-is" class="md-nav__link">
<span class="md-ellipsis">
--shannon: measuring how informative a family is
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#-entropy-mu-entropy-sd-sigma-biasing-the-sample-toward-informative-families" class="md-nav__link">
<span class="md-ellipsis">
--entropy MU / --entropy-sd SIGMA: biasing the sample toward informative families
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#sankoff-calibration-and-phylogenetic-exports" class="md-nav__link">
<span class="md-ellipsis">
Sankoff calibration and phylogenetic exports
</span>
</a>
<nav class="md-nav" aria-label="Sankoff calibration and phylogenetic exports">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#the-16-state-model" class="md-nav__link">
<span class="md-ellipsis">
The 16-state model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#exports" class="md-nav__link">
<span class="md-ellipsis">
Exports
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#output-files" class="md-nav__link">
<span class="md-ellipsis">
Output files
</span>
</a>
<nav class="md-nav" aria-label="Output files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#distance-matrix" class="md-nav__link">
<span class="md-ellipsis">
Distance matrix
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#central-position-snp-model_1" class="md-nav__link">
<span class="md-ellipsis">
Central-position SNP model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sankoff-calibration-and-exports" class="md-nav__link">
<span class="md-ellipsis">
Sankoff calibration and exports
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rare-states-and-iqtree-min-freq" class="md-nav__link">
<span class="md-ellipsis">
Rare states and --iqtree-min-freq
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="phylo">phylo</h1>
<p>Compute pairwise distances between the genomes stored in an index, optionally build trees (NJ/UPGMA) from them, and optionally calibrate a 16-state parsimony model for a central-position SNP character with exports for external phylogenetic tools (TNT, PhyG, IQ-TREE).</p>
<div class="highlight"><pre><span></span><code>obikmer<span class="w"> </span>phylo<span class="w"> </span>INDEX<span class="w"> </span><span class="o">[</span>OPTIONS<span class="o">]</span>
</code></pre></div>
<h2 id="arguments">Arguments</h2>
<table>
<thead>
<tr>
<th>Argument</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>INDEX</code></td>
<td>Index directory</td>
</tr>
</tbody>
</table>
<h2 id="distance-matrix-distance">Distance matrix (<code>--distance</code>)</h2>
<table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--distance</code></td>
<td><code>jaccard</code></td>
<td>See the two tables below for the full list of accepted values</td>
</tr>
<tr>
<td><code>--gamma-shape ALPHA</code></td>
<td>none</td>
<td>Rate-heterogeneity correction, for <code>snp-*</code> values that support it (see below). No effect on the other values; rejected if given together with a value that doesn't support it</td>
</tr>
<tr>
<td><code>--presence-threshold</code></td>
<td><code>1</code></td>
<td>Minimum count for a kmer to be considered present, for <code>jaccard</code>/<code>mash</code> on a count index</td>
</tr>
<tr>
<td><code>--csv</code></td>
<td>off</td>
<td>Write the matrix as plain CSV instead of the default relaxed-PHYLIP format</td>
</tr>
<tr>
<td><code>--shared-kmers</code></td>
<td>off</td>
<td>Also write the shared-kmer count matrix. Only valid with a whole-index metric, not a <code>snp-*</code> value</td>
</tr>
<tr>
<td><code>--nj</code></td>
<td>off</td>
<td>Compute and write a Neighbor-Joining tree (Newick)</td>
</tr>
<tr>
<td><code>--upgma</code></td>
<td>off</td>
<td>Compute and write a UPGMA tree (Newick)</td>
</tr>
<tr>
<td><code>-o, --output</code></td>
<td>none (stdout)</td>
<td>Output file prefix</td>
</tr>
</tbody>
</table>
<p>Every value routes to one of two independent computations:</p>
<h3 id="whole-index-metrics">Whole-index metrics</h3>
<table>
<thead>
<tr>
<th>Value</th>
<th>Definition</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>jaccard</code></td>
<td><span class="arithmatex">\(D = 1 - \dfrac{\lvert A \cap B \rvert}{\lvert A \cup B \rvert}\)</span> over the sets of kmers present in each genome</td>
</tr>
<tr>
<td><code>mash</code></td>
<td>derived from the Jaccard distance via <span class="arithmatex">\(D = -\dfrac{1}{k} \ln\!\left(\dfrac{2J}{1+J}\right)\)</span> where <span class="arithmatex">\(J = 1 - D_{\text{jaccard}}\)</span> and <span class="arithmatex">\(k\)</span> is the index's kmer size; clamped to 1.0 when <span class="arithmatex">\(J \le 0\)</span></td>
</tr>
<tr>
<td><code>hamming</code></td>
<td>number of kmer positions where presence differs between the two genomes (presence index only, not normalized): <span class="arithmatex">\(D = \sum_i \mathbb{1}[a_i \ne b_i]\)</span></td>
</tr>
<tr>
<td><code>bray-curtis</code></td>
<td><span class="arithmatex">\(D = 1 - \dfrac{2 \sum_i \min(c_i^A, c_i^B)}{\sum_i c_i^A + \sum_i c_i^B}\)</span> on raw per-kmer counts</td>
</tr>
<tr>
<td><code>relfreq-bray-curtis</code></td>
<td>the same formula computed on per-genome relative frequencies <span class="arithmatex">\(p_i = c_i / \sum_j c_j\)</span> instead of raw counts</td>
</tr>
<tr>
<td><code>euclidean</code></td>
<td><span class="arithmatex">\(D = \sqrt{\sum_i (c_i^A - c_i^B)^2}\)</span> on raw counts</td>
</tr>
<tr>
<td><code>relfreq-euclidean</code></td>
<td>the same formula on relative frequencies</td>
</tr>
<tr>
<td><code>hellinger</code></td>
<td><span class="arithmatex">\(D = \dfrac{1}{\sqrt{2}} \sqrt{\sum_i \left(\sqrt{p_i^A} - \sqrt{p_i^B}\right)^2}\)</span> on relative frequencies, bounded in <span class="arithmatex">\([0, 1]\)</span></td>
</tr>
<tr>
<td><code>hellinger-euclidean</code></td>
<td>the unnormalized variant, <span class="arithmatex">\(D = \sqrt{2} \times D_{\text{hellinger}}\)</span></td>
</tr>
</tbody>
</table>
<p><code>hamming</code> requires a presence/absence index; the others work on either index type.</p>
<h3 id="snp-corrections"><code>snp-*</code> corrections</h3>
<p>Computed from the central-position SNP model (see "Central-position SNP model" below): a family is the set of up to 4 kmers sharing identical flanking sequence and differing only at the central base. These values require the sibling annex (<code>--sibling-annex</code>, below) and are, by default, computed exhaustively over every non-monomorphic family in the index; add <code>--subsample N</code> to bound the computation to approximately <code>N</code> families instead (see "Sampling at scale" below — the same flag <code>--pseudo-alignment</code>/<code>--sankoff</code> use, but optional here).</p>
<p>For a genome pair, let <span class="arithmatex">\(L\)</span> be its total number of eligible loci (both genomes single-copy at that family), <span class="arithmatex">\(p\)</span> the raw proportion of substitutions among those loci, <span class="arithmatex">\(P\)</span>/<span class="arithmatex">\(Q\)</span> the transition/transversion proportions, <span class="arithmatex">\(Q_1\)</span>/<span class="arithmatex">\(Q_2\)</span> Kimura's two transversion categories (A↔C &amp; G↔T vs. A↔T &amp; C↔G), <span class="arithmatex">\(P_1\)</span>/<span class="arithmatex">\(P_2\)</span> the purine (A↔G) / pyrimidine (C↔T) transition proportions, and <span class="arithmatex">\(\pi_A,\pi_C,\pi_G,\pi_T\)</span> the pair's pooled base frequencies.</p>
<p><strong><code>snp-raw</code></strong></p>
<div class="arithmatex">\[d = p\]</div>
<p><strong><code>snp-jc</code></strong></p>
<div class="arithmatex">\[d = -\frac{3}{4}\ln\!\left(1-\frac{4p}{3}\right)\]</div>
<p><strong><code>snp-k2p</code></strong></p>
<div class="arithmatex">\[
\begin{aligned}
a_1 &amp;= 1-2P-Q \\
a_2 &amp;= 1-2Q \\
d &amp;= -\frac{1}{2}\ln a_1-\frac{1}{4}\ln a_2
\end{aligned}
\]</div>
<p><strong><code>snp-k81</code></strong></p>
<div class="arithmatex">\[
\begin{aligned}
a_1 &amp;= 1-2P-2Q_1 \\
a_2 &amp;= 1-2P-2Q_2 \\
a_3 &amp;= 1-2Q_1-2Q_2 \\
d &amp;= -\frac{1}{4}\left(\ln a_1+\ln a_2+\ln a_3\right)
\end{aligned}
\]</div>
<p><strong><code>snp-f81</code></strong></p>
<div class="arithmatex">\[
\begin{aligned}
E &amp;= 1-\left(\pi_A^2+\pi_C^2+\pi_G^2+\pi_T^2\right) \\
d &amp;= -E\ln\!\left(1-\frac{p}{E}\right)
\end{aligned}
\]</div>
<p><strong><code>snp-t92</code></strong></p>
<div class="arithmatex">\[
\begin{aligned}
g &amp;= \pi_C+\pi_G \\
w &amp;= 2g(1-g) \\
a_1 &amp;= 1-\frac{P}{w}-Q \\
a_2 &amp;= 1-2Q \\
d &amp;= -w\ln a_1-\frac{1}{2}(1-w)\ln a_2
\end{aligned}
\]</div>
<p><strong><code>snp-tn93</code></strong></p>
<div class="arithmatex">\[
\begin{aligned}
g_R &amp;= \pi_A+\pi_G \\
g_Y &amp;= \pi_C+\pi_T \\
k_1 &amp;= \frac{2\pi_A\pi_G}{g_R} \\
k_2 &amp;= \frac{2\pi_C\pi_T}{g_Y} \\
k_3 &amp;= 2\left(g_Rg_Y-\frac{\pi_A\pi_G\,g_Y}{g_R}-\frac{\pi_C\pi_T\,g_R}{g_Y}\right) \\
w_1 &amp;= 1-\frac{P_1}{k_1}-\frac{Q}{2g_R} \\
w_2 &amp;= 1-\frac{P_2}{k_2}-\frac{Q}{2g_Y} \\
w_3 &amp;= 1-\frac{Q}{2g_Rg_Y} \\
d &amp;= -k_1\ln w_1-k_2\ln w_2-k_3\ln w_3
\end{aligned}
\]</div>
<p><strong><code>snp-tv</code></strong> — transversions only, deliberately uncorrected:</p>
<div class="arithmatex">\[d = Q\]</div>
<p><code>--gamma-shape ALPHA</code> applies to every value above except <code>snp-raw</code> and <code>snp-tv</code>: each <span class="arithmatex">\(-\ln(x)\)</span> term in the formulas above is replaced by <span class="arithmatex">\(\alpha\left(x^{-1/\alpha}-1\right)\)</span> (the same weight, same <span class="arithmatex">\(x\)</span>).</p>
<h3 id="output">Output</h3>
<p>Without <code>-o</code>, the matrix goes to stdout in relaxed-PHYLIP format (<code>n</code> on the first line, then one <code>label&lt;TAB&gt;value...</code> row per genome). With <code>--csv</code>, the format is instead a header row <code>genome,&lt;label1&gt;,&lt;label2&gt;,...</code> followed by one <code>&lt;label&gt;,&lt;value1&gt;,&lt;value2&gt;,...</code> row per genome, 6 decimals. Both formats are symmetric with a zero diagonal, except where noted below.</p>
<h2 id="-exclude-genome-min-shared-family"><code>--exclude-genome</code>, <code>--min-shared-family</code></h2>
<table>
<thead>
<tr>
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--exclude-genome LABEL</code></td>
<td>Exclude a genome (repeatable). Drops its row/column from the distance/shared-kmer matrix output, and removes it from the sampling used by <code>--pseudo-alignment</code>/<code>--sankoff</code>/a <code>snp-*</code> <code>--distance</code> value. Does not change the value computed for any remaining pair</td>
</tr>
<tr>
<td><code>--min-shared-family N</code></td>
<td>Auto-exclude, on top of <code>--exclude-genome</code>, any genome whose mean shared-family count against every other genome (see "Family Overlap" below) falls below <code>N</code>. Applies only to <code>--pseudo-alignment</code>/<code>--sankoff</code>/<code>snp-*</code> <code>--distance</code> — never to the whole-index metrics or their matrix/NJ/UPGMA output</td>
</tr>
</tbody>
</table>
<p>Neighbor-Joining and UPGMA trees (<code>--nj</code>/<code>--upgma</code>) are always built from every genome in the index, regardless of <code>--exclude-genome</code>/<code>--min-shared-family</code>.</p>
<h2 id="central-position-snp-model">Central-position SNP model</h2>
<p>Requires the sibling annex, built once per index:</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--sibling-annex</code></td>
<td>Build (or rebuild) the sibling-count/minorant annex — prerequisite for every option in this section, and for a <code>snp-*</code> <code>--distance</code> value</td>
</tr>
<tr>
<td><code>--sibling-stats</code></td>
<td>Write <code>&lt;prefix&gt;_siblings.csv</code>: the family-size distribution, per genome and globally</td>
</tr>
<tr>
<td><code>--sibling-hist</code></td>
<td>Print the global family-size histogram (1-4 members) only</td>
</tr>
<tr>
<td><code>--family-overlap</code></td>
<td>Write <code>&lt;prefix&gt;_family_overlap.csv</code>: for every genome pair, how many variable families both genomes carry a call for</td>
</tr>
<tr>
<td><code>--shannon</code></td>
<td>Write <code>&lt;prefix&gt;_entropy.csv</code>: per-family Shannon entropy, one row per family, full unsampled scan</td>
</tr>
<tr>
<td><code>--pseudo-alignment</code></td>
<td>Write <code>&lt;prefix&gt;_alignment.fasta</code>: a SNP-only pseudo-alignment. Requires <code>--subsample N</code></td>
</tr>
</tbody>
</table>
<p>A family is eligible for a genome pair <span class="arithmatex">\((i,j)\)</span> only if both genomes carry exactly one of its observed forms (single-copy, unambiguous).</p>
<h3 id="-sibling-stats"><code>--sibling-stats</code></h3>
<p><code>&lt;prefix&gt;_siblings.csv</code> — family size = number of distinct central bases observed at a family (1-4).</p>
<table>
<thead>
<tr>
<th>Column</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>genome</code></td>
<td>genome label, or the literal <code>global</code> for the last row</td>
</tr>
<tr>
<td><code>1</code>, <code>2</code>, <code>3</code>, <code>4</code></td>
<td>for a genome row: number of families of that size where the genome carries ≥ 1 member. For the <code>global</code> row: the actual deduplicated family-size histogram — not the sum of the rows above</td>
</tr>
</tbody>
</table>
<h3 id="family-overlap">Family Overlap</h3>
<p><code>--family-overlap</code> writes <code>&lt;prefix&gt;_family_overlap.csv</code>: header <code>genome,&lt;label1&gt;,&lt;label2&gt;,...</code>, one row per genome, cell <code>[i][j]</code> = number of variable families (family size ≥ 2) where both genome <code>i</code> and genome <code>j</code> carry a call. The diagonal is always <code>0</code>. Every genome is written, unfiltered by <code>--exclude-genome</code>/<code>--min-shared-family</code>.</p>
<p><code>--min-shared-family N</code> uses the mean of each genome's own row (excluding the diagonal) against this same matrix as its exclusion statistic. There is no universal value for <code>N</code> — inspect <code>--family-overlap</code>'s own output to find where the real gap sits in a given genome collection before choosing a threshold.</p>
<h3 id="-pseudo-alignment"><code>--pseudo-alignment</code></h3>
<p><code>&lt;prefix&gt;_alignment.fasta</code> — one record per non-excluded genome, one column per variable family (family size ≥ 2). Each site is IUPAC-coded from the genome's presence mask at that family: a single observed form → the plain base; several forms → the matching IUPAC ambiguity code; no form → <code>-</code>.</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--subsample N</code></td>
<td>none (mandatory here)</td>
<td>Target number of families to sample</td>
</tr>
<tr>
<td><code>--free-loss</code></td>
<td>off</td>
<td>Treat a genome carrying none of a family's observed members as missing data (<code>?</code>) instead of <code>-</code></td>
</tr>
<tr>
<td><code>--no-ambiguity</code></td>
<td>off</td>
<td>Treat a genome carrying more than one member of a family as missing data (<code>?</code>) instead of an IUPAC ambiguity code</td>
</tr>
<tr>
<td><code>--entropy MU</code></td>
<td>off (<code>1.0</code> if only <code>--entropy-sd</code> is given)</td>
<td>Center of the entropy band to favor when sampling</td>
</tr>
<tr>
<td><code>--entropy-sd SIGMA</code></td>
<td>off (<code>0.5</code> if only <code>--entropy</code> is given)</td>
<td>Width of that band</td>
</tr>
</tbody>
</table>
<h2 id="sampling-at-scale-subsample-shannon-entropy">Sampling at scale: <code>--subsample</code>, <code>--shannon</code>, <code>--entropy</code></h2>
<p><code>--subsample</code>, <code>--free-loss</code>, <code>--no-ambiguity</code>, <code>--entropy</code>/<code>--entropy-sd</code> are shared by <code>--pseudo-alignment</code>, <code>--sankoff</code> (and everything it implies: <code>--tnt</code>/<code>--phyg</code>/<code>--iqtree</code>), and a <code>snp-*</code> <code>--distance</code> value — one draw feeds all of them in a single invocation. <code>--subsample</code> is mandatory for <code>--pseudo-alignment</code>/<code>--sankoff</code>; for a <code>snp-*</code> <code>--distance</code> value it is optional (omitted means every non-monomorphic family in the index, not an approximation).</p>
<p>Without <code>--subsample</code>, every variable family (family size ≥ 2) is used. With <code>--subsample N</code>, roughly <code>N</code> families are kept instead, drawn in proportion to how many candidate families each part of the index actually holds, so the sample stays representative of the whole index. If the index has fewer than <code>N</code> candidate families, <code>--subsample</code> has no effect.</p>
<h3 id="-shannon-measuring-how-informative-a-family-is"><code>--shannon</code>: measuring how informative a family is</h3>
<p><code>&lt;prefix&gt;_entropy.csv</code> has one row per family visited:</p>
<table>
<thead>
<tr>
<th>Column</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>layer</code></td>
<td>an internal index-layer identifier — stable within one run, not meaningful across indexes</td>
</tr>
<tr>
<td><code>family_idx</code></td>
<td>the family's position within that layer</td>
</tr>
<tr>
<td><code>entropy15</code></td>
<td>Shannon entropy (bits) over the 16 possible states (the 15 non-empty subsets of <code>{A,C,G,T}</code>), genomes absent from the family excluded from the count</td>
</tr>
<tr>
<td><code>entropy4</code></td>
<td>Shannon entropy (bits) reduced to the 4 plain bases, kept alongside <code>entropy15</code> for comparison</td>
</tr>
<tr>
<td><code>family_size</code></td>
<td>number of distinct central bases observed anywhere in the index for this family (2-4)</td>
</tr>
<tr>
<td><code>n_genomes_present</code></td>
<td>how many genomes the entropy was computed over</td>
</tr>
</tbody>
</table>
<p>Run with <code>--subsample N --shannon</code> to get a bounded diagnostic sample instead of a full-index pass — useful for choosing <code>--entropy</code>/<code>--entropy-sd</code> values before a full run.</p>
<h3 id="-entropy-mu-entropy-sd-sigma-biasing-the-sample-toward-informative-families"><code>--entropy MU</code> / <code>--entropy-sd SIGMA</code>: biasing the sample toward informative families</h3>
<p>By default, <code>--subsample</code> draws families uniformly. With <code>--entropy</code>/<code>--entropy-sd</code>, each family's chance of being kept is instead weighted by how close its own entropy (<code>entropy15</code>) is to <code>MU</code>, using a Gaussian curve of width <code>SIGMA</code> — no hard cutoff. The filter activates as soon as either flag is given; the other defaults to <code>1.0</code>/<code>0.5</code>. Combine with <code>--subsample N</code> (expect somewhat fewer than <code>N</code> families kept in practice) or use alone (a soft filter over the whole index, no size target).</p>
<p>The first <code>phylo</code> run on a given index that uses <code>--entropy</code>/<code>--entropy-sd</code> pays a one-time extra cost (every candidate family's entropy is computed once and saved alongside the index); later runs, even with different <code>MU</code>/<code>SIGMA</code>, reuse that saved data.</p>
<h2 id="sankoff-calibration-and-phylogenetic-exports">Sankoff calibration and phylogenetic exports</h2>
<table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--sankoff</code></td>
<td>off</td>
<td>Calibrate a 16-state parsimony cost matrix and matching pseudo-alignment. Requires <code>--subsample N</code></td>
</tr>
<tr>
<td><code>--sankoff-ratio-ceiling</code></td>
<td><code>0.5</code></td>
<td>Exclude genome pairs whose raw SNP ratio exceeds this value from the base-composition part of the calibration</td>
</tr>
<tr>
<td><code>--free-loss</code></td>
<td>off</td>
<td>Recode a family's non-detection as the <code>?</code> missing-data symbol instead of an ordinary, costed state, throughout <code>--sankoff</code> and every export built from it</td>
</tr>
<tr>
<td><code>--tnt</code></td>
<td>off</td>
<td>Also write a TNT script (implies <code>--sankoff</code>)</td>
</tr>
<tr>
<td><code>--phyg</code></td>
<td>off</td>
<td>Also write PhyG input files (implies <code>--sankoff</code>)</td>
</tr>
<tr>
<td><code>--iqtree</code></td>
<td>off</td>
<td>Also write an IQ-TREE custom model and alignment (implies <code>--sankoff</code>)</td>
</tr>
<tr>
<td><code>--iqtree-min-freq</code></td>
<td><code>0.001</code></td>
<td>With <code>--iqtree --free-loss</code>: also treat as missing any state rarer than this in the alignment</td>
</tr>
<tr>
<td><code>--sankoff-cost-scale</code></td>
<td><code>100</code></td>
<td>Integer scaling factor applied to costs before rounding, for TNT/PhyG's integer-only cost commands</td>
</tr>
</tbody>
</table>
<h3 id="the-16-state-model">The 16-state model</h3>
<p>Each family is a character with 16 possible states: one per subset of the 4 possible central bases (including the empty subset). Calibration combines a <span class="arithmatex">\(5 \times 5\)</span> transition matrix over family cardinality (0-4 observed forms) and a <span class="arithmatex">\(4 \times 4\)</span> base-substitution matrix from unambiguous single-copy loci, both restricted to genome pairs at or below <code>--sankoff-ratio-ceiling</code>, into a row-normalized <span class="arithmatex">\(16 \times 16\)</span> transition probability matrix <span class="arithmatex">\(P\)</span>, converted to a symmetric cost matrix via <span class="arithmatex">\(\text{cost}(a,b) = -\ln P(a,b)\)</span>.</p>
<p><code>--sankoff</code> alone writes the cost matrix, the calibration parameters, and a pseudo-alignment recoded so the empty state uses the symbol <code>0</code> (never a gap character). It does not run any external tool.</p>
<p>With <code>--free-loss</code>, the empty state is recoded to <code>?</code> (TNT/PhyG/IQ-TREE's own missing-data symbol) instead of an ordinary, costed 16th state — <code>?</code> rather than <code>-</code>, since <code>-</code> still carries gap/indel semantics in these tools. <code>--free-loss</code> also zeroes the cardinality-transition cost between any two states, not just to/from the empty one: gaining or losing a sibling is priced the same way — for free — as gaining or losing the whole family.</p>
<h3 id="exports">Exports</h3>
<p>All three exports reuse the <code>--sankoff</code> calibrated matrix and pseudo-alignment, recoded for the target tool:</p>
<ul>
<li><strong><code>--tnt</code></strong>: a self-contained TNT script (alignment recoded to TNT's fixed 16-symbol alphabet, integer-scaled cost matrix re-closed to a metric, a default search block).</li>
<li><strong><code>--phyg</code></strong>: a custom cost-matrix file plus a PhyG script reusing the <code>--sankoff</code> alignment directly.</li>
<li><strong><code>--iqtree</code></strong>: a custom substitution-model file (exchangeability matrix recovered as <span class="arithmatex">\(R(a,b) = e^{-\text{cost}(a,b)}\)</span>, plus empirical state frequencies) and a matching alignment, for maximum-likelihood inference with real branch lengths. Only states actually occurring in the alignment are kept and compactly renumbered.</li>
</ul>
<p>TNT and PhyG both write trees with bare numeric leaf labels (<code>1</code>, <code>2</code>, ..., in the order the genomes appear in <code>&lt;prefix&gt;_sankoff.fasta</code>).</p>
<h2 id="output-files">Output files</h2>
<p>With <code>-o/--output PREFIX</code>, the relevant subset of the files below is written. Without <code>-o</code>, only the distance matrix is produced, on stdout. All matrices use genome labels as row/column headers, in index order.</p>
<h3 id="distance-matrix">Distance matrix</h3>
<table>
<thead>
<tr>
<th>File</th>
<th>Written by</th>
<th>Format</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;prefix&gt;_dist.phy</code></td>
<td>always, unless <code>--csv</code></td>
<td>relaxed PHYLIP</td>
<td>the <code>--distance</code> matrix</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_dist.csv</code></td>
<td><code>--csv</code></td>
<td>CSV matrix</td>
<td>the <code>--distance</code> matrix, 6 decimals</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_shared.csv</code></td>
<td><code>--shared-kmers</code></td>
<td>CSV matrix</td>
<td>shared-kmer count per genome pair (integers)</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_nj.nwk</code></td>
<td><code>--nj</code></td>
<td>Newick</td>
<td>Neighbor-Joining tree</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_upgma.nwk</code></td>
<td><code>--upgma</code></td>
<td>Newick</td>
<td>UPGMA tree</td>
</tr>
</tbody>
</table>
<p>CSV matrix layout (<code>_dist.csv</code>, <code>_shared.csv</code>, <code>_family_overlap.csv</code>): header <code>genome,&lt;label1&gt;,&lt;label2&gt;,...</code>, one data row per genome, <code>&lt;label&gt;,&lt;value1&gt;,&lt;value2&gt;,...</code>.</p>
<h3 id="central-position-snp-model_1">Central-position SNP model</h3>
<table>
<thead>
<tr>
<th>File</th>
<th>Written by</th>
<th>Format</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;prefix&gt;_siblings.csv</code></td>
<td><code>--sibling-stats</code></td>
<td>CSV table</td>
<td>family-size distribution, per genome and global</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_family_overlap.csv</code></td>
<td><code>--family-overlap</code></td>
<td>CSV matrix</td>
<td>variable families both genomes of a pair carry a call for</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_entropy.csv</code></td>
<td><code>--shannon</code></td>
<td>CSV table</td>
<td>per-family Shannon entropy, see "Sampling at scale" above</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_alignment.fasta</code></td>
<td><code>--pseudo-alignment</code></td>
<td>FASTA</td>
<td>SNP-only pseudo-alignment, IUPAC-coded</td>
</tr>
</tbody>
</table>
<h3 id="sankoff-calibration-and-exports">Sankoff calibration and exports</h3>
<table>
<thead>
<tr>
<th>File</th>
<th>Written by</th>
<th>Format</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;prefix&gt;_sankoff_matrix.csv</code></td>
<td><code>--sankoff</code>/<code>--tnt</code>/<code>--phyg</code>/<code>--iqtree</code></td>
<td>CSV matrix</td>
<td>calibrated 16×16 cost matrix</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_sankoff_params.yaml</code></td>
<td>same flags</td>
<td>YAML</td>
<td>calibration report (raw tallies + derived probabilities)</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_sankoff.fasta</code></td>
<td>same flags</td>
<td>FASTA</td>
<td>Sankoff-recoded pseudo-alignment, header carries an <code>n_sites</code> annotation</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_sankoff.tnt</code></td>
<td><code>--tnt</code></td>
<td>TNT script</td>
<td>ready-to-run parsimony search</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_sankoff.tcm</code></td>
<td><code>--phyg</code></td>
<td>PhyG TCM</td>
<td>cost matrix in PhyG's own format</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_sankoff.pg</code></td>
<td><code>--phyg</code></td>
<td>PhyG script</td>
<td>ready-to-run parsimony search</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_iqtree.model</code></td>
<td><code>--iqtree</code></td>
<td>IQ-TREE model file</td>
<td>custom ML substitution model</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_iqtree.fasta</code></td>
<td><code>--iqtree</code></td>
<td>FASTA</td>
<td>alignment recoded for that model</td>
</tr>
<tr>
<td><code>&lt;prefix&gt;_iqtree_states.csv</code></td>
<td><code>--iqtree</code></td>
<td>CSV table</td>
<td>maps <code>_iqtree.model</code>/<code>_iqtree.fasta</code>'s compact state symbols back to <code>_sankoff_matrix.csv</code>'s alphabet</td>
</tr>
</tbody>
</table>
<p><strong><code>_sankoff_matrix.csv</code></strong> — header <code>state,0,A,C,M,G,R,S,V,T,W,Y,H,K,D,B,N</code>: the 16 symbols are IUPAC codes for the 16 subsets of the 4 possible central bases (bit 0=A, 1=C, 2=G, 3=T), <code>0</code> standing for the empty/absent state. One row per source state, one value per destination state, cost <span class="arithmatex">\(-\ln P(a,b)\)</span>, 4 decimals.</p>
<p><strong><code>_sankoff_params.yaml</code></strong>:</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ratio_ceiling</code></td>
<td>the <code>--sankoff-ratio-ceiling</code> value used</td>
</tr>
<tr>
<td><code>cardinality_transitions</code></td>
<td>5×5 list of <code>{from, to, count, probability}</code>, family cardinality (0-4 observed forms)</td>
</tr>
<tr>
<td><code>composition_transitions</code></td>
<td>4×4 list of <code>{from, to, count, probability}</code>, base letters <code>A/C/G/T</code>, single-copy substitutions</td>
</tr>
</tbody>
</table>
<p><strong><code>_sankoff.fasta</code></strong> — recoded to match <code>_sankoff_matrix.csv</code>'s alphabet: absent state is <code>0</code> (or <code>?</code> under <code>--free-loss</code>). Excluded genomes dropped; columns left monomorphic by that exclusion are re-checked and dropped too.</p>
<p><strong><code>_sankoff.tnt</code></strong> (<code>--tnt</code>) — <code>xread</code> block (alignment recoded to TNT's fixed <code>0-9A-F</code> alphabet), an integer-scaled (<code>--sankoff-cost-scale</code>) and metric-closed <code>smatrix</code>, a default <code>hold 20; mult; export</code> search. Run with <code>printf 'proc &lt;path&gt;;\nquit;\n' | tnt</code>. Produces <code>&lt;prefix&gt;_sankoff.tre</code> (bare numeric leaf labels, order matching <code>_sankoff.fasta</code>).</p>
<p><strong><code>_sankoff.tcm</code></strong> (<code>--phyg</code>) — first line: the 16-symbol alphabet plus a trailing gap symbol (17 total). Each following line: one row of the integer-scaled, metric-closed cost matrix (17 values — the extra gap column/row reuses the cost to/from the empty state <code>0</code>).</p>
<p><strong><code>_sankoff.pg</code></strong> (<code>--phyg</code>) — script: <code>read(prefasta:..., tcm:...)</code> against <code>_sankoff.fasta</code>/<code>_sankoff.tcm</code>, a default 300s/4-instance <code>search</code>, <code>report(...)</code> writing <code>&lt;prefix&gt;_sankoff.tre</code>. Run with <code>phyg</code> from the output directory (the script uses relative file names).</p>
<p><strong><code>_iqtree.model</code></strong> (<code>--iqtree</code>) — lower-triangular exchangeability matrix <span class="arithmatex">\(R(a,b) = e^{-\text{cost}(a,b)}\)</span> (one row of increasing length per state, whitespace-separated, PAML order), followed by one line of empirical state frequencies. Only states actually occurring in the alignment are kept, compactly renumbered <code>0..k-1</code>.</p>
<p><strong><code>_iqtree.fasta</code></strong> (<code>--iqtree</code>) — alignment recoded to that same compact <code>0..k-1</code> alphabet (symbols <code>0-9A-F</code>). Under <code>--free-loss</code>, non-detection becomes <code>?</code> and columns left non-informative once missing calls are ignored are dropped first (required for <code>+ASC</code>); with <code>--iqtree-min-freq</code> also set (the default), any state rarer than that threshold is folded into the same <code>?</code> treatment, and non-informative columns are re-checked and dropped again. Run with:
<div class="highlight"><pre><span></span><code>iqtree3 -s &lt;prefix&gt;_iqtree.fasta --seqtype MORPH -m &lt;prefix&gt;_iqtree.model+ASC --prefix &lt;prefix&gt;_iqtree -T AUTO
</code></pre></div></p>
<p><strong><code>_iqtree_states.csv</code></strong> (<code>--iqtree</code>) — one row per state actually kept in <code>_iqtree.model</code>/<code>_iqtree.fasta</code> (header <code>iqtree_symbol,canonical_symbol,frequency</code>): <code>iqtree_symbol</code> is the compact <code>0-9A-F</code> symbol as written in those two files, <code>canonical_symbol</code> is the matching <code>_sankoff_matrix.csv</code> state, <code>frequency</code> is that state's empirical frequency at full precision. Under <code>--free-loss</code>, absent (<code>0</code>/<code>?</code>) is never a kept state, so it never appears here — nor does any state <code>--iqtree-min-freq</code> folded away for being too rare.</p>
<h3 id="rare-states-and-iqtree-min-freq">Rare states and <code>--iqtree-min-freq</code></h3>
<p>States that combine 3 or 4 central bases at once (IUPAC <code>V</code>/<code>H</code>/<code>K</code>.../<code>N</code>) are inherently rare, and can make <code>iqtree3</code> itself numerically unstable ("Numerical underflow for lh-derivative" warnings). With <code>--free-loss</code> set, <code>--iqtree-min-freq</code> (default <code>0.001</code>, one in a thousand) extends the missing-data treatment to any state below this frequency, not just absence. Check <code>_iqtree_states.csv</code> to see exactly which states survived and at what frequency; set <code>--iqtree-min-freq 0</code> to keep every state that occurs at all. Has no effect without <code>--free-loss</code>.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": [], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>