documentation updates

Former-commit-id: 39653082c9cd026299f6fcabef7446d569704e1f
This commit is contained in:
2023-08-14 15:20:02 +02:00
parent 70a77c9ec6
commit 845c76abeb
30 changed files with 4303 additions and 117 deletions

View File

@ -213,7 +213,7 @@
\begin{document}
\maketitle
\ifdefined\Shaded\renewenvironment{Shaded}{\begin{tcolorbox}[sharp corners, borderline west={3pt}{0pt}{shadecolor}, enhanced, breakable, interior hidden, frame hidden, boxrule=0pt]}{\end{tcolorbox}}\fi
\ifdefined\Shaded\renewenvironment{Shaded}{\begin{tcolorbox}[frame hidden, borderline west={3pt}{0pt}{shadecolor}, sharp corners, boxrule=0pt, enhanced, interior hidden, breakable]}{\end{tcolorbox}}\fi
\renewcommand*\contentsname{Table of contents}
{
@ -1746,47 +1746,75 @@ language}\label{function-defined-in-the-language}}
\subsection*{Instrospection functions}\label{instrospection-functions}}
\addcontentsline{toc}{subsection}{Instrospection functions}
\begin{itemize}
\tightlist
\item
\texttt{len(x)}is a generic function allowing to retreive the size of
a object. It returns the length of a sequences, the number of element
in a map like \texttt{annotations}, the number of elements in an
array. The reurned value is an \texttt{int}.
\end{itemize}
\begin{description}
\item[\textbf{\texttt{len(x)}}]
It is a generic function allowing to retreive the size of a object. It
returns the length of a sequences, the number of element in a map like
\texttt{annotations}, the number of elements in an array. The reurned
value is an \texttt{int}.
\item[\textbf{\texttt{contains(map,key)}}]
Tests if the \texttt{map} contains a value assciated to \texttt{key}
\end{description}
\hypertarget{cast-functions}{%
\subsection*{Cast functions}\label{cast-functions}}
\addcontentsline{toc}{subsection}{Cast functions}
\begin{itemize}
\tightlist
\item
\texttt{int(x)} converts if possible the \texttt{x} value to an
integer value. The function returns an \texttt{int}.
\item
\texttt{numeric(x)} converts if possible the \texttt{x} value to a
float value. The function returns a \texttt{float}.
\item
\texttt{bool(x)} converts if possible the \texttt{x} value to a
boolean value. The function returns a \texttt{bool}.
\end{itemize}
\begin{description}
\item[\textbf{\texttt{int(x)}}]
Converts if possible the \texttt{x} value to an integer value. The
function returns an \texttt{int}.
\item[\textbf{\texttt{numeric(x)}}]
Converts if possible the \texttt{x} value to a float value. The function
returns a \texttt{float}.
\item[\textbf{\texttt{bool(x)}}]
Converts if possible the \texttt{x} value to a boolean value. The
function returns a \texttt{bool}.
\end{description}
\hypertarget{string-related-functions}{%
\subsection*{String related functions}\label{string-related-functions}}
\addcontentsline{toc}{subsection}{String related functions}
\begin{itemize}
\tightlist
\item
\texttt{printf(format,...)} allows to combine several values to build
a string. \texttt{format} follows the classical C \texttt{printf}
syntax. The function returns a \texttt{string}.
\item
\texttt{subspc(x)} substitutes every space in the \texttt{x} string by
the underscore (\texttt{\_}) character. The function returns a
\texttt{string}.
\end{itemize}
\begin{description}
\item[\textbf{\texttt{printf(format,...)}}]
Allows to combine several values to build a string. \texttt{format}
follows the classical C \texttt{printf} syntax. The function returns a
\texttt{string}.
\item[\textbf{\texttt{subspc(x)}}]
substitutes every space in the \texttt{x} string by the underscore
(\texttt{\_}) character. The function returns a \texttt{string}.
\end{description}
\hypertarget{condition-function}{%
\subsection*{Condition function}\label{condition-function}}
\addcontentsline{toc}{subsection}{Condition function}
\begin{description}
\item[\textbf{\texttt{ifelse(condition,val1,val2)}}]
The \texttt{condition} value has to be a \texttt{bool} value. If it is
\texttt{true} the function returns \texttt{val1}, otherwise, it is
returning \texttt{val2}.
\end{description}
\hypertarget{sequence-analysis-related-function}{%
\subsection{Sequence analysis related
function}\label{sequence-analysis-related-function}}
\begin{description}
\item[\textbf{\texttt{composition(sequence)}}]
The nucleotide composition of the sequence is returned as as map indexed
by \texttt{a}, \texttt{c}, \texttt{g}, or \texttt{t} and each value is
the number of occurrences of that nucleotide. A fifth key
\texttt{others} accounts for all others symboles.
\item[\textbf{\texttt{gcskew(sequence)}}]
Computes the excess of g compare to c of the sequence, known as the GC
skew.
\[
Skew_{GC}=\frac{G-C}{G+C}
\]
\end{description}
\hypertarget{accessing-to-the-sequence-annotations}{%
\section{Accessing to the sequence
@ -1825,6 +1853,12 @@ methods of the \texttt{sequence} object.
THe sequence definition : \texttt{Definition()}
\end{itemize}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{sequence}\OperatorTok{.}\NormalTok{Id}\OperatorTok{()}
\end{Highlighting}
\end{Shaded}
\hypertarget{metabarcode-design-and-quality-assessment}{%
\chapter{Metabarcode design and quality
assessment}\label{metabarcode-design-and-quality-assessment}}
@ -1851,6 +1885,9 @@ Replace the \texttt{ecoPCR} original \emph{OBITools}
\hypertarget{obitag}{%
\section{\texorpdfstring{\texttt{obitag}}{obitag}}\label{obitag}}
\hypertarget{obitagpcr}{%
\section{\texorpdfstring{\texttt{obitagpcr}}{obitagpcr}}\label{obitagpcr}}
\hypertarget{computations-on-sequences}{%
\chapter{Computations on sequences}\label{computations-on-sequences}}
@ -2061,6 +2098,50 @@ Sequences can be selected on several of their caracteristics, their
length, their id, their sequence. Options allow for specifying the
condition if selection.
\textbf{Selection based on the sequence}
Sequence records can be selected according if they match or not with a
pattern. The simplest pattern is as short sequence (\emph{e.g}
\texttt{AACCTT}). But the usage of regular patterns allows for looking
for more complex pattern. As example, \texttt{A{[}TG{]}C+G} matches a
\texttt{A}, followed by a \texttt{T} or a \texttt{G}, then one or
several \texttt{C} and endly a \texttt{G}.
\begin{description}
\item[\textbf{-\/-sequence}\textbar{}\textbf{-s} \emph{PATTERN}]
Regular expression pattern to be tested against the sequence itself. The
pattern is case insensitive. A complete description of the regular
pattern grammar is available
\href{https://yourbasic.org/golang/regexp-cheat-sheet/\#cheat-sheet}{here}.
\item[\emph{Examples:}]
Selects only the sequence records that contain an \emph{EcoRI}
restriction site.
\end{description}
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}GAATTC\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
\end{Highlighting}
\end{Shaded}
: Selects only the sequence records that contain a stretch of at least
10 \texttt{A}.
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}A\{10,\}\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
\end{Highlighting}
\end{Shaded}
: Selects only the sequence records that do not contain ambiguous
nucleotides.
\begin{Shaded}
\begin{Highlighting}[]
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}\^{}[ACGT]+$\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
\end{Highlighting}
\end{Shaded}
\begin{description}
\item[\textbf{-\/-min-count} \textbar{} \textbf{-c} \emph{COUNT}]
only sequences reprensenting at least \emph{COUNT} reads will be
@ -2072,7 +2153,7 @@ only sequences reprensenting no more than \emph{COUNT} reads will be
selected. That option rely on the \texttt{count} attribute. If the
\texttt{count} attribute is not defined for a sequence record, it is
assumed equal to \(1\).
\item[Example]
\item[\emph{Examples}]
Selecting sequence records representing at least five reads in the
dataset.
\end{description}
@ -2495,25 +2576,18 @@ A function consuming a \texttt{obiiter.IBioSequence} and returning two
\chapter{Annexes}\label{annexes}}
\hypertarget{sequence-attributes}{%
\subsection{Sequence attributes}\label{sequence-attributes}}
\section{Sequence attributes}\label{sequence-attributes}}
\hypertarget{reserved-sequence-attributes}{%
\subsubsection{Reserved sequence
attributes}\label{reserved-sequence-attributes}}
\textbf{ali\_dir (\texttt{string})}
\hypertarget{ali_dir}{%
\paragraph{\texorpdfstring{\texttt{ali\_dir}}{ali\_dir}}\label{ali_dir}}
\hypertarget{type-string}{%
\subparagraph{\texorpdfstring{Type :
\texttt{string}}{Type : string}}\label{type-string}}
The attribute can contain 2 string values \texttt{"left"} or
\texttt{"right".}
\hypertarget{set-by-the-obipairing-tool}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\item
The attribute can contain 2 string values \texttt{left} or
\texttt{right}.
\end{itemize}
The alignment generated by \emph{obipairing} is a 3'-end gap free
algorithm. Two cases can occur when aligning the forward and reverse
@ -2524,46 +2598,44 @@ the paired reads overlap by their 5' ends, and the complete barcode is
sequenced by both the reads. In that later case, \texttt{ali\_dir} is
set to \emph{right}.
\hypertarget{ali_length}{%
\paragraph{\texorpdfstring{\texttt{ali\_length}}{ali\_length}}\label{ali_length}}
\textbf{ali\_length (\texttt{int})}
\hypertarget{set-by-the-obipairing-tool-1}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-1}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
Length of the aligned parts when merging forward and reverse reads
\hypertarget{count-the-number-of-sequence-occurrences}{%
\paragraph{\texorpdfstring{\texttt{count} : the number of sequence
occurrences}{count : the number of sequence occurrences}}\label{count-the-number-of-sequence-occurrences}}
\textbf{count (\texttt{int})}
\hypertarget{set-by-the-obiuniq-tool}{%
\subparagraph{\texorpdfstring{Set by the \emph{obiuniq}
tool}{Set by the obiuniq tool}}\label{set-by-the-obiuniq-tool}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obiuniq} tool
\item
Getter : method \texttt{Count()}
\item
Setter : method \texttt{SetCount(int)}
\end{itemize}
The \texttt{count} attribute indicates how-many strictly identical
sequences have been merged in a single record. It contains an integer
value. If it is absent this means that the sequence record represents a
single occurrence of the sequence.
\hypertarget{getter-method-count}{%
\subparagraph{\texorpdfstring{Getter : method
\texttt{Count()}}{Getter : method Count()}}\label{getter-method-count}}
The \texttt{count} attribute indicates how-many strictly identical reads
have been merged in a single record. It contains an integer value. If it
is absent this means that the sequence record represents a single
occurrence of the sequence.
The \texttt{Count()} method allows to access to the count attribute as
an integer value. If the \texttt{count} attribute is not defined for the
given sequence, the value \emph{1} is returned
\hypertarget{merged_}{%
\paragraph{\texorpdfstring{\texttt{merged\_*}}{merged\_*}}\label{merged_}}
\textbf{merged\_* (\texttt{map{[}string{]}int})}
\hypertarget{type-mapstringint}{%
\subparagraph{\texorpdfstring{Type :
\texttt{map{[}string{]}int}}{Type : map{[}string{]}int}}\label{type-mapstringint}}
\hypertarget{set-by-the-obiuniq-tool-1}{%
\subparagraph{\texorpdfstring{Set by the \emph{obiuniq}
tool}{Set by the obiuniq tool}}\label{set-by-the-obiuniq-tool-1}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obiuniq} tool
\end{itemize}
The \texttt{-m} option of the \emph{obiuniq} tools allows for keeping
track of the distribution of the values stored in given attribute of
@ -2574,47 +2646,98 @@ the name of the monitored attribute. If \texttt{-m} option is used with
the attribute \emph{sample}, then this attribute names
\emph{merged\_sample}.
\hypertarget{mode}{%
\paragraph{\texorpdfstring{\texttt{mode}}{mode}}\label{mode}}
\textbf{mode (\texttt{string})}
\hypertarget{set-by-the-obipairing-tool-2}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-2}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\item
The attribute can contain 2 string values \texttt{join} or
\texttt{alignment}.
\end{itemize}
\textbf{\texttt{obitag\_ref\_index}}
\textbf{obitag\_ref\_index (\texttt{map{[}string{]}string})}
\hypertarget{set-by-the-obirefidx-tool.}{%
\subparagraph{\texorpdfstring{Set by the \emph{obirefidx}
tool.}{Set by the obirefidx tool.}}\label{set-by-the-obirefidx-tool.}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obirefidx} tool.
\end{itemize}
It resumes to which taxonomic annotation a match to that sequence must
lead according to the number of differences existing between the query
sequence and the reference sequence having that tag.
\hypertarget{getter-method-count-1}{%
\subparagraph{\texorpdfstring{Getter : method
\texttt{Count()}}{Getter : method Count()}}\label{getter-method-count-1}}
\begin{Shaded}
\begin{Highlighting}[]
\FunctionTok{\{}\DataTypeTok{"0"}\FunctionTok{:}\StringTok{"9606@Homo sapiens@species"}\FunctionTok{,}
\DataTypeTok{"2"}\FunctionTok{:}\StringTok{"207598@Homininae@subfamily"}\FunctionTok{,}
\DataTypeTok{"3"}\FunctionTok{:}\StringTok{"9604@Hominidae@family"}\FunctionTok{,}
\DataTypeTok{"8"}\FunctionTok{:}\StringTok{"314295@Hominoidea@superfamily"}\FunctionTok{,}
\DataTypeTok{"10"}\FunctionTok{:}\StringTok{"9526@Catarrhini@parvorder"}\FunctionTok{,}
\DataTypeTok{"12"}\FunctionTok{:}\StringTok{"1437010@Boreoeutheria@clade"}\FunctionTok{,}
\DataTypeTok{"16"}\FunctionTok{:}\StringTok{"9347@Eutheria@clade"}\FunctionTok{,}
\DataTypeTok{"17"}\FunctionTok{:}\StringTok{"40674@Mammalia@class"}\FunctionTok{,}
\DataTypeTok{"22"}\FunctionTok{:}\StringTok{"117571@Euteleostomi@clade"}\FunctionTok{,}
\DataTypeTok{"25"}\FunctionTok{:}\StringTok{"7776@Gnathostomata@clade"}\FunctionTok{,}
\DataTypeTok{"29"}\FunctionTok{:}\StringTok{"33213@Bilateria@clade"}\FunctionTok{,}
\DataTypeTok{"30"}\FunctionTok{:}\StringTok{"6072@Eumetazoa@clade"}\FunctionTok{\}}
\end{Highlighting}
\end{Shaded}
\hypertarget{pairing_mismatches}{%
\paragraph{\texorpdfstring{\texttt{pairing\_mismatches}}{pairing\_mismatches}}\label{pairing_mismatches}}
\textbf{pairing\_mismatches (\texttt{map{[}string{]}string})}
\hypertarget{set-by-the-obipairing-tool-3}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-3}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
\hypertarget{score}{%
\paragraph{\texorpdfstring{\texttt{score}}{score}}\label{score}}
\textbf{seq\_a\_single (\texttt{int})}
\hypertarget{set-by-the-obipairing-tool-4}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-4}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
\hypertarget{score_norm}{%
\paragraph{\texorpdfstring{\texttt{score\_norm}}{score\_norm}}\label{score_norm}}
\textbf{seq\_ab\_match (\texttt{int})}
\hypertarget{set-by-the-obipairing-tool-5}{%
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-5}}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
\textbf{seq\_b\_single (\texttt{int})}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
\textbf{score (\texttt{int})}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\end{itemize}
\textbf{score\_norm (\texttt{float})}
\begin{itemize}
\tightlist
\item
Set by the \emph{obipairing} tool
\item
The value ranges between 0 and 1.
\end{itemize}
Score of the alignment between forward and reverse reads expressed as a
fraction of identity.
\hypertarget{references}{%
\chapter*{References}\label{references}}

