Files

1288 lines
23 KiB
HTML
Raw Permalink Normal View History

2026-04-16 22:38:20 +02:00
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
2026-08-15 20:56:29 +02:00
<link rel="prev" href="../entropy_filter/">
2026-04-16 22:38:20 +02:00
2026-08-15 20:56:29 +02:00
<link rel="next" href="../indexing_architecture/">
2026-04-16 22:38:20 +02:00
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
2026-08-15 20:56:29 +02:00
<title>Minimizer selection - obikmer — User Guide</title>
2026-04-16 22:38:20 +02:00
<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">
2026-08-15 20:56:29 +02:00
<a href="#minimizer-selection" class="md-skip">
2026-04-16 22:38:20 +02:00
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">
2026-08-15 20:56:29 +02:00
<a href="../.." title="obikmer — User Guide" class="md-header__button md-logo" aria-label="obikmer — User Guide" data-md-component="logo">
2026-04-16 22:38:20 +02:00
<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">
2026-08-15 20:56:29 +02:00
obikmer — User Guide
2026-04-16 22:38:20 +02:00
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Minimizer selection
2026-04-16 22:38:20 +02:00
</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">
2026-08-15 20:56:29 +02:00
<a href="../.." title="obikmer — User Guide" class="md-nav__button md-logo" aria-label="obikmer — User Guide" data-md-component="logo">
2026-04-16 22:38:20 +02:00
<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>
2026-08-15 20:56:29 +02:00
obikmer — User Guide
2026-04-16 22:38:20 +02:00
</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>
2026-08-15 20:56:29 +02:00
<li class="md-nav__item">
<a href="../../installation/" class="md-nav__link">
<span class="md-ellipsis">
Installation
</span>
</a>
</li>
2026-04-16 22:38:20 +02:00
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
2026-08-15 20:56:29 +02:00
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
2026-04-16 22:38:20 +02:00
2026-08-15 20:56:29 +02:00
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
Theory
</span>
<span class="md-nav__icon md-icon"></span>
</label>
2026-08-15 20:56:29 +02:00
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
2026-04-16 22:38:20 +02:00
<span class="md-nav__icon md-icon"></span>
Theory
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="../kmers_and_superkmers/" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
Kmers and super-kmers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../encoding/" class="md-nav__link">
<span class="md-ellipsis">
DNA encoding
</span>
</a>
</li>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="../entropy_filter/" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Low-complexity kmer filter
</span>
</a>
</li>
2026-04-16 22:38:20 +02:00
<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">
2026-08-15 20:56:29 +02:00
Minimizer selection
2026-04-16 22:38:20 +02:00
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Minimizer selection
2026-04-16 22:38:20 +02:00
</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">
2026-08-15 20:56:29 +02:00
<a href="#definition" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Definition
2026-04-16 22:38:20 +02:00
</span>
</a>
</li>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="#hash-based-random-minimizer" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Hash-based ("random") minimizer
</span>
</a>
<nav class="md-nav" aria-label="Hash-based (&#34;random&#34;) minimizer">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#hash-function" class="md-nav__link">
<span class="md-ellipsis">
Hash function
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#partition-routing-is-independent-of-minimizer-selection" class="md-nav__link">
<span class="md-ellipsis">
Partition routing is independent of minimizer selection
2026-04-16 22:38:20 +02:00
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="../indexing_architecture/" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Partitioning and indexing architecture
</span>
</a>
</li>
2026-04-16 22:38:20 +02:00
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Usage
2026-04-16 22:38:20 +02:00
</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="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
2026-08-15 20:56:29 +02:00
Usage
2026-04-16 22:38:20 +02:00
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="../../usage/superkmer/" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
superkmer
2026-04-16 22:38:20 +02:00
</span>
</a>
</li>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="../../usage/index_command/" class="md-nav__link">
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/merge/" class="md-nav__link">
<span class="md-ellipsis">
merge
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/filter/" class="md-nav__link">
<span class="md-ellipsis">
filter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/select/" class="md-nav__link">
<span class="md-ellipsis">
select
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/query/" class="md-nav__link">
<span class="md-ellipsis">
query
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/dump/" class="md-nav__link">
<span class="md-ellipsis">
dump
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/annotate/" class="md-nav__link">
<span class="md-ellipsis">
annotate
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/phylo/" class="md-nav__link">
<span class="md-ellipsis">
phylo
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/name-tree/" class="md-nav__link">
<span class="md-ellipsis">
name-tree
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/unitig/" class="md-nav__link">
<span class="md-ellipsis">
unitig
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/estimate/" class="md-nav__link">
<span class="md-ellipsis">
estimate
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/reindex/" class="md-nav__link">
<span class="md-ellipsis">
reindex
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/utils/" class="md-nav__link">
<span class="md-ellipsis">
utils
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/pack/" class="md-nav__link">
<span class="md-ellipsis">
pack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../usage/predicates/" class="md-nav__link">
<span class="md-ellipsis">
Predicates and taxonomy paths
</span>
</a>
</li>
2026-04-16 22:38:20 +02:00
</ul>
</nav>
</li>
2026-08-15 20:56:29 +02:00
<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>
2026-04-16 22:38:20 +02:00
</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">
2026-08-15 20:56:29 +02:00
<a href="#definition" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Definition
2026-04-16 22:38:20 +02:00
</span>
</a>
</li>
<li class="md-nav__item">
2026-08-15 20:56:29 +02:00
<a href="#hash-based-random-minimizer" class="md-nav__link">
2026-04-16 22:38:20 +02:00
<span class="md-ellipsis">
2026-08-15 20:56:29 +02:00
Hash-based ("random") minimizer
</span>
</a>
<nav class="md-nav" aria-label="Hash-based (&#34;random&#34;) minimizer">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#hash-function" class="md-nav__link">
<span class="md-ellipsis">
Hash function
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#partition-routing-is-independent-of-minimizer-selection" class="md-nav__link">
<span class="md-ellipsis">
Partition routing is independent of minimizer selection
2026-04-16 22:38:20 +02:00
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
2026-08-15 20:56:29 +02:00
<h1 id="minimizer-selection">Minimizer selection</h1>
<h2 id="definition">Definition</h2>
<p>A <strong>minimizer</strong> of a kmer window is the m-mer (<span class="arithmatex">\(m &lt; k\)</span>) that is smallest, among all <span class="arithmatex">\(k - m + 1\)</span> overlapping m-mers in the window, under a chosen ordering. The minimizer is always taken in canonical form (lexicographic minimum of forward and reverse complement) so that selection is strand-independent.</p>
<p>The minimizer partitions a sequence into super-kmers: maximal runs of overlapping kmers that share the same minimizer (see <a href="../kmers_and_superkmers/">Kmers and super-kmers</a>).</p>
<h2 id="hash-based-random-minimizer">Hash-based ("random") minimizer</h2>
<p><code>obikmer</code> selects minimizers by hash order rather than plain lexicographic order. Ordering m-mers lexicographically on their 2-bit encoding systematically favors AT-rich m-mers (an all-A m-mer always encodes to 0), which causes low-complexity regions to dominate as minimizers and produces unbalanced partitions.</p>
<p>Instead, a well-distributed hash function <span class="arithmatex">\(H\)</span> is applied to the canonical (lexicographically minimal) form of each m-mer, and the m-mer with the smallest <span class="arithmatex">\(H\)</span> value wins. Because <span class="arithmatex">\(H\)</span> is a bijection with good avalanche properties, every distinct m-mer in a window has an equal chance of holding the minimum hash value, independent of its nucleotide composition.</p>
<p>The canonical form used as input to <span class="arithmatex">\(H\)</span> is still the lexicographic minimum of forward/reverse-complement — hashing is applied on top of it, not used to redefine it. Defining canonicity by hash value instead would bias the <em>distribution of hash values themselves</em> toward small values (the minimum of two independent hashes is not uniformly distributed), reintroducing a bias one layer down.</p>
<h3 id="hash-function">Hash function</h3>
<p>The hash function is a 64-bit mixing function (splitmix64-style finalizer) applied to the m-mer XORed with a fixed non-zero seed:</p>
<div class="arithmatex">\[H(x) = \text{mix64}(x \oplus s), \quad s = \lfloor 2^{64}/\varphi \rfloor = \texttt{0x9e3779b97f4a7c15}\]</div>
<div class="highlight"><pre><span></span><code>H(x):
x ← x ⊕ 0x9e3779b97f4a7c15
x ← x ⊕ (x &gt;&gt; 30)
x ← x × 0xbf58476d1ce4e5b9
x ← x ⊕ (x &gt;&gt; 27)
x ← x × 0x94d049bb133111eb
return x ⊕ (x &gt;&gt; 31)
2026-04-16 22:38:20 +02:00
</code></pre></div>
2026-08-15 20:56:29 +02:00
<p>The XOR seed avoids the finalizer's fixed point at 0 (<span class="arithmatex">\(\text{mix64}(0) = 0\)</span>), which would otherwise make an all-A m-mer (canonical value 0) win every window comparison.</p>
<h2 id="partition-routing-is-independent-of-minimizer-selection">Partition routing is independent of minimizer selection</h2>
<p>The hash used to select a minimizer within a window (the minimum of several hash values) and the hash used to route a super-kmer to a storage partition are computed separately:</p>
<ul>
<li><strong>Selection</strong> uses <span class="arithmatex">\(H\)</span> applied to every candidate m-mer in the window, keeping the minimum.</li>
<li><strong>Partition routing</strong> recomputes <span class="arithmatex">\(H\)</span> on the single selected minimizer only, once its position is fixed. This is a hash of one specific value, not the minimum of several, so it is uniformly distributed and safe to use directly for routing.</li>
</ul>
<p>See <a href="../indexing_architecture/">Partitioning and indexing architecture</a> for how the routing value is turned into a partition index.</p>
2026-04-16 22:38:20 +02:00
</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>