Compare commits
3 Commits
071723accc
...
2417959fbd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2417959fbd | ||
|
|
4e338bc1d4 | ||
|
|
053d2e28cb |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -3,6 +3,8 @@
|
||||
/jupyterhub_volumes/shared
|
||||
/jupyterhub_volumes/jupyterhub
|
||||
/jupyterhub_volumes/caddy
|
||||
/jupyterhub_volumes/course/data/Genbank
|
||||
/jupyterhub_volumes/web/
|
||||
/**/.DS_Store
|
||||
/web_src/**/*.RData
|
||||
/web_src/**/*.pdf
|
||||
@@ -11,3 +13,7 @@
|
||||
/.luarc.json
|
||||
/sandbox
|
||||
*.log
|
||||
ncbitaxo_*
|
||||
Readme_files
|
||||
Readme.html
|
||||
tmp.*
|
||||
709
Readme.html
Normal file
709
Readme.html
Normal file
@@ -0,0 +1,709 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.8.26">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>readme</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for syntax highlighting */
|
||||
html { -webkit-text-size-adjust: 100%; }
|
||||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||
.sourceCode { overflow: visible; }
|
||||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||
div.sourceCode { margin: 1em 0; }
|
||||
pre.sourceCode { margin: 0; }
|
||||
@media screen {
|
||||
div.sourceCode { overflow: auto; }
|
||||
}
|
||||
@media print {
|
||||
pre > code.sourceCode { white-space: pre-wrap; }
|
||||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||
}
|
||||
pre.numberSource code
|
||||
{ counter-reset: source-line 0; }
|
||||
pre.numberSource code > span
|
||||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||
pre.numberSource code > span > a:first-child::before
|
||||
{ content: counter(source-line);
|
||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||
border: none; display: inline-block;
|
||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||
-khtml-user-select: none; -moz-user-select: none;
|
||||
-ms-user-select: none; user-select: none;
|
||||
padding: 0 4px; width: 4em;
|
||||
}
|
||||
pre.numberSource { margin-left: 3em; padding-left: 4px; }
|
||||
div.sourceCode
|
||||
{ }
|
||||
@media screen {
|
||||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script src="Readme_files/libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/quarto.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/tabsets/tabsets.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/axe/axe-check.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/popper.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="Readme_files/libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="Readme_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="Readme_files/libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="Readme_files/libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="Readme_files/libs/bootstrap/bootstrap-d6a003b94517c951b2d65075d42fb01b.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="fullcontent quarto-light">
|
||||
|
||||
<div id="quarto-content" class="page-columns page-rows-contents page-layout-article">
|
||||
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
|
||||
|
||||
|
||||
<section id="obijupyterhub---the-dna-metabarcoding-learning-server" class="level1">
|
||||
<h1>OBIJupyterHub - the DNA Metabarcoding Learning Server</h1>
|
||||
<section id="intended-use" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="intended-use">Intended use</h2>
|
||||
<p>This project packages the MetabarcodingSchool training lab into one reproducible bundle. You get Python, R, and Bash kernels, a Quarto-built course website, and preconfigured admin/student accounts, so onboarding a class is a single command instead of a day of setup. Everything runs locally on a single machine, student work persists between sessions, and <code>./start-jupyterhub.sh</code> takes care of building images, rendering the site, preparing volumes, and bringing JupyterHub up at <code>http://localhost:8888</code>. Defaults (accounts, passwords, volumes) live in the repo so instructors can tweak them quickly.</p>
|
||||
</section>
|
||||
<section id="prerequisites-with-quick-checks" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="prerequisites-with-quick-checks">Prerequisites (with quick checks)</h2>
|
||||
<p>You need Docker, Docker Compose, Quarto, and Python 3 available on the machine that will host the lab.</p>
|
||||
<ul>
|
||||
<li>macOS: install <a href="https://orbstack.dev/">OrbStack</a> (recommended) or Docker Desktop; both ship Docker Engine and Compose.</li>
|
||||
<li>Linux: install Docker Engine and the Compose plugin from your distribution (e.g., <code>sudo apt install docker.io docker-compose-plugin</code>) or from Docker’s official packages.</li>
|
||||
<li>Windows: install Docker Desktop with the WSL2 backend enabled.</li>
|
||||
<li>Quarto CLI: get installers from <a href="https://quarto.org/docs/get-started/" class="uri">https://quarto.org/docs/get-started/</a>.</li>
|
||||
<li>Python 3: any recent version is fine (only the standard library is used).</li>
|
||||
</ul>
|
||||
<p>Verify from a terminal; if a command is missing, install it before moving on:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> <span class="at">--version</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> compose version <span class="co"># or: docker-compose --version</span></span>
|
||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">quarto</span> <span class="at">--version</span></span>
|
||||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">--version</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="how-the-startup-script-works" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="how-the-startup-script-works">How the startup script works</h2>
|
||||
<p><code>./start-jupyterhub.sh</code> is the single entry point. It builds the Docker images, renders the course website, prepares the volume folders, and starts the stack. Internally it:</p>
|
||||
<ul>
|
||||
<li>creates the <code>jupyterhub_volumes/</code> tree (caddy, course, shared, users, web…)</li>
|
||||
<li>builds <code>jupyterhub-student</code> and <code>jupyterhub-hub</code> images</li>
|
||||
<li>renders the Quarto site from <code>web_src/</code>, generates PDF galleries and <code>pages.json</code>, and copies everything into <code>jupyterhub_volumes/web/</code></li>
|
||||
<li>runs <code>docker-compose up -d --remove-orphans</code></li>
|
||||
</ul>
|
||||
<p>You can tailor what it does with a few flags:</p>
|
||||
<ul>
|
||||
<li><code>--no-build</code> (or <code>--offline</code>): skip Docker image builds and reuse existing images (useful when offline).</li>
|
||||
<li><code>--force-rebuild</code>: rebuild images without cache.</li>
|
||||
<li><code>--stop-server</code>: stop the stack and remove student containers, then exit.</li>
|
||||
<li><code>--update-lectures</code>: rebuild the course website only (no Docker stop/start).</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="installation-and-first-run" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="installation-and-first-run">Installation and first run</h2>
|
||||
<ol type="1">
|
||||
<li>Clone the project:</li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> clone https://forge.metabarcoding.org/MetabarcodingSchool/OBIJupyterHub.git</span>
|
||||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> OBIJupyterHub</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<ol start="2" type="1">
|
||||
<li>(Optional) glance at the structure you’ll populate:</li>
|
||||
</ol>
|
||||
<pre><code>OBIJupyterHub
|
||||
├── start-jupyterhub.sh - single entry point (build + render + start)
|
||||
├── obijupyterhub - Docker images and stack definitions
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── Dockerfile
|
||||
│ ├── Dockerfile.hub
|
||||
│ └── jupyterhub_config.py
|
||||
├── jupyterhub_volumes - data persisted on the host
|
||||
│ ├── course - read-only for students (notebooks, data, bin, R packages)
|
||||
│ ├── shared - shared read/write space for everyone
|
||||
│ ├── users - per-user persistent data
|
||||
│ └── web - rendered course website
|
||||
└── web_src - Quarto sources for the course website</code></pre>
|
||||
<ol start="3" type="1">
|
||||
<li>Prepare course materials (optional before first run):</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Put notebooks, datasets, scripts, binaries, or PDFs for students under <code>jupyterhub_volumes/course/</code>. They will appear read-only at <code>/home/jovyan/work/course/</code>.</li>
|
||||
<li>For collaborative work, drop files in <code>jupyterhub_volumes/shared/</code> (read/write for all at <code>/home/jovyan/work/shared/</code>).</li>
|
||||
<li>Edit or add Quarto sources in <code>web_src/</code> to update the course website; the script will render them.</li>
|
||||
</ul>
|
||||
<ol start="4" type="1">
|
||||
<li>Start everything (build + render + launch):</li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./start-jupyterhub.sh</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<ol start="5" type="1">
|
||||
<li><p>Access JupyterHub in a browser at <code>http://localhost:8888</code>.</p></li>
|
||||
<li><p>Stop the stack when you’re done (run from <code>obijupyterhub/</code>):</p></li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker-compose</span> down</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<section id="operating-the-stack-one-command-a-few-options" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="operating-the-stack-one-command-a-few-options">Operating the stack (one command, a few options)</h3>
|
||||
<ul>
|
||||
<li>Start or rebuild: <code>./start-jupyterhub.sh</code> (rebuilds images, regenerates the website, starts the stack).</li>
|
||||
<li>Start without rebuilding images (offline): <code>./start-jupyterhub.sh --no-build</code></li>
|
||||
<li>Force rebuild without cache: <code>./start-jupyterhub.sh --force-rebuild</code></li>
|
||||
<li>Stop only: <code>./start-jupyterhub.sh --stop-server</code></li>
|
||||
<li>Rebuild website only (no Docker stop/start): <code>./start-jupyterhub.sh --update-lectures</code></li>
|
||||
<li>Access at <code>http://localhost:8888</code> (students: any username / password <code>metabar2025</code>; admin: <code>admin</code> / <code>admin2025</code>).</li>
|
||||
<li>Check logs from <code>obijupyterhub/</code> with <code>docker-compose logs -f jupyterhub</code>.</li>
|
||||
<li>Stop with <code>docker-compose down</code> (from <code>obijupyterhub/</code>). Rerun <code>./start-jupyterhub.sh</code> to start again or after config changes.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="managing-shared-data" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="managing-shared-data">Managing shared data</h2>
|
||||
<p>Each student lands in <code>/home/jovyan/work/</code> with three key areas: their own files, a shared space, and a read-only course space. Everything under <code>work/</code> is persisted on the host in <code>jupyterhub_volumes</code>.</p>
|
||||
<pre><code>work/ # Personal workspace root (persistent)
|
||||
├── [student files] # Their own files and notebooks
|
||||
├── R_packages/ # Personal R packages (writable by student)
|
||||
├── shared/ # Shared workspace (read/write, shared with all)
|
||||
└── course/ # Course files (read-only, managed by admin)
|
||||
├── R_packages/ # Shared R packages (read-only, installed by prof)
|
||||
├── bin/ # Shared executables (in PATH)
|
||||
└── [course materials] # Your course files</code></pre>
|
||||
<p>R looks for packages in this order: personal <code>work/R_packages/</code>, then shared <code>work/course/R_packages/</code>, then system libraries. Because everything lives under <code>work/</code>, student files survive restarts.</p>
|
||||
<section id="user-accounts" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="user-accounts">User Accounts</h3>
|
||||
<p>Defaults are defined in <code>obijupyterhub/docker-compose.yml</code>: admin (<code>admin</code> / <code>admin2025</code>) with write access to <code>course/</code>, and students (any username, password <code>metabar2025</code>) with read-only access to <code>course/</code>. Adjust <code>JUPYTERHUB_ADMIN_PASSWORD</code> and <code>JUPYTERHUB_PASSWORD</code> there, then rerun <code>./start-jupyterhub.sh</code>.</p>
|
||||
</section>
|
||||
<section id="installing-r-packages-admin-only" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="installing-r-packages-admin-only">Installing R Packages (Admin Only)</h3>
|
||||
<p>From the host, install shared R packages into <code>course/R_packages/</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Install packages</span></span>
|
||||
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">tools/install_packages.sh</span> reshape2 plotly knitr</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Students can install their own packages into their personal <code>work/R_packages/</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Install in personal library (each student has their own)</span></span>
|
||||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">install.packages</span>(<span class="st">'mypackage'</span>) <span class="co"># Will install in work/R_packages/</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="using-r-packages-students" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="using-r-packages-students">Using R Packages (Students)</h3>
|
||||
<p>Students simply load packages normally:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(reshape2) <span class="co"># R checks: 1) work/R_packages/ 2) work/course/R_packages/ 3) system</span></span>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(plotly)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>R automatically searches in this order:</p>
|
||||
<ol type="1">
|
||||
<li>Personal packages: <code>/home/jovyan/work/R_packages/</code> (R_LIBS_USER)</li>
|
||||
<li>Prof packages: <code>/home/jovyan/work/course/R_packages/</code> (R_LIBS_SITE)</li>
|
||||
<li>System packages</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="list-available-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="list-available-packages">List Available Packages</h3>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co"># List all available packages (personal + course + system)</span></span>
|
||||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">installed.packages</span>()[,<span class="st">"Package"</span>]</span>
|
||||
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="co"># Check personal packages</span></span>
|
||||
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="fu">list.files</span>(<span class="st">"/home/jovyan/work/R_packages"</span>)</span>
|
||||
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="co"># Check course packages (installed by prof)</span></span>
|
||||
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="fu">list.files</span>(<span class="st">"/home/jovyan/work/course/R_packages"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="deposit-or-retrieve-course-and-student-files" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="deposit-or-retrieve-course-and-student-files">Deposit or retrieve course and student files</h3>
|
||||
<p>On the host, place course files in <code>jupyterhub_volumes/course/</code> (they appear read-only to students), shared files in <code>jupyterhub_volumes/shared/</code>, and collect student work from <code>jupyterhub_volumes/users/</code>.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="user-management" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="user-management">User Management</h2>
|
||||
<section id="option-1-predefined-user-list" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="option-1-predefined-user-list">Option 1: Predefined User List</h3>
|
||||
<p>In <code>jupyterhub_config.py</code>, uncomment and modify:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>c.Authenticator.allowed_users <span class="op">=</span> {<span class="st">'student1'</span>, <span class="st">'student2'</span>, <span class="st">'student3'</span>}</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="option-2-allow-everyone-for-testing" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="option-2-allow-everyone-for-testing">Option 2: Allow Everyone (for testing)</h3>
|
||||
<p>By default, the configuration allows any user:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>c.Authenticator.allow_all <span class="op">=</span> <span class="va">True</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>⚠️ <strong>Warning</strong>: DummyAuthenticator is ONLY for local testing!</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="kernel-verification" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="kernel-verification">Kernel Verification</h2>
|
||||
<p>Once logged in, create a new notebook and verify you have access to:</p>
|
||||
<ul>
|
||||
<li><strong>Python 3</strong> (default kernel)</li>
|
||||
<li><strong>R</strong> (R kernel)</li>
|
||||
<li><strong>Bash</strong> (bash kernel)</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="customization-for-your-labs" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="customization-for-your-labs">Customization for Your Labs</h2>
|
||||
<section id="add-additional-r-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="add-additional-r-packages">Add Additional R Packages</h3>
|
||||
<p>Modify the <code>Dockerfile</code> (before <code>USER ${NB_UID}</code>):</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13"><pre class="sourceCode dockerfile code-with-copy"><code class="sourceCode dockerfile"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">RUN</span> <span class="ex">R</span> <span class="at">-e</span> <span class="st">"install.packages(c('your_package'), repos='http://cran.rstudio.com/')"</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Then rerun <code>./start-jupyterhub.sh</code> to rebuild and restart.</p>
|
||||
</section>
|
||||
<section id="add-python-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="add-python-packages">Add Python Packages</h3>
|
||||
<p>Add to the <code>Dockerfile</code> (before <code>USER ${NB_UID}</code>):</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14"><pre class="sourceCode dockerfile code-with-copy"><code class="sourceCode dockerfile"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">RUN</span> <span class="ex">pip</span> install numpy pandas matplotlib seaborn</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Then rerun <code>./start-jupyterhub.sh</code> to rebuild and restart.</p>
|
||||
</section>
|
||||
<section id="change-port-if-8000-is-occupied" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="change-port-if-8000-is-occupied">Change Port (if 8000 is occupied)</h3>
|
||||
<p>Modify in <code>docker-compose.yml</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ports</span><span class="kw">:</span></span>
|
||||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> </span><span class="st">"8001:8000"</span><span class="co"> # Accessible on localhost:8001</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="advantages-of-this-approach" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="advantages-of-this-approach">Advantages of This Approach</h2>
|
||||
<p>✅ <strong>Everything in Docker</strong>: No need to install Python/JupyterHub on your computer<br>
|
||||
✅ <strong>Portable</strong>: Easy to deploy on another server<br>
|
||||
✅ <strong>Isolated</strong>: No pollution of your system environment<br>
|
||||
✅ <strong>Easy to Clean</strong>: A simple <code>docker-compose down</code> is enough<br>
|
||||
✅ <strong>Reproducible</strong>: Students will have exactly the same environment</p>
|
||||
</section>
|
||||
<section id="troubleshooting" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="troubleshooting">Troubleshooting</h2>
|
||||
<ul>
|
||||
<li>Docker daemon unavailable: make sure OrbStack/Docker Desktop/daemon is running; verify <code>/var/run/docker.sock</code> exists.</li>
|
||||
<li>Student containers do not start: check <code>docker-compose logs jupyterhub</code> and confirm the images exist with <code>docker images | grep jupyterhub-student</code>.</li>
|
||||
<li>Port conflict: change the published port in <code>docker-compose.yml</code>.</li>
|
||||
</ul>
|
||||
<p><strong>I want to start from scratch</strong>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="bu">pushd</span> obijupyterhub</span>
|
||||
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker-compose</span> down <span class="at">-v</span></span>
|
||||
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> rmi jupyterhub-hub jupyterhub-student</span>
|
||||
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="bu">popd</span></span>
|
||||
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a><span class="co"># Then rebuild everything</span></span>
|
||||
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ex">./start-jupyterhub.sh</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
<!-- /main column -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const onCopySuccess = function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
}
|
||||
const getTextToCopy = function(trigger) {
|
||||
const outerScaffold = trigger.parentElement.cloneNode(true);
|
||||
const codeEl = outerScaffold.querySelector('code');
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
|
||||
text: getTextToCopy
|
||||
});
|
||||
clipboard.on('success', onCopySuccess);
|
||||
if (window.document.getElementById('quarto-embedded-source-code-modal')) {
|
||||
const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
|
||||
text: getTextToCopy,
|
||||
container: window.document.getElementById('quarto-embedded-source-code-modal')
|
||||
});
|
||||
clipboardModal.on('success', onCopySuccess);
|
||||
}
|
||||
var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
|
||||
var mailtoRegex = new RegExp(/^mailto:/);
|
||||
var filterRegex = new RegExp('/' + window.location.host + '/');
|
||||
var isInternal = (href) => {
|
||||
return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
|
||||
}
|
||||
// Inspect non-navigation links and adorn them if external
|
||||
var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
|
||||
for (var i=0; i<links.length; i++) {
|
||||
const link = links[i];
|
||||
if (!isInternal(link.href)) {
|
||||
// undo the damage that might have been done by quarto-nav.js in the case of
|
||||
// links that we want to consider external
|
||||
if (link.dataset.originalHref !== undefined) {
|
||||
link.href = link.dataset.originalHref;
|
||||
}
|
||||
}
|
||||
}
|
||||
function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start',
|
||||
};
|
||||
if (contentFn) {
|
||||
config.content = contentFn;
|
||||
}
|
||||
if (onTriggerFn) {
|
||||
config.onTrigger = onTriggerFn;
|
||||
}
|
||||
if (onUntriggerFn) {
|
||||
config.onUntrigger = onUntriggerFn;
|
||||
}
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
if (note) {
|
||||
return note.innerHTML;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
const xrefs = window.document.querySelectorAll('a.quarto-xref');
|
||||
const processXRef = (id, note) => {
|
||||
// Strip column container classes
|
||||
const stripColumnClz = (el) => {
|
||||
el.classList.remove("page-full", "page-columns");
|
||||
if (el.children) {
|
||||
for (const child of el.children) {
|
||||
stripColumnClz(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
stripColumnClz(note)
|
||||
if (id === null || id.startsWith('sec-')) {
|
||||
// Special case sections, only their first couple elements
|
||||
const container = document.createElement("div");
|
||||
if (note.children && note.children.length > 2) {
|
||||
container.appendChild(note.children[0].cloneNode(true));
|
||||
for (let i = 1; i < note.children.length; i++) {
|
||||
const child = note.children[i];
|
||||
if (child.tagName === "P" && child.innerText === "") {
|
||||
continue;
|
||||
} else {
|
||||
container.appendChild(child.cloneNode(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(container);
|
||||
}
|
||||
return container.innerHTML
|
||||
} else {
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(note);
|
||||
}
|
||||
return note.innerHTML;
|
||||
}
|
||||
} else {
|
||||
// Remove any anchor links if they are present
|
||||
const anchorLink = note.querySelector('a.anchorjs-link');
|
||||
if (anchorLink) {
|
||||
anchorLink.remove();
|
||||
}
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(note);
|
||||
}
|
||||
if (note.classList.contains("callout")) {
|
||||
return note.outerHTML;
|
||||
} else {
|
||||
return note.innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i=0; i<xrefs.length; i++) {
|
||||
const xref = xrefs[i];
|
||||
tippyHover(xref, undefined, function(instance) {
|
||||
instance.disable();
|
||||
let url = xref.getAttribute('href');
|
||||
let hash = undefined;
|
||||
if (url.startsWith('#')) {
|
||||
hash = url;
|
||||
} else {
|
||||
try { hash = new URL(url).hash; } catch {}
|
||||
}
|
||||
if (hash) {
|
||||
const id = hash.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
if (note !== null) {
|
||||
try {
|
||||
const html = processXRef(id, note.cloneNode(true));
|
||||
instance.setContent(html);
|
||||
} finally {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
}
|
||||
} else {
|
||||
// See if we can fetch this
|
||||
fetch(url.split('#')[0])
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(html, "text/html");
|
||||
const note = htmlDoc.getElementById(id);
|
||||
if (note !== null) {
|
||||
const html = processXRef(id, note);
|
||||
instance.setContent(html);
|
||||
}
|
||||
}).finally(() => {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// See if we can fetch a full url (with no hash to target)
|
||||
// This is a special case and we should probably do some content thinning / targeting
|
||||
fetch(url)
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(html, "text/html");
|
||||
const note = htmlDoc.querySelector('main.content');
|
||||
if (note !== null) {
|
||||
// This should only happen for chapter cross references
|
||||
// (since there is no id in the URL)
|
||||
// remove the first header
|
||||
if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
|
||||
note.children[0].remove();
|
||||
}
|
||||
const html = processXRef(null, note);
|
||||
instance.setContent(html);
|
||||
}
|
||||
}).finally(() => {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
});
|
||||
}
|
||||
}, function(instance) {
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
div.style.left = 0;
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
elRect = undefined;
|
||||
if (selectedAnnoteEl) {
|
||||
selectCodeLines(selectedAnnoteEl);
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
function throttle(fn, ms) {
|
||||
let throttle = false;
|
||||
let timer;
|
||||
return (...args) => {
|
||||
if(!throttle) { // first call gets through
|
||||
fn.apply(this, args);
|
||||
throttle = true;
|
||||
} else { // all the others get throttled
|
||||
if(timer) clearTimeout(timer); // cancel #2
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args);
|
||||
timer = throttle = false;
|
||||
}, ms);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
283
Readme.md
283
Readme.md
@@ -1,146 +1,106 @@
|
||||
# JupyterHub Configuration with OrbStack on Mac (all in Docker)
|
||||
# OBIJupyterHub - the DNA Metabarcoding Learning Server
|
||||
|
||||
## Prerequisites
|
||||
## Intended use
|
||||
|
||||
You must have docker running on your computer
|
||||
This project packages the MetabarcodingSchool training lab into one reproducible bundle. You get Python, R, and Bash kernels, a Quarto-built course website, and preconfigured admin/student accounts, so onboarding a class is a single command instead of a day of setup. Everything runs locally on a single machine, student work persists between sessions, and `./start-jupyterhub.sh` takes care of building images, rendering the site, preparing volumes, and bringing JupyterHub up at `http://localhost:8888`. Defaults (accounts, passwords, volumes) live in the repo so instructors can tweak them quickly.
|
||||
|
||||
- On MacOS, [OrbStack](https://orbstack.dev/ "A Docker implementation optimised for MacOS") is recommanded
|
||||
## Prerequisites (with quick checks)
|
||||
|
||||
## Installation Steps
|
||||
You need Docker, Docker Compose, Quarto, and Python 3 available on the machine that will host the lab.
|
||||
|
||||
### 1. Create Directory Structure
|
||||
- macOS: install [OrbStack](https://orbstack.dev/) (recommended) or Docker Desktop; both ship Docker Engine and Compose.
|
||||
- Linux: install Docker Engine and the Compose plugin from your distribution (e.g., `sudo apt install docker.io docker-compose-plugin`) or from Docker’s official packages.
|
||||
- Windows: install Docker Desktop with the WSL2 backend enabled.
|
||||
- Quarto CLI: get installers from <https://quarto.org/docs/get-started/>.
|
||||
- Python 3: any recent version is fine (only the standard library is used).
|
||||
|
||||
Verify from a terminal; if a command is missing, install it before moving on:
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
docker compose version # or: docker-compose --version
|
||||
quarto --version
|
||||
python3 --version
|
||||
```
|
||||
|
||||
## How the startup script works
|
||||
|
||||
`./start-jupyterhub.sh` is the single entry point. It builds the Docker images, renders the course website, prepares the volume folders, and starts the stack. Internally it:
|
||||
|
||||
- creates the `jupyterhub_volumes/` tree (caddy, course, shared, users, web…)
|
||||
- builds `jupyterhub-student` and `jupyterhub-hub` images
|
||||
- renders the Quarto site from `web_src/`, generates PDF galleries and `pages.json`, and copies everything into `jupyterhub_volumes/web/`
|
||||
- runs `docker-compose up -d --remove-orphans`
|
||||
|
||||
You can tailor what it does with a few flags:
|
||||
|
||||
- `--no-build` (or `--offline`): skip Docker image builds and reuse existing images (useful when offline).
|
||||
- `--force-rebuild`: rebuild images without cache.
|
||||
- `--stop-server`: stop the stack and remove student containers, then exit.
|
||||
- `--update-lectures`: rebuild the course website only (no Docker stop/start).
|
||||
- `--build-obidoc`: force rebuilding the obidoc documentation (auto-built if empty; skipped in offline mode).
|
||||
|
||||
## Installation and first run
|
||||
|
||||
1) Clone the project:
|
||||
|
||||
```bash
|
||||
git clone https://forge.metabarcoding.org/MetabarcodingSchool/OBIJupyterHub.git
|
||||
```
|
||||
|
||||
Enter into the `OBIJupyterHub` directory
|
||||
|
||||
```bash
|
||||
cd OBIJupyterHub
|
||||
```
|
||||
|
||||
#### File Structure
|
||||
|
||||
Your `OBIJupyterHub` directory should contain:
|
||||
2) (Optional) glance at the structure you’ll populate:
|
||||
|
||||
```
|
||||
OBIJupyterHub
|
||||
├── start-jupyterhub.sh - The script used to setup and start the server
|
||||
├── obijupyterhub - The files describing the docker images and the stack
|
||||
│ ├── Caddyfile
|
||||
├── start-jupyterhub.sh - single entry point (build + render + start)
|
||||
├── obijupyterhub - Docker images and stack definitions
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── Dockerfile
|
||||
│ ├── Dockerfile.hub
|
||||
│ ├── jupyterhub_config.py
|
||||
│ ├── sftpgo_config.json
|
||||
│ └── start-notebook.sh
|
||||
├── jupyterhub_volumes - The directory containing the docker volumes
|
||||
│ ├── caddy
|
||||
│ ├── course - Read only volume mounted on every student container
|
||||
│ │ ├── bin
|
||||
│ │ └── R_packages
|
||||
│ ├── jupyterhub
|
||||
│ ├── shared - Read write volume shared in every student container
|
||||
│ ├── users
|
||||
│ └── web
|
||||
│ ├── img
|
||||
│ │ └── welcome_metabar.webp
|
||||
│ ├── index.html
|
||||
│ └── pages
|
||||
├── Readme.md - This documentation
|
||||
├── tools
|
||||
│ ├── generate_pages_json.py
|
||||
│ └── install_packages.sh
|
||||
└─── web_src - The quarto document sources used to build the web site
|
||||
├── _output
|
||||
├── _quarto.yml
|
||||
├── 00_home.qmd
|
||||
├── lectures
|
||||
│ └── computers
|
||||
│ └── regex
|
||||
│ ├── lecture_regex.qmd
|
||||
│ ├── slides_regex.qmd
|
||||
│ └── slides.css
|
||||
└── scripts
|
||||
└── copy-to-web.sh
|
||||
│ └── jupyterhub_config.py
|
||||
├── jupyterhub_volumes - data persisted on the host
|
||||
│ ├── course - read-only for students (notebooks, data, bin, R packages)
|
||||
│ ├── shared - shared read/write space for everyone
|
||||
│ ├── users - per-user persistent data
|
||||
│ └── web - rendered course website
|
||||
└── web_src - Quarto sources for the course website
|
||||
```
|
||||
|
||||
### 2. Start JupyterHub
|
||||
3) Prepare course materials (optional before first run):
|
||||
- Put notebooks, datasets, scripts, binaries, or PDFs for students under `jupyterhub_volumes/course/`. They will appear read-only at `/home/jovyan/work/course/`.
|
||||
- For collaborative work, drop files in `jupyterhub_volumes/shared/` (read/write for all at `/home/jovyan/work/shared/`).
|
||||
- Edit or add Quarto sources in `web_src/` to update the course website; the script will render them.
|
||||
|
||||
From the terminal, in the `OBIJupyterHub` directory, run the following command:
|
||||
4) Start everything (build + render + launch):
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
|
||||
### 3. Access JupyterHub
|
||||
5) Access JupyterHub in a browser at `http://localhost:8888`.
|
||||
|
||||
Open your browser and go to: **http://localhost:8888**
|
||||
6) Stop the stack when you’re done (run from `obijupyterhub/`):
|
||||
|
||||
You can log in as a student with any username and password: `metabar2025`
|
||||
|
||||
## Useful Commands
|
||||
|
||||
### View JupyterHub logs
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
docker-compose logs -f jupyterhub
|
||||
```
|
||||
|
||||
### View all containers (hub + students)
|
||||
|
||||
``` bash
|
||||
docker ps | grep jupyterhub
|
||||
```
|
||||
|
||||
### Stop JupyterHub
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Restart JupyterHub (after config modification)
|
||||
### Operating the stack (one command, a few options)
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
docker-compose restart jupyterhub
|
||||
```
|
||||
- Start or rebuild: `./start-jupyterhub.sh` (rebuilds images, regenerates the website, starts the stack).
|
||||
- Start without rebuilding images (offline): `./start-jupyterhub.sh --no-build`
|
||||
- Force rebuild without cache: `./start-jupyterhub.sh --force-rebuild`
|
||||
- Stop only: `./start-jupyterhub.sh --stop-server`
|
||||
- Rebuild website only (no Docker stop/start): `./start-jupyterhub.sh --update-lectures`
|
||||
- Rebuild obidoc docs: `./start-jupyterhub.sh --build-obidoc` (also builds automatically if `jupyterhub_volumes/web/obidoc` is empty; skipped in offline mode)
|
||||
- Access at `http://localhost:8888` (students: any username / password `metabar2025`; admin: `admin` / `admin2025`).
|
||||
- Check logs from `obijupyterhub/` with `docker-compose logs -f jupyterhub`.
|
||||
- Stop with `docker-compose down` (from `obijupyterhub/`). Rerun `./start-jupyterhub.sh` to start again or after config changes.
|
||||
|
||||
### View logs for a specific student
|
||||
## Managing shared data
|
||||
|
||||
``` bash
|
||||
docker logs jupyter-<username>
|
||||
```
|
||||
|
||||
Replace `<username>` by the actual username of the student.
|
||||
|
||||
### Clean up after lab
|
||||
|
||||
``` bash
|
||||
# Stop and remove all containers
|
||||
cd obijupyterhub
|
||||
docker-compose down
|
||||
|
||||
# Remove student containers
|
||||
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f
|
||||
|
||||
# Remove volumes (WARNING: deletes student data)
|
||||
docker volume ls | grep jupyterhub-user | awk '{print $2}' | xargs docker volume rm
|
||||
|
||||
# Clean everything (containers + volumes + network)
|
||||
docker-compose down -v
|
||||
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f
|
||||
docker volume prune -f
|
||||
```
|
||||
|
||||
## Managing Shared Data
|
||||
|
||||
### Directory Structure for Each Student
|
||||
|
||||
Each student will see this directory structure in their JupyterLab (everything under `work/` is persistent):
|
||||
Each student lands in `/home/jovyan/work/` with three key areas: their own files, a shared space, and a read-only course space. Everything under `work/` is persisted on the host in `jupyterhub_volumes`.
|
||||
|
||||
```
|
||||
work/ # Personal workspace root (persistent)
|
||||
@@ -153,42 +113,22 @@ work/ # Personal workspace root (persistent)
|
||||
└── [course materials] # Your course files
|
||||
```
|
||||
|
||||
**R Package Priority:**
|
||||
|
||||
1. R checks `work/R_packages/` first (personal, writable)
|
||||
1. Then `work/course/R_packages/` (shared, read-only, installed by prof)
|
||||
1. Then system libraries
|
||||
|
||||
**Important:** Everything is under `work/`, so all student files are automatically saved in their persistent volume.
|
||||
R looks for packages in this order: personal `work/R_packages/`, then shared `work/course/R_packages/`, then system libraries. Because everything lives under `work/`, student files survive restarts.
|
||||
|
||||
### User Accounts
|
||||
|
||||
**Admin Account:**
|
||||
|
||||
- Username: `admin`
|
||||
- Password: `admin2025` (change in docker-compose.yml: `JUPYTERHUB_ADMIN_PASSWORD`)
|
||||
- Can write to `course/` directory
|
||||
|
||||
**Student Accounts:**
|
||||
|
||||
- Username: any name
|
||||
- Password: `metabar2025` (change in docker-compose.yml: `JUPYTERHUB_PASSWORD`)
|
||||
- Read-only access to `course/` directory
|
||||
Defaults are defined in `obijupyterhub/docker-compose.yml`: admin (`admin` / `admin2025`) with write access to `course/`, and students (any username, password `metabar2025`) with read-only access to `course/`. Adjust `JUPYTERHUB_ADMIN_PASSWORD` and `JUPYTERHUB_PASSWORD` there, then rerun `./start-jupyterhub.sh`.
|
||||
|
||||
### Installing R Packages (Admin Only)
|
||||
|
||||
**From your Mac (recommended):**
|
||||
From the host, install shared R packages into `course/R_packages/`:
|
||||
|
||||
``` bash
|
||||
# Install packages
|
||||
tools/install_packages.sh reshape2 plotly knitr
|
||||
```
|
||||
|
||||
This script: - Installs packages in the `course/R_packages/` directory - All students can use them (read-only) - No need to rebuild the image
|
||||
|
||||
**Students can also install their own packages:**
|
||||
|
||||
Students can install packages in their personal `work/R_packages/`:
|
||||
Students can install their own packages into their personal `work/R_packages/`:
|
||||
|
||||
```r
|
||||
# Install in personal library (each student has their own)
|
||||
@@ -223,43 +163,9 @@ list.files("/home/jovyan/work/R_packages")
|
||||
list.files("/home/jovyan/work/course/R_packages")
|
||||
```
|
||||
|
||||
### Deposit Files for Course
|
||||
### Deposit or retrieve course and student files
|
||||
|
||||
To put files in the `course/` directory (accessible read-only):
|
||||
|
||||
``` bash
|
||||
# Create a temporary directory
|
||||
mkdir -p ~/jupyterhub-tp/course-files
|
||||
|
||||
# Copy your files into it
|
||||
cp my_notebooks.ipynb ~/jupyterhub-tp/course-files/
|
||||
cp my_data.csv ~/jupyterhub-tp/course-files/
|
||||
|
||||
# Copy into Docker volume
|
||||
docker run --rm \
|
||||
-v jupyterhub-course:/target \
|
||||
-v ~/jupyterhub-tp/course-files:/source \
|
||||
alpine sh -c "cp -r /source/* /target/"
|
||||
```
|
||||
|
||||
### Retrieve Student Work
|
||||
|
||||
``` bash
|
||||
# List user volumes
|
||||
docker volume ls | grep 'obijupyterhub_user-'
|
||||
|
||||
# Copy files from a specific student
|
||||
docker run --rm \
|
||||
-v obijupyterhub_user-alice:/source \
|
||||
-v ~/submissions:/target \
|
||||
alpine sh -c "cp -r /source/* /target/alice/"
|
||||
|
||||
# Copy all shared work
|
||||
docker run --rm \
|
||||
-v obijupyterhub_shared:/source \
|
||||
-v ~/submissions/shared:/target \
|
||||
alpine sh -c "cp -r /source/* /target/"
|
||||
```
|
||||
On the host, place course files in `jupyterhub_volumes/course/` (they appear read-only to students), shared files in `jupyterhub_volumes/shared/`, and collect student work from `jupyterhub_volumes/users/`.
|
||||
|
||||
## User Management
|
||||
|
||||
@@ -299,11 +205,7 @@ Modify the `Dockerfile` (before `USER ${NB_UID}`):
|
||||
RUN R -e "install.packages(c('your_package'), repos='http://cran.rstudio.com/')"
|
||||
```
|
||||
|
||||
Then restart the server (it rebuilds the images if needed):
|
||||
|
||||
```bash
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
Then rerun `./start-jupyterhub.sh` to rebuild and restart.
|
||||
|
||||
### Add Python Packages
|
||||
|
||||
@@ -313,14 +215,7 @@ Add to the `Dockerfile` (before `USER ${NB_UID}`):
|
||||
RUN pip install numpy pandas matplotlib seaborn
|
||||
```
|
||||
|
||||
### Distribute Files to Students
|
||||
|
||||
Create a `files_lab/` directory and add to the `Dockerfile`:
|
||||
|
||||
``` dockerfile
|
||||
COPY files_lab/ /home/${NB_USER}/lab/
|
||||
RUN chown -R ${NB_UID}:${NB_GID} /home/${NB_USER}/lab
|
||||
```
|
||||
Then rerun `./start-jupyterhub.sh` to rebuild and restart.
|
||||
|
||||
### Change Port (if 8000 is occupied)
|
||||
|
||||
@@ -341,29 +236,19 @@ ports:
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Error "Cannot connect to Docker daemon"**:
|
||||
|
||||
- Check that OrbStack is running
|
||||
- Verify the socket exists: `ls -la /var/run/docker.sock`
|
||||
|
||||
**Student containers don't start**:
|
||||
|
||||
- Check logs: `docker-compose logs jupyterhub`
|
||||
- Verify student image exists: `docker images | grep jupyterhub-student`
|
||||
|
||||
**Port 8000 already in use**:
|
||||
|
||||
- Change port in `docker-compose.yml`
|
||||
- Docker daemon unavailable: make sure OrbStack/Docker Desktop/daemon is running; verify `/var/run/docker.sock` exists.
|
||||
- Student containers do not start: check `docker-compose logs jupyterhub` and confirm the images exist with `docker images | grep jupyterhub-student`.
|
||||
- Port conflict: change the published port in `docker-compose.yml`.
|
||||
|
||||
|
||||
**I want to start from scratch**:
|
||||
|
||||
``` bash
|
||||
push obijupyterhub
|
||||
pushd obijupyterhub
|
||||
docker-compose down -v
|
||||
docker rmi jupyterhub-hub jupyterhub-student
|
||||
popd
|
||||
|
||||
# Then rebuild everything
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
```
|
||||
|
||||
12
Readme_files/libs/bootstrap/bootstrap-d6a003b94517c951b2d65075d42fb01b.min.css
vendored
Normal file
12
Readme_files/libs/bootstrap/bootstrap-d6a003b94517c951b2d65075d42fb01b.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2106
Readme_files/libs/bootstrap/bootstrap-icons.css
vendored
Normal file
2106
Readme_files/libs/bootstrap/bootstrap-icons.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Readme_files/libs/bootstrap/bootstrap-icons.woff
Normal file
BIN
Readme_files/libs/bootstrap/bootstrap-icons.woff
Normal file
Binary file not shown.
7
Readme_files/libs/bootstrap/bootstrap.min.js
vendored
Normal file
7
Readme_files/libs/bootstrap/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
Readme_files/libs/clipboard/clipboard.min.js
vendored
Normal file
7
Readme_files/libs/clipboard/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
Readme_files/libs/quarto-html/anchor.min.js
vendored
Normal file
9
Readme_files/libs/quarto-html/anchor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
145
Readme_files/libs/quarto-html/axe/axe-check.js
Normal file
145
Readme_files/libs/quarto-html/axe/axe-check.js
Normal file
@@ -0,0 +1,145 @@
|
||||
class QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
this.axeResult = axeResult;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
report() {
|
||||
throw new Error("report() is an abstract method");
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeJsonReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
report() {
|
||||
console.log(JSON.stringify(this.axeResult, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeConsoleReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
report() {
|
||||
for (const violation of this.axeResult.violations) {
|
||||
console.log(violation.description);
|
||||
for (const node of violation.nodes) {
|
||||
for (const target of node.target) {
|
||||
console.log(target);
|
||||
console.log(document.querySelector(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeDocumentReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
createViolationElement(violation) {
|
||||
const violationElement = document.createElement("div");
|
||||
|
||||
const descriptionElement = document.createElement("div");
|
||||
descriptionElement.className = "quarto-axe-violation-description";
|
||||
descriptionElement.innerText = `${violation.impact.replace(/^[a-z]/, match => match.toLocaleUpperCase())}: ${violation.description}`;
|
||||
violationElement.appendChild(descriptionElement);
|
||||
|
||||
const helpElement = document.createElement("div");
|
||||
helpElement.className = "quarto-axe-violation-help";
|
||||
helpElement.innerText = violation.help;
|
||||
violationElement.appendChild(helpElement);
|
||||
|
||||
const nodesElement = document.createElement("div");
|
||||
nodesElement.className = "quarto-axe-violation-nodes";
|
||||
violationElement.appendChild(nodesElement);
|
||||
const nodeElement = document.createElement("div");
|
||||
nodeElement.className = "quarto-axe-violation-selector";
|
||||
for (const node of violation.nodes) {
|
||||
for (const target of node.target) {
|
||||
const targetElement = document.createElement("span");
|
||||
targetElement.className = "quarto-axe-violation-target";
|
||||
targetElement.innerText = target;
|
||||
nodeElement.appendChild(targetElement);
|
||||
nodeElement.addEventListener("mouseenter", () => {
|
||||
const element = document.querySelector(target);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
element.classList.add("quarto-axe-hover-highlight");
|
||||
setTimeout(() => {
|
||||
element.style.border = "";
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
nodeElement.addEventListener("mouseleave", () => {
|
||||
const element = document.querySelector(target);
|
||||
if (element) {
|
||||
element.classList.remove("quarto-axe-hover-highlight");
|
||||
}
|
||||
});
|
||||
nodeElement.addEventListener("click", () => {
|
||||
console.log(document.querySelector(target));
|
||||
});
|
||||
nodeElement.appendChild(targetElement);
|
||||
}
|
||||
nodesElement.appendChild(nodeElement);
|
||||
}
|
||||
return violationElement;
|
||||
}
|
||||
|
||||
report() {
|
||||
const violations = this.axeResult.violations;
|
||||
const reportElement = document.createElement("div");
|
||||
reportElement.className = "quarto-axe-report";
|
||||
if (violations.length === 0) {
|
||||
const noViolationsElement = document.createElement("div");
|
||||
noViolationsElement.className = "quarto-axe-no-violations";
|
||||
noViolationsElement.innerText = "No axe-core violations found.";
|
||||
reportElement.appendChild(noViolationsElement);
|
||||
}
|
||||
violations.forEach((violation) => {
|
||||
reportElement.appendChild(this.createViolationElement(violation));
|
||||
});
|
||||
document.querySelector("main").appendChild(reportElement);
|
||||
}
|
||||
}
|
||||
|
||||
const reporters = {
|
||||
json: QuartoAxeJsonReporter,
|
||||
console: QuartoAxeConsoleReporter,
|
||||
document: QuartoAxeDocumentReporter,
|
||||
};
|
||||
|
||||
class QuartoAxeChecker {
|
||||
constructor(opts) {
|
||||
this.options = opts;
|
||||
}
|
||||
async init() {
|
||||
const axe = (await import("https://cdn.skypack.dev/pin/axe-core@v4.10.3-aVOFXWsJaCpVrtv89pCa/mode=imports,min/optimized/axe-core.js")).default;
|
||||
const result = await axe.run({
|
||||
exclude: [
|
||||
// https://github.com/microsoft/tabster/issues/288
|
||||
// MS has claimed they won't fix this, so we need to add an exclusion to
|
||||
// all tabster elements
|
||||
"[data-tabster-dummy]"
|
||||
],
|
||||
preload: { assets: ['cssom'], timeout: 50000 }
|
||||
});
|
||||
const reporter = this.options === true ? new QuartoAxeConsoleReporter(result) : new reporters[this.options.output](result, this.options);
|
||||
reporter.report();
|
||||
}
|
||||
}
|
||||
|
||||
export async function init() {
|
||||
const opts = document.querySelector("#quarto-axe-checker-options");
|
||||
if (opts) {
|
||||
const jsonOptions = JSON.parse(atob(opts.textContent));
|
||||
const checker = new QuartoAxeChecker(jsonOptions);
|
||||
await checker.init();
|
||||
}
|
||||
}
|
||||
6
Readme_files/libs/quarto-html/popper.min.js
vendored
Normal file
6
Readme_files/libs/quarto-html/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,236 @@
|
||||
/* quarto syntax highlight colors */
|
||||
:root {
|
||||
--quarto-hl-ot-color: #003B4F;
|
||||
--quarto-hl-at-color: #657422;
|
||||
--quarto-hl-ss-color: #20794D;
|
||||
--quarto-hl-an-color: #5E5E5E;
|
||||
--quarto-hl-fu-color: #4758AB;
|
||||
--quarto-hl-st-color: #20794D;
|
||||
--quarto-hl-cf-color: #003B4F;
|
||||
--quarto-hl-op-color: #5E5E5E;
|
||||
--quarto-hl-er-color: #AD0000;
|
||||
--quarto-hl-bn-color: #AD0000;
|
||||
--quarto-hl-al-color: #AD0000;
|
||||
--quarto-hl-va-color: #111111;
|
||||
--quarto-hl-bu-color: inherit;
|
||||
--quarto-hl-ex-color: inherit;
|
||||
--quarto-hl-pp-color: #AD0000;
|
||||
--quarto-hl-in-color: #5E5E5E;
|
||||
--quarto-hl-vs-color: #20794D;
|
||||
--quarto-hl-wa-color: #5E5E5E;
|
||||
--quarto-hl-do-color: #5E5E5E;
|
||||
--quarto-hl-im-color: #00769E;
|
||||
--quarto-hl-ch-color: #20794D;
|
||||
--quarto-hl-dt-color: #AD0000;
|
||||
--quarto-hl-fl-color: #AD0000;
|
||||
--quarto-hl-co-color: #5E5E5E;
|
||||
--quarto-hl-cv-color: #5E5E5E;
|
||||
--quarto-hl-cn-color: #8f5902;
|
||||
--quarto-hl-sc-color: #5E5E5E;
|
||||
--quarto-hl-dv-color: #AD0000;
|
||||
--quarto-hl-kw-color: #003B4F;
|
||||
}
|
||||
|
||||
/* other quarto variables */
|
||||
:root {
|
||||
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
/* syntax highlight based on Pandoc's rules */
|
||||
pre > code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
div.sourceCode,
|
||||
div.sourceCode pre.sourceCode {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
/* Normal */
|
||||
code span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
/* Alert */
|
||||
code span.al {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Annotation */
|
||||
code span.an {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Attribute */
|
||||
code span.at {
|
||||
color: #657422;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* BaseN */
|
||||
code span.bn {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* BuiltIn */
|
||||
code span.bu {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* ControlFlow */
|
||||
code span.cf {
|
||||
color: #003B4F;
|
||||
font-weight: bold;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Char */
|
||||
code span.ch {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Constant */
|
||||
code span.cn {
|
||||
color: #8f5902;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
code span.co {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* CommentVar */
|
||||
code span.cv {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Documentation */
|
||||
code span.do {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* DataType */
|
||||
code span.dt {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* DecVal */
|
||||
code span.dv {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
code span.er {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Extension */
|
||||
code span.ex {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Float */
|
||||
code span.fl {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Function */
|
||||
code span.fu {
|
||||
color: #4758AB;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Import */
|
||||
code span.im {
|
||||
color: #00769E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Information */
|
||||
code span.in {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Keyword */
|
||||
code span.kw {
|
||||
color: #003B4F;
|
||||
font-weight: bold;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Operator */
|
||||
code span.op {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Other */
|
||||
code span.ot {
|
||||
color: #003B4F;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Preprocessor */
|
||||
code span.pp {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* SpecialChar */
|
||||
code span.sc {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* SpecialString */
|
||||
code span.ss {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* String */
|
||||
code span.st {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Variable */
|
||||
code span.va {
|
||||
color: #111111;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* VerbatimString */
|
||||
code span.vs {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
code span.wa {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.prevent-inlining {
|
||||
content: "</";
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=2dce1cc6c82594539e1579de68416b47.css.map */
|
||||
847
Readme_files/libs/quarto-html/quarto.js
Normal file
847
Readme_files/libs/quarto-html/quarto.js
Normal file
@@ -0,0 +1,847 @@
|
||||
import * as tabsets from "./tabsets/tabsets.js";
|
||||
import * as axe from "./axe/axe-check.js";
|
||||
|
||||
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
const layoutMarginEls = () => {
|
||||
// Find any conflicting margin elements and add margins to the
|
||||
// top to prevent overlap
|
||||
const marginChildren = window.document.querySelectorAll(
|
||||
".column-margin.column-container > *, .margin-caption, .aside"
|
||||
);
|
||||
|
||||
let lastBottom = 0;
|
||||
for (const marginChild of marginChildren) {
|
||||
if (marginChild.offsetParent !== null) {
|
||||
// clear the top margin so we recompute it
|
||||
marginChild.style.marginTop = null;
|
||||
const top = marginChild.getBoundingClientRect().top + window.scrollY;
|
||||
if (top < lastBottom) {
|
||||
const marginChildStyle = window.getComputedStyle(marginChild);
|
||||
const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
|
||||
const margin = lastBottom - top + marginBottom;
|
||||
marginChild.style.marginTop = `${margin}px`;
|
||||
}
|
||||
const styles = window.getComputedStyle(marginChild);
|
||||
const marginTop = parseFloat(styles["marginTop"]);
|
||||
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function (_event) {
|
||||
// Recompute the position of margin elements anytime the body size changes
|
||||
if (window.ResizeObserver) {
|
||||
const resizeObserver = new window.ResizeObserver(
|
||||
throttle(() => {
|
||||
layoutMarginEls();
|
||||
if (
|
||||
window.document.body.getBoundingClientRect().width < 990 &&
|
||||
isReaderMode()
|
||||
) {
|
||||
quartoToggleReader();
|
||||
}
|
||||
}, 50)
|
||||
);
|
||||
resizeObserver.observe(window.document.body);
|
||||
}
|
||||
|
||||
const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
|
||||
const sidebarEl = window.document.getElementById("quarto-sidebar");
|
||||
const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
|
||||
const marginSidebarEl = window.document.getElementById(
|
||||
"quarto-margin-sidebar"
|
||||
);
|
||||
// function to determine whether the element has a previous sibling that is active
|
||||
const prevSiblingIsActiveLink = (el) => {
|
||||
const sibling = el.previousElementSibling;
|
||||
if (sibling && sibling.tagName === "A") {
|
||||
return sibling.classList.contains("active");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// dispatch for htmlwidgets
|
||||
// they use slideenter event to trigger resize
|
||||
function fireSlideEnter() {
|
||||
const event = window.document.createEvent("Event");
|
||||
event.initEvent("slideenter", true, true);
|
||||
window.document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
tabs.forEach((tab) => {
|
||||
tab.addEventListener("shown.bs.tab", fireSlideEnter);
|
||||
});
|
||||
|
||||
// dispatch for shiny
|
||||
// they use BS shown and hidden events to trigger rendering
|
||||
function distpatchShinyEvents(previous, current) {
|
||||
if (window.jQuery) {
|
||||
if (previous) {
|
||||
window.jQuery(previous).trigger("hidden");
|
||||
}
|
||||
if (current) {
|
||||
window.jQuery(current).trigger("shown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tabby.js listener: Trigger event for htmlwidget and shiny
|
||||
document.addEventListener(
|
||||
"tabby",
|
||||
function (event) {
|
||||
fireSlideEnter();
|
||||
distpatchShinyEvents(event.detail.previousTab, event.detail.tab);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Track scrolling and mark TOC links as active
|
||||
// get table of contents and sidebar (bail if we don't have at least one)
|
||||
const tocLinks = tocEl
|
||||
? [...tocEl.querySelectorAll("a[data-scroll-target]")]
|
||||
: [];
|
||||
const makeActive = (link) => tocLinks[link].classList.add("active");
|
||||
const removeActive = (link) => tocLinks[link].classList.remove("active");
|
||||
const removeAllActive = () =>
|
||||
[...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
|
||||
|
||||
// activate the anchor for a section associated with this TOC entry
|
||||
tocLinks.forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
if (link.href.indexOf("#") !== -1) {
|
||||
const anchor = link.href.split("#")[1];
|
||||
const heading = window.document.querySelector(
|
||||
`[data-anchor-id="${anchor}"]`
|
||||
);
|
||||
if (heading) {
|
||||
// Add the class
|
||||
heading.classList.add("reveal-anchorjs-link");
|
||||
|
||||
// function to show the anchor
|
||||
const handleMouseout = () => {
|
||||
heading.classList.remove("reveal-anchorjs-link");
|
||||
heading.removeEventListener("mouseout", handleMouseout);
|
||||
};
|
||||
|
||||
// add a function to clear the anchor when the user mouses out of it
|
||||
heading.addEventListener("mouseout", handleMouseout);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const sections = tocLinks.map((link) => {
|
||||
const target = link.getAttribute("data-scroll-target");
|
||||
if (target.startsWith("#")) {
|
||||
return window.document.getElementById(decodeURI(`${target.slice(1)}`));
|
||||
} else {
|
||||
return window.document.querySelector(decodeURI(`${target}`));
|
||||
}
|
||||
});
|
||||
|
||||
const sectionMargin = 200;
|
||||
let currentActive = 0;
|
||||
// track whether we've initialized state the first time
|
||||
let init = false;
|
||||
|
||||
const updateActiveLink = () => {
|
||||
// The index from bottom to top (e.g. reversed list)
|
||||
let sectionIndex = -1;
|
||||
if (
|
||||
window.innerHeight + window.pageYOffset >=
|
||||
window.document.body.offsetHeight
|
||||
) {
|
||||
// This is the no-scroll case where last section should be the active one
|
||||
sectionIndex = 0;
|
||||
} else {
|
||||
// This finds the last section visible on screen that should be made active
|
||||
sectionIndex = [...sections].reverse().findIndex((section) => {
|
||||
if (section) {
|
||||
return window.pageYOffset >= section.offsetTop - sectionMargin;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (sectionIndex > -1) {
|
||||
const current = sections.length - sectionIndex - 1;
|
||||
if (current !== currentActive) {
|
||||
removeAllActive();
|
||||
currentActive = current;
|
||||
makeActive(current);
|
||||
if (init) {
|
||||
window.dispatchEvent(sectionChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const inHiddenRegion = (top, bottom, hiddenRegions) => {
|
||||
for (const region of hiddenRegions) {
|
||||
if (top <= region.bottom && bottom >= region.top) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const categorySelector = "header.quarto-title-block .quarto-category";
|
||||
const activateCategories = (href) => {
|
||||
// Find any categories
|
||||
// Surround them with a link pointing back to:
|
||||
// #category=Authoring
|
||||
try {
|
||||
const categoryEls = window.document.querySelectorAll(categorySelector);
|
||||
for (const categoryEl of categoryEls) {
|
||||
const categoryText = categoryEl.textContent;
|
||||
if (categoryText) {
|
||||
const link = `${href}#category=${encodeURIComponent(categoryText)}`;
|
||||
const linkEl = window.document.createElement("a");
|
||||
linkEl.setAttribute("href", link);
|
||||
for (const child of categoryEl.childNodes) {
|
||||
linkEl.append(child);
|
||||
}
|
||||
categoryEl.appendChild(linkEl);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
};
|
||||
function hasTitleCategories() {
|
||||
return window.document.querySelector(categorySelector) !== null;
|
||||
}
|
||||
|
||||
function offsetRelativeUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
return offset ? offset + url : url;
|
||||
}
|
||||
|
||||
function offsetAbsoluteUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
const baseUrl = new URL(offset, window.location);
|
||||
|
||||
const projRelativeUrl = url.replace(baseUrl, "");
|
||||
if (projRelativeUrl.startsWith("/")) {
|
||||
return projRelativeUrl;
|
||||
} else {
|
||||
return "/" + projRelativeUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// read a meta tag value
|
||||
function getMeta(metaName) {
|
||||
const metas = window.document.getElementsByTagName("meta");
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
if (metas[i].getAttribute("name") === metaName) {
|
||||
return metas[i].getAttribute("content");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async function findAndActivateCategories() {
|
||||
// Categories search with listing only use path without query
|
||||
const currentPagePath = offsetAbsoluteUrl(
|
||||
window.location.origin + window.location.pathname
|
||||
);
|
||||
const response = await fetch(offsetRelativeUrl("listings.json"));
|
||||
if (response.status == 200) {
|
||||
return response.json().then(function (listingPaths) {
|
||||
const listingHrefs = [];
|
||||
for (const listingPath of listingPaths) {
|
||||
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
|
||||
for (const item of listingPath.items) {
|
||||
const encodedItem = encodeURI(item);
|
||||
if (
|
||||
encodedItem === currentPagePath ||
|
||||
encodedItem === currentPagePath + "index.html"
|
||||
) {
|
||||
// Resolve this path against the offset to be sure
|
||||
// we already are using the correct path to the listing
|
||||
// (this adjusts the listing urls to be rooted against
|
||||
// whatever root the page is actually running against)
|
||||
const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
|
||||
const baseUrl = window.location;
|
||||
const resolvedPath = new URL(relative, baseUrl);
|
||||
listingHrefs.push(resolvedPath.pathname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const nearestListing = findNearestParentListing(
|
||||
offsetAbsoluteUrl(window.location.pathname),
|
||||
listingHrefs
|
||||
);
|
||||
if (nearestListing) {
|
||||
activateCategories(nearestListing);
|
||||
} else {
|
||||
// See if the referrer is a listing page for this item
|
||||
const referredRelativePath = offsetAbsoluteUrl(document.referrer);
|
||||
const referrerListing = listingHrefs.find((listingHref) => {
|
||||
const isListingReferrer =
|
||||
listingHref === referredRelativePath ||
|
||||
listingHref === referredRelativePath + "index.html";
|
||||
return isListingReferrer;
|
||||
});
|
||||
|
||||
if (referrerListing) {
|
||||
// Try to use the referrer if possible
|
||||
activateCategories(referrerListing);
|
||||
} else if (listingHrefs.length > 0) {
|
||||
// Otherwise, just fall back to the first listing
|
||||
activateCategories(listingHrefs[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (hasTitleCategories()) {
|
||||
findAndActivateCategories();
|
||||
}
|
||||
|
||||
const findNearestParentListing = (href, listingHrefs) => {
|
||||
if (!href || !listingHrefs) {
|
||||
return undefined;
|
||||
}
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const relativeParts = href.substring(1).split("/");
|
||||
while (relativeParts.length > 0) {
|
||||
const path = relativeParts.join("/");
|
||||
for (const listingHref of listingHrefs) {
|
||||
if (listingHref.startsWith(path)) {
|
||||
return listingHref;
|
||||
}
|
||||
}
|
||||
relativeParts.pop();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const manageSidebarVisiblity = (el, placeholderDescriptor) => {
|
||||
let isVisible = true;
|
||||
let elRect;
|
||||
|
||||
return (hiddenRegions) => {
|
||||
if (el === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the last element of the TOC
|
||||
const lastChildEl = el.lastElementChild;
|
||||
|
||||
if (lastChildEl) {
|
||||
// Converts the sidebar to a menu
|
||||
const convertToMenu = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 0;
|
||||
child.style.overflow = "hidden";
|
||||
child.style.pointerEvents = "none";
|
||||
}
|
||||
|
||||
nexttick(() => {
|
||||
const toggleContainer = window.document.createElement("div");
|
||||
toggleContainer.style.width = "100%";
|
||||
toggleContainer.classList.add("zindex-over-content");
|
||||
toggleContainer.classList.add("quarto-sidebar-toggle");
|
||||
toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
|
||||
toggleContainer.id = placeholderDescriptor.id;
|
||||
toggleContainer.style.position = "fixed";
|
||||
|
||||
const toggleIcon = window.document.createElement("i");
|
||||
toggleIcon.classList.add("quarto-sidebar-toggle-icon");
|
||||
toggleIcon.classList.add("bi");
|
||||
toggleIcon.classList.add("bi-caret-down-fill");
|
||||
|
||||
const toggleTitle = window.document.createElement("div");
|
||||
const titleEl = window.document.body.querySelector(
|
||||
placeholderDescriptor.titleSelector
|
||||
);
|
||||
if (titleEl) {
|
||||
toggleTitle.append(
|
||||
titleEl.textContent || titleEl.innerText,
|
||||
toggleIcon
|
||||
);
|
||||
}
|
||||
toggleTitle.classList.add("zindex-over-content");
|
||||
toggleTitle.classList.add("quarto-sidebar-toggle-title");
|
||||
toggleContainer.append(toggleTitle);
|
||||
|
||||
const toggleContents = window.document.createElement("div");
|
||||
toggleContents.classList = el.classList;
|
||||
toggleContents.classList.add("zindex-over-content");
|
||||
toggleContents.classList.add("quarto-sidebar-toggle-contents");
|
||||
for (const child of el.children) {
|
||||
if (child.id === "toc-title") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const clone = child.cloneNode(true);
|
||||
clone.style.opacity = 1;
|
||||
clone.style.pointerEvents = null;
|
||||
clone.style.display = null;
|
||||
toggleContents.append(clone);
|
||||
}
|
||||
toggleContents.style.height = "0px";
|
||||
const positionToggle = () => {
|
||||
// position the element (top left of parent, same width as parent)
|
||||
if (!elRect) {
|
||||
elRect = el.getBoundingClientRect();
|
||||
}
|
||||
toggleContainer.style.left = `${elRect.left}px`;
|
||||
toggleContainer.style.top = `${elRect.top}px`;
|
||||
toggleContainer.style.width = `${elRect.width}px`;
|
||||
};
|
||||
positionToggle();
|
||||
|
||||
toggleContainer.append(toggleContents);
|
||||
el.parentElement.prepend(toggleContainer);
|
||||
|
||||
// Process clicks
|
||||
let tocShowing = false;
|
||||
// Allow the caller to control whether this is dismissed
|
||||
// when it is clicked (e.g. sidebar navigation supports
|
||||
// opening and closing the nav tree, so don't dismiss on click)
|
||||
const clickEl = placeholderDescriptor.dismissOnClick
|
||||
? toggleContainer
|
||||
: toggleTitle;
|
||||
|
||||
const closeToggle = () => {
|
||||
if (tocShowing) {
|
||||
toggleContainer.classList.remove("expanded");
|
||||
toggleContents.style.height = "0px";
|
||||
tocShowing = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Get rid of any expanded toggle if the user scrolls
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
closeToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
elRect = undefined;
|
||||
positionToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
window.addEventListener("quarto-hrChanged", () => {
|
||||
elRect = undefined;
|
||||
});
|
||||
|
||||
// Process the click
|
||||
clickEl.onclick = () => {
|
||||
if (!tocShowing) {
|
||||
toggleContainer.classList.add("expanded");
|
||||
toggleContents.style.height = null;
|
||||
tocShowing = true;
|
||||
} else {
|
||||
closeToggle();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Converts a sidebar from a menu back to a sidebar
|
||||
const convertToSidebar = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 1;
|
||||
child.style.overflow = null;
|
||||
child.style.pointerEvents = null;
|
||||
}
|
||||
|
||||
const placeholderEl = window.document.getElementById(
|
||||
placeholderDescriptor.id
|
||||
);
|
||||
if (placeholderEl) {
|
||||
placeholderEl.remove();
|
||||
}
|
||||
|
||||
el.classList.remove("rollup");
|
||||
};
|
||||
|
||||
if (isReaderMode()) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
} else {
|
||||
// Find the top and bottom o the element that is being managed
|
||||
const elTop = el.offsetTop;
|
||||
const elBottom =
|
||||
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
|
||||
|
||||
if (!isVisible) {
|
||||
// If the element is current not visible reveal if there are
|
||||
// no conflicts with overlay regions
|
||||
if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToSidebar();
|
||||
isVisible = true;
|
||||
}
|
||||
} else {
|
||||
// If the element is visible, hide it if it conflicts with overlay regions
|
||||
// and insert a placeholder toggle (or if we're in reader mode)
|
||||
if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
for (const tabEl of tabEls) {
|
||||
const id = tabEl.getAttribute("data-bs-target");
|
||||
if (id) {
|
||||
const columnEl = document.querySelector(
|
||||
`${id} .column-margin, .tabset-margin-content`
|
||||
);
|
||||
if (columnEl)
|
||||
tabEl.addEventListener("shown.bs.tab", function (event) {
|
||||
const el = event.srcElement;
|
||||
if (el) {
|
||||
const visibleCls = `${el.id}-margin-content`;
|
||||
// walk up until we find a parent tabset
|
||||
let panelTabsetEl = el.parentElement;
|
||||
while (panelTabsetEl) {
|
||||
if (panelTabsetEl.classList.contains("panel-tabset")) {
|
||||
break;
|
||||
}
|
||||
panelTabsetEl = panelTabsetEl.parentElement;
|
||||
}
|
||||
|
||||
if (panelTabsetEl) {
|
||||
const prevSib = panelTabsetEl.previousElementSibling;
|
||||
if (
|
||||
prevSib &&
|
||||
prevSib.classList.contains("tabset-margin-container")
|
||||
) {
|
||||
const childNodes = prevSib.querySelectorAll(
|
||||
".tabset-margin-content"
|
||||
);
|
||||
for (const childEl of childNodes) {
|
||||
if (childEl.classList.contains(visibleCls)) {
|
||||
childEl.classList.remove("collapse");
|
||||
} else {
|
||||
childEl.classList.add("collapse");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layoutMarginEls();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the visibility of the toc and the sidebar
|
||||
const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
|
||||
id: "quarto-toc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
|
||||
id: "quarto-sidebarnav-toggle",
|
||||
titleSelector: ".title",
|
||||
dismissOnClick: false,
|
||||
});
|
||||
let tocLeftScrollVisibility;
|
||||
if (leftTocEl) {
|
||||
tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
|
||||
id: "quarto-lefttoc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Find the first element that uses formatting in special columns
|
||||
const conflictingEls = window.document.body.querySelectorAll(
|
||||
'[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
|
||||
);
|
||||
|
||||
// Filter all the possibly conflicting elements into ones
|
||||
// the do conflict on the left or ride side
|
||||
const arrConflictingEls = Array.from(conflictingEls);
|
||||
const leftSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return false;
|
||||
}
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("right") &&
|
||||
!className.endsWith("container") &&
|
||||
className !== "column-margin"
|
||||
);
|
||||
});
|
||||
});
|
||||
const rightSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasMarginCaption = Array.from(el.classList).find((className) => {
|
||||
return className == "margin-caption";
|
||||
});
|
||||
if (hasMarginCaption) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
!className.endsWith("container") &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("left")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const kOverlapPaddingSize = 10;
|
||||
function toRegions(els) {
|
||||
return els.map((el) => {
|
||||
const boundRect = el.getBoundingClientRect();
|
||||
const top =
|
||||
boundRect.top +
|
||||
document.documentElement.scrollTop -
|
||||
kOverlapPaddingSize;
|
||||
return {
|
||||
top,
|
||||
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let hasObserved = false;
|
||||
const visibleItemObserver = (els) => {
|
||||
let visibleElements = [...els];
|
||||
const intersectionObserver = new IntersectionObserver(
|
||||
(entries, _observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
if (visibleElements.indexOf(entry.target) === -1) {
|
||||
visibleElements.push(entry.target);
|
||||
}
|
||||
} else {
|
||||
visibleElements = visibleElements.filter((visibleEntry) => {
|
||||
return visibleEntry !== entry;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasObserved) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
hasObserved = true;
|
||||
},
|
||||
{}
|
||||
);
|
||||
els.forEach((el) => {
|
||||
intersectionObserver.observe(el);
|
||||
});
|
||||
|
||||
return {
|
||||
getVisibleEntries: () => {
|
||||
return visibleElements;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const rightElementObserver = visibleItemObserver(rightSideConflictEls);
|
||||
const leftElementObserver = visibleItemObserver(leftSideConflictEls);
|
||||
|
||||
const hideOverlappedSidebars = () => {
|
||||
marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
|
||||
sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
|
||||
if (tocLeftScrollVisibility) {
|
||||
tocLeftScrollVisibility(
|
||||
toRegions(leftElementObserver.getVisibleEntries())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
window.quartoToggleReader = () => {
|
||||
// Applies a slow class (or removes it)
|
||||
// to update the transition speed
|
||||
const slowTransition = (slow) => {
|
||||
const manageTransition = (id, slow) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
if (slow) {
|
||||
el.classList.add("slow");
|
||||
} else {
|
||||
el.classList.remove("slow");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
manageTransition("TOC", slow);
|
||||
manageTransition("quarto-sidebar", slow);
|
||||
};
|
||||
const readerMode = !isReaderMode();
|
||||
setReaderModeValue(readerMode);
|
||||
|
||||
// If we're entering reader mode, slow the transition
|
||||
if (readerMode) {
|
||||
slowTransition(readerMode);
|
||||
}
|
||||
highlightReaderToggle(readerMode);
|
||||
hideOverlappedSidebars();
|
||||
|
||||
// If we're exiting reader mode, restore the non-slow transition
|
||||
if (!readerMode) {
|
||||
slowTransition(!readerMode);
|
||||
}
|
||||
};
|
||||
|
||||
const highlightReaderToggle = (readerMode) => {
|
||||
const els = document.querySelectorAll(".quarto-reader-toggle");
|
||||
if (els) {
|
||||
els.forEach((el) => {
|
||||
if (readerMode) {
|
||||
el.classList.add("reader");
|
||||
} else {
|
||||
el.classList.remove("reader");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setReaderModeValue = (val) => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
window.localStorage.setItem("quarto-reader-mode", val);
|
||||
} else {
|
||||
localReaderMode = val;
|
||||
}
|
||||
};
|
||||
|
||||
const isReaderMode = () => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
return window.localStorage.getItem("quarto-reader-mode") === "true";
|
||||
} else {
|
||||
return localReaderMode;
|
||||
}
|
||||
};
|
||||
let localReaderMode = null;
|
||||
|
||||
const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
|
||||
const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
|
||||
|
||||
// Walk the TOC and collapse/expand nodes
|
||||
// Nodes are expanded if:
|
||||
// - they are top level
|
||||
// - they have children that are 'active' links
|
||||
// - they are directly below an link that is 'active'
|
||||
const walk = (el, depth) => {
|
||||
// Tick depth when we enter a UL
|
||||
if (el.tagName === "UL") {
|
||||
depth = depth + 1;
|
||||
}
|
||||
|
||||
// It this is active link
|
||||
let isActiveNode = false;
|
||||
if (el.tagName === "A" && el.classList.contains("active")) {
|
||||
isActiveNode = true;
|
||||
}
|
||||
|
||||
// See if there is an active child to this element
|
||||
let hasActiveChild = false;
|
||||
for (const child of el.children) {
|
||||
hasActiveChild = walk(child, depth) || hasActiveChild;
|
||||
}
|
||||
|
||||
// Process the collapse state if this is an UL
|
||||
if (el.tagName === "UL") {
|
||||
if (tocOpenDepth === -1 && depth > 1) {
|
||||
// toc-expand: false
|
||||
el.classList.add("collapse");
|
||||
} else if (
|
||||
depth <= tocOpenDepth ||
|
||||
hasActiveChild ||
|
||||
prevSiblingIsActiveLink(el)
|
||||
) {
|
||||
el.classList.remove("collapse");
|
||||
} else {
|
||||
el.classList.add("collapse");
|
||||
}
|
||||
|
||||
// untick depth when we leave a UL
|
||||
depth = depth - 1;
|
||||
}
|
||||
return hasActiveChild || isActiveNode;
|
||||
};
|
||||
|
||||
// walk the TOC and expand / collapse any items that should be shown
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
|
||||
// Throttle the scroll event and walk peridiocally
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 5)
|
||||
);
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
hideOverlappedSidebars();
|
||||
highlightReaderToggle(isReaderMode());
|
||||
});
|
||||
|
||||
tabsets.init();
|
||||
axe.init();
|
||||
|
||||
function throttle(func, wait) {
|
||||
let waiting = false;
|
||||
return function () {
|
||||
if (!waiting) {
|
||||
func.apply(this, arguments);
|
||||
waiting = true;
|
||||
setTimeout(function () {
|
||||
waiting = false;
|
||||
}, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function nexttick(func) {
|
||||
return setTimeout(func, 0);
|
||||
}
|
||||
95
Readme_files/libs/quarto-html/tabsets/tabsets.js
Normal file
95
Readme_files/libs/quarto-html/tabsets/tabsets.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// grouped tabsets
|
||||
|
||||
export function init() {
|
||||
window.addEventListener("pageshow", (_event) => {
|
||||
function getTabSettings() {
|
||||
const data = localStorage.getItem("quarto-persistent-tabsets-data");
|
||||
if (!data) {
|
||||
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
|
||||
return {};
|
||||
}
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
function setTabSettings(data) {
|
||||
localStorage.setItem(
|
||||
"quarto-persistent-tabsets-data",
|
||||
JSON.stringify(data)
|
||||
);
|
||||
}
|
||||
|
||||
function setTabState(groupName, groupValue) {
|
||||
const data = getTabSettings();
|
||||
data[groupName] = groupValue;
|
||||
setTabSettings(data);
|
||||
}
|
||||
|
||||
function toggleTab(tab, active) {
|
||||
const tabPanelId = tab.getAttribute("aria-controls");
|
||||
const tabPanel = document.getElementById(tabPanelId);
|
||||
if (active) {
|
||||
tab.classList.add("active");
|
||||
tabPanel.classList.add("active");
|
||||
} else {
|
||||
tab.classList.remove("active");
|
||||
tabPanel.classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAll(selectedGroup, selectorsToSync) {
|
||||
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
|
||||
const active = selectedGroup === thisGroup;
|
||||
for (const tab of tabs) {
|
||||
toggleTab(tab, active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSelectorsToSyncByLanguage() {
|
||||
const result = {};
|
||||
const tabs = Array.from(
|
||||
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
|
||||
);
|
||||
for (const item of tabs) {
|
||||
const div = item.parentElement.parentElement.parentElement;
|
||||
const group = div.getAttribute("data-group");
|
||||
if (!result[group]) {
|
||||
result[group] = {};
|
||||
}
|
||||
const selectorsToSync = result[group];
|
||||
const value = item.innerHTML;
|
||||
if (!selectorsToSync[value]) {
|
||||
selectorsToSync[value] = [];
|
||||
}
|
||||
selectorsToSync[value].push(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function setupSelectorSync() {
|
||||
const selectorsToSync = findSelectorsToSyncByLanguage();
|
||||
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
|
||||
Object.entries(tabSetsByValue).forEach(([value, items]) => {
|
||||
items.forEach((item) => {
|
||||
item.addEventListener("click", (_event) => {
|
||||
setTabState(group, value);
|
||||
toggleAll(value, selectorsToSync[group]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return selectorsToSync;
|
||||
}
|
||||
|
||||
const selectorsToSync = setupSelectorSync();
|
||||
for (const [group, selectedName] of Object.entries(getTabSettings())) {
|
||||
const selectors = selectorsToSync[group];
|
||||
// it's possible that stale state gives us empty selections, so we explicitly check here.
|
||||
if (selectors) {
|
||||
toggleAll(selectedName, selectors);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
1
Readme_files/libs/quarto-html/tippy.css
Normal file
1
Readme_files/libs/quarto-html/tippy.css
Normal file
@@ -0,0 +1 @@
|
||||
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
||||
2
Readme_files/libs/quarto-html/tippy.umd.min.js
vendored
Normal file
2
Readme_files/libs/quarto-html/tippy.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_F.fastq
Normal file
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_F.fastq
Normal file
File diff suppressed because it is too large
Load Diff
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_R.fastq
Normal file
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_R.fastq
Normal file
File diff suppressed because it is too large
Load Diff
3
jupyterhub_volumes/web/.gitignore
vendored
3
jupyterhub_volumes/web/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.quarto/
|
||||
**/*.quarto_ipynb
|
||||
/pages/
|
||||
/pages/
|
||||
/obidoc/
|
||||
@@ -1,56 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#343a40">
|
||||
<meta name="color-scheme" content="light dark"><meta property="og:url" content="http://metabar:8888/obidoc/404.html">
|
||||
<meta property="og:site_name" content="OBITools4 documentation">
|
||||
<meta property="og:title" content="404 Page not found">
|
||||
<meta property="og:locale" content="en_us">
|
||||
<meta property="og:type" content="website">
|
||||
<title>404 Page not found | OBITools4 documentation</title>
|
||||
<link rel="icon" href="/obidoc/favicon.png" >
|
||||
<link rel="manifest" href="/obidoc/manifest.json">
|
||||
<link rel="canonical" href="http://metabar:8888/obidoc/404.html">
|
||||
<link rel="stylesheet" href="/obidoc/book.min.5fd7b8e2d1c0ae15da279c52ff32731130386f71b58f011468f20d0056fe6b78.css" integrity="sha256-X9e44tHArhXaJ5xS/zJzETA4b3G1jwEUaPINAFb+a3g=" crossorigin="anonymous">
|
||||
<script defer src="/obidoc/fuse.min.js"></script>
|
||||
<script defer src="/obidoc/en.search.min.4da51bdd2d833922fdbc0e19df517221387fc625ffb68ee140d605b3c5b68058.js" integrity="sha256-TaUb3S2DOSL9vA4Z31FyITh/xiX/to7hQNYFs8W2gFg=" crossorigin="anonymous"></script>
|
||||
|
||||
<script defer src="/obidoc/sw.min.32af8eafce4180aa1c5dea66d99fb26ba9043ea7c7a4c706138c91d9051b285e.js" integrity="sha256-Mq+Or85BgKocXepm2Z+ya6kEPqfHpMcGE4yR2QUbKF4=" crossorigin="anonymous"></script>
|
||||
<!--
|
||||
Made with Book Theme
|
||||
https://github.com/alex-shpak/hugo-book
|
||||
-->
|
||||
<link rel="stylesheet" type="text/css" href="http://metabar:8888/obidoc/hugo-cite.css" />
|
||||
|
||||
<style>
|
||||
.not-found {
|
||||
text-align: center;
|
||||
}
|
||||
.not-found h1 {
|
||||
margin: .25em 0 0 0;
|
||||
opacity: .25;
|
||||
font-size: 40vmin;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="flex justify-center not-found">
|
||||
<div>
|
||||
<h1>404</h1>
|
||||
<h2>Page Not Found</h2>
|
||||
<h3>
|
||||
<a href="/obidoc/">OBITools4 documentation</a>
|
||||
</h3>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Categories on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/categories/</link>
|
||||
<description>Recent content in Categories on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/categories/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<title>http://metabar:8888/obidoc/categories/</title>
|
||||
<link rel="canonical" href="http://metabar:8888/obidoc/categories/">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=http://metabar:8888/obidoc/categories/">
|
||||
</head>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Commands on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/commands/</link>
|
||||
<description>Recent content in Commands on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/commands/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<title>http://metabar:8888/obidoc/commands/</title>
|
||||
<link rel="canonical" href="http://metabar:8888/obidoc/commands/">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=http://metabar:8888/obidoc/commands/">
|
||||
</head>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
.admonition{margin:1rem 0;border-radius:4px;box-shadow:0 1px 3px rgba(0,0,0,0.12);transition:all 0.3s ease}.admonition-header{padding:0.5rem 1rem;display:flex;align-items:center;font-weight:600;border-bottom:1px solid rgba(0,0,0,0.1);font-size:1.1rem;border-radius:4px 4px 0 0}.admonition-header svg{width:1.1em;height:1.1em;margin-right:0.5rem;fill:currentColor}.admonition-content{padding:1rem;background-color:#fff;border-radius:0 0 4px 4px;color:#000;transition:background-color 0.3s ease, color 0.3s ease}.admonition-content p{margin:0 0 0.5rem 0}.admonition-content p:last-child{margin-bottom:0}.admonition-content ul,.admonition-content ol{margin:0 0 0.5rem 0;padding-left:1.2rem}.admonition-content ul:last-child,.admonition-content ol:last-child{margin-bottom:0}.admonition-content blockquote{margin:0 0 0.5rem 0;padding-left:1rem;border-left:3px solid #e0e0e0}.admonition-content blockquote:last-child{margin-bottom:0}.admonition-content code{background-color:#f5f5f5;color:#24292e;padding:0.2em 0.4em;border-radius:3px;font-size:0.9em}@media (prefers-color-scheme: dark){.admonition-content{background-color:#1D1E20;color:#e6e6e6}.admonition-content code{background-color:#313244;color:#cdd6f4}.admonition-content blockquote{border-left-color:#45475a;color:#cdd6f4}}body.dark .admonition-content{background-color:#1D1E20;color:#e6e6e6}body.dark .admonition-content code{background-color:#313244;color:#cdd6f4}body.dark .admonition-content blockquote{border-left-color:#45475a;color:#cdd6f4}.admonition.abstract{background:transparent;border-left:4px solid #209fb5}.admonition.abstract .admonition-header{background:rgba(32,159,181,0.1);color:#209fb5}.admonition.caution{background:transparent;border-left:4px solid #e64553}.admonition.caution .admonition-header{background:rgba(230,69,83,0.1);color:#e64553}.admonition.code{background:transparent;border-left:4px solid #7287fd}.admonition.code .admonition-header{background:rgba(114,135,253,0.1);color:#7287fd}.admonition.conclusion{background:transparent;border-left:4px solid #dd7878}.admonition.conclusion .admonition-header{background:rgba(221,120,120,0.1);color:#dd7878}.admonition.danger{background:transparent;border-left:4px solid #fe640b}.admonition.danger .admonition-header{background:rgba(254,100,11,0.1);color:#fe640b}.admonition.error{background:transparent;border-left:4px solid #d20f39}.admonition.error .admonition-header{background:rgba(210,15,57,0.1);color:#d20f39}.admonition.example{background:transparent;border-left:4px solid #dc8a78}.admonition.example .admonition-header{background:rgba(220,138,120,0.1);color:#dc8a78}.admonition.experiment{background:transparent;border-left:4px solid #51bb2a}.admonition.experiment .admonition-header{background:rgba(81,187,42,0.1);color:#51bb2a}.admonition.goal{background:transparent;border-left:4px solid #e64553}.admonition.goal .admonition-header{background:rgba(230,69,83,0.1);color:#e64553}.admonition.idea{background:transparent;border-left:4px solid #df8e1d}.admonition.idea .admonition-header{background:rgba(223,142,29,0.1);color:#df8e1d}.admonition.important{background:transparent;border-left:4px solid #7D4DDA}.admonition.important .admonition-header{background:rgba(125,77,218,0.1);color:#7D4DDA}.admonition.info{background:transparent;border-left:4px solid #04a5e5}.admonition.info .admonition-header{background:rgba(4,165,229,0.1);color:#04a5e5}.admonition.memo{background:transparent;border-left:4px solid #e64553}.admonition.memo .admonition-header{background:rgba(230,69,83,0.1);color:#e64553}.admonition.note{background:transparent;border-left:4px solid #096ae1}.admonition.note .admonition-header{background:rgba(9,106,225,0.1);color:#096ae1}.admonition.notify{background:transparent;border-left:4px solid #0d48bd}.admonition.notify .admonition-header{background:rgba(13,72,189,0.1);color:#0d48bd}.admonition.question{background:transparent;border-left:4px solid #179299}.admonition.question .admonition-header{background:rgba(23,146,153,0.1);color:#179299}.admonition.quote{background:transparent;border-left:4px solid #7287fd}.admonition.quote .admonition-header{background:rgba(114,135,253,0.1);color:#7287fd}.admonition.success{background:transparent;border-left:4px solid #40a02b}.admonition.success .admonition-header{background:rgba(64,160,43,0.1);color:#40a02b}.admonition.task{background:transparent;border-left:4px solid #8839ef}.admonition.task .admonition-header{background:rgba(136,57,239,0.1);color:#8839ef}.admonition.tip{background:transparent;border-left:4px solid #179299}.admonition.tip .admonition-header{background:rgba(23,146,153,0.1);color:#179299}.admonition.warning{background:transparent;border-left:4px solid #df8e1d}.admonition.warning .admonition-header{background:rgba(223,142,29,0.1);color:#df8e1d}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Advanced tools on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/advanced/</link>
|
||||
<description>Recent content in Advanced tools on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/advanced/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Sequence alignments on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/alignments/</link>
|
||||
<description>Recent content in Sequence alignments on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/alignments/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Exact alignment on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/alignments/obipairing/exact-alignment/</link>
|
||||
<description>Recent content in Exact alignment on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/alignments/obipairing/exact-alignment/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,149 +0,0 @@
|
||||
---
|
||||
title: "Untitled"
|
||||
format: html
|
||||
editor: visual
|
||||
---
|
||||
|
||||
```{r}
|
||||
library(tidyverse)
|
||||
library(plotly)
|
||||
library(matrixStats)
|
||||
```
|
||||
|
||||
```{r}
|
||||
log_sum_exp <- function(a,b) {
|
||||
m <- map2_dbl(a,b,max)
|
||||
m + log(exp(a-m)+exp(b-m))
|
||||
}
|
||||
```
|
||||
|
||||
$$
|
||||
\log(1 - e^b) = \log\left(-e^{(1-b)}\right)
|
||||
$$
|
||||
|
||||
```{r}
|
||||
log1m_exp <- function(b) {
|
||||
if (any(b >= 0)) {
|
||||
stop(glue::glue("b must be negative (b={b})"))
|
||||
}
|
||||
return(log(-expm1(b))) # expm1(b) = exp(b) - 1, pour éviter les erreurs d'arrondi
|
||||
}
|
||||
```
|
||||
|
||||
$$
|
||||
\log(e^a - e^b) = a + \log(1 - e^{b-a})
|
||||
$$
|
||||
|
||||
```{r}
|
||||
log_diff_exp <- function(a, b) {
|
||||
# Vérifier si a > b pour éviter des résultats indéfinis
|
||||
if (any(a < b)) {
|
||||
stop(glue::glue("Erreur : a ({a}) doit etre strictement sup<75>rieur <20> b ({b}) pour que e^a - e^b soit positif."))
|
||||
}
|
||||
|
||||
# Calculer log(e^a - e^b) de manière stable
|
||||
ifelse(a == b, -Inf,a + log1m_exp(b-a))
|
||||
}
|
||||
```
|
||||
|
||||
$$
|
||||
P_{error} = 10^{-\frac{Q}{10}}
|
||||
$$
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
q_F &= -\frac{Q_F}{10} \cdot \log(10) \\
|
||||
q_R &= -\frac{Q_R}{10} \cdot \log(10) \\
|
||||
P(macth | Obs(match)) &= (1-e^{q_F}) (1-e^{q_R}) + (1-e^{q_F})\frac{e^{q_R}}{4}+ (1-e^{q_R})\frac{e^{q_F}}{4} + \frac{e^{q_F+q_R}}{4} \\
|
||||
&=1 - e^{q_R} - e^{q_F} + e^{q_F+q_R} + \frac{e^{q_R}}{4} - \frac{e^{q_F+q_R}}{4} + \frac{e^{q_F}}{4} - \frac{e^{q_F+q_R}}{4} + \frac{e^{q_F+q_R}}{4} \\
|
||||
&= \frac{4 - 4e^{q_F} - 4e^{q_R} + 4e^{q_F+q_R} + e^{q_F} + e^{q_R} - e^{q_F+q_R}}{4} \\
|
||||
&= \frac{4 - 3e^{q_F}- 3e^{q_R} + 3e^{q_F+q_R}}{4}\\
|
||||
&= \frac{4 - 3(e^{q_F}+e^{q_R}-e^{q_F+q_R})}{4} \\
|
||||
&= 1 - \frac{3}{4}\left(e^{q_F}+e^{q_R}-e^{q_F+q_R}\right)
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
```{r}
|
||||
Pm_match_observed <- function(Q_F, Q_R) {
|
||||
l10 <- log(10)
|
||||
l3 <- log(3)
|
||||
l4 <- log(4)
|
||||
|
||||
q_F <- -Q_F/10*l10
|
||||
q_R <- -Q_R/10*l10
|
||||
|
||||
term1 <- log_sum_exp(q_F,q_R)
|
||||
term2 <- log_diff_exp(term1,q_F+q_R) + l3 - l4
|
||||
|
||||
log1m_exp(term2)
|
||||
}
|
||||
```
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
P(macth | Obs(mismatch)) &= \frac{(1-e^{q_F})e^{q_R}}{4} + \frac{(1-e^{q_R})e^{q_F}}{4} + \frac{e^{q_F+q_R}}{4} \\
|
||||
&= \frac{(1-e^{q_F})e^{q_R} + (1-e^{q_R})e^{q_F} + e^{q_F+q_R}}{4} \\
|
||||
&= \frac{e^{q_R} - e^{q_F+q_R} + e^{q_F} - e^{q_F+q_R} + e^{q_F+q_R}}{4} \\
|
||||
&= \frac{e^{q_F} + e^{q_R} - e^{q_F+q_R}}{4}
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
```{r}
|
||||
Pm_mismatch_observed <- function(Q_F, Q_R) {
|
||||
l10 <- log(10)
|
||||
l3 <- log(3)
|
||||
l4 <- log(4)
|
||||
|
||||
q_F <- -Q_F/10*l10
|
||||
q_R <- -Q_R/10*l10
|
||||
|
||||
term1 <- log_sum_exp(q_F,q_R)
|
||||
log_diff_exp(term1,q_F+q_R) - l4
|
||||
}
|
||||
```
|
||||
|
||||
```{r}
|
||||
score_match_observed <- function(Q_F, Q_R) {
|
||||
Pm_match_observed(Q_F,Q_R) - log1m_exp(Pm_match_observed(Q_F,Q_R))
|
||||
}
|
||||
|
||||
score_mismatch_observed <- function(Q_F, Q_R) {
|
||||
Pm_mismatch_observed(Q_F,Q_R) - log1m_exp(Pm_mismatch_observed(Q_F,Q_R))
|
||||
}
|
||||
```
|
||||
|
||||
```{r}
|
||||
scores <- expand_grid(QF=0:40,QR=0:40) %>%
|
||||
mutate(score_match_observed = round(score_match_observed(QF,QR),2),
|
||||
score_mismatch_observed = round(score_mismatch_observed(QF,QR),2))
|
||||
```
|
||||
|
||||
```{r}
|
||||
plot_match <- plot_ly(scores,
|
||||
x=~QF, y=~QR, z=~score_match_observed,
|
||||
type="mesh3d") %>%
|
||||
layout(
|
||||
plot_bgcolor = "#bababa",
|
||||
scene = list(
|
||||
xaxis = list(title = "Q forward read"), # Change x/y/z axis title
|
||||
yaxis = list(title = "Q reverse read"),
|
||||
zaxis = list(title = "Score match")))
|
||||
```
|
||||
|
||||
```{r}
|
||||
plot_mismatch <- plot_ly(scores,
|
||||
x=~QF, y=~QR, z=~score_mismatch_observed,
|
||||
type="mesh3d") %>%
|
||||
layout(
|
||||
plot_bgcolor = "#bababa",
|
||||
scene = list(
|
||||
xaxis = list(title = "Q forward read"), # Change x/y/z axis title
|
||||
yaxis = list(title = "Q reverse read"),
|
||||
zaxis = list(title = "Score mismatch")))
|
||||
```
|
||||
|
||||
```{r}
|
||||
write(plotly_json(plot_match,FALSE),"content/docs/commands/alignments/obipairing/exact-alignment/match.json")
|
||||
write(plotly_json(plot_mismatch,FALSE),"content/docs/commands/alignments/obipairing/exact-alignment/mismatch.json")
|
||||
|
||||
```
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>The FASTA-like alignment on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/alignments/obipairing/fasta-like/</link>
|
||||
<description>Recent content in The FASTA-like alignment on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/alignments/obipairing/fasta-like/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Basics on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/basics/</link>
|
||||
<description>Recent content in Basics on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/basics/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Demultiplexing samples on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/demultiplexing/</link>
|
||||
<description>Recent content in Demultiplexing samples on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/demultiplexing/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Experimentals on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/experimental/</link>
|
||||
<description>Recent content in Experimentals on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/experimental/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>The OBITools4 commands on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/</link>
|
||||
<description>Recent content in The OBITools4 commands on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>Fri, 04 Oct 2024 17:16:03 +0200</lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>Glossary of tags</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/tags/</link>
|
||||
<pubDate>Fri, 04 Oct 2024 17:16:03 +0200</pubDate>
|
||||
<guid>http://metabar:8888/obidoc/docs/commands/tags/</guid>
|
||||
<description><h1 id="glossary-of-tags">
 Glossary of tags
 <a class="anchor" href="#glossary-of-tags">#</a>
</h1>
<h3 id="--d--">
 - D -
 <a class="anchor" href="#--d--">#</a>
</h3>
<ul>
<li>
<p><strong>definition</strong> :</p>
<blockquote>
<p>text information about the sequence present in the original sequence file.</p>
</blockquote>
</li>
<li>
<p><strong>direction</strong> :</p>
<blockquote>
<p>set to “forward” if the original sequence did not need to be reverse-complemented to be processed, set to “reverse” otherwise.
(
 <a href="http://metabar:8888/obidoc/obitools/obipcr/">obipcr</a>)</p>
</blockquote>
</li>
</ul>
<h3 id="--f--">
 - F -
 <a class="anchor" href="#--f--">#</a>
</h3>
<ul>
<li>
<p><strong>forward_error</strong> :</p>
<blockquote>
<p>Number of mismatch between forward primer and priming site
(
 <a href="http://metabar:8888/obidoc/obitools/obipcr/">obipcr</a>)</p>
</blockquote>
</li>
<li>
<p><strong>forward_match</strong> :</p>
<blockquote>
<p>Forward primer priming site sequence
(
 <a href="http://metabar:8888/obidoc/obitools/obipcr/">obipcr</a>)</p>
</blockquote>
</li>
<li>
<p><strong>forward_primer</strong> :</p>
<blockquote>
<p>Forward primer sequence
(
 <a href="http://metabar:8888/obidoc/obitools/obipcr/">obipcr</a>)</p></description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Shared command options on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/options/</link>
|
||||
<description>Recent content in Shared command options on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/options/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,6 +0,0 @@
|
||||
>AB061527 {"count":1,"definition":"Sorex unguiculatus mitochondrial NA, complete genome.","family_name":"Soricidae","family_taxid":9376,"genus_name":"Sorex","genus_taxid":9379,"obicleandb_level":"family","obicleandb_trusted":2.2137847111025621e-13,"species_name":"Sorex unguiculatus","species_taxid":62275,"taxid":62275}
|
||||
ttagccctaaacttaggtatttaatctaacaaaaatacccgtcagagaactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>AL355887 {"count":2,"definition":"Human chromosome 14 NA sequence BAC R-179O11 of library RPCI-11 from chromosome 14 of Homo sapiens (Human)XXKW HTG.; HTGS_ACTIVFIN.","family_name":"Hominidae","family_taxid":9604,"genus_name":"Homo","genus_taxid":9605,"obicleandb_level":"genus","obicleandb_trusted":0,"species_name":"Homo sapiens","species_taxid":9606,"taxid":9606}
|
||||
ttagccctaaactctagtagttacattaacaaaaccattcgtcagaatactacgagcaac
|
||||
agcttaaaactcaaaggacctggcagttctttatatccct
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Others on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/others/</link>
|
||||
<description>Recent content in Others on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/others/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Taxonomy on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/commands/taxonomy/</link>
|
||||
<description>Recent content in Taxonomy on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/commands/taxonomy/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,604 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import re
|
||||
import gzip
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
from functools import cmp_to_key
|
||||
|
||||
_dbenable=False
|
||||
|
||||
#####
|
||||
#
|
||||
#
|
||||
# Generic file function
|
||||
#
|
||||
#
|
||||
#####
|
||||
|
||||
def universalOpen(file):
|
||||
if isinstance(file,str):
|
||||
if file[-3:] == '.gz':
|
||||
rep = gzip.open(file)
|
||||
else:
|
||||
rep = open(file)
|
||||
else:
|
||||
rep = file
|
||||
return rep
|
||||
|
||||
def universalTell(file):
|
||||
if isinstance(file, gzip.GzipFile):
|
||||
file=file.myfileobj
|
||||
return file.tell()
|
||||
|
||||
def fileSize(file):
|
||||
if isinstance(file, gzip.GzipFile):
|
||||
file=file.myfileobj
|
||||
pos = file.tell()
|
||||
file.seek(0,2)
|
||||
length = file.tell()
|
||||
file.seek(pos,0)
|
||||
return length
|
||||
|
||||
def progressBar(pos,max,reset=False,delta=[]):
|
||||
if reset:
|
||||
del delta[:]
|
||||
if not delta:
|
||||
delta.append(time.time())
|
||||
delta.append(time.time())
|
||||
|
||||
delta[1]=time.time()
|
||||
elapsed = delta[1]-delta[0]
|
||||
percent = float(pos)/max * 100
|
||||
remain = time.strftime('%H:%M:%S',time.gmtime(elapsed / percent * (100-percent)))
|
||||
bar = '#' * int(percent/2)
|
||||
bar+= '|/-\\-'[pos % 5]
|
||||
bar+= ' ' * (50 - int(percent/2))
|
||||
sys.stderr.write('\r%5.1f %% |%s] remain : %s' %(percent,bar,remain))
|
||||
|
||||
#####
|
||||
#
|
||||
#
|
||||
# NCBI Dump Taxonomy reader
|
||||
#
|
||||
#
|
||||
#####
|
||||
|
||||
def endLessIterator(endedlist):
|
||||
for x in endedlist:
|
||||
yield x
|
||||
while(1):
|
||||
yield endedlist[-1]
|
||||
|
||||
class ColumnFile(object):
|
||||
|
||||
def __init__(self,stream,sep=None,strip=True,types=None):
|
||||
if isinstance(stream,str):
|
||||
self._stream = open(stream)
|
||||
else:
|
||||
try:
|
||||
iter(stream)
|
||||
self._stream = stream
|
||||
except TypeError:
|
||||
raise ValueError('stream must be string or an iterator')
|
||||
self._delimiter=sep
|
||||
self._strip=strip
|
||||
if types:
|
||||
self._types=[x for x in types]
|
||||
for i in range(len(self._types)):
|
||||
if self._types[i] is bool:
|
||||
self._types[i]=ColumnFile.str2bool
|
||||
else:
|
||||
self._types=None
|
||||
|
||||
def str2bool(x):
|
||||
return bool(eval(x.strip()[0].upper(),{'T':True,'V':True,'F':False}))
|
||||
|
||||
str2bool = staticmethod(str2bool)
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
ligne = next(self._stream)
|
||||
data = ligne.split(self._delimiter)
|
||||
if self._strip or self._types:
|
||||
data = [x.strip() for x in data]
|
||||
if self._types:
|
||||
it = endLessIterator(self._types)
|
||||
data = [x[1](x[0]) for x in ((y,next(it)) for y in data)]
|
||||
return data
|
||||
|
||||
def taxonCmp(t1,t2):
|
||||
if t1[0] < t2[0]:
|
||||
return -1
|
||||
elif t1[0] > t2[0]:
|
||||
return +1
|
||||
return 0
|
||||
|
||||
def bsearchTaxon(taxonomy,taxid):
|
||||
taxCount = len(taxonomy)
|
||||
begin = 0
|
||||
end = taxCount
|
||||
oldcheck=taxCount
|
||||
check = int(begin + end / 2)
|
||||
while check != oldcheck and taxonomy[check][0]!=taxid :
|
||||
if taxonomy[check][0] < taxid:
|
||||
begin=check
|
||||
else:
|
||||
end=check
|
||||
oldcheck=check
|
||||
check = int((begin + end) / 2)
|
||||
|
||||
|
||||
if taxonomy[check][0]==taxid:
|
||||
return check
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def readNodeTable(file):
|
||||
|
||||
file = universalOpen(file)
|
||||
|
||||
nodes = ColumnFile(file,
|
||||
sep='|',
|
||||
types=(int,int,str,
|
||||
str,str,bool,
|
||||
int,bool,int,
|
||||
bool,bool,bool,str))
|
||||
print("Reading taxonomy dump file...", file=sys.stderr)
|
||||
taxonomy=[[n[0],n[2],n[1]] for n in nodes]
|
||||
print("List all taxonomy rank...", file=sys.stderr)
|
||||
ranks =list(set(x[1] for x in taxonomy))
|
||||
ranks.sort()
|
||||
ranks = {rank: index for index, rank in enumerate(ranks)}
|
||||
|
||||
print("Sorting taxons...", file=sys.stderr)
|
||||
taxonomy.sort(key=lambda x: x[0])
|
||||
|
||||
print("Indexing taxonomy...", file=sys.stderr)
|
||||
index = {}
|
||||
for t in taxonomy:
|
||||
index[t[0]]=bsearchTaxon(taxonomy, t[0])
|
||||
|
||||
print("Indexing parent and rank...", file=sys.stderr)
|
||||
for t in taxonomy:
|
||||
t[1]=ranks[t[1]]
|
||||
t[2]=index[t[2]]
|
||||
|
||||
|
||||
return taxonomy,ranks,index
|
||||
|
||||
def nameIterator(file):
|
||||
file = universalOpen(file)
|
||||
names = ColumnFile(file,
|
||||
sep='|',
|
||||
types=(int,str,
|
||||
str,str))
|
||||
for taxid,name,unique,classname,white in names:
|
||||
yield taxid,name,classname
|
||||
|
||||
def mergedNodeIterator(file):
|
||||
file = universalOpen(file)
|
||||
merged = ColumnFile(file,
|
||||
sep='|',
|
||||
types=(int,int,str))
|
||||
for taxid,current,white in merged:
|
||||
yield taxid,current
|
||||
|
||||
def deletedNodeIterator(file):
|
||||
file = universalOpen(file)
|
||||
deleted = ColumnFile(file,
|
||||
sep='|',
|
||||
types=(int,str))
|
||||
for taxid,white in deleted:
|
||||
yield taxid
|
||||
|
||||
def readTaxonomyDump(taxdir):
|
||||
taxonomy,ranks,index = readNodeTable('%s/nodes.dmp' % taxdir)
|
||||
|
||||
print("Adding scientific name...", file=sys.stderr)
|
||||
|
||||
alternativeName=[]
|
||||
for taxid,name,classname in nameIterator('%s/names.dmp' % taxdir):
|
||||
alternativeName.append((name,classname,index[taxid]))
|
||||
if classname == 'scientific name':
|
||||
taxonomy[index[taxid]].append(name)
|
||||
|
||||
print("Adding taxid alias...", file=sys.stderr)
|
||||
for taxid,current in mergedNodeIterator('%s/merged.dmp' % taxdir):
|
||||
index[taxid]=index[current]
|
||||
|
||||
print("Adding deleted taxid...", file=sys.stderr)
|
||||
for taxid in deletedNodeIterator('%s/delnodes.dmp' % taxdir):
|
||||
index[taxid]=None
|
||||
|
||||
return taxonomy,ranks,alternativeName,index
|
||||
|
||||
#####
|
||||
#
|
||||
#
|
||||
# Genbank/EMBL sequence reader
|
||||
#
|
||||
#
|
||||
#####
|
||||
|
||||
def entryIterator(file):
|
||||
file = universalOpen(file)
|
||||
rep =[]
|
||||
ligne = file.readline()
|
||||
while ligne:
|
||||
rep.append(ligne)
|
||||
if ligne == '//\n':
|
||||
rep = ''.join(rep)
|
||||
yield rep
|
||||
rep = []
|
||||
ligne = file.readline()
|
||||
|
||||
def fastaEntryIterator(file):
|
||||
file = universalOpen(file)
|
||||
rep =[]
|
||||
ligne = file.readline()
|
||||
while ligne:
|
||||
if ligne[0] == '>' and rep:
|
||||
rep = ''.join(rep)
|
||||
yield rep
|
||||
rep = []
|
||||
rep.append(ligne)
|
||||
ligne = file.readline()
|
||||
|
||||
if rep:
|
||||
rep = ''.join(rep)
|
||||
yield rep
|
||||
|
||||
_cleanSeq = re.compile('[ \n0-9]+')
|
||||
|
||||
def cleanSeq(seq):
|
||||
return _cleanSeq.sub('',seq)
|
||||
|
||||
|
||||
_gbParseID = re.compile('(?<=^LOCUS {7})[^ ]+(?= )',re.MULTILINE)
|
||||
_gbParseDE = re.compile('(?<=^DEFINITION {2}).+?\\. *$(?=[^ ])',re.MULTILINE+re.DOTALL)
|
||||
_gbParseSQ = re.compile('(?<=^ORIGIN).+?(?=^//$)',re.MULTILINE+re.DOTALL)
|
||||
_gbParseTX = re.compile('(?<= /db_xref="taxon:)[0-9]+(?=")')
|
||||
|
||||
def genbankEntryParser(entry):
|
||||
Id = _gbParseID.findall(entry)[0]
|
||||
De = ' '.join(_gbParseDE.findall(entry)[0].split())
|
||||
Sq = cleanSeq(_gbParseSQ.findall(entry)[0].upper())
|
||||
try:
|
||||
Tx = int(_gbParseTX.findall(entry)[0])
|
||||
except IndexError:
|
||||
Tx = None
|
||||
return {'id':Id,'taxid':Tx,'definition':De,'sequence':Sq}
|
||||
|
||||
######################
|
||||
|
||||
_cleanDef = re.compile('[\nDE]')
|
||||
|
||||
def cleanDef(definition):
|
||||
return _cleanDef.sub('',definition)
|
||||
|
||||
_emblParseID = re.compile('(?<=^ID {3})[^ ]+(?=;)',re.MULTILINE)
|
||||
_emblParseDE = re.compile('(?<=^DE {3}).+?\\. *$(?=[^ ])',re.MULTILINE+re.DOTALL)
|
||||
_emblParseSQ = re.compile('(?<=^ ).+?(?=^//$)',re.MULTILINE+re.DOTALL)
|
||||
_emblParseTX = re.compile('(?<= /db_xref="taxon:)[0-9]+(?=")')
|
||||
|
||||
def emblEntryParser(entry):
|
||||
Id = _emblParseID.findall(entry)[0]
|
||||
De = ' '.join(cleanDef(_emblParseDE.findall(entry)[0]).split())
|
||||
Sq = cleanSeq(_emblParseSQ.findall(entry)[0].upper())
|
||||
try:
|
||||
Tx = int(_emblParseTX.findall(entry)[0])
|
||||
except IndexError:
|
||||
Tx = None
|
||||
return {'id':Id,'taxid':Tx,'definition':De,'sequence':Sq}
|
||||
|
||||
|
||||
######################
|
||||
|
||||
_fastaSplit=re.compile(';\\W*')
|
||||
|
||||
def parseFasta(seq):
|
||||
seq=seq.split('\n')
|
||||
title = seq[0].strip()[1:].split(None,1)
|
||||
id=title[0]
|
||||
if len(title) == 2:
|
||||
field = _fastaSplit.split(title[1])
|
||||
else:
|
||||
field=[]
|
||||
info = dict(x.split('=',1) for x in field if '=' in x)
|
||||
definition = ' '.join([x for x in field if '=' not in x])
|
||||
seq=(''.join([x.strip() for x in seq[1:]])).upper()
|
||||
return id,seq,definition,info
|
||||
|
||||
|
||||
def fastaEntryParser(entry):
|
||||
id,seq,definition,info = parseFasta(entry)
|
||||
Tx = info.get('taxid',None)
|
||||
if Tx is not None:
|
||||
match = re.search(r'taxon:(\d+)', Tx)
|
||||
if match:
|
||||
Tx = match.group(1)
|
||||
Tx=int(Tx)
|
||||
return {'id':id,'taxid':Tx,'definition':definition,'sequence':seq}
|
||||
|
||||
|
||||
def sequenceIteratorFactory(entryParser,entryIterator):
|
||||
def sequenceIterator(file):
|
||||
for entry in entryIterator(file):
|
||||
yield entryParser(entry)
|
||||
return sequenceIterator
|
||||
|
||||
|
||||
def taxonomyInfo(entry,connection):
|
||||
taxid = entry['taxid']
|
||||
curseur = connection.cursor()
|
||||
curseur.execute("""
|
||||
select taxid,species,genus,family,
|
||||
taxonomy.scientificName(taxid) as sn,
|
||||
taxonomy.scientificName(species) as species_sn,
|
||||
taxonomy.scientificName(genus) as genus_sn,
|
||||
taxonomy.scientificName(family) as family_sn
|
||||
from
|
||||
(
|
||||
select alias as taxid,
|
||||
taxonomy.getSpecies(alias) as species,
|
||||
taxonomy.getGenus(alias) as genus,
|
||||
taxonomy.getFamily(alias) as family
|
||||
from taxonomy.aliases
|
||||
where id=%d ) as tax
|
||||
""" % taxid)
|
||||
rep = curseur.fetchone()
|
||||
entry['current_taxid']=rep[0]
|
||||
entry['species']=rep[1]
|
||||
entry['genus']=rep[2]
|
||||
entry['family']=rep[3]
|
||||
entry['scientific_name']=rep[4]
|
||||
entry['species_sn']=rep[5]
|
||||
entry['genus_sn']=rep[6]
|
||||
entry['family_sn']=rep[7]
|
||||
return entry
|
||||
|
||||
#####
|
||||
#
|
||||
#
|
||||
# Binary writer
|
||||
#
|
||||
#
|
||||
#####
|
||||
|
||||
def ecoSeqPacker(sq):
|
||||
|
||||
compactseq = gzip.zlib.compress(bytes(sq['sequence'],"ascii"),9)
|
||||
cptseqlength = len(compactseq)
|
||||
delength = len(sq['definition'])
|
||||
|
||||
totalSize = 4 + 20 + 4 + 4 + 4 + cptseqlength + delength
|
||||
|
||||
packed = struct.pack('> I I 20s I I I %ds %ds' % (delength,cptseqlength),
|
||||
totalSize,
|
||||
sq['taxid'],
|
||||
bytes(sq['id'],"ascii"),
|
||||
delength,
|
||||
len(sq['sequence']),
|
||||
cptseqlength,
|
||||
bytes(sq['definition'],"ascii"),
|
||||
compactseq)
|
||||
|
||||
assert len(packed) == totalSize+4, "error in sequence packing"
|
||||
|
||||
return packed
|
||||
|
||||
def ecoTaxPacker(tx):
|
||||
|
||||
namelength = len(tx[3])
|
||||
|
||||
totalSize = 4 + 4 + 4 + 4 + namelength
|
||||
|
||||
packed = struct.pack('> I I I I I %ds' % namelength,
|
||||
totalSize,
|
||||
tx[0],
|
||||
tx[1],
|
||||
tx[2],
|
||||
namelength,
|
||||
bytes(tx[3],"ascii"))
|
||||
|
||||
return packed
|
||||
|
||||
def ecoRankPacker(rank):
|
||||
|
||||
namelength = len(rank)
|
||||
|
||||
packed = struct.pack('> I %ds' % namelength,
|
||||
namelength,
|
||||
bytes(rank, 'ascii'))
|
||||
|
||||
return packed
|
||||
|
||||
def ecoNamePacker(name):
|
||||
|
||||
namelength = len(name[0])
|
||||
classlength= len(name[1])
|
||||
totalSize = namelength + classlength + 4 + 4 + 4 + 4
|
||||
|
||||
packed = struct.pack('> I I I I I %ds %ds' % (namelength,classlength),
|
||||
totalSize,
|
||||
int(name[1]=='scientific name'),
|
||||
namelength,
|
||||
classlength,
|
||||
name[2],
|
||||
bytes(name[0], 'ascii'),
|
||||
bytes(name[1], 'ascii'))
|
||||
|
||||
return packed
|
||||
|
||||
def ecoSeqWriter(file,input,taxindex,parser):
|
||||
output = open(file,'wb')
|
||||
input = universalOpen(input)
|
||||
inputsize = fileSize(input)
|
||||
entries = parser(input)
|
||||
seqcount=0
|
||||
skipped = []
|
||||
|
||||
output.write(struct.pack('> I',seqcount))
|
||||
|
||||
progressBar(1, inputsize,reset=True)
|
||||
for entry in entries:
|
||||
if entry['taxid'] is not None:
|
||||
try:
|
||||
entry['taxid']=taxindex[entry['taxid']]
|
||||
except KeyError:
|
||||
entry['taxid']=None
|
||||
if entry['taxid'] is not None:
|
||||
seqcount+=1
|
||||
output.write(ecoSeqPacker(entry))
|
||||
else:
|
||||
skipped.append(entry['id'])
|
||||
where = universalTell(input)
|
||||
progressBar(where, inputsize)
|
||||
print(" Readed sequences : %d " % seqcount, end=' ', file=sys.stderr)
|
||||
else:
|
||||
skipped.append(entry['id'])
|
||||
|
||||
print(file=sys.stderr)
|
||||
output.seek(0,0)
|
||||
output.write(struct.pack('> I',seqcount))
|
||||
|
||||
output.close()
|
||||
return skipped
|
||||
|
||||
|
||||
def ecoTaxWriter(file,taxonomy):
|
||||
output = open(file,'wb')
|
||||
output.write(struct.pack('> I',len(taxonomy)))
|
||||
|
||||
for tx in taxonomy:
|
||||
output.write(ecoTaxPacker(tx))
|
||||
|
||||
output.close()
|
||||
|
||||
def ecoRankWriter(file,ranks):
|
||||
output = open(file,'wb')
|
||||
output.write(struct.pack('> I',len(ranks)))
|
||||
|
||||
rankNames = list(ranks.keys())
|
||||
rankNames.sort()
|
||||
|
||||
for rank in rankNames:
|
||||
output.write(ecoRankPacker(rank))
|
||||
|
||||
output.close()
|
||||
|
||||
def nameCmp(n1,n2):
|
||||
name1=n1[0].upper()
|
||||
name2=n2[0].upper()
|
||||
if name1 < name2:
|
||||
return -1
|
||||
elif name1 > name2:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def ecoNameWriter(file,names):
|
||||
output = open(file,'wb')
|
||||
output.write(struct.pack('> I',len(names)))
|
||||
|
||||
names.sort(key=lambda x:x[0].upper())
|
||||
|
||||
for name in names:
|
||||
output.write(ecoNamePacker(name))
|
||||
|
||||
output.close()
|
||||
|
||||
def ecoDBWriter(prefix,taxonomy,seqFileNames,parser):
|
||||
|
||||
ecoRankWriter('%s.rdx' % prefix, taxonomy[1])
|
||||
ecoTaxWriter('%s.tdx' % prefix, taxonomy[0])
|
||||
ecoNameWriter('%s.ndx' % prefix, taxonomy[2])
|
||||
|
||||
filecount = 0
|
||||
for filename in seqFileNames:
|
||||
filecount+=1
|
||||
sk=ecoSeqWriter('%s_%03d.sdx' % (prefix,filecount),
|
||||
filename,
|
||||
taxonomy[3],
|
||||
parser)
|
||||
if sk:
|
||||
print("Skipped entry :", file=sys.stderr)
|
||||
print(sk, file=sys.stderr)
|
||||
|
||||
def ecoParseOptions(arguments):
|
||||
opt = {
|
||||
'prefix' : 'ecodb',
|
||||
'taxdir' : 'taxdump',
|
||||
'parser' : sequenceIteratorFactory(genbankEntryParser,
|
||||
entryIterator)
|
||||
}
|
||||
|
||||
o,filenames = getopt.getopt(arguments,
|
||||
'ht:T:n:gfe',
|
||||
['help',
|
||||
'taxonomy=',
|
||||
'taxonomy_db=',
|
||||
'name=',
|
||||
'genbank',
|
||||
'fasta',
|
||||
'embl'])
|
||||
|
||||
for name,value in o:
|
||||
if name in ('-h','--help'):
|
||||
printHelp()
|
||||
exit()
|
||||
elif name in ('-t','--taxonomy'):
|
||||
opt['taxmod']='dump'
|
||||
opt['taxdir']=value
|
||||
elif name in ('-T','--taxonomy_db'):
|
||||
opt['taxmod']='db'
|
||||
opt['taxdb']=value
|
||||
elif name in ('-n','--name'):
|
||||
opt['prefix']=value
|
||||
elif name in ('-g','--genbank'):
|
||||
opt['parser']=sequenceIteratorFactory(genbankEntryParser,
|
||||
entryIterator)
|
||||
|
||||
elif name in ('-f','--fasta'):
|
||||
opt['parser']=sequenceIteratorFactory(fastaEntryParser,
|
||||
fastaEntryIterator)
|
||||
|
||||
elif name in ('-e','--embl'):
|
||||
opt['parser']=sequenceIteratorFactory(emblEntryParser,
|
||||
entryIterator)
|
||||
else:
|
||||
raise ValueError('Unknown option %s' % name)
|
||||
|
||||
return opt,filenames
|
||||
|
||||
def printHelp():
|
||||
print("-----------------------------------")
|
||||
print(" ecoPCRFormat.py")
|
||||
print("-----------------------------------")
|
||||
print("ecoPCRFormat.py [option] <argument>")
|
||||
print("-----------------------------------")
|
||||
print("-e --embl :[E]mbl format")
|
||||
print("-f --fasta :[F]asta format")
|
||||
print("-g --genbank :[G]enbank format")
|
||||
print("-h --help :[H]elp - print this help")
|
||||
print("-n --name :[N]ame of the new database created")
|
||||
print("-t --taxonomy :[T]axonomy - path to the taxonomy database")
|
||||
print(" :bcp-like dump from GenBank taxonomy database.")
|
||||
print("-----------------------------------")
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
opt,filenames = ecoParseOptions(sys.argv[1:])
|
||||
|
||||
taxonomy = readTaxonomyDump(opt['taxdir'])
|
||||
|
||||
ecoDBWriter(opt['prefix'], taxonomy, filenames, opt['parser'])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Designing new barcodes on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/ecoprimers/</link>
|
||||
<description>Recent content in Designing new barcodes on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/ecoprimers/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 168 KiB |
@@ -1,103 +0,0 @@
|
||||
SHELL := /bin/bash
|
||||
FTPNCBI=ftp.ncbi.nlm.nih.gov
|
||||
GBURL=https://$(FTPNCBI)/genbank
|
||||
GBRELEASE_URL=$(GBURL)/GB_Release_Number
|
||||
|
||||
TAXOURL=https://$(FTPNCBI)/pub/taxonomy/taxdump.tar.gz
|
||||
|
||||
GBRELEASE:=$(shell curl $(GBRELEASE_URL))
|
||||
|
||||
GBDIV_ALL:=$(shell curl -L ${GBURL} \
|
||||
| grep -E 'gb.+\.seq\.gz' \
|
||||
| sed -E 's@^.*<a href="gb([^0-9]+)[0-9]+\.seq.gz.*$$@\1@' \
|
||||
| sort \
|
||||
| uniq)
|
||||
|
||||
GBDIV=bct inv mam phg pln pri rod vrl vrt
|
||||
DIRECTORIES=fasta fasta_fgs
|
||||
|
||||
GBFILE_ALL:=$(shell curl -L ${GBURL} \
|
||||
| grep -E "gb($$(tr ' ' '|' <<< "${GBDIV}"))[0-9]+" \
|
||||
| sed -E 's@^<a href="(gb.+.seq.gz)">.*$$@\1@')
|
||||
|
||||
|
||||
SUFFIXES += .d
|
||||
NODEPS:=clean taxonomy
|
||||
DEPFILES:=$(wildcard Release_$(GBRELEASE)/depends/*.d)
|
||||
|
||||
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
|
||||
#Chances are, these files don't exist. GMake will create them and
|
||||
#clean up automatically afterwards
|
||||
-include $(DEPFILES)
|
||||
endif
|
||||
|
||||
|
||||
all: depends directories FORCE
|
||||
@make downloads
|
||||
|
||||
downloads: taxonomy fasta_files
|
||||
@echo Genbank Release number $(GBRELEASE)
|
||||
@echo all divisions : $(GBDIV_ALL)
|
||||
|
||||
FORCE:
|
||||
@sleep 1
|
||||
|
||||
.PHONY: all directories depends taxonomy fasta_files FORCE
|
||||
|
||||
depends: directories Release_$(GBRELEASE)/depends/gbfiles.d Makefile
|
||||
|
||||
division: $(GBDIV)
|
||||
|
||||
taxonomy: directories Release_$(GBRELEASE)/taxonomy
|
||||
|
||||
directories: Release_$(GBRELEASE)/fasta Release_$(GBRELEASE)/stamp Release_$(GBRELEASE)/tmp
|
||||
|
||||
Release_$(GBRELEASE):
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/fasta: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/stamp: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/tmp: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/depends/gbfiles.d: Makefile
|
||||
@echo Create depends directory
|
||||
@mkdir -p Release_$(GBRELEASE)/depends
|
||||
@for f in ${GBFILE_ALL} ; do \
|
||||
echo -e "Release_$(GBRELEASE)/stamp/$$f.stamp:" ; \
|
||||
echo -e "\t@echo Downloading file : $$f..." ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/tmp" ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/stamp" ; \
|
||||
echo -e "\t@curl -L ${GBURL}/$$f > Release_$(GBRELEASE)/tmp/$$f && touch \$$@" ; \
|
||||
echo ; \
|
||||
div=$$(sed -E 's@^gb(...).*$$@\1@' <<< $$f) ; \
|
||||
fasta="Release_$(GBRELEASE)/fasta/$$div/$${f/.seq.gz/.fasta.gz}" ; \
|
||||
fasta_fgs="Release_$(GBRELEASE)/fasta_fgs/$$div/$${f/.seq.gz/.fasta.gz}" ; \
|
||||
fasta_files="$$fasta_files $$fasta" ; \
|
||||
fasta_fgs_files="$$fasta_fgs_files $$fasta_fgs" ; \
|
||||
echo -e "$$fasta: Release_$(GBRELEASE)/stamp/$$f.stamp" ; \
|
||||
echo -e "\t@echo converting file : \$$< in fasta" ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/fasta/$$div" ; \
|
||||
echo -e "\t@obiconvert -Z --fasta-output --skip-empty \\" ; \
|
||||
echo -e "\t Release_$(GBRELEASE)/tmp/$$f > Release_$(GBRELEASE)/tmp/$${f/.seq.gz/.fasta.gz} \\" ; \
|
||||
echo -e "\t && mv Release_$(GBRELEASE)/tmp/$${f/.seq.gz/.fasta.gz} \$$@ \\" ; \
|
||||
echo -e "\t && rm -f Release_$(GBRELEASE)/tmp/$$f \\" ; \
|
||||
echo -e "\t || rm -f \$$@" ; \
|
||||
echo -e "\t@echo conversion of $$@ done." ; \
|
||||
echo ; \
|
||||
done > $@ ; \
|
||||
echo >> $@ ; \
|
||||
echo "fasta_files: $$fasta_files" >> $@ ;
|
||||
|
||||
Release_$(GBRELEASE)/taxonomy:
|
||||
mkdir -p $@
|
||||
curl -iL $(TAXOURL) \
|
||||
| tar -C $@ -zxf -
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Analysing an Illumina data set on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/illumina/</link>
|
||||
<description>Recent content in Analysing an Illumina data set on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/illumina/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
>HELIUM_000100422_612GNAAXX:7:118:3572:14633#0/1_sub[28..126] {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:99:9351:13090#0/1_sub[28..127] {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:10111:9078#0/1_sub[28..127] {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:38:14204:12725#0/1_sub[28..126] {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:98:16207:5869#0/1_sub[78..81] {"count":2007,"merged_sample":{"29a_F260619":2007},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":2021}}
|
||||
tttt
|
||||
>HELIUM_000100422_612GNAAXX:7:30:9942:4495#0/1_sub[28..126] {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:51:16702:19393#0/1_sub[28..127] {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_head":true,"obiclean_headcount":2,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":0,"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127] {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376}}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126] {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":4,"obiclean_singletoncount":3,"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
||||
>HELIUM_000100422_612GNAAXX:7:118:3572:14633#0/1_sub[28..126] {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:99:9351:13090#0/1_sub[28..127] {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:10111:9078#0/1_sub[28..127] {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:38:14204:12725#0/1_sub[28..126] {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:30:9942:4495#0/1_sub[28..126] {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:51:16702:19393#0/1_sub[28..127] {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_head":true,"obiclean_headcount":2,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":0,"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127] {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376}}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126] {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":4,"obiclean_singletoncount":3,"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
@@ -1,329 +0,0 @@
|
||||
>HELIUM_000100422_612GNAAXX:7:56:19300:10949#0/1_sub[28..127] {"count":37,"merged_sample":{"29a_F260619":37},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":43}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:63:4595:15643#0/1_sub[28..126] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":4}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagtactaccggcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:7:8807:7823#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtcataccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:19171:11413#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":1,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":1,"obiclean_mutation":{"HELIUM_000100422_612GNAAXX:7:8:6794:4925#0/1_sub[28..127]":"(t)->(g)@38"},"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"i","29a_F260619":"s"},"obiclean_weight":{"15a_F730814":1,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattaatataacaaaagtagtcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:44:5008:2115#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:53:16956:10563#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":4}}
|
||||
ttagccctaaacataaacattcaataaacaaggatgttcgcaagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:54:10323:7022#0/1_sub[28..127] {"count":3,"merged_sample":{"13a_F730603":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":7}}
|
||||
ttagccctaaacacaaataattatataaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:45:7460:13396#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatgcccgt
|
||||
>HELIUM_000100422_612GNAAXX:7:58:8409:9911#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaacattcaataaacaaaataattcgccagaggactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:118:3572:14633#0/1_sub[28..126] {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:100:18844:15930#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":2}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaagcgcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:29:9723:20435#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":4}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:43:4660:16319#0/1_sub[28..126] {"count":22,"merged_sample":{"26a_F040644":22},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":42}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:103:11045:3860#0/1_sub[28..127] {"count":4,"merged_sample":{"15a_F730814":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":4}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaagggcttggcggtgctttatgccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:67:10944:19430#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgtcagagtactaccggcaat
|
||||
agcttaaaactcaaaggacgtggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:56:6962:17278#0/1_sub[28..126] {"count":4,"merged_sample":{"26a_F040644":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":7}}
|
||||
ttagccctaaacataaacattcaataaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:60:13553:20530#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":1,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":2,"obiclean_status":{"15a_F730814":"s","29a_F260619":"s"},"obiclean_weight":{"15a_F730814":1,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
atgttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:35:13167:18371#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccggagaactactaggaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:105:1895:7593#0/1_sub[28..127] {"count":11,"merged_sample":{"29a_F260619":11},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":13}}
|
||||
ttagccctaaacctcaacagttaaatcaacaaaactgctcgccagaacactacgagccac
|
||||
agcttaaaactcaaaggacctggcggtgcttcatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:118:15661:12736#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":2}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattatccgcaagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:30:8391:13152#0/1_sub[28..127] {"count":17,"merged_sample":{"13a_F730603":17},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":25}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaac
|
||||
agcccaaaactcaaaggacttggcggtgcttcacaccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:95:14375:10838#0/1_sub[28..127] {"count":4,"merged_sample":{"29a_F260619":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":5}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:82:13334:18499#0/1_sub[28..127] {"count":6,"merged_sample":{"29a_F260619":6},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":10}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:11272:1128#0/1_sub[28..127] {"count":2,"merged_sample":{"13a_F730603":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":2}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:7:6016:14767#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":4}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtacgtctagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:99:9351:13090#0/1_sub[28..127] {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:9:8337:12329#0/1_sub[28..126] {"count":5,"merged_sample":{"26a_F040644":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":6}}
|
||||
ttagccctaaacataaacagtcaataaacaaggatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:15:12854:18952#0/1_sub[28..126] {"count":10,"merged_sample":{"29a_F260619":10},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":16}}
|
||||
ttagccctaaacataagctattccataacaaaattattcgccagagtactaccggcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:1:4513:20277#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaaccattctataacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:57:18237:6765#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattatgcgccagagtactgccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:10111:9078#0/1_sub[28..127] {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:119:8691:15994#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":2}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcgat
|
||||
agcttaaaacgcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:6:1739:11421#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgctagagtactactagcaaca
|
||||
gcctgacactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:73:17136:17728#0/1_sub[28..127] {"count":6,"merged_sample":{"13a_F730603":6},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":7}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaattattcgccagagtactaccggcaac
|
||||
agcccaaaactcaaaggacttggcggtgcttcacaccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:76:9874:3117#0/1_sub[28..127] {"count":9,"merged_sample":{"29a_F260619":9},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":12}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:38:14204:12725#0/1_sub[28..126] {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:18:16679:15889#0/1_sub[28..127] {"count":4,"merged_sample":{"29a_F260619":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":4}}
|
||||
ttagccctaaacctcaacagttaaatcaacaaaactgctcgccagaacactacgagccac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:52:6908:8410#0/1_sub[28..126] {"count":5,"merged_sample":{"26a_F040644":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":10}}
|
||||
ttagccctaaacataagctattctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:71:13461:7411#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagaagactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:98:16207:5869#0/1_sub[78..81] {"count":2007,"merged_sample":{"29a_F260619":2007},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":2021}}
|
||||
tttt
|
||||
>HELIUM_000100422_612GNAAXX:7:47:6989:13864#0/1_sub[28..126] {"count":3,"merged_sample":{"26a_F040644":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaaccattctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:72:8941:18482#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggtggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:25:10818:13742#0/1_sub[28..133] {"count":8,"merged_sample":{"26a_F040644":8},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":8}}
|
||||
ttagccctaaacgtaaactgcaaactattccataataaaataattcgcccaagaactact
|
||||
agcaacagcttaaaactcaaaggacttggtggtgctttctacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:70:11509:6042#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":2}}
|
||||
ttagccctaaacacaagaaattaatataacaaaaatattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:30:9942:4495#0/1_sub[28..126] {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:46:4342:17317#0/1_sub[28..126] {"count":5,"merged_sample":{"26a_F040644":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":8}}
|
||||
ttagccctaaacataaatcattctataacaaaataattcgccggagaactactaggaaca
|
||||
gcttaaaactcaaaggacttggcggtgccttacgtccct
|
||||
>HELIUM_000100422_612GNAAXX:7:111:17844:17230#0/1_sub[28..126] {"count":13,"merged_sample":{"26a_F040644":13},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":17}}
|
||||
ttagccctaaacataaatcagtctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacgtggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:34:17680:16952#0/1_sub[28..127] {"count":15,"merged_sample":{"13a_F730603":15},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":15}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgcttcacaccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:34:2640:2539#0/1_sub[28..127] {"count":19,"merged_sample":{"29a_F260619":19},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":25}}
|
||||
ttagccctaaacacaaataattacacaaacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:71:18891:9661#0/1_sub[28..126] {"count":3,"merged_sample":{"26a_F040644":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaatcagtctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacgtggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:26:16553:1613#0/1_sub[77..81] {"count":38,"merged_sample":{"13a_F730603":38},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":38}}
|
||||
caata
|
||||
>HELIUM_000100422_612GNAAXX:7:45:5732:11220#0/1_sub[28..126] {"count":3,"merged_sample":{"26a_F040644":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggtggtgctttctacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:1:14254:1103#0/1_sub[28..126] {"count":8,"merged_sample":{"26a_F040644":8},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":11}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:50:17151:20608#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:96:13203:2879#0/1_sub[28..127] {"count":5,"merged_sample":{"13a_F730603":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":6}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaac
|
||||
agcccaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:78:18041:18996#0/1_sub[28..126] {"count":13,"merged_sample":{"13a_F730603":9,"15a_F730814":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":2,"obiclean_status":{"13a_F730603":"s","15a_F730814":"s"},"obiclean_weight":{"13a_F730603":9,"15a_F730814":4}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:80:18387:10166#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":1,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":1,"obiclean_mutation":{"HELIUM_000100422_612GNAAXX:7:100:14685:15065#0/1_sub[28..127]":"(a)->(t)@24","HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127]":"(t)->(g)@71"},"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s","29a_F260619":"i"},"obiclean_weight":{"15a_F730814":1,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaacgcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:54:10113:12172#0/1_sub[28..127] {"count":7,"merged_sample":{"15a_F730814":4,"29a_F260619":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":2,"obiclean_status":{"15a_F730814":"s","29a_F260619":"s"},"obiclean_weight":{"15a_F730814":5,"29a_F260619":4}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:97:17822:18365#0/1_sub[28..127] {"count":3,"merged_sample":{"29a_F260619":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":4}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactgccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatcccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:87:6328:12406#0/1_sub[28..126] {"count":6,"merged_sample":{"26a_F040644":6},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":8}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:7:4611:13145#0/1_sub[28..127] {"count":3,"merged_sample":{"13a_F730603":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":4}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtacgtccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:51:16702:19393#0/1_sub[28..127] {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_head":true,"obiclean_headcount":2,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":0,"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:78:6346:5817#0/1_sub[28..127] {"count":5,"merged_sample":{"13a_F730603":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":5}}
|
||||
ttagccctaaacacaaataattatataaacaaaattattcgccagagtactaccggcaac
|
||||
agcccaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:7:15122:17310#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":1,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":1,"obiclean_mutation":{"HELIUM_000100422_612GNAAXX:7:94:6384:20392#0/1_sub[28..127]":"(a)->(t)@52"},"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"i","29a_F260619":"s"},"obiclean_weight":{"15a_F730814":1,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtacttcctgcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:27:7695:17738#0/1_sub[28..126] {"count":7,"merged_sample":{"26a_F040644":7},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":11}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:48:15379:13773#0/1_sub[28..126] {"count":5,"merged_sample":{"26a_F040644":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":5}}
|
||||
ttagccctaaacatagataattttacaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:117:16246:17184#0/1_sub[28..127] {"count":5,"merged_sample":{"13a_F730603":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":10}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagaggactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:87:11044:6323#0/1_sub[28..126] {"count":69,"merged_sample":{"26a_F040644":69},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":84}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:40:12248:18615#0/1_sub[28..126] {"count":4,"merged_sample":{"26a_F040644":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":4}}
|
||||
ttagccctaaacataagctattctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:7:6470:13562#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":2}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtacctccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:72:11850:15705#0/1_sub[28..126] {"count":4,"merged_sample":{"26a_F040644":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":4}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:82:8566:4827#0/1_sub[28..126] {"count":6,"merged_sample":{"26a_F040644":6},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":9}}
|
||||
ttagccctaaacataaacattcaataaacaaggatgttcgcaagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggtggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:43:16297:17399#0/1_sub[28..127] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":3}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattgttcaccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:7:15117:2564#0/1_sub[28..127] {"count":2,"merged_sample":{"13a_F730603":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":2}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtacctccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:90:4058:17862#0/1_sub[28..127] {"count":4,"merged_sample":{"13a_F730603":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":5}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagaggactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:43:13909:1377#0/1_sub[28..126] {"count":10,"merged_sample":{"26a_F040644":10},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":14}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:36:3584:21256#0/1_sub[28..127] {"count":2,"merged_sample":{"13a_F730603":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":2}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaagctattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatgccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:80:13357:2959#0/1_sub[74..81] {"count":12,"merged_sample":{"29a_F260619":12},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":12}}
|
||||
ccgatagg
|
||||
>HELIUM_000100422_612GNAAXX:7:70:8097:4516#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaagaaacaagaatgttcaccagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggcagtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:7:8746:5790#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtacctctagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:8:9165:18915#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactatgaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:85:7323:6139#0/1_sub[28..126] {"count":9,"merged_sample":{"26a_F040644":9},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":16}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:23:6103:3418#0/1_sub[28..126] {"count":3,"merged_sample":{"26a_F040644":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":4}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:107:2103:10677#0/1_sub[28..127] {"count":20,"merged_sample":{"13a_F730603":20},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":22}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:1:15993:20360#0/1_sub[28..127] {"count":4,"merged_sample":{"13a_F730603":4},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":4}}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactacctgcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatgccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:103:1205:6990#0/1_sub[28..127] {"count":2,"merged_sample":{"13a_F730603":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":2}}
|
||||
ttagccctaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:111:2380:10482#0/1_sub[28..126] {"count":2,"merged_sample":{"29a_F260619":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":2}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:76:10530:11312#0/1_sub[28..126] {"count":43,"merged_sample":{"26a_F040644":43},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":69}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:40:15984:4911#0/1_sub[28..126] {"count":16,"merged_sample":{"26a_F040644":16},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":30}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:109:19171:17424#0/1_sub[28..126] {"count":2,"merged_sample":{"13a_F730603":1,"26a_F040644":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":1,"obiclean_mutation":{"HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126]":"(a)->(t)@51"},"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s","26a_F040644":"i"},"obiclean_weight":{"13a_F730603":1,"26a_F040644":1}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggacttctagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:77:17898:19592#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":1,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":2,"obiclean_status":{"15a_F730814":"s","29a_F260619":"s"},"obiclean_weight":{"15a_F730814":1,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattaatataacaaaataattcgccagaggactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:32:4908:16517#0/1_sub[78..81] {"count":7,"merged_sample":{"29a_F260619":7},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":7}}
|
||||
ccgc
|
||||
>HELIUM_000100422_612GNAAXX:7:100:8022:19461#0/1_sub[28..127] {"count":5,"merged_sample":{"29a_F260619":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":11}}
|
||||
ttagccctaaacacaagtaattaatataacaaaataattcgccagagaactactagcaac
|
||||
agattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:59:2390:15297#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaaggatgttcgcaagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:98:10839:20244#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":2}}
|
||||
ttagccctaaacataaacattcaataaacaaggatgttcgccagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:34:13086:6440#0/1_sub[28..127] {"count":14,"merged_sample":{"13a_F730603":14},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":18}}
|
||||
ttagccctaaacacaaataattatataaacaaaattattcgccagagtactaccggcaac
|
||||
agcccaaaactcaaaggacttggcggtgcttcacaccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:73:10944:14101#0/1_sub[28..127] {"count":2,"merged_sample":{"13a_F730603":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"13a_F730603":"s"},"obiclean_weight":{"13a_F730603":3}}
|
||||
ttagccctaaacacaaataattatataaacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:61:17561:21218#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaatcattctataacaaaataattcgccggagaactactaggaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:93:7569:17305#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaatcagtctataacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:55:11954:15731#0/1_sub[28..126] {"count":6,"merged_sample":{"29a_F260619":6},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":7}}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127] {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376}}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:54:15067:12524#0/1_sub[28..126] {"count":26,"merged_sample":{"26a_F040644":26},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":49}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:6:10451:2548#0/1_sub[28..126] {"count":12,"merged_sample":{"26a_F040644":12},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":15}}
|
||||
ttagccctaaacataaacagtcaataaacaaggatgttcgccagagtactactagcaatg
|
||||
gcctaaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:23:10872:20213#0/1_sub[28..126] {"count":2,"merged_sample":{"26a_F040644":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":3}}
|
||||
ttagccctaaacataaatcattctataacaaaataattcgccggagaactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgccttacgtccct
|
||||
>HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126] {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":4,"obiclean_singletoncount":3,"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1}}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:98:6034:5203#0/1_sub[28..127] {"count":3,"merged_sample":{"29a_F260619":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":4}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:70:2429:19509#0/1_sub[28..126] {"count":5,"merged_sample":{"26a_F040644":5},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":5}}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgccttacgtccct
|
||||
>HELIUM_000100422_612GNAAXX:7:65:1843:2567#0/1_sub[28..126] {"count":7,"merged_sample":{"26a_F040644":7},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s"},"obiclean_weight":{"26a_F040644":11}}
|
||||
ttagccctaaacataaaccattctataacaaaataattcgccagagaactactagcaaca
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:92:1339:19811#0/1_sub[28..127] {"count":3,"merged_sample":{"29a_F260619":3},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"29a_F260619":"s"},"obiclean_weight":{"29a_F260619":3}}
|
||||
ttagccctaaacacaagtaattacacaaacaaaattgttcacaagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:15:13855:1746#0/1_sub[28..127] {"count":3,"merged_sample":{"15a_F730814":2,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":1,"obiclean_mutation":{"HELIUM_000100422_612GNAAXX:7:7:14405:19348#0/1_sub[28..127]":"(t)->(g)@51"},"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s","29a_F260619":"i"},"obiclean_weight":{"15a_F730814":3,"29a_F260619":1}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtgcgaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:7:7092:11003#0/1_sub[28..127] {"count":2,"merged_sample":{"15a_F730814":2},"obiclean_head":true,"obiclean_headcount":0,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":1,"obiclean_status":{"15a_F730814":"s"},"obiclean_weight":{"15a_F730814":2}}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtacgtccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
@@ -1,24 +0,0 @@
|
||||
>HELIUM_000100422_612GNAAXX:7:118:3572:14633#0/1_sub[28..126] {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205},"obitag_bestid":0.9797979797979798,"obitag_bestmatch":"AY227529","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","taxid":"taxon:9992 [Marmota]@genus"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:99:9351:13090#0/1_sub[28..127] {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337},"obitag_bestid":0.9405940594059405,"obitag_bestmatch":"AF154263","obitag_match_count":9,"obitag_rank":"infraorder","obitag_similarity_method":"lcs","taxid":"taxon:35500 [Pecora]@infraorder"}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:10111:9078#0/1_sub[28..127] {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039},"obitag_bestid":1,"obitag_bestmatch":"AB245427","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9860 [Cervus elaphus]@species"}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:38:14204:12725#0/1_sub[28..126] {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202},"obitag_bestid":0.9494949494949495,"obitag_bestmatch":"AY227530","obitag_match_count":2,"obitag_rank":"tribe","obitag_similarity_method":"lcs","taxid":"taxon:337730 [Marmotini]@tribe"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:30:9942:4495#0/1_sub[28..126] {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":1,"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105},"obitag_bestid":0.9595959595959596,"obitag_bestmatch":"AC187326","obitag_match_count":1,"obitag_rank":"subspecies","obitag_similarity_method":"lcs","taxid":"taxon:9615 [Canis lupus familiaris]@subspecies"}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:51:16702:19393#0/1_sub[28..127] {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_head":true,"obiclean_headcount":2,"obiclean_internalcount":0,"obiclean_samplecount":2,"obiclean_singletoncount":0,"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789},"obitag_bestid":1,"obitag_bestmatch":"AJ885202","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127] {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":1,"obiclean_singletoncount":0,"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376},"obitag_bestid":1,"obitag_bestmatch":"AJ972683","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126] {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_head":true,"obiclean_headcount":1,"obiclean_internalcount":0,"obiclean_samplecount":4,"obiclean_singletoncount":3,"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1},"obitag_bestid":1,"obitag_bestmatch":"AB048590","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","taxid":"taxon:9611 [Canis]@genus"}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
@@ -1,24 +0,0 @@
|
||||
>seq0001 {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205},"obitag_bestid":0.9797979797979798,"obitag_bestmatch":"AY227529","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","seq_number":1,"taxid":"taxon:9992 [Marmota]@genus"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>seq0002 {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337},"obitag_bestid":0.9405940594059405,"obitag_bestmatch":"AF154263","obitag_match_count":9,"obitag_rank":"infraorder","obitag_similarity_method":"lcs","seq_number":2,"taxid":"taxon:35500 [Pecora]@infraorder"}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>seq0003 {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039},"obitag_bestid":1,"obitag_bestmatch":"AB245427","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","seq_number":3,"taxid":"taxon:9860 [Cervus elaphus]@species"}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>seq0004 {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202},"obitag_bestid":0.9494949494949495,"obitag_bestmatch":"AY227530","obitag_match_count":2,"obitag_rank":"tribe","obitag_similarity_method":"lcs","seq_number":4,"taxid":"taxon:337730 [Marmotini]@tribe"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>seq0005 {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105},"obitag_bestid":0.9595959595959596,"obitag_bestmatch":"AC187326","obitag_match_count":1,"obitag_rank":"subspecies","obitag_similarity_method":"lcs","seq_number":5,"taxid":"taxon:9615 [Canis lupus familiaris]@subspecies"}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>seq0006 {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789},"obitag_bestid":1,"obitag_bestmatch":"AJ885202","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","seq_number":6,"taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>seq0007 {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376},"obitag_bestid":1,"obitag_bestmatch":"AJ972683","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","seq_number":7,"taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>seq0008 {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1},"obitag_bestid":1,"obitag_bestmatch":"AB048590","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","seq_number":8,"taxid":"taxon:9611 [Canis]@genus"}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
@@ -1,9 +0,0 @@
|
||||
id,count,obitag_bestid,obitag_bestmatch,obitag_match_count,obitag_rank,obitag_similarity_method,seq_number,taxid,sequence
|
||||
seq0001,10172,0.9797979797979798,AY227529,1,genus,lcs,1,taxon:9992 [Marmota]@genus,ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaacagcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
seq0002,260,0.9405940594059405,AF154263,9,infraorder,lcs,2,taxon:35500 [Pecora]@infraorder,ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaacagcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
seq0003,7146,1,AB245427,1,species,lcs,3,taxon:9860 [Cervus elaphus]@species,ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaatagcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
seq0004,87,0.9494949494949495,AY227530,2,tribe,lcs,4,taxon:337730 [Marmotini]@tribe,ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaatagcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
seq0005,95,0.9595959595959596,AC187326,1,subspecies,lcs,5,taxon:9615 [Canis lupus familiaris]@subspecies,ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaacagattaaacctcaaaggacttggcagtgctttatacccct
|
||||
seq0006,12004,1,AJ885202,1,species,lcs,6,taxon:9858 [Capreolus capreolus]@species,ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaatagcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
seq0007,319,1,AJ972683,1,species,lcs,7,taxon:9858 [Capreolus capreolus]@species,ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaatagcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
seq0008,366,1,AB048590,1,genus,lcs,8,taxon:9611 [Canis]@genus,ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaatagcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
|
@@ -1,6 +0,0 @@
|
||||
id,seq0001,seq0002,seq0003,seq0004,seq0005,seq0006,seq0007,seq0008
|
||||
29a_F260619,0,337,0,0,105,5789,376,1
|
||||
15a_F730814,0,0,0,0,0,8822,0,5
|
||||
13a_F730603,0,0,8039,0,0,0,0,17
|
||||
26a_F040644,12205,0,0,202,12,0,0,468
|
||||
|
||||
|
@@ -1,24 +0,0 @@
|
||||
>HELIUM_000100422_612GNAAXX:7:118:3572:14633#0/1_sub[28..126] {"count":10172,"merged_sample":{"26a_F040644":10172},"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":12205},"obitag_bestid":0.9797979797979798,"obitag_bestmatch":"AY227529","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","taxid":"taxon:9992 [Marmota]@genus"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagagtactactagcaaca
|
||||
gcctgaaactcaaaggacttggcggtgctttacatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:99:9351:13090#0/1_sub[28..127] {"count":260,"merged_sample":{"29a_F260619":260},"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":337},"obitag_bestid":0.9405940594059405,"obitag_bestmatch":"AF154263","obitag_match_count":9,"obitag_rank":"infraorder","obitag_similarity_method":"lcs","taxid":"taxon:35500 [Pecora]@infraorder"}
|
||||
ttagccctaaacacaaataattacacaaacaaaattgttcaccagagtactagcggcaac
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:108:10111:9078#0/1_sub[28..127] {"count":7146,"merged_sample":{"13a_F730603":7146},"obiclean_status":{"13a_F730603":"h"},"obiclean_weight":{"13a_F730603":8039},"obitag_bestid":1,"obitag_bestmatch":"AB245427","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9860 [Cervus elaphus]@species"}
|
||||
ctagccttaaacacaaatagttatgcaaacaaaactattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:38:14204:12725#0/1_sub[28..126] {"count":87,"merged_sample":{"26a_F040644":87},"obiclean_status":{"26a_F040644":"h"},"obiclean_weight":{"26a_F040644":202},"obitag_bestid":0.9494949494949495,"obitag_bestmatch":"AY227530","obitag_match_count":2,"obitag_rank":"tribe","obitag_similarity_method":"lcs","taxid":"taxon:337730 [Marmotini]@tribe"}
|
||||
ttagccctaaacataaacattcaataaacaagaatgttcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>HELIUM_000100422_612GNAAXX:7:30:9942:4495#0/1_sub[28..126] {"count":95,"merged_sample":{"26a_F040644":11,"29a_F260619":84},"obiclean_status":{"26a_F040644":"s","29a_F260619":"h"},"obiclean_weight":{"26a_F040644":12,"29a_F260619":105},"obitag_bestid":0.9595959595959596,"obitag_bestmatch":"AC187326","obitag_match_count":1,"obitag_rank":"subspecies","obitag_similarity_method":"lcs","taxid":"taxon:9615 [Canis lupus familiaris]@subspecies"}
|
||||
ttagccctaaacataagctattccataacaaaataattcgccagagaactactagcaaca
|
||||
gattaaacctcaaaggacttggcagtgctttatacccct
|
||||
>HELIUM_000100422_612GNAAXX:7:51:16702:19393#0/1_sub[28..127] {"count":12004,"merged_sample":{"15a_F730814":7465,"29a_F260619":4539},"obiclean_status":{"15a_F730814":"h","29a_F260619":"h"},"obiclean_weight":{"15a_F730814":8822,"29a_F260619":5789},"obitag_bestid":1,"obitag_bestmatch":"AJ885202","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:84:14502:1617#0/1_sub[28..127] {"count":319,"merged_sample":{"29a_F260619":319},"obiclean_status":{"29a_F260619":"h"},"obiclean_weight":{"29a_F260619":376},"obitag_bestid":1,"obitag_bestmatch":"AJ972683","obitag_match_count":1,"obitag_rank":"species","obitag_similarity_method":"lcs","taxid":"taxon:9858 [Capreolus capreolus]@species"}
|
||||
ttagccctaaacacaagtaattattataacaaaattattcgccagagtactaccggcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttataccctt
|
||||
>HELIUM_000100422_612GNAAXX:7:50:10637:6527#0/1_sub[28..126] {"count":366,"merged_sample":{"13a_F730603":13,"15a_F730814":5,"26a_F040644":347,"29a_F260619":1},"obiclean_status":{"13a_F730603":"s","15a_F730814":"s","26a_F040644":"h","29a_F260619":"s"},"obiclean_weight":{"13a_F730603":17,"15a_F730814":5,"26a_F040644":468,"29a_F260619":1},"obitag_bestid":1,"obitag_bestmatch":"AB048590","obitag_match_count":1,"obitag_rank":"genus","obitag_similarity_method":"lcs","taxid":"taxon:9611 [Canis]@genus"}
|
||||
ttagccctaaacatagataattttacaacaaaataattcgccagaggactactagcaata
|
||||
gcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Cookbook on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/</link>
|
||||
<description>Recent content in Cookbook on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,102 +0,0 @@
|
||||
SHELL := /bin/bash
|
||||
FTPNCBI=ftp.ncbi.nlm.nih.gov
|
||||
GBURL=https://$(FTPNCBI)/genbank
|
||||
GBRELEASE_URL=$(GBURL)/GB_Release_Number
|
||||
|
||||
TAXOURL=https://$(FTPNCBI)/pub/taxonomy/taxdump.tar.gz
|
||||
|
||||
GBRELEASE:=$(shell curl $(GBRELEASE_URL))
|
||||
|
||||
GBDIV_ALL:=$(shell curl -L ${GBURL} \
|
||||
| grep -E 'gb.+\.seq\.gz' \
|
||||
| sed -E 's@^.*<a href="gb([^0-9]+)[0-9]+\.seq.gz.*$$@\1@' \
|
||||
| sort \
|
||||
| uniq)
|
||||
|
||||
GBDIV=bct inv mam phg pln pri rod vrl vrt
|
||||
DIRECTORIES=fasta fasta_fgs
|
||||
|
||||
GBFILE_ALL:=$(shell curl -L ${GBURL} \
|
||||
| grep -E "gb($$(tr ' ' '|' <<< "${GBDIV}"))[0-9]+" \
|
||||
| sed -E 's@^<a href="(gb.+.seq.gz)">.*$$@\1@')
|
||||
|
||||
|
||||
SUFFIXES += .d
|
||||
NODEPS:=clean taxonomy
|
||||
DEPFILES:=$(wildcard Release_$(GBRELEASE)/depends/*.d)
|
||||
|
||||
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
|
||||
#Chances are, these files don't exist. GMake will create them and
|
||||
#clean up automatically afterwards
|
||||
-include $(DEPFILES)
|
||||
endif
|
||||
|
||||
|
||||
all: depends directories FORCE
|
||||
@make downloads
|
||||
|
||||
downloads: taxonomy fasta_files
|
||||
@echo Genbank Release number $(GBRELEASE)
|
||||
@echo all divisions : $(GBDIV_ALL)
|
||||
|
||||
FORCE:
|
||||
|
||||
.PHONY: all directories depends taxonomy fasta_files FORCE
|
||||
|
||||
depends: directories Release_$(GBRELEASE)/depends/gbfiles.d Makefile
|
||||
|
||||
division: $(GBDIV)
|
||||
|
||||
taxonomy: directories Release_$(GBRELEASE)/taxonomy
|
||||
|
||||
directories: Release_$(GBRELEASE)/fasta Release_$(GBRELEASE)/stamp Release_$(GBRELEASE)/tmp
|
||||
|
||||
Release_$(GBRELEASE):
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/fasta: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/stamp: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/tmp: Release_$(GBRELEASE)
|
||||
@mkdir -p $@
|
||||
@echo Create $@ directory
|
||||
|
||||
Release_$(GBRELEASE)/depends/gbfiles.d: Makefile
|
||||
@echo Create depends directory
|
||||
@mkdir -p Release_$(GBRELEASE)/depends
|
||||
@for f in ${GBFILE_ALL} ; do \
|
||||
echo -e "Release_$(GBRELEASE)/stamp/$$f.stamp:" ; \
|
||||
echo -e "\t@echo Downloading file : $$f..." ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/tmp" ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/stamp" ; \
|
||||
echo -e "\t@curl -L ${GBURL}/$$f > Release_$(GBRELEASE)/tmp/$$f && touch \$$@" ; \
|
||||
echo ; \
|
||||
div=$$(sed -E 's@^gb(...).*$$@\1@' <<< $$f) ; \
|
||||
fasta="Release_$(GBRELEASE)/fasta/$$div/$${f/.seq.gz/.fasta.gz}" ; \
|
||||
fasta_fgs="Release_$(GBRELEASE)/fasta_fgs/$$div/$${f/.seq.gz/.fasta.gz}" ; \
|
||||
fasta_files="$$fasta_files $$fasta" ; \
|
||||
fasta_fgs_files="$$fasta_fgs_files $$fasta_fgs" ; \
|
||||
echo -e "$$fasta: Release_$(GBRELEASE)/stamp/$$f.stamp" ; \
|
||||
echo -e "\t@echo converting file : \$$< in fasta" ; \
|
||||
echo -e "\t@mkdir -p Release_$(GBRELEASE)/fasta/$$div" ; \
|
||||
echo -e "\t@obiconvert -Z --fasta-output --skip-empty \\" ; \
|
||||
echo -e "\t Release_$(GBRELEASE)/tmp/$$f > Release_$(GBRELEASE)/tmp/$${f/.seq.gz/.fasta.gz} \\" ; \
|
||||
echo -e "\t && mv Release_$(GBRELEASE)/tmp/$${f/.seq.gz/.fasta.gz} \$$@ \\" ; \
|
||||
echo -e "\t && rm -f Release_$(GBRELEASE)/tmp/$$f \\" ; \
|
||||
echo -e "\t || rm -f \$$@" ; \
|
||||
echo -e "\t@echo conversion of $$@ done." ; \
|
||||
echo ; \
|
||||
done > $@ ; \
|
||||
echo >> $@ ; \
|
||||
echo "fasta_files: $$fasta_files" >> $@ ;
|
||||
|
||||
Release_$(GBRELEASE)/taxonomy:
|
||||
mkdir -p $@
|
||||
curl -iL $(TAXOURL) \
|
||||
| tar -C $@ -zxf -
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Prepare a local copy of Genbank on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/local_genbank/</link>
|
||||
<description>Recent content in Prepare a local copy of Genbank on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/local_genbank/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Oxford Nanopore data analysis on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/minion/</link>
|
||||
<description>Recent content in Oxford Nanopore data analysis on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/minion/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Build a reference database on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/cookbook/reference_db/</link>
|
||||
<description>Recent content in Build a reference database on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate></lastBuildDate>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/cookbook/reference_db/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>File formats on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/file_format/</link>
|
||||
<description>Recent content in File formats on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/file_format/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Annotation of sequences on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/file_format/sequence_files/annotations/</link>
|
||||
<description>Recent content in Annotation of sequences on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/file_format/sequence_files/annotations/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>CSV format on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/file_format/sequence_files/csv/</link>
|
||||
<description>Recent content in CSV format on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/file_format/sequence_files/csv/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,6 +0,0 @@
|
||||
>AB061527 {"count":1,"definition":"Sorex unguiculatus mitochondrial NA, complete genome.","family_name":"Soricidae","family_taxid":9376,"genus_name":"Sorex","genus_taxid":9379,"obicleandb_level":"family","obicleandb_trusted":2.2137847111025621e-13,"species_name":"Sorex unguiculatus","species_taxid":62275,"taxid":62275}
|
||||
ttagccctaaacttaggtatttaatctaacaaaaatacccgtcagagaactactagcaat
|
||||
agcttaaaactcaaaggacttggcggtgctttatatccct
|
||||
>AL355887 {"count":2,"definition":"Human chromosome 14 NA sequence BAC R-179O11 of library RPCI-11 from chromosome 14 of Homo sapiens (Human)XXKW HTG.; HTGS_ACTIVFIN.","family_name":"Hominidae","family_taxid":9604,"genus_name":"Homo","genus_taxid":9605,"obicleandb_level":"genus","obicleandb_trusted":0,"species_name":"Homo sapiens","species_taxid":9606,"taxid":9606}
|
||||
ttagccctaaactctagtagttacattaacaaaaccattcgtcagaatactacgagcaac
|
||||
agcttaaaactcaaaggacctggcagttctttatatccct
|
||||
@@ -1,8 +0,0 @@
|
||||
@HELIUM_000100422_612GNAAXX:7:108:5640:3823#0/1 {"ali_dir":"left","ali_length":62,"mode":"alignment","pairing_mismatches":{"(T:26)->(G:13)":62,"(T:34)->(G:18)":48},"score":484,"score_norm":0.968,"seq_a_single":46,"seq_ab_match":60,"seq_b_single":46}
|
||||
ccgcctcctttagataccccactatgcttagccctaaacacaagtaattaatataacaaaattgttcgccagagtactaccggcaatagcttaaaactcaaaggacttggcggtgctttatacccttctagaggagcctgttctaaggaggcgg
|
||||
+
|
||||
CCCCCCCBCCCCCCCCCCCCCCCCCCCCCCBCCCCCBCCCCCCC<CcCccbe[`F`accXV<TA\RYU\\ee_e[XZ[XEEEEEEEEEE?EEEEEEEEEEDEEEEEEECCCCCCCCCCCCCCCCCCCCCCCACCCCCACCCCCCCCCCCCCCCC
|
||||
@HELIUM_000100422_612GNAAXX:7:97:14311:19299#0/1 {"ali_dir":"left","ali_length":62,"mode":"alignment","pairing_mismatches":{"(A:02)->(G:30)":104,"(A:34)->(G:14)":64,"(C:02)->(A:30)":86,"(C:02)->(T:20)":108,"(C:27)->(G:32)":83,"(C:34)->(G:18)":57,"(T:02)->(G:26)":87,"(T:22)->(G:14)":66,"(T:29)->(G:11)":62,"(T:32)->(G:30)":48},"score":283,"score_norm":0.839,"seq_a_single":46,"seq_ab_match":52,"seq_b_single":46}
|
||||
ccgcctcctttagataccccactatgcttagccctaaacacaagtaattaatataacaaaattattcgccagagtactaccggcaagagcttaaaactcaaaggacttggcggtgctttatacccttctagaggagcctgttctaaggaggcgg
|
||||
+
|
||||
CCCCCCCCCCCCCCCCCCCCCCCBBCCC?BCCCCCBC?CCCC@@;AVA`cWeb_TYC\UIN?IDP8QJMKRPVGLQAFPPc`AbAFB5A4>AAA56A><>8>>F@A><8??@BB+<?;?C@9CCCCCC<CC=CCCCCCCCCBC?CBCCCCC@CC
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Sequence file formats on OBITools4 documentation</title>
|
||||
<link>http://metabar:8888/obidoc/docs/file_format/sequence_files/</link>
|
||||
<description>Recent content in Sequence file formats on OBITools4 documentation</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en-us</language>
|
||||
<atom:link href="http://metabar:8888/obidoc/docs/file_format/sequence_files/index.xml" rel="self" type="application/rss+xml" />
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,30 +0,0 @@
|
||||
taxid,parent,taxonomic_rank,scientific_name
|
||||
taxon:1 [root]@no rank,taxon:1 [root]@no rank,no rank,root
|
||||
taxon:131567 [cellular organisms]@no rank,taxon:1 [root]@no rank,no rank,cellular organisms
|
||||
taxon:2759 [Eukaryota]@superkingdom,taxon:131567 [cellular organisms]@no rank,superkingdom,Eukaryota
|
||||
taxon:33090 [Viridiplantae]@kingdom,taxon:2759 [Eukaryota]@superkingdom,kingdom,Viridiplantae
|
||||
taxon:35493 [Streptophyta]@phylum,taxon:33090 [Viridiplantae]@kingdom,phylum,Streptophyta
|
||||
taxon:131221 [Streptophytina]@subphylum,taxon:35493 [Streptophyta]@phylum,subphylum,Streptophytina
|
||||
taxon:3193 [Embryophyta]@clade,taxon:131221 [Streptophytina]@subphylum,clade,Embryophyta
|
||||
taxon:58023 [Tracheophyta]@clade,taxon:3193 [Embryophyta]@clade,clade,Tracheophyta
|
||||
taxon:78536 [Euphyllophyta]@clade,taxon:58023 [Tracheophyta]@clade,clade,Euphyllophyta
|
||||
taxon:58024 [Spermatophyta]@clade,taxon:78536 [Euphyllophyta]@clade,clade,Spermatophyta
|
||||
taxon:3398 [Magnoliopsida]@class,taxon:58024 [Spermatophyta]@clade,class,Magnoliopsida
|
||||
taxon:1437183 [Mesangiospermae]@clade,taxon:3398 [Magnoliopsida]@class,clade,Mesangiospermae
|
||||
taxon:71240 [eudicotyledons]@clade,taxon:1437183 [Mesangiospermae]@clade,clade,eudicotyledons
|
||||
taxon:91827 [Gunneridae]@clade,taxon:71240 [eudicotyledons]@clade,clade,Gunneridae
|
||||
taxon:1437201 [Pentapetalae]@clade,taxon:91827 [Gunneridae]@clade,clade,Pentapetalae
|
||||
taxon:71275 [rosids]@clade,taxon:1437201 [Pentapetalae]@clade,clade,rosids
|
||||
taxon:91835 [fabids]@clade,taxon:71275 [rosids]@clade,clade,fabids
|
||||
taxon:3502 [Fagales]@order,taxon:91835 [fabids]@clade,order,Fagales
|
||||
taxon:3514 [Betulaceae]@family,taxon:3502 [Fagales]@order,family,Betulaceae
|
||||
taxon:3504 [Betula]@genus,taxon:3514 [Betulaceae]@family,genus,Betula
|
||||
taxon:1685988 [Betula murrayana]@species,taxon:3504 [Betula]@genus,species,Betula murrayana
|
||||
taxon:361422 [Betula ovalifolia]@species,taxon:3504 [Betula]@genus,species,Betula ovalifolia
|
||||
taxon:1685972 [Betula x caerulea]@species,taxon:3504 [Betula]@genus,species,Betula x caerulea
|
||||
taxon:216986 [Betula schmidtii]@species,taxon:3504 [Betula]@genus,species,Betula schmidtii
|
||||
taxon:312791 [Betula michauxii]@species,taxon:3504 [Betula]@genus,species,Betula michauxii
|
||||
taxon:3015411 [Betula pamirica]@species,taxon:3504 [Betula]@genus,species,Betula pamirica
|
||||
taxon:312792 [Betula raddeana]@species,taxon:3504 [Betula]@genus,species,Betula raddeana
|
||||
taxon:216991 [Betula humilis]@species,taxon:3504 [Betula]@genus,species,Betula humilis
|
||||
taxon:2218489 [Betula ovalifolia x Betula ermanii]@species,taxon:3504 [Betula]@genus,species,Betula ovalifolia x Betula ermanii
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user