View File

@ -4,3 +4,4 @@
## `obitag`
## `obitagpcr`

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@ -17,6 +17,10 @@ Several OBITools (*e.g.* obigrep, obiannotate) allow the user to specify some si
the length of a sequences, the number of element in a map like `annotations`, the number
of elements in an array. The reurned value is an `int`.
**`contains(map,key)`**
: Tests if the `map` contains a value assciated to `key`
### Cast functions {.unnumbered}
**`int(x)`**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@ -19,11 +19,11 @@ for f in $(egrep "gb(${DIV})[0-9]+\.seq\.gz" index.html \
fi
while [[ ! -f $f ]] ; do
echo downloading
wget2 --progress bar -v -o - $URL$f
if [[ -f $f ]] ; then
gzip -t $f && echo " ok" || rm -f $f
fi
echo downloading
wget2 --progress bar -v -o - $URL$f
if [[ -f $f ]] ; then
gzip -t $f && echo " ok" || rm -f $f
fi
done
done

Binary file not shown.

Binary file not shown.

View File

@ -217,6 +217,7 @@ ul.task-list li input[type="checkbox"] {
<ul>
<li><a href="#obiannotate" id="toc-obiannotate" class="nav-link active" data-scroll-target="#obiannotate"><span class="toc-section-number">10.1</span> <code>obiannotate</code></a></li>
<li><a href="#obitag" id="toc-obitag" class="nav-link" data-scroll-target="#obitag"><span class="toc-section-number">10.2</span> <code>obitag</code></a></li>
<li><a href="#obitagpcr" id="toc-obitagpcr" class="nav-link" data-scroll-target="#obitagpcr"><span class="toc-section-number">10.3</span> <code>obitagpcr</code></a></li>
</ul>
</nav>
</div>
@ -245,6 +246,9 @@ ul.task-list li input[type="checkbox"] {
</section>
<section id="obitag" class="level2" data-number="10.2">
<h2 data-number="10.2" class="anchored" data-anchor-id="obitag"><span class="header-section-number">10.2</span> <code>obitag</code></h2>
</section>
<section id="obitagpcr" class="level2" data-number="10.3">
<h2 data-number="10.3" class="anchored" data-anchor-id="obitagpcr"><span class="header-section-number">10.3</span> <code>obitagpcr</code></h2>
</section>

View File

@ -329,6 +329,10 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
<dd>
<p>It is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like <code>annotations</code>, the number of elements in an array. The reurned value is an <code>int</code>.</p>
</dd>
<dt><strong><code>contains(map,key)</code></strong></dt>
<dd>
<p>Tests if the <code>map</code> contains a value assciated to <code>key</code></p>
</dd>
</dl>
</section>
<section id="cast-functions" class="level3 unnumbered">

View File

@ -137,14 +137,14 @@
"href": "expressions.html#function-defined-in-the-language",
"title": "7  OBITools expression language",
"section": "7.2 Function defined in the language",
"text": "7.2 Function defined in the language\n\nInstrospection functions\n\nlen(x)is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like annotations, the number of elements in an array. The reurned value is an int.\n\n\n\nCast functions\n\nint(x) converts if possible the x value to an integer value. The function returns an int.\nnumeric(x) converts if possible the x value to a float value. The function returns a float.\nbool(x) converts if possible the x value to a boolean value. The function returns a bool.\n\n\n\nString related functions\n\nprintf(format,...) allows to combine several values to build a string. format follows the classical C printf syntax. The function returns a string.\nsubspc(x) substitutes every space in the x string by the underscore (_) character. The function returns a string."
"text": "7.2 Function defined in the language\n\nInstrospection functions\n\nlen(x)\n\nIt is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like annotations, the number of elements in an array. The reurned value is an int.\n\ncontains(map,key)\n\nTests if the map contains a value assciated to key\n\n\n\n\nCast functions\n\nint(x)\n\nConverts if possible the x value to an integer value. The function returns an int.\n\nnumeric(x)\n\nConverts if possible the x value to a float value. The function returns a float.\n\nbool(x)\n\nConverts if possible the x value to a boolean value. The function returns a bool.\n\n\n\n\nString related functions\n\nprintf(format,...)\n\nAllows to combine several values to build a string. format follows the classical C printf syntax. The function returns a string.\n\nsubspc(x)\n\nsubstitutes every space in the x string by the underscore (_) character. The function returns a string.\n\n\n\n\nCondition function\n\nifelse(condition,val1,val2)\n\nThe condition value has to be a bool value. If it is true the function returns val1, otherwise, it is returning val2.\n\n\n\n\n7.2.1 Sequence analysis related function\n\ncomposition(sequence)\n\nThe nucleotide composition of the sequence is returned as as map indexed by a, c, g, or t and each value is the number of occurrences of that nucleotide. A fifth key others accounts for all others symboles.\n\ngcskew(sequence)\n\nComputes the excess of g compare to c of the sequence, known as the GC skew.\n\\[\nSkew_{GC}=\\frac{G-C}{G+C}\n\\]"
},
{
"objectID": "expressions.html#accessing-to-the-sequence-annotations",
"href": "expressions.html#accessing-to-the-sequence-annotations",
"title": "7  OBITools expression language",
"section": "7.3 Accessing to the sequence annotations",
"text": "7.3 Accessing to the sequence annotations\nThe annotations variable is a map object containing all the annotations associated to the currently processed sequence. Index of the map are the attribute names. It exists to possibillities to retreive an annotation. It is possible to use the classical [] indexing operator, putting the attribute name quoted by double quotes between them.\nannotations[\"direction\"]\nThe above code retreives the direction annotation. A second notation using the dot (.) is often more convenient.\nannotations.direction\nSpecial attributes of the sequence are accessible only by dedicated methods of the sequence object.\n\nThe sequence identifier : Id()\nTHe sequence definition : Definition()"
"text": "7.3 Accessing to the sequence annotations\nThe annotations variable is a map object containing all the annotations associated to the currently processed sequence. Index of the map are the attribute names. It exists to possibillities to retreive an annotation. It is possible to use the classical [] indexing operator, putting the attribute name quoted by double quotes between them.\nannotations[\"direction\"]\nThe above code retreives the direction annotation. A second notation using the dot (.) is often more convenient.\nannotations.direction\nSpecial attributes of the sequence are accessible only by dedicated methods of the sequence object.\n\nThe sequence identifier : Id()\nTHe sequence definition : Definition()\n\nsequence.Id()"
},
{
"objectID": "comm_metabarcode_design.html#obipcr",
@ -174,6 +174,13 @@
"section": "10.2 obitag",
"text": "10.2 obitag"
},
{
"objectID": "comm_annotation.html#obitagpcr",
"href": "comm_annotation.html#obitagpcr",
"title": "10  Sequence annotations",
"section": "10.3 obitagpcr",
"text": "10.3 obitagpcr"
},
{
"objectID": "comm_computation.html#obipairing",
"href": "comm_computation.html#obipairing",
@ -214,7 +221,7 @@
"href": "comm_sampling.html#obigrep-filters-sequence-files-according-to-numerous-conditions",
"title": "12  Sequence sampling and filtering",
"section": "12.1 obigrep filters sequence files according to numerous conditions",
"text": "12.1 obigrep filters sequence files according to numerous conditions\nThe obigrep command is somewhat analogous to the standard Unix grep command. It selects a subset of sequence records from a sequence file. A sequence record is a complex object consisting of an identifier, a set of attributes (a key, defined by its name, associated with a value), a definition, and the sequence itself. Instead of working text line by text line like the standard Unix tool, obigrep selection is done sequence record by sequence record. A large number of options allow you to refine the selection on any element of the sequence. obigrep allows you to specify multiple conditions simultaneously (which take on the value TRUE or FALSE) and only those sequence records which meet all conditions (all conditions are TRUE) are selected. obigrep is able to work on two paired read files. The selection criteria apply to one or the other of the readings in each pair depending on the mode chosen (--paired-mode option). In all cases the selection is applied in the same way to both files, thus maintaining their consistency.\n\n12.1.1 The options usable with obigrep\n\n12.1.1.1 Selecting sequences based on their caracteristics\nSequences can be selected on several of their caracteristics, their length, their id, their sequence. Options allow for specifying the condition if selection.\n\n--min-count | -c COUNT\n\nonly sequences reprensenting at least COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\n--max-count | -C COUNT\n\nonly sequences reprensenting no more than COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\nExample\n\nSelecting sequence records representing at least five reads in the dataset.\n\n\nobigrep -c 5 data_SPER01.fasta > data_norare_SPER01.fasta"
"text": "12.1 obigrep filters sequence files according to numerous conditions\nThe obigrep command is somewhat analogous to the standard Unix grep command. It selects a subset of sequence records from a sequence file. A sequence record is a complex object consisting of an identifier, a set of attributes (a key, defined by its name, associated with a value), a definition, and the sequence itself. Instead of working text line by text line like the standard Unix tool, obigrep selection is done sequence record by sequence record. A large number of options allow you to refine the selection on any element of the sequence. obigrep allows you to specify multiple conditions simultaneously (which take on the value TRUE or FALSE) and only those sequence records which meet all conditions (all conditions are TRUE) are selected. obigrep is able to work on two paired read files. The selection criteria apply to one or the other of the readings in each pair depending on the mode chosen (--paired-mode option). In all cases the selection is applied in the same way to both files, thus maintaining their consistency.\n\n12.1.1 The options usable with obigrep\n\n12.1.1.1 Selecting sequences based on their caracteristics\nSequences can be selected on several of their caracteristics, their length, their id, their sequence. Options allow for specifying the condition if selection.\nSelection based on the sequence\nSequence records can be selected according if they match or not with a pattern. The simplest pattern is as short sequence (e.g AACCTT). But the usage of regular patterns allows for looking for more complex pattern. As example, A[TG]C+G matches a A, followed by a T or a G, then one or several C and endly a G.\n\n--sequence|-s PATTERN\n\nRegular expression pattern to be tested against the sequence itself. The pattern is case insensitive. A complete description of the regular pattern grammar is available here.\n\nExamples:\n\nSelects only the sequence records that contain an EcoRI restriction site.\n\n\nobigrep -s 'GAATTC' seq1.fasta > seq2.fasta\n: Selects only the sequence records that contain a stretch of at least 10 A.\nobigrep -s 'A{10,}' seq1.fasta > seq2.fasta\n: Selects only the sequence records that do not contain ambiguous nucleotides.\nobigrep -s '^[ACGT]+$' seq1.fasta > seq2.fasta\n\n--min-count | -c COUNT\n\nonly sequences reprensenting at least COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\n--max-count | -C COUNT\n\nonly sequences reprensenting no more than COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\nExamples\n\nSelecting sequence records representing at least five reads in the dataset.\n\n\nobigrep -c 5 data_SPER01.fasta > data_norare_SPER01.fasta"
},
{
"objectID": "comm_utilities.html#obicount",
@ -252,11 +259,11 @@
"text": "The sequence iterator\nThe pakage obiter provides an iterator mecanism for manipulating sequences. The main class provided by this package is obiiter.IBioSequence. An IBioSequence iterator provides batch of sequences.\n\nBasic usage of a sequence iterator\nMany functions, among them functions reading sequences from a text file, return a IBioSequence iterator. The iterator class provides two main methods:\n\nNext() bool\nGet() obiiter.BioSequenceBatch\n\nThe Next method moves the iterator to the next value, while the Get method returns the currently pointed value. Using them, it is possible to loop over the data as in the following code chunk.\nimport (\n \"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiformats\"\n)\n\nfunc main() {\n mydata := obiformats.ReadFastSeqFromFile(\"myfile.fasta\")\n \n for mydata.Next() {\n data := mydata.Get()\n //\n // Whatever you want to do with the data chunk\n //\n }\n}\nAn obiseq.BioSequenceBatch instance is a set of sequences stored in an obiseq.BioSequenceSlice and a sequence number. The number of sequences in a batch is not defined. A batch can even contain zero sequences, if for example all sequences initially included in the batch have been filtered out at some stage of their processing.\n\n\nThe Pipable functions\nA function consuming a obiiter.IBioSequence and returning a obiiter.IBioSequence is of class obiiter.Pipable.\n\n\nThe Teeable functions\nA function consuming a obiiter.IBioSequence and returning two obiiter.IBioSequence instance is of class obiiter.Teeable."
},
{
"objectID": "annexes.html",
"href": "annexes.html",
"objectID": "annexes.html#sequence-attributes",
"href": "annexes.html#sequence-attributes",
"title": "Appendix A — Annexes",
"section": "",
"text": "A.0.1 Sequence attributes\n\nA.0.1.1 Reserved sequence attributes\n\nA.0.1.1.1 ali_dir\n\nA.0.1.1.1.1 Type : string\nThe attribute can contain 2 string values \"left\" or \"right\".\n\n\nA.0.1.1.1.2 Set by the obipairing tool\nThe alignment generated by obipairing is a 3-end gap free algorithm. Two cases can occur when aligning the forward and reverse reads. If the barcode is long enough, both the reads overlap only on their 3 ends. In such case, the alignment direction ali_dir is set to left. If the barcode is shorter than the read length, the paired reads overlap by their 5 ends, and the complete barcode is sequenced by both the reads. In that later case, ali_dir is set to right.\n\n\n\nA.0.1.1.2 ali_length\n\nA.0.1.1.2.1 Set by the obipairing tool\nLength of the aligned parts when merging forward and reverse reads\n\n\n\nA.0.1.1.3 count : the number of sequence occurrences\n\nA.0.1.1.3.1 Set by the obiuniq tool\nThe count attribute indicates how-many strictly identical sequences have been merged in a single record. It contains an integer value. If it is absent this means that the sequence record represents a single occurrence of the sequence.\n\n\nA.0.1.1.3.2 Getter : method Count()\nThe Count() method allows to access to the count attribute as an integer value. If the count attribute is not defined for the given sequence, the value 1 is returned\n\n\n\nA.0.1.1.4 merged_*\n\nA.0.1.1.4.1 Type : map[string]int\n\n\nA.0.1.1.4.2 Set by the obiuniq tool\nThe -m option of the obiuniq tools allows for keeping track of the distribution of the values stored in given attribute of interest. Often this option is used to summarise distribution of a sequence variant accross samples when obiuniq is run after running obimultiplex. The actual name of the attribute depends on the name of the monitored attribute. If -m option is used with the attribute sample, then this attribute names merged_sample.\n\n\n\nA.0.1.1.5 mode\n\nA.0.1.1.5.1 Set by the obipairing tool\nobitag_ref_index\n\n\nA.0.1.1.5.2 Set by the obirefidx tool.\nIt resumes to which taxonomic annotation a match to that sequence must lead according to the number of differences existing between the query sequence and the reference sequence having that tag.\n\n\nA.0.1.1.5.3 Getter : method Count()\n\n\n\nA.0.1.1.6 pairing_mismatches\n\nA.0.1.1.6.1 Set by the obipairing tool\n\n\n\nA.0.1.1.7 score\n\nA.0.1.1.7.1 Set by the obipairing tool\n\n\n\nA.0.1.1.8 score_norm\n\nA.0.1.1.8.1 Set by the obipairing tool"
"section": "A.1 Sequence attributes",
"text": "A.1 Sequence attributes\nali_dir (string)\n\nSet by the obipairing tool\nThe attribute can contain 2 string values left or right.\n\nThe alignment generated by obipairing is a 3-end gap free algorithm. Two cases can occur when aligning the forward and reverse reads. If the barcode is long enough, both the reads overlap only on their 3 ends. In such case, the alignment direction ali_dir is set to left. If the barcode is shorter than the read length, the paired reads overlap by their 5 ends, and the complete barcode is sequenced by both the reads. In that later case, ali_dir is set to right.\nali_length (int)\n\nSet by the obipairing tool\n\nLength of the aligned parts when merging forward and reverse reads\ncount (int)\n\nSet by the obiuniq tool\nGetter : method Count()\nSetter : method SetCount(int)\n\nThe count attribute indicates how-many strictly identical reads have been merged in a single record. It contains an integer value. If it is absent this means that the sequence record represents a single occurrence of the sequence.\nThe Count() method allows to access to the count attribute as an integer value. If the count attribute is not defined for the given sequence, the value 1 is returned\nmerged_* (map[string]int)\n\nSet by the obiuniq tool\n\nThe -m option of the obiuniq tools allows for keeping track of the distribution of the values stored in given attribute of interest. Often this option is used to summarise distribution of a sequence variant accross samples when obiuniq is run after running obimultiplex. The actual name of the attribute depends on the name of the monitored attribute. If -m option is used with the attribute sample, then this attribute names merged_sample.\nmode (string)\n\nSet by the obipairing tool\nThe attribute can contain 2 string values join or alignment.\n\nobitag_ref_index (map[string]string)\n\nSet by the obirefidx tool.\n\nIt resumes to which taxonomic annotation a match to that sequence must lead according to the number of differences existing between the query sequence and the reference sequence having that tag.\n {\"0\":\"9606@Homo sapiens@species\",\n \"2\":\"207598@Homininae@subfamily\",\n \"3\":\"9604@Hominidae@family\",\n \"8\":\"314295@Hominoidea@superfamily\",\n \"10\":\"9526@Catarrhini@parvorder\",\n \"12\":\"1437010@Boreoeutheria@clade\",\n \"16\":\"9347@Eutheria@clade\",\n \"17\":\"40674@Mammalia@class\",\n \"22\":\"117571@Euteleostomi@clade\",\n \"25\":\"7776@Gnathostomata@clade\",\n \"29\":\"33213@Bilateria@clade\",\n \"30\":\"6072@Eumetazoa@clade\"}\npairing_mismatches (map[string]string)\n\nSet by the obipairing tool\n\nseq_a_single (int)\n\nSet by the obipairing tool\n\nseq_ab_match (int)\n\nSet by the obipairing tool\n\nseq_b_single (int)\n\nSet by the obipairing tool\n\nscore (int)\n\nSet by the obipairing tool\n\nscore_norm (float)\n\nSet by the obipairing tool\nThe value ranges between 0 and 1.\n\nScore of the alignment between forward and reverse reads expressed as a fraction of identity."
},
{
"objectID": "references.html",

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,171 @@
/* 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;
}
pre > code.sourceCode > span {
color: #003B4F;
}
code span {
color: #003B4F;
}
code.sourceCode > span {
color: #003B4F;
}
div.sourceCode,
div.sourceCode pre.sourceCode {
color: #003B4F;
}
code span.ot {
color: #003B4F;
}
code span.at {
color: #657422;
}
code span.ss {
color: #20794D;
}
code span.an {
color: #5E5E5E;
}
code span.fu {
color: #4758AB;
}
code span.st {
color: #20794D;
}
code span.cf {
color: #003B4F;
}
code span.op {
color: #5E5E5E;
}
code span.er {
color: #AD0000;
}
code span.bn {
color: #AD0000;
}
code span.al {
color: #AD0000;
}
code span.va {
color: #111111;
}
code span.pp {
color: #AD0000;
}
code span.in {
color: #5E5E5E;
}
code span.vs {
color: #20794D;
}
code span.wa {
color: #5E5E5E;
font-style: italic;
}
code span.do {
color: #5E5E5E;
font-style: italic;
}
code span.im {
color: #00769E;
}
code span.ch {
color: #20794D;
}
code span.dt {
color: #AD0000;
}
code span.fl {
color: #AD0000;
}
code span.co {
color: #5E5E5E;
}
code span.cv {
color: #5E5E5E;
font-style: italic;
}
code span.cn {
color: #8f5902;
}
code span.sc {
color: #5E5E5E;
}
code span.dv {
color: #AD0000;
}
code span.kw {
color: #003B4F;
}
.prevent-inlining {
content: "</";
}
/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */

View File

@ -0,0 +1,770 @@
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
detail: {},
bubbles: true,
cancelable: false,
composed: false,
});
window.document.addEventListener("DOMContentLoaded", function (_event) {
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;
}
};
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
function fireSlideEnter(e) {
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);
});
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
document.addEventListener("tabby", fireSlideEnter, 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
) {
sectionIndex = 0;
} else {
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() {
const currentPagePath = offsetAbsoluteUrl(window.location.href);
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) {
if (
item === currentPagePath ||
item === 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;
return (hiddenRegions) => {
if (el === null) {
return;
}
// Find the last element of the TOC
const lastChildEl = el.lastElementChild;
if (lastChildEl) {
// Find the top and bottom o the element that is being managed
const elTop = el.offsetTop;
const elBottom =
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
// Converts the sidebar to a menu
const convertToMenu = () => {
for (const child of el.children) {
child.style.opacity = 0;
child.style.overflow = "hidden";
}
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.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.display = null;
toggleContents.append(clone);
}
toggleContents.style.height = "0px";
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;
}
};
const positionToggle = () => {
// position the element (top left of parent, same width as parent)
const elRect = el.getBoundingClientRect();
toggleContainer.style.left = `${elRect.left}px`;
toggleContainer.style.top = `${elRect.top}px`;
toggleContainer.style.width = `${elRect.width}px`;
};
// 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(() => {
positionToggle();
}, 50)
);
positionToggle();
// 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;
}
const placeholderEl = window.document.getElementById(
placeholderDescriptor.id
);
if (placeholderEl) {
placeholderEl.remove();
}
el.classList.remove("rollup");
};
if (isReaderMode()) {
convertToMenu();
isVisible = false;
} else {
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;
}
}
}
}
};
};
// Find any conflicting margin elements and add margins to the
// top to prevent overlap
const marginChildren = window.document.querySelectorAll(
".column-margin.column-container > * "
);
nexttick(() => {
let lastBottom = 0;
for (const marginChild of marginChildren) {
const top = marginChild.getBoundingClientRect().top + window.scrollY;
if (top < lastBottom) {
const margin = lastBottom - top;
marginChild.style.marginTop = `${margin}px`;
}
const styles = window.getComputedStyle(marginChild);
const marginTop = parseFloat(styles["marginTop"]);
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
}
});
// 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 top =
el.getBoundingClientRect().top +
document.documentElement.scrollTop -
kOverlapPaddingSize;
return {
top,
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
};
});
}
const hideOverlappedSidebars = () => {
marginScrollVisibility(toRegions(rightSideConflictEls));
sidebarScrollVisiblity(toRegions(leftSideConflictEls));
if (tocLeftScrollVisibility) {
tocLeftScrollVisibility(toRegions(leftSideConflictEls));
}
};
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;
// 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 (child of el.children) {
hasActiveChild = walk(child, depth) || hasActiveChild;
}
// Process the collapse state if this is an UL
if (el.tagName === "UL") {
if (depth === 1 || 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) {
walk(tocEl, 0);
updateActiveLink();
}
// 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 (!isReaderMode()) {
hideOverlappedSidebars();
}
}, 10)
);
hideOverlappedSidebars();
highlightReaderToggle(isReaderMode());
});
// grouped tabsets
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);
}
}
});
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);
}

