--- a
+++ b/docs/registration.html
@@ -0,0 +1,1081 @@
+<!DOCTYPE html>
+
+<html>
+
+<head>
+
+<meta charset="utf-8" />
+<meta name="generator" content="pandoc" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
+
+
+
+
+<title>Image Registration</title>
+
+<script src="site_libs/header-attrs-2.29/header-attrs.js"></script>
+<script src="site_libs/jquery-3.6.0/jquery-3.6.0.min.js"></script>
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<link href="site_libs/bootstrap-3.3.5/css/flatly.min.css" rel="stylesheet" />
+<script src="site_libs/bootstrap-3.3.5/js/bootstrap.min.js"></script>
+<script src="site_libs/bootstrap-3.3.5/shim/html5shiv.min.js"></script>
+<script src="site_libs/bootstrap-3.3.5/shim/respond.min.js"></script>
+<style>h1 {font-size: 34px;}
+       h1.title {font-size: 38px;}
+       h2 {font-size: 30px;}
+       h3 {font-size: 24px;}
+       h4 {font-size: 18px;}
+       h5 {font-size: 16px;}
+       h6 {font-size: 12px;}
+       code {color: inherit; background-color: rgba(0, 0, 0, 0.04);}
+       pre:not([class]) { background-color: white }</style>
+<script src="site_libs/jqueryui-1.13.2/jquery-ui.min.js"></script>
+<link href="site_libs/tocify-1.9.1/jquery.tocify.css" rel="stylesheet" />
+<script src="site_libs/tocify-1.9.1/jquery.tocify.js"></script>
+<script src="site_libs/navigation-1.1/tabsets.js"></script>
+<link href="site_libs/highlightjs-9.12.0/textmate.css" rel="stylesheet" />
+<script src="site_libs/highlightjs-9.12.0/highlight.js"></script>
+<link href="site_libs/font-awesome-6.5.2/css/all.min.css" rel="stylesheet" />
+<link href="site_libs/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet" />
+
+<style type="text/css">
+  code{white-space: pre-wrap;}
+  span.smallcaps{font-variant: small-caps;}
+  span.underline{text-decoration: underline;}
+  div.column{display: inline-block; vertical-align: top; width: 50%;}
+  div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
+  ul.task-list{list-style: none;}
+    </style>
+
+<style type="text/css">code{white-space: pre;}</style>
+<script type="text/javascript">
+if (window.hljs) {
+  hljs.configure({languages: []});
+  hljs.initHighlightingOnLoad();
+  if (document.readyState && document.readyState === "complete") {
+    window.setTimeout(function() { hljs.initHighlighting(); }, 0);
+  }
+}
+</script>
+
+
+
+
+
+
+
+
+
+<style type = "text/css">
+.main-container {
+  max-width: 940px;
+  margin-left: auto;
+  margin-right: auto;
+}
+img {
+  max-width:100%;
+}
+.tabbed-pane {
+  padding-top: 12px;
+}
+.html-widget {
+  margin-bottom: 20px;
+}
+button.code-folding-btn:focus {
+  outline: none;
+}
+summary {
+  display: list-item;
+}
+details > summary > p:only-child {
+  display: inline;
+}
+pre code {
+  padding: 0;
+}
+</style>
+
+
+<style type="text/css">
+.dropdown-submenu {
+  position: relative;
+}
+.dropdown-submenu>.dropdown-menu {
+  top: 0;
+  left: 100%;
+  margin-top: -6px;
+  margin-left: -1px;
+  border-radius: 0 6px 6px 6px;
+}
+.dropdown-submenu:hover>.dropdown-menu {
+  display: block;
+}
+.dropdown-submenu>a:after {
+  display: block;
+  content: " ";
+  float: right;
+  width: 0;
+  height: 0;
+  border-color: transparent;
+  border-style: solid;
+  border-width: 5px 0 5px 5px;
+  border-left-color: #cccccc;
+  margin-top: 5px;
+  margin-right: -10px;
+}
+.dropdown-submenu:hover>a:after {
+  border-left-color: #adb5bd;
+}
+.dropdown-submenu.pull-left {
+  float: none;
+}
+.dropdown-submenu.pull-left>.dropdown-menu {
+  left: -100%;
+  margin-left: 10px;
+  border-radius: 6px 0 6px 6px;
+}
+</style>
+
+<script type="text/javascript">
+// manage active state of menu based on current page
+$(document).ready(function () {
+  // active menu anchor
+  href = window.location.pathname
+  href = href.substr(href.lastIndexOf('/') + 1)
+  if (href === "")
+    href = "index.html";
+  var menuAnchor = $('a[href="' + href + '"]');
+
+  // mark the anchor link active (and if it's in a dropdown, also mark that active)
+  var dropdown = menuAnchor.closest('li.dropdown');
+  if (window.bootstrap) { // Bootstrap 4+
+    menuAnchor.addClass('active');
+    dropdown.find('> .dropdown-toggle').addClass('active');
+  } else { // Bootstrap 3
+    menuAnchor.parent().addClass('active');
+    dropdown.addClass('active');
+  }
+
+  // Navbar adjustments
+  var navHeight = $(".navbar").first().height() + 15;
+  var style = document.createElement('style');
+  var pt = "padding-top: " + navHeight + "px; ";
+  var mt = "margin-top: -" + navHeight + "px; ";
+  var css = "";
+  // offset scroll position for anchor links (for fixed navbar)
+  for (var i = 1; i <= 6; i++) {
+    css += ".section h" + i + "{ " + pt + mt + "}\n";
+  }
+  style.innerHTML = "body {" + pt + "padding-bottom: 40px; }\n" + css;
+  document.head.appendChild(style);
+});
+</script>
+
+<!-- tabsets -->
+
+<style type="text/css">
+.tabset-dropdown > .nav-tabs {
+  display: inline-table;
+  max-height: 500px;
+  min-height: 44px;
+  overflow-y: auto;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+}
+
+.tabset-dropdown > .nav-tabs > li.active:before, .tabset-dropdown > .nav-tabs.nav-tabs-open:before {
+  content: "\e259";
+  font-family: 'Glyphicons Halflings';
+  display: inline-block;
+  padding: 10px;
+  border-right: 1px solid #ddd;
+}
+
+.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before {
+  content: "\e258";
+  font-family: 'Glyphicons Halflings';
+  border: none;
+}
+
+.tabset-dropdown > .nav-tabs > li.active {
+  display: block;
+}
+
+.tabset-dropdown > .nav-tabs > li > a,
+.tabset-dropdown > .nav-tabs > li > a:focus,
+.tabset-dropdown > .nav-tabs > li > a:hover {
+  border: none;
+  display: inline-block;
+  border-radius: 4px;
+  background-color: transparent;
+}
+
+.tabset-dropdown > .nav-tabs.nav-tabs-open > li {
+  display: block;
+  float: none;
+}
+
+.tabset-dropdown > .nav-tabs > li {
+  display: none;
+}
+</style>
+
+<!-- code folding -->
+
+
+
+<style type="text/css">
+
+#TOC {
+  margin: 25px 0px 20px 0px;
+}
+@media (max-width: 768px) {
+#TOC {
+  position: relative;
+  width: 100%;
+}
+}
+
+@media print {
+.toc-content {
+  /* see https://github.com/w3c/csswg-drafts/issues/4434 */
+  float: right;
+}
+}
+
+.toc-content {
+  padding-left: 30px;
+  padding-right: 40px;
+}
+
+div.main-container {
+  max-width: 1200px;
+}
+
+div.tocify {
+  width: 20%;
+  max-width: 260px;
+  max-height: 85%;
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+  div.tocify {
+    width: 25%;
+  }
+}
+
+@media (max-width: 767px) {
+  div.tocify {
+    width: 100%;
+    max-width: none;
+  }
+}
+
+.tocify ul, .tocify li {
+  line-height: 20px;
+}
+
+.tocify-subheader .tocify-item {
+  font-size: 0.90em;
+}
+
+.tocify .list-group-item {
+  border-radius: 0px;
+}
+
+.tocify-subheader {
+  display: inline;
+}
+.tocify-subheader .tocify-item {
+  font-size: 0.95em;
+}
+
+</style>
+
+
+
+</head>
+
+<body>
+
+
+<div class="container-fluid main-container">
+
+
+<!-- setup 3col/9col grid for toc_float and main content  -->
+<div class="row">
+<div class="col-xs-12 col-sm-4 col-md-3">
+<div id="TOC" class="tocify">
+</div>
+</div>
+
+<div class="toc-content col-xs-12 col-sm-8 col-md-9">
+
+
+
+
+<div class="navbar navbar-default  navbar-fixed-top" role="navigation">
+  <div class="container">
+    <div class="navbar-header">
+      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-bs-toggle="collapse" data-target="#navbar" data-bs-target="#navbar">
+        <span class="icon-bar"></span>
+        <span class="icon-bar"></span>
+        <span class="icon-bar"></span>
+      </button>
+      <a class="navbar-brand" href="index.html">VoltRon</a>
+    </div>
+    <div id="navbar" class="navbar-collapse collapse">
+      <ul class="nav navbar-nav">
+        <li>
+  <a href="tutorials.html">Explore</a>
+</li>
+<li class="dropdown">
+  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+    Vignette
+     
+    <span class="caret"></span>
+  </a>
+  <ul class="dropdown-menu" role="menu">
+    <li class="dropdown-submenu">
+      <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">Spatial Data Integration</a>
+      <ul class="dropdown-menu" role="menu">
+        <li>
+          <a href="registration.html">Spatial Data Alignment</a>
+        </li>
+        <li>
+          <a href="multiomic.html">Multi-omic Integration</a>
+        </li>
+        <li>
+          <a href="nicheclustering.html">Niche Clustering</a>
+        </li>
+      </ul>
+    </li>
+    <li class="dropdown-submenu">
+      <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">Downstream Analysis</a>
+      <ul class="dropdown-menu" role="menu">
+        <li>
+          <a href="roianalysis.html">ROI Analysis</a>
+        </li>
+        <li>
+          <a href="spotanalysis.html">Cell/Spot Analysis</a>
+        </li>
+        <li>
+          <a href="moleculeanalysis.html">Molecule Analysis</a>
+        </li>
+        <li>
+          <a href="pixelanalysis.html">Pixels (Image Only) Analysis</a>
+        </li>
+      </ul>
+    </li>
+    <li class="dropdown-submenu">
+      <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">Utilities</a>
+      <ul class="dropdown-menu" role="menu">
+        <li>
+          <a href="interactive.html">Interactive Utilities</a>
+        </li>
+        <li>
+          <a href="importingdata.html">Importing Spatial Data</a>
+        </li>
+        <li>
+          <a href="voltronobjects.html">Working with VoltRon Objects</a>
+        </li>
+        <li>
+          <a href="conversion.html">Converting VoltRon Objects</a>
+        </li>
+        <li>
+          <a href="ondisk.html">OnDisk-based Analysis Utilities</a>
+        </li>
+      </ul>
+    </li>
+  </ul>
+</li>
+      </ul>
+      <ul class="nav navbar-nav navbar-right">
+        <li class="dropdown">
+  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+    <span class="fa fa-envelope-o"></span>
+     
+    Contact
+     
+    <span class="caret"></span>
+  </a>
+  <ul class="dropdown-menu" role="menu">
+    <li>
+      <a href="https://bioinformatics.mdc-berlin.de">Altuna Lab/BIMSB Bioinfo</a>
+    </li>
+    <li>
+      <a href="https://www.mdc-berlin.de/landthaler">Landthaler Lab/BIMSB</a>
+    </li>
+  </ul>
+</li>
+<li class="dropdown">
+  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+    <span class="fa fa-github"></span>
+     
+    GitHub
+     
+    <span class="caret"></span>
+  </a>
+  <ul class="dropdown-menu" role="menu">
+    <li>
+      <a href="https://github.com/BIMSBbioinfo/VoltRon">VoltRon</a>
+    </li>
+    <li>
+      <a href="https://github.com/BIMSBbioinfo">BIMSB Bioinfo</a>
+    </li>
+  </ul>
+</li>
+      </ul>
+    </div><!--/.nav-collapse -->
+  </div><!--/.container -->
+</div><!--/.navbar -->
+
+<div id="header">
+
+
+
+<h1 class="title toc-ignore">Image Registration</h1>
+
+</div>
+
+
+<style>
+.title{
+  display: none;
+}
+body {
+  text-align: justify
+}
+.center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+</style>
+<style type="text/css">
+.watch-out {
+  color: black;
+}
+</style>
+<p><br></p>
+<div id="spatial-data-alignment" class="section level1">
+<h1>Spatial Data Alignment</h1>
+<p>Spatial genomic technologies often generate diverse images and
+spatial readouts, even though the tissue slices are from adjacent
+sections of a single tissue block. Hence, the alignment of images and
+spatial coordinates across tissue sections are of utmost importance to
+dissect the correct spatial closeness across these sections.</p>
+<p>VoltRon allows users to <strong>align spatial omics datasets of these
+serial sections</strong> for data transfer and 3 dimensional stack
+alignment. The order of the tissue/sample slices should be provided by
+the user. VoltRon provides a fully embedded <strong>shiny
+application</strong> to either automatically or manually align images.
+The automatic alignment is achieved with the <strong>OpenCV</strong>’s
+C++ library fully embedded in the VoltRon package.</p>
+<table>
+<tbody>
+<tr style="vertical-align: center">
+<td style="width:43%; vertical-align: center">
+<img src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/manualregistration.png" class="center">
+</td>
+<td style="width:43%; vertical-align: center">
+<img src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/autoregistration.png" class="center">
+</td>
+</tr>
+</tbody>
+</table>
+<p><br></p>
+<div id="alignment-of-xenium-and-visium" class="section level2">
+<h2>Alignment of Xenium and Visium</h2>
+<p>In this use case, we will align <strong>immunofluorescence
+(IF)</strong> and <strong>H&amp;E images</strong> of the <strong>Xenium
+In Situ</strong> and <strong>Visium CytAssist</strong> platforms
+readouts. Three tissue sections are derived from a single
+formalin-fixed, paraffin-embedded (FFPE) breast cancer tissue block. A 5
+<span class="math inline">\(\mu\)</span>m section was taken for Visium
+CytAssist and two replicate 5 <span class="math inline">\(\mu\)</span>m
+sections were taken for the Xenium replicates. More information on the
+spatial datasets and the study can be also be found on the <a
+href="https://www.biorxiv.org/content/10.1101/2022.10.06.510405v1">BioArxiv
+preprint</a>.</p>
+<p>You can download the Xenium and Visium readouts from the <a
+href="https://www.10xgenomics.com/products/xenium-in-situ/preview-dataset-human-breast">10x
+Genomics website</a> (specifically, import <strong>In Situ Replicate 1/2
+and Visium Spatial</strong>). Alternatively, you can <strong>download a
+zipped collection of three Visium and Xenium readouts</strong> from <a
+href="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/SpatialDataAlignment/Xenium_vs_Visium/10X_Xenium_Visium.zip">here</a>.</p>
+<p>VoltRon includes built-in functions for converting readouts from both
+Xenium and Visium platforms into VoltRon objects. We will import both
+Xenium replicates alongside with the Visium CytAssist data so that we
+can register images of these assays and merge them into one VoltRon
+object.</p>
+<pre class="r watch-out"><code>library(VoltRon)
+Xen_R1 &lt;- importXenium(&quot;Xenium_R1/outs&quot;, sample_name = &quot;XeniumR1&quot;)
+Xen_R2 &lt;- importXenium(&quot;Xenium_R2/outs&quot;, sample_name = &quot;XeniumR2&quot;)
+Vis &lt;- importVisium(&quot;Visium/&quot;, sample_name = &quot;VisiumR1&quot;)</code></pre>
+<p>Before moving on to image alignment, we can inspect both Xenium and
+Visium images. We use the <strong>vrImages</strong> function to call and
+visualize reference images of all VoltRon objects.</p>
+<pre class="r watch-out"><code>vrImages(Xen_R1)
+vrImages(Xen_R2)
+vrImages(Vis)</code></pre>
+<table>
+<tbody>
+<tr style="vertical-align: center">
+<td style="width:33%; vertical-align: center">
+<img src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/xeniumr1.png" class="center">
+</td>
+<td style="width:33%; vertical-align: center">
+<img src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/xeniumr2.png" class="center">
+</td>
+<td style="width:33%; vertical-align: center">
+<img src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/visium.png" class="center">
+</td>
+</tr>
+</tbody>
+</table>
+<p><br></p>
+<p>Although images of the first Xenium replicate and the Visium assay
+are workable, we have to adjust the brightness of the second Xenium
+replicate before image alignment. You can use
+<strong>modulateImage</strong> function to change the brightness and`
+saturation of the reference image of this VoltRon object. This
+functionality is optional for VoltRon objects and should be used when
+images require further adjustments.</p>
+<pre class="r watch-out"><code>Xen_R2 &lt;- modulateImage(Xen_R2, brightness = 800)
+vrImages(Xen_R2)</code></pre>
+<p><img width="40%" height="40%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/xeniumr2_new.png" class="center"></p>
+<p><br></p>
+<div id="automated-image-alignment" class="section level3">
+<h3>Automated Image Alignment</h3>
+<p>In order to achieve data transfer and integration across these two
+modalities, we need to first make sure that spatial coordinates of these
+three datasets are perfectly aligned. To this end, we will make use of
+the <strong>registerSpatialData</strong> function which calls a
+<strong>shiny app</strong> embedded into VoltRon. The function takes a
+single list as an input where the order of VoltRon objects in the list
+should be the same as the <strong>order of serial sections</strong>.</p>
+<p>We will make use of the <strong>registerSpatialData</strong> function
+to <strong>automatically register two Xenium assays onto the Visium
+assay</strong>. The Visium CytAssist image (or the <strong>image on the
+center</strong> of the list) would be taken as the image of reference,
+and hence all other images (or spatial datasets) are to be aligned to
+the Visium data. Then, registerSpatialData will return a list of VoltRon
+objects whose assays include both the original and registered versions
+of spatial coordinates. The shiny app will provide <strong>two
+images</strong> for this task:</p>
+<ul>
+<li>An image that shows the matched points across two images, and</li>
+<li>A slideshow with of the reference and registered images that
+demonstrates the alignment accuracy.</li>
+</ul>
+<p>We will select <strong>FLANN</strong> method for automated alignment
+which incorporates the <strong>SIFT</strong> method for automated
+keypoints selection and utilizes the <strong>Fast library for
+Approximate Nearest Neighbors (FLANN) algorithm</strong> for matching
+keypoints. <strong>NOTE:</strong> For better alignment performance,
+users can incorporate image manipulation tools above each image and sync
+images into the same orientation by rotating, flipping (horizontally and
+vertically) and negating these images. We always negate DAPI images to
+align them onto H&amp;E images.</p>
+<pre class="r watch-out"><code>xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2))</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/XeniumVisiumRegistration_FLANN.gif" class="center"></p>
+<p><br></p>
+<p>You can save and use the same parameters later, and reproduce the
+alignment without choosing parameters the second time.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- xen_reg$mapping_parameters
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters)</code></pre>
+<p>You can find a presaved set of parameters <a
+href="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/SpatialDataAlignment/Xenium_vs_Visium/mapping_parameters.rds">here</a>.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- readRDS(&quot;mapping_parameters.rds&quot;)
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters)</code></pre>
+<p>If the pre-saved parameters are available, the registration can also
+be performed without using the shiny app. By using <strong>interactive =
+FALSE</strong>, we can register images and VoltRon objects directly.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- xen_reg$mapping_parameters
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters, 
+                               interactive = FALSE)</code></pre>
+<p>In case there are only two images, <strong>the first image will be
+taken as the image of reference</strong>. Hence, in order to align the
+first Xenium Replicate to the Visium dataset, we can create a list of
+two VoltRon objects as given below.</p>
+<pre class="r watch-out"><code>xen_reg &lt;- registerSpatialData(object_list = list(Vis, Xen_R2))</code></pre>
+<p><br></p>
+</div>
+<div id="manual-image-alignment" class="section level3">
+<h3>Manual Image Alignment</h3>
+<p>Given the diverse types of tissue sections and their complex
+morphology, we need an alternative alignment strategy if automated
+registration may fail. VoltRon allows <strong>manually choosing
+keypoints (or landmarks)</strong> on images that are locations on the
+tissue with structural/morphological similarity. Similar to the
+automated mode, <strong>the image on the center</strong> will be taken
+as reference and the users will be able to observe the quality of the
+registration and remove/reselect keypoints as they see fit.</p>
+<pre class="r watch-out"><code>xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2))</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/XeniumVisiumRegistration.gif" class="center"></p>
+<p><br></p>
+<p>You can save and use the same keypoints later, and reproduce the
+manual alignment without choosing keypoints for the second time.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- xen_reg$mapping_parameters
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters)</code></pre>
+<p>You can find a presaved set of parameters with selected manual
+keypoints <a
+href="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/SpatialDataAlignment/Xenium_vs_Visium/mapping_parameters_manual.rds">here</a>.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- readRDS(&quot;mapping_parameters_manual.rds&quot;)
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters)</code></pre>
+<p>If the pre-saved keypoints are available with parameters, the
+registration can also be performed without using the shiny app. By using
+<strong>interactive = FALSE</strong>, we can register images and VoltRon
+objects directly.</p>
+<pre class="r watch-out"><code>mapping_parameters &lt;- xen_reg$mapping_parameters
+xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Vis, Xen_R2), 
+                               mapping_parameters = mapping_parameters, 
+                               interactive = FALSE)</code></pre>
+<p>In case there are only two images, <strong>the first image will be
+taken as the image of reference</strong>. Hence, in order to align the
+first Xenium Replicate to the Visium dataset. We can create a list of
+two VoltRon objects as given below.</p>
+<pre class="r watch-out"><code>xen_reg &lt;- registerSpatialData(object_list = list(Vis, Xen_R2))</code></pre>
+<p><br></p>
+</div>
+<div id="combine-voltron-object" class="section level3">
+<h3>Combine VoltRon object</h3>
+<p>Now that the VoltRon objects of Xenium and Visium datasets are
+accurately aligned, we can combine these objects to create <strong>one
+VoltRon object with three layers</strong>. Since all sections are
+derived from the same tissue block, we want them to be associated with
+the same sample, hence we define the sample name as well. VoltRon will
+recognize that all layers are originated from the same sample/block, and
+choose the majority assay as the main assay.</p>
+<pre class="r watch-out"><code>merge_list &lt;- xen_reg$registered_spat
+VRBlock &lt;- merge(merge_list[[1]], merge_list[-1], samples = &quot;10XBlock&quot;)
+VRBlock</code></pre>
+<pre><code>10XBlock: 
+  Layers: Section1 Section2 Section3 
+Assays: Xenium(Main) Visium
+Features: RNA(Main) </code></pre>
+<p>Here, we can quickly check the change in spatial coordinate systems
+in the new tissue block. The <code>registerSpatialData</code> function
+syncronizes the coordinate systems of all VoltRon objects in the list
+before merging. Both Xenium sections have now two coordinate system
+where the registered system <strong>main_reg</strong> is the default
+one.</p>
+<pre class="r watch-out"><code>vrSpatialNames(VRBlock, assay = &quot;all&quot;)</code></pre>
+<pre><code>        Assay    Layer   Sample       Spatial     Main
+Assay1 Xenium Section1 10XBlock main,main_reg main_reg
+Assay2 Visium Section2 10XBlock          main     main
+Assay3 Xenium Section3 10XBlock main,main_reg main_reg</code></pre>
+<p><br></p>
+</div>
+<div id="datalabel-transfer-across-layers" class="section level3">
+<h3>Data/Label Transfer Across Layers</h3>
+<p>The combined VoltRon object of Visium and Xenium datasets can be used
+to transfer information across layers and assays. This is accomplished
+by aggregating and summarizing, for example, gene counts of cells from
+the Xenium assay aligned to Visium spots. Either labels or cell types
+can be summarized to generate:</p>
+<ul>
+<li>pseudo cell type abundance assays or</li>
+<li>pseudo gene expression assays.</li>
+</ul>
+<p><br></p>
+<div id="data-transfer-cells-spots" class="section level4">
+<h4>Data Transfer (Cells-&gt;Spots)</h4>
+<p>We must first determine the names of the assays where labels are
+transfered <strong>from</strong> one <strong>to</strong> the other. For
+the sake of this tutorial, we can select Assay1 of <strong>Xenium as the
+source</strong> assay and the Assay2 of <strong>Visium as the
+destination</strong> assay.</p>
+<pre class="r watch-out"><code>SampleMetadata(VRBlock)</code></pre>
+<pre><code>        Assay    Layer   Sample
+Assay1 Xenium Section1 10XBlock
+Assay2 Visium Section2 10XBlock
+Assay3 Xenium Section3 10XBlock</code></pre>
+<p>The <strong>transferData</strong> function detects the types of both
+the <strong>source (from)</strong> and the <strong>destination
+(to)</strong> assays and determines the how the data should be
+transfered. We can first transfer data from the Xenium assay to the
+Visium assay (hence <strong>Cells -&gt; Spots</strong>), the raw count
+data of each cell in the source Xenium assay will be aggregated into
+spots in a newly create pseudo Visium assay. The new assay with
+aggregated counts will be named <strong>Visium_pseudo</strong>.</p>
+<pre class="r watch-out"><code>VRBlock &lt;- transferData(VRBlock, from = &quot;Assay1&quot;, to = &quot;Assay2&quot;)</code></pre>
+<p>VoltRon supports multiple feature type within each assay. Now, the
+Visium assay includes two spot-type features:</p>
+<ul>
+<li>the original Visium spot feature counts,</li>
+<li>a pseudo Visium feature count matrix with aggregated Xenium raw
+counts.</li>
+</ul>
+<pre class="r watch-out"><code>vrMainAssay(VRBlock) &lt;- &quot;Visium&quot;
+VRBlock</code></pre>
+<pre><code>VoltRon Object 
+10XBlock: 
+  Layers: Section1 Section2 Section3 
+Assays: Visium(Main) Xenium 
+Features: RNA(Main) RNA_pseudo </code></pre>
+<p>We can now visualize both the original and aggregated counts of a
+gene, such as ERBB2 and ESR1 that marks ductal carcinoma in situ (DCIS)
+regions, to validate the correlation of gene signatures across adjacent
+tissue sections, and to validate the accuracy of the automated image
+alignment. Here, PGR is also expressed at a small DCIS region found on
+adipocyte niche of the tissue.</p>
+<pre class="r watch-out"><code>library(patchwork)
+vrMainFeatureType(VRBlock, assay = &quot;Visium&quot;) &lt;- &quot;RNA&quot;
+g1 &lt;- vrSpatialFeaturePlot(VRBlock,  
+                           features = c(&quot;ERBB2&quot;, &quot;ESR1&quot;, &quot;PGR&quot;), crop = FALSE, 
+                           norm = FALSE, ncol = 3)
+vrMainFeatureType(VRBlock, assay = &quot;Visium&quot;) &lt;- &quot;RNA_pseudo&quot;
+g2 &lt;- vrSpatialFeaturePlot(VRBlock, 
+                           features = c(&quot;ERBB2&quot;, &quot;ESR1&quot;, &quot;PGR&quot;), crop = FALSE, 
+                           norm = FALSE, ncol = 3)
+g1 / g2</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_TACSTD2.png" class="center"></p>
+</div>
+<div id="data-transfer-spots-cells" class="section level4">
+<h4>Data Transfer (Spots-&gt;Cells)</h4>
+<p>A similar transfer can be achieved on the opposite direction. We can
+select Assay2 of <strong>Visium as the source</strong> assay and Assay1
+of <strong>Xenium as the destination</strong>, thus we can transfer
+whole transcriptome counts of the Visium assays to Xenium to create new
+feature sets for Xenium data with more features originally available in
+the Xenium panel.</p>
+<pre class="r watch-out"><code>vrMainFeatureType(VRBlock, assay = &quot;Visium&quot;) &lt;- &quot;RNA&quot;
+VRBlock &lt;- transferData(VRBlock, from = &quot;Assay2&quot;, to = &quot;Assay1&quot;)</code></pre>
+<p>We now set the main feature set of the Xenium assays.</p>
+<pre class="r watch-out"><code>vrMainFeatureType(VRBlock, assay = &quot;Xenium&quot;) &lt;- &quot;RNA_pseudo&quot;
+vrMainFeatureType(VRBlock, assay = &quot;all&quot;)</code></pre>
+<pre><code>   Assay    Feature
+1 Assay1 RNA_pseudo
+2 Assay2        RNA
+3 Assay3        RNA</code></pre>
+<pre class="r watch-out"><code>library(patchwork)
+g1 &lt;- vrSpatialFeaturePlot(VRBlock, 
+                           assay = &quot;Assay1&quot;, features = c(&quot;ERBB2&quot;, &quot;ESR1&quot;, &quot;PGR&quot;), 
+                           crop = TRUE, norm = FALSE, alpha = 1, n.tile = 300, ncol = 3)
+g2 &lt;- vrSpatialFeaturePlot(VRBlock, 
+                           assay = &quot;Assay2&quot;, features = c(&quot;ERBB2&quot;, &quot;ESR1&quot;, &quot;PGR&quot;), 
+                           crop = TRUE, norm = FALSE, alpha = 1, ncol = 3)
+g1 / g2</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_spot2cell.png" class="center"></p>
+</div>
+<div id="label-transfer-cells-spots" class="section level4">
+<h4>Label Transfer (Cells-&gt;Spots)</h4>
+<p>The <strong>transferData</strong> function can also transfer
+<strong>metadata features</strong> across layers and assays. In this
+case, we will transfer cell type labels that were trained on the Xenium
+sections onto the Visium sections. We will use the cluster labels
+generated at the end of the Xenium analysis section of workflow from <a
+href="spotanalysis.html">Cell/Spot Analysis</a>. You can download the
+VoltRon object with clustered and annotated Xenium cells along with the
+Visium assay from <a
+href="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/SpatialDataAlignment/Xenium_vs_Visium/VRBlock_data_clustered.rds">here</a>.</p>
+<pre class="r watch-out"><code>VRBlock &lt;- readRDS(&quot;VRBlock_data_clustered.rds&quot;)
+vrSpatialPlot(VRBlock, assay = &quot;Xenium&quot;, group.by = &quot;CellType&quot;, pt.size = 0.4)</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/cellspot_spatial_xenium_annotated.png" class="center"></p>
+<p>Here, we can see that both Xenium layers are clustered and annotated
+where we can use these cell annotations and transfer them to the Visium
+assay to create an assay of <strong>estimated cell type
+abundances</strong>. If the features argument is specified, and if its a
+single metadata feature with, e.g. cell types, then the each spot at the
+new pseudo Visium will be collection of abundances of the categories
+within that metadata feature.</p>
+<pre class="r watch-out"><code>VRBlock &lt;- transferData(VRBlock, from = &quot;Assay1&quot;, to = &quot;Assay2&quot;, features = &quot;CellType&quot;, 
+                        new_assay_name = &quot;Visium_CellType&quot;)
+VRBlock</code></pre>
+<pre><code>VoltRon Object 
+10XBlock: 
+  Layers: Section1 Section2 Section3 
+Assays: Visium(Main) Xenium 
+Features: RNA_pseudo(Main) RNA Visium_CellType </code></pre>
+<p>By visualizing the transferred labels on the Visium spots, we can see
+abundance of some DCIS and invasive tumor subtypes.</p>
+<pre class="r watch-out"><code>vrMainFeatureType(VRBlock) &lt;- &quot;Visium_CellType&quot;
+vrSpatialFeaturePlot(VRBlock, assay = &quot;Visium&quot;,
+                     features = c(&quot;IT_1&quot;,&quot;DCIS_2&quot;), 
+                     crop = TRUE, alpha = 1, ncol = 3)</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_CellType.png" class="center"></p>
+<p><br></p>
+</div>
+<div id="label-transfer-rois-" class="section level4">
+<h4>Label Transfer (ROIs-&gt;…)</h4>
+<p>VoltRon allows users to annotate regions of interests (ROIs) in a
+given assay and transfer the annotations to these ROIs across other
+assays within the same tissue block. Let us annotate two specific tumor
+regions in the Visium section. In the process, a new assay called
+<strong>ROIAnnotation</strong> will be added to the VoltRon object.</p>
+<pre class="r watch-out"><code>VRBlock &lt;- annotateSpatialData(VRBlock, assay = &quot;Visium&quot;, 
+                               label = &quot;annotation&quot;, use.image.only = TRUE)</code></pre>
+<p><img width="80%" height="80%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_ROIAnnotation.png" class="center"></p>
+<p><br></p>
+<p>You can observe the changes in the object and check the assay ID of
+this new ROI type assay using <code>SampleMetadata</code> function.</p>
+<pre class="r watch-out"><code>VRBlock</code></pre>
+<pre><code>VoltRon Object 
+10XBlock: 
+  Layers: Section1 Section2 Section3 
+Assays: Xenium(Main) Visium ROIAnnotation 
+Features: RNA(Main) </code></pre>
+<pre class="r watch-out"><code>SampleMetadata(VRBlock)</code></pre>
+<pre><code>               Assay    Layer   Sample
+Assay1        Xenium Section1 10XBlock
+Assay2        Visium Section2 10XBlock
+Assay3        Xenium Section3 10XBlock
+Assay4 ROIAnnotation Section2 10XBlock</code></pre>
+<p>The metadata of the ROI assay will include the annotation of the ROIs
+as well.</p>
+<pre class="r watch-out"><code>Metadata(VRBlock, assay = &quot;ROIAnnotation&quot;)</code></pre>
+<pre><code>                               Assay    Layer   Sample      annotation
+InvasiveTumor_Assay4   ROIAnnotation Section2 10XBlock   InvasiveTumor
+DuctalCarcinoma_Assay4 ROIAnnotation Section2 10XBlock DuctalCarcinoma</code></pre>
+<p>Now we can transfer the ROI labels from the
+<strong>annotation</strong> metadata column and define the same metadata
+column in the remaining assays.</p>
+<pre class="r watch-out"><code>VRBlock &lt;- transferData(object = VRBlock, from = &quot;Assay4&quot;, to = &quot;Assay1&quot;, 
+                        features = &quot;annotation&quot;)
+VRBlock &lt;- transferData(object = VRBlock, from = &quot;Assay4&quot;, to = &quot;Assay3&quot;, 
+                        features = &quot;annotation&quot;)</code></pre>
+<p>Let us observe the changes across all assays.</p>
+<pre class="r watch-out"><code>vrSpatialPlot(VRBlock, group.by = &quot;annotation&quot;, assay = &quot;Xenium&quot;, crop = TRUE)
+vrSpatialPlot(VRBlock, group.by = &quot;annotation&quot;, assay = &quot;Visium&quot;, crop = TRUE)</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_ROI_xenium.png" class="center"></p>
+<p><img width="50%" height="50%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_ROI_visium.png" class="center"></p>
+<p><br></p>
+<p>You can also use the <strong>addSpatialLayer</strong> function to
+overlay annotation segments to the spatial plot of the Xenium data.</p>
+<pre class="r watch-out"><code>vrSpatialPlot(VRBlock_new2, group.by = &quot;CellType&quot;, assay = &quot;Assay1&quot;, crop = TRUE) |&gt;
+  addSpatialLayer(VRBlock_new2, assay = &quot;ROIAnnotation&quot;, group.by = &quot;annotation&quot;, spatial = &quot;main&quot;, alpha = 0.4)</code></pre>
+<p><img width="50%" height="50%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_ROI_xenium_overlay.png" class="center"></p>
+<p><br></p>
+</div>
+</div>
+</div>
+<div id="alignment-of-xenium-and-he" class="section level2">
+<h2>Alignment of Xenium and H&amp;E</h2>
+<p>In this use case, we will align <strong>immunofluorescence
+(IF)</strong> of the <strong>Xenium In Situ</strong> platform to an
+<strong>H&amp;E images</strong> generated from the same sections as the
+Xenium. VoltRon provides built-in utilities to import images as spatial
+datasets where <strong>tiles</strong> are the spatial points. We will
+import both Xenium and H&amp;E images into two separate VoltRon objects
+and overlay H&amp;E images.</p>
+<p>You can download the Xenium readout and the H&amp;E image of the same
+tissue section from the <a
+href="https://www.10xgenomics.com/products/xenium-in-situ/preview-dataset-human-breast">10x
+Genomics website</a> (specifically, import <strong>In Situ Replicate
+1</strong> and <strong>Supplemental: Post-Xenium H&amp;E image
+(TIFF)</strong>).</p>
+<pre class="r watch-out"><code>library(VoltRon)
+
+# import Xenium 
+Xen_R1 &lt;- importXenium(&quot;Xenium_R1/outs&quot;, sample_name = &quot;XeniumR1&quot;)
+
+# import H&amp;E image and build a VoltRon object
+Xen_R1_image &lt;- importImageData(&quot;Xenium_FFPE_Human_Breast_Cancer_Rep1_he_image.tif&quot;,
+                                sample_name = &quot;XeniumR1image&quot;, 
+                                channel_names = &quot;H&amp;E&quot;)
+Xen_R1_image</code></pre>
+<pre><code>VoltRon Object 
+XeniumR1image: 
+  Layers: Section1 
+Assays: ImageData(Main) </code></pre>
+<p>Lets take a look at the image of the Xen_R1_image object</p>
+<pre class="r watch-out"><code>vrImages(Xen_R1_image)</code></pre>
+<p><img width="70%" height="70%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/importdata_HE.png" class="center"></p>
+<p><br></p>
+<div id="automated-image-alignment-1" class="section level3">
+<h3>Automated Image Alignment</h3>
+<p>We can use the <strong>registerSpatialData</strong> function to
+warp/align images across multiple VoltRon objects and define these
+aligned images additional channels of existing coordinate systems of
+assays in one of these VoltRon objects.</p>
+<p>First we align the H&amp;E image to the DAPI image of the Xenium
+replicate. Similar to the first use case, we need to negate the DAPI
+image and change the alignment of the image to match it with the H&amp;E
+image. We can also scale the resolution of the H&amp;E image to
+9103.71x6768.63.</p>
+<pre class="r watch-out"><code>xen_reg &lt;- registerSpatialData(object_list = list(Xen_R1, Xen_R1_image))</code></pre>
+<p><img width="92%" height="92%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_HE_function.png" class="center"></p>
+<p><br></p>
+<p>Now we create a new channel for the existing coordinate system of the
+Xenium data. Here, the spatial key of the registered H&amp;E image will
+be <strong>main_reg</strong>. We choose the destination of the
+registered image which is the first Assay of the Xenium data
+(i.e. <strong>Assay1</strong>). The original DAPI coordinate system, and
+we give a name for the new image/channel which is
+<strong>H&amp;E</strong>.</p>
+<pre class="r watch-out"><code>Xen_R1_image_reg &lt;- xen_reg$registered_spat[[2]]
+vrImages(Xen_R1[[&quot;Assay1&quot;]], channel = &quot;H&amp;E&quot;) &lt;- vrImages(Xenium_reg, name = &quot;main_reg&quot;, channel = &quot;H&amp;E&quot;)</code></pre>
+<p>We can now observe the new channels (H&amp;E) available for the
+Xenium assay using <strong>vrImageChannelNames</strong>.</p>
+<pre class="r watch-out"><code>vrImageChannelNames(Xen_R1)</code></pre>
+<pre><code>       Assay    Layer           Sample Spatial                                               Channels
+Assay1 GeoMx Section1 prolonged case 4    main scanimage,DNA,PanCK,CD45,Alpha Smooth Muscle Actin,H&amp;E</code></pre>
+<p>We can call the registered H&amp;E image of the Xenium data or later
+put the aligned H&amp;E when calling <strong>vrSpatialPlot</strong> or
+<strong>vrSpatialFeaturePlot</strong>.</p>
+<pre class="r watch-out"><code>vrImages(Xen_R1, channel = &quot;H&amp;E&quot;, scale.perc = 5)</code></pre>
+<p><img width="70%" height="70%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/registration_HE.png" class="center"></p>
+<p><br></p>
+</div>
+</div>
+<div id="alignment-of-visium-and-visium" class="section level2">
+<h2>Alignment of Visium and Visium</h2>
+<p>In the next use case, we will align <strong>H&amp;E images</strong>
+associated with Visium data generated from tissue block sections of
+<strong>adult humans with postmortem dorsolateral prefrontal cortex
+(DLPFC)</strong>. Two pairs of adjacent sections was obtained from the
+tissue block of the third donor. Each pair are composed of two 10 <span
+class="math inline">\(\mu\)</span>m serial tissue sections, and pairs
+are located 300 <span class="math inline">\(\mu\)</span>m apart from
+each other. Hence, we align each pair individually. The datasets can be
+downloaded from <a
+href="https://research.libd.org/spatialLIBD/">here</a>.</p>
+<pre class="r watch-out"><code>library(VoltRon)
+DLPFC_1 &lt;- importVisium(&quot;DLPFC/151673&quot;, sample_name = &quot;DLPFC_1&quot;)
+DLPFC_2 &lt;- importVisium(&quot;DLPFC/151674&quot;, sample_name = &quot;DLPFC_2&quot;)
+DLPFC_3 &lt;- importVisium(&quot;DLPFC/151675&quot;, sample_name = &quot;DLPFC_3&quot;)
+DLPFC_4 &lt;- importVisium(&quot;DLPFC/151676&quot;, sample_name = &quot;DLPFC_4&quot;)</code></pre>
+<p><br></p>
+<div id="automated-image-alignment-2" class="section level3">
+<h3>Automated Image Alignment</h3>
+<p>We will again use the registerSpatialData function to
+<strong>automatically register two Visium assays (two H&amp;E
+images)</strong>. This time, we will use the
+<strong>BRUTE-FORCE</strong> method for automated alignment which we
+found to be more accurate compared to FLANN when aligning two H&amp;E
+images. The shiny app also provides two tuning parameters that used by
+the the BRUTE-FORCE workflow:</p>
+<ul>
+<li><strong># of Features</strong> option specifies the number of
+maximum image features spotted within each image which later be used to
+match to the other image.</li>
+<li><strong>Match %</strong> specifies the percentage of these features
+matching at max which in turn used to compute the
+registration/transformation matrix.</li>
+</ul>
+<p>We will use <strong>1000 features</strong> for this alignment, set
+<strong>Match %</strong> to 20% of the features to be matched across
+images. The quality of the alignment will be determined by the fine
+tuning of these parameters where users will immediately observe the
+alignment quality looking at the slideshow.</p>
+<pre class="r watch-out"><code>DLPFC_list &lt;- list(DLPFC_1, DLPFC_2)
+reg1and2 &lt;- registerSpatialData(object_list = DLPFC_list)</code></pre>
+<p><img width="100%" height="100%" src="https://bimsbstatic.mdc-berlin.de/landthaler/VoltRon/Package/images/VisiumDLFPCRegistration.gif" class="center"></p>
+<p><br></p>
+<p>We can now apply a similar alignment across the second pair of
+VoltRon objects. We will use <strong>800 features</strong> for this
+alignment, set <strong>Match %</strong> to 50% of the features to be
+matched across images.</p>
+<pre class="r watch-out"><code>DLPFC_list &lt;- list(DLPFC_3, DLPFC_4)
+reg3and4 &lt;- registerSpatialData(object_list = DLPFC_list)</code></pre>
+<p><br></p>
+</div>
+<div id="d-spot-clustering" class="section level3">
+<h3>3D Spot Clustering</h3>
+<p>We can now combine all sections into one VoltRon object. There are
+two pairs of serial tissue sections, but both pairs (thus 4 sections)
+are from the same tissue block. Hence, we can combine these two lists
+into one list and merge VoltRon objects even though sections were
+aligned separately.</p>
+<pre class="r watch-out"><code>merge_list &lt;- c(reg1and2$registered_spat, reg3and4$registered_spat)
+SRBlock &lt;- merge(merge_list[[1]], merge_list[-1], samples = &quot;DLPFC_Block&quot;)
+SRBlock</code></pre>
+<pre><code>VoltRon Object 
+DLPFC_Block: 
+  Layers: Section1 Section2 Section3 Section4 
+Assays: Visium(Main) </code></pre>
+<p><br></p>
+<p>Aligning spots along the z dimension allows us to cluster these spots
+using both the gene expression similarities and spatial adjacency (both
+along the x-y direction and in the z direction). We first generate a
+spatial neighborhood graph and use this graph along with the gene
+expression neighborhood graph <strong>(under development)</strong>.</p>
+</div>
+</div>
+</div>
+
+
+
+</div>
+</div>
+
+</div>
+
+<script>
+
+// add bootstrap table styles to pandoc tables
+function bootstrapStylePandocTables() {
+  $('tr.odd').parent('tbody').parent('table').addClass('table table-condensed');
+}
+$(document).ready(function () {
+  bootstrapStylePandocTables();
+});
+
+
+</script>
+
+<!-- tabsets -->
+
+<script>
+$(document).ready(function () {
+  window.buildTabsets("TOC");
+});
+
+$(document).ready(function () {
+  $('.tabset-dropdown > .nav-tabs > li').click(function () {
+    $(this).parent().toggleClass('nav-tabs-open');
+  });
+});
+</script>
+
+<!-- code folding -->
+
+<script>
+$(document).ready(function ()  {
+
+    // temporarily add toc-ignore selector to headers for the consistency with Pandoc
+    $('.unlisted.unnumbered').addClass('toc-ignore')
+
+    // move toc-ignore selectors from section div to header
+    $('div.section.toc-ignore')
+        .removeClass('toc-ignore')
+        .children('h1,h2,h3,h4,h5').addClass('toc-ignore');
+
+    // establish options
+    var options = {
+      selectors: "h1,h2,h3,h4,h5",
+      theme: "bootstrap3",
+      context: '.toc-content',
+      hashGenerator: function (text) {
+        return text.replace(/[.\\/?&!#<>]/g, '').replace(/\s/g, '_');
+      },
+      ignoreSelector: ".toc-ignore",
+      scrollTo: 0
+    };
+    options.showAndHide = false;
+    options.smoothScroll = true;
+
+    // tocify
+    var toc = $("#TOC").tocify(options).data("toc-tocify");
+});
+</script>
+
+<!-- dynamically load mathjax for compatibility with self-contained -->
+<script>
+  (function () {
+    var script = document.createElement("script");
+    script.type = "text/javascript";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    document.getElementsByTagName("head")[0].appendChild(script);
+  })();
+</script>
+
+</body>
+</html>