View 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}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
/*!
* headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=l<t?"down":"up",a.distance=Math.abs(t-l),a.isOutOfBounds=t<0||o<t+n,a.top=t<=s.offset[a.direction],a.bottom=o<=t+n,a.toleranceExceeded=a.distance>s.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s});

View File

@ -0,0 +1,221 @@
const headroomChanged = new CustomEvent("quarto-hrChanged", {
detail: {},
bubbles: true,
cancelable: false,
composed: false,
});
window.document.addEventListener("DOMContentLoaded", function () {
let init = false;
function throttle(func, wait) {
var timeout;
return function () {
const context = this;
const args = arguments;
const later = function () {
clearTimeout(timeout);
timeout = null;
func.apply(context, args);
};
if (!timeout) {
timeout = setTimeout(later, wait);
}
};
}
function headerOffset() {
// Set an offset if there is are fixed top navbar
const headerEl = window.document.querySelector("header.fixed-top");
if (headerEl) {
return headerEl.clientHeight;
} else {
return 0;
}
}
function footerOffset() {
const footerEl = window.document.querySelector("footer.footer");
if (footerEl) {
return footerEl.clientHeight;
} else {
return 0;
}
}
function updateDocumentOffsetWithoutAnimation() {
updateDocumentOffset(false);
}
function updateDocumentOffset(animated) {
// set body offset
const topOffset = headerOffset();
const bodyOffset = topOffset + footerOffset();
const bodyEl = window.document.body;
bodyEl.setAttribute("data-bs-offset", topOffset);
bodyEl.style.paddingTop = topOffset + "px";
// deal with sidebar offsets
const sidebars = window.document.querySelectorAll(
".sidebar, .headroom-target"
);
sidebars.forEach((sidebar) => {
if (!animated) {
sidebar.classList.add("notransition");
// Remove the no transition class after the animation has time to complete
setTimeout(function () {
sidebar.classList.remove("notransition");
}, 201);
}
if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) {
sidebar.style.top = "0";
sidebar.style.maxHeight = "100vh";
} else {
sidebar.style.top = topOffset + "px";
sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)";
}
});
// allow space for footer
const mainContainer = window.document.querySelector(".quarto-container");
if (mainContainer) {
mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)";
}
// link offset
let linkStyle = window.document.querySelector("#quarto-target-style");
if (!linkStyle) {
linkStyle = window.document.createElement("style");
window.document.head.appendChild(linkStyle);
}
while (linkStyle.firstChild) {
linkStyle.removeChild(linkStyle.firstChild);
}
if (topOffset > 0) {
linkStyle.appendChild(
window.document.createTextNode(`
section:target::before {
content: "";
display: block;
height: ${topOffset}px;
margin: -${topOffset}px 0 0;
}`)
);
}
if (init) {
window.dispatchEvent(headroomChanged);
}
init = true;
}
// initialize headroom
var header = window.document.querySelector("#quarto-header");
if (header && window.Headroom) {
const headroom = new window.Headroom(header, {
tolerance: 5,
onPin: function () {
const sidebars = window.document.querySelectorAll(
".sidebar, .headroom-target"
);
sidebars.forEach((sidebar) => {
sidebar.classList.remove("sidebar-unpinned");
});
updateDocumentOffset();
},
onUnpin: function () {
const sidebars = window.document.querySelectorAll(
".sidebar, .headroom-target"
);
sidebars.forEach((sidebar) => {
sidebar.classList.add("sidebar-unpinned");
});
updateDocumentOffset();
},
});
headroom.init();
let frozen = false;
window.quartoToggleHeadroom = function () {
if (frozen) {
headroom.unfreeze();
frozen = false;
} else {
headroom.freeze();
frozen = true;
}
};
}
// Observe size changed for the header
const headerEl = window.document.querySelector("header.fixed-top");
if (headerEl && window.ResizeObserver) {
const observer = new window.ResizeObserver(
updateDocumentOffsetWithoutAnimation
);
observer.observe(headerEl, {
attributes: true,
childList: true,
characterData: true,
});
} else {
window.addEventListener(
"resize",
throttle(updateDocumentOffsetWithoutAnimation, 50)
);
}
setTimeout(updateDocumentOffsetWithoutAnimation, 250);
// fixup index.html links if we aren't on the filesystem
if (window.location.protocol !== "file:") {
const links = window.document.querySelectorAll("a");
for (let i = 0; i < links.length; i++) {
links[i].href = links[i].href.replace(/\/index\.html/, "/");
}
// Fixup any sharing links that require urls
// Append url to any sharing urls
const sharingLinks = window.document.querySelectorAll(
"a.sidebar-tools-main-item"
);
for (let i = 0; i < sharingLinks.length; i++) {
const sharingLink = sharingLinks[i];
const href = sharingLink.getAttribute("href");
if (href) {
sharingLink.setAttribute(
"href",
href.replace("|url|", window.location.href)
);
}
}
// Scroll the active navigation item into view, if necessary
const navSidebar = window.document.querySelector("nav#quarto-sidebar");
if (navSidebar) {
// Find the active item
const activeItem = navSidebar.querySelector("li.sidebar-item a.active");
if (activeItem) {
// Wait for the scroll height and height to resolve by observing size changes on the
// nav element that is scrollable
const resizeObserver = new ResizeObserver((_entries) => {
// The bottom of the element
const elBottom = activeItem.offsetTop;
const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight;
// The element height and scroll height are the same, then we are still loading
if (viewBottom !== navSidebar.scrollHeight) {
// Determine if the item isn't visible and scroll to it
if (elBottom >= viewBottom) {
navSidebar.scrollTop = elBottom;
}
// stop observing now since we've completed the scroll
resizeObserver.unobserve(navSidebar);
}
});
resizeObserver.observe(navSidebar);
}
}
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff