<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://blog.dask.org</id>
  <title>Dask Working Notes - Posts tagged dask-image</title>
  <updated>2026-03-05T15:05:26.119743+00:00</updated>
  <link href="https://blog.dask.org"/>
  <link href="https://blog.dask.org/blog/tag/dask-image/atom.xml" rel="self"/>
  <generator uri="https://ablog.readthedocs.io/" version="0.11.12">ABlog</generator>
  <entry>
    <id>https://blog.dask.org/2019/06/20/load-image-data/</id>
    <title>Load Large Image Data with Dask Array</title>
    <updated>2019-06-20T00:00:00+00:00</updated>
    <author>
      <name>John Kirkham</name>
    </author>
    <content type="html">&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 9)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;section id="executive-summary"&gt;

&lt;p&gt;This post explores simple workflows to load large stacks of image data with Dask array.&lt;/p&gt;
&lt;p&gt;In particular, we start with a &lt;a class="reference external" href="https://drive.google.com/drive/folders/13mpIfqspKTIINkfoWbFsVtFF8D7jbTqJ"&gt;directory full of TIFF
files&lt;/a&gt;
of images like the following:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ $ ls raw/ | head
ex6-2_CamA_ch1_CAM1_stack0000_560nm_0000000msec_0001291795msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0001_560nm_0043748msec_0001335543msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0002_560nm_0087497msec_0001379292msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0003_560nm_0131245msec_0001423040msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0004_560nm_0174993msec_0001466788msecAbs_000x_000y_000z_0000t.tif
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and show how to stitch these together into large lazy arrays
using the &lt;a class="reference external" href="https://image.dask.org/en/latest/"&gt;dask-image&lt;/a&gt; library&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;dask_image&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dask_image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;raw/*.tif&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;or by writing your own Dask delayed image reader function.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 3.16 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (2010, 1024, 768) &lt;/td&gt; &lt;td&gt; (201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 30 Tasks &lt;/td&gt;&lt;td&gt; 10 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="176" height="181" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="80" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="10" y1="61" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="10" y2="61" style="stroke-width:2" /&gt;
  &lt;line x1="17" y1="7" x2="17" y2="68" /&gt;
  &lt;line x1="24" y1="14" x2="24" y2="75" /&gt;
  &lt;line x1="31" y1="21" x2="31" y2="82" /&gt;
  &lt;line x1="38" y1="28" x2="38" y2="89" /&gt;
  &lt;line x1="45" y1="35" x2="45" y2="96" /&gt;
  &lt;line x1="52" y1="42" x2="52" y2="103" /&gt;
  &lt;line x1="59" y1="49" x2="59" y2="110" /&gt;
  &lt;line x1="66" y1="56" x2="66" y2="117" /&gt;
  &lt;line x1="73" y1="63" x2="73" y2="124" /&gt;
  &lt;line x1="80" y1="70" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 80.588235,70.588235 80.588235,131.722564 10.000000,61.134328" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="55" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="17" y1="7" x2="62" y2="7" /&gt;
  &lt;line x1="24" y1="14" x2="69" y2="14" /&gt;
  &lt;line x1="31" y1="21" x2="77" y2="21" /&gt;
  &lt;line x1="38" y1="28" x2="84" y2="28" /&gt;
  &lt;line x1="45" y1="35" x2="91" y2="35" /&gt;
  &lt;line x1="52" y1="42" x2="98" y2="42" /&gt;
  &lt;line x1="59" y1="49" x2="105" y2="49" /&gt;
  &lt;line x1="66" y1="56" x2="112" y2="56" /&gt;
  &lt;line x1="73" y1="63" x2="119" y2="63" /&gt;
  &lt;line x1="80" y1="70" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="80" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="55" y1="0" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 55.850746,0.000000 126.438982,70.588235 80.588235,70.588235" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="80" y1="70" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="80" y1="131" x2="126" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="80" y1="70" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;line x1="126" y1="70" x2="126" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="80.588235,70.588235 126.438982,70.588235 126.438982,131.722564 80.588235,131.722564" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="103.513608" y="151.722564" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="146.438982" y="101.155399" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,146.438982,101.155399)"&gt;1024&lt;/text&gt;
&lt;text x="35.294118" y="116.428446" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,35.294118,116.428446)"&gt;2010&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Some day we’ll eventually be able to perform complex calculations on this dask array.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/mrocklin/raw-host/gh-pages/images/aollsm-index-1.jpg"
     width="45%"
     alt="Light Microscopy data rendered with NVidia IndeX"&gt;
&lt;img src="https://raw.githubusercontent.com/mrocklin/raw-host/gh-pages/images/aollsm-index-2.jpg"
     width="45%"
     alt="Light Microscopy data rendered with NVidia IndeX"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: we’re not going to produce rendered images like the above in this
post. These were created with &lt;a class="reference external" href="https://developer.nvidia.com/index"&gt;NVidia
IndeX&lt;/a&gt;, a completely separate tool chain
from what is being discussed here. This post covers the first step of image
loading.&lt;/em&gt;&lt;/p&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 128)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="series-overview"&gt;
&lt;h1&gt;Series Overview&lt;/h1&gt;
&lt;p&gt;A common case in fields that acquire large amounts of imaging data is to write
out smaller acquisitions into many small files. These files can tile a larger
space, sub-sample from a larger time period, and may contain multiple channels.
The acquisition techniques themselves are often state of the art and constantly
pushing the envelope in term of how large a field of view can be acquired, at
what resolution, and what quality.&lt;/p&gt;
&lt;p&gt;Once acquired this data presents a number of challenges. Algorithms often
designed and tested to work on very small pieces of this data need to be scaled
up to work on the full dataset. It might not be clear at the outset what will
actually work and so exploration still plays a very big part of the whole
process.&lt;/p&gt;
&lt;p&gt;Historically this analytical process has involved a lot of custom code. Often
the analytical process is stitched together by a series of scripts possibly in
several different languages that write various intermediate results to disk.
Thanks to advances in modern tooling these process can be significantly
improved. In this series of blogposts, we will outline ways for image
scientists to leverage different tools to move towards a high level, friendly,
cohesive, interactive analytical pipeline.&lt;/p&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 151)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="post-overview"&gt;
&lt;h1&gt;Post Overview&lt;/h1&gt;
&lt;p&gt;This post in particular focuses on loading and managing large stacks of image
data in parallel from Python.&lt;/p&gt;
&lt;p&gt;Loading large image data can be a complex and often unique problem. Different
groups may choose to store this across many files on disk, a commodity or
custom database solution, or they may opt to store it in the cloud. Not all
datasets within the same group may be treated the same for a variety of
reasons. In short, this means loading data is a hard and expensive problem.&lt;/p&gt;
&lt;p&gt;Despite data being stored in many different ways, often groups want to reapply
the same analytical pipeline to these datasets. However if the data pipeline is
tightly coupled to a particular way of loading the data for later analytical
steps, it may be very difficult if not impossible to reuse an existing
pipeline. In other words, there is friction between the loading and analysis
steps, which frustrates efforts to make things reusable.&lt;/p&gt;
&lt;p&gt;Having a modular and general way to load data makes it easy to present data
stored differently in a standard way. Further having a standard way to present
data to analytical pipelines allows that part of the pipeline to focus on what
it does best, analysis! In general, this should decouple these to components in
a way that improves the experience of users involved in all parts of the
pipeline.&lt;/p&gt;
&lt;p&gt;We will use
&lt;a class="reference external" href="https://drive.google.com/drive/folders/13mpIfqspKTIINkfoWbFsVtFF8D7jbTqJ"&gt;image data&lt;/a&gt;
generously provided by
&lt;a class="reference external" href="https://scholar.google.com/citations?user=nxwNAEgAAAAJ&amp;amp;amp;hl=en"&gt;Gokul Upadhyayula&lt;/a&gt;
at the
&lt;a class="reference external" href="http://microscopy.berkeley.edu/"&gt;Advanced Bioimaging Center&lt;/a&gt;
at UC Berkeley and discussed in
&lt;a class="reference external" href="https://science.sciencemag.org/content/360/6386/eaaq1392"&gt;this paper&lt;/a&gt;
(&lt;a class="reference external" href="https://www.biorxiv.org/content/10.1101/243352v2"&gt;preprint&lt;/a&gt;),
though the workloads presented here should work for any kind of imaging data,
or array data generally.&lt;/p&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 188)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="load-image-data-with-dask"&gt;
&lt;h1&gt;Load image data with Dask&lt;/h1&gt;
&lt;p&gt;Let’s start again with our image data from the top of the post:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ $ ls /path/to/files/raw/ | head
ex6-2_CamA_ch1_CAM1_stack0000_560nm_0000000msec_0001291795msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0001_560nm_0043748msec_0001335543msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0002_560nm_0087497msec_0001379292msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0003_560nm_0131245msec_0001423040msecAbs_000x_000y_000z_0000t.tif
ex6-2_CamA_ch1_CAM1_stack0004_560nm_0174993msec_0001466788msecAbs_000x_000y_000z_0000t.tif
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="load-a-single-sample-image-with-scikit-image"&gt;
&lt;h2&gt;Load a single sample image with Scikit-Image&lt;/h2&gt;
&lt;p&gt;To load a single image, we use &lt;a class="reference external" href="https://scikit-image.org/"&gt;Scikit-Image&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;glob&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;filenames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/path/to/files/raw/*.tif&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;597&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;imageio&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imageio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;span class="go"&gt;(201, 1024, 768)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each filename corresponds to some 3d chunk of a larger image. We can look at a
few 2d slices of this single 3d chunk to get some context.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;plt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;skimage.io&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;skimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/mrocklin/raw-host/gh-pages/images/aollsm-sample-1.png"
     width="60%"&gt;&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;skimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/mrocklin/raw-host/gh-pages/images/aollsm-sample-2.png"
     width="60%"&gt;&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;skimage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/mrocklin/raw-host/gh-pages/images/aollsm-sample-3.png"
     width="60%"&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="investigate-filename-structure"&gt;
&lt;h2&gt;Investigate Filename Structure&lt;/h2&gt;
&lt;p&gt;These are slices from only one chunk of a much larger aggregate image.
Our interest here is combining the pieces into a large image stack.
It is common to see a naming structure in the filenames. Each
filename then may indicate a channel, time step, and spatial location with the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;i&amp;gt;&lt;/span&gt;&lt;/code&gt; being some numeric values (possibly with units). Individual filenames may
have more or less information and may notate it differently than we have.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;mydata_ch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;t_&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x_&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;y_&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tif&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In principle with NumPy we might allocate a giant array and then iteratively
load images and place them into the giant array.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;full_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imageio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_location_from_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# We need to write this function&lt;/span&gt;
    &lt;span class="n"&gt;full_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However if our data is large then we can’t load it all into memory at once like
this into a single Numpy array, and instead we need to be a bit more clever to
handle it efficiently. One approach here is to use &lt;a class="reference external" href="https://dask.org"&gt;Dask&lt;/a&gt;,
which handles larger-than-memory workloads easily.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="lazily-load-images-with-dask-array"&gt;
&lt;h2&gt;Lazily load images with Dask Array&lt;/h2&gt;
&lt;p&gt;Now we learn how to lazily load and stitch together image data with Dask array.
We’ll start with simple examples first and then move onto the full example with
this more complex dataset afterwards.&lt;/p&gt;
&lt;p&gt;We can delay the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;imageio.imread&lt;/span&gt;&lt;/code&gt; calls with &lt;a class="reference external" href="https://docs.dassk.org/en/latest/delayed.html"&gt;Dask
Delayed&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;dask&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;dask.array&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;da&lt;/span&gt;

&lt;span class="n"&gt;lazy_arrays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;lazy_arrays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Note: here we’re assuming that all of the images have the same shape and dtype
as the sample file that we loaded above. This is not always the case. See the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dask_image&lt;/span&gt;&lt;/code&gt; note below in the Future Work section for an alternative.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We haven’t yet stitched these together. We have hundreds of single-chunk Dask
arrays, each of which lazily loads a single 3d chunk of data from disk. Lets look at a single array.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 316.15 MB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (201, 1024, 768) &lt;/td&gt; &lt;td&gt; (201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 2 Tasks &lt;/td&gt;&lt;td&gt; 1 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="174" height="194" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="34" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="10" y1="120" x2="34" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="10" y2="120" style="stroke-width:2" /&gt;
  &lt;line x1="34" y1="24" x2="34" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 34.664918,24.664918 34.664918,144.664918 10.000000,120.000000" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="100" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="34" y1="24" x2="124" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="34" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="100" y1="0" x2="124" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 100.000000,0.000000 124.664918,24.664918 34.664918,24.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="34" y1="24" x2="124" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="34" y1="144" x2="124" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="34" y1="24" x2="34" y2="144" style="stroke-width:2" /&gt;
  &lt;line x1="124" y1="24" x2="124" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="34.664918,24.664918 124.664918,24.664918 124.664918,144.664918 34.664918,144.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="79.664918" y="164.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="144.664918" y="84.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,144.664918,84.664918)"&gt;1024&lt;/text&gt;
&lt;text x="12.332459" y="152.332459" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,12.332459,152.332459)"&gt;201&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;This is a lazy 3-dimensional Dask array of a &lt;em&gt;single&lt;/em&gt; 300MB chunk of data.
That chunk is created by loading in a particular TIFF file. Normally Dask
arrays are composed of &lt;em&gt;many&lt;/em&gt; chunks. We can concatenate many of these
single-chunked Dask arrays into a multi-chunked Dask array with functions like
&lt;a class="reference external" href="https://docs.dask.org/en/latest/array-api.html#dask.array.concatenate"&gt;da.concatenate&lt;/a&gt;
and
&lt;a class="reference external" href="https://docs.dask.org/en/latest/array-api.html#dask.array.stack"&gt;da.stack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here we concatenate the first ten Dask arrays along a few axes, to get an
easier-to-understand picture of how this looks. Take a look both at how the
shape changes as we change the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;axis=&lt;/span&gt;&lt;/code&gt; parameter both in the table on the left
and the image on the right.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 3.16 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (2010, 1024, 768) &lt;/td&gt; &lt;td&gt; (201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 30 Tasks &lt;/td&gt;&lt;td&gt; 10 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="176" height="181" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="80" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="10" y1="61" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="10" y2="61" style="stroke-width:2" /&gt;
  &lt;line x1="17" y1="7" x2="17" y2="68" /&gt;
  &lt;line x1="24" y1="14" x2="24" y2="75" /&gt;
  &lt;line x1="31" y1="21" x2="31" y2="82" /&gt;
  &lt;line x1="38" y1="28" x2="38" y2="89" /&gt;
  &lt;line x1="45" y1="35" x2="45" y2="96" /&gt;
  &lt;line x1="52" y1="42" x2="52" y2="103" /&gt;
  &lt;line x1="59" y1="49" x2="59" y2="110" /&gt;
  &lt;line x1="66" y1="56" x2="66" y2="117" /&gt;
  &lt;line x1="73" y1="63" x2="73" y2="124" /&gt;
  &lt;line x1="80" y1="70" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 80.588235,70.588235 80.588235,131.722564 10.000000,61.134328" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="55" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="17" y1="7" x2="62" y2="7" /&gt;
  &lt;line x1="24" y1="14" x2="69" y2="14" /&gt;
  &lt;line x1="31" y1="21" x2="77" y2="21" /&gt;
  &lt;line x1="38" y1="28" x2="84" y2="28" /&gt;
  &lt;line x1="45" y1="35" x2="91" y2="35" /&gt;
  &lt;line x1="52" y1="42" x2="98" y2="42" /&gt;
  &lt;line x1="59" y1="49" x2="105" y2="49" /&gt;
  &lt;line x1="66" y1="56" x2="112" y2="56" /&gt;
  &lt;line x1="73" y1="63" x2="119" y2="63" /&gt;
  &lt;line x1="80" y1="70" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="80" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="55" y1="0" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 55.850746,0.000000 126.438982,70.588235 80.588235,70.588235" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="80" y1="70" x2="126" y2="70" style="stroke-width:2" /&gt;
  &lt;line x1="80" y1="131" x2="126" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="80" y1="70" x2="80" y2="131" style="stroke-width:2" /&gt;
  &lt;line x1="126" y1="70" x2="126" y2="131" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="80.588235,70.588235 126.438982,70.588235 126.438982,131.722564 80.588235,131.722564" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="103.513608" y="151.722564" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="146.438982" y="101.155399" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,146.438982,101.155399)"&gt;1024&lt;/text&gt;
&lt;text x="35.294118" y="116.428446" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,35.294118,116.428446)"&gt;2010&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 3.16 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (201, 10240, 768) &lt;/td&gt; &lt;td&gt; (201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 30 Tasks &lt;/td&gt;&lt;td&gt; 10 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="113" height="187" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="27" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="10" y1="12" x2="27" y2="29" /&gt;
  &lt;line x1="10" y1="24" x2="27" y2="41" /&gt;
  &lt;line x1="10" y1="36" x2="27" y2="53" /&gt;
  &lt;line x1="10" y1="48" x2="27" y2="65" /&gt;
  &lt;line x1="10" y1="60" x2="27" y2="77" /&gt;
  &lt;line x1="10" y1="72" x2="27" y2="89" /&gt;
  &lt;line x1="10" y1="84" x2="27" y2="101" /&gt;
  &lt;line x1="10" y1="96" x2="27" y2="113" /&gt;
  &lt;line x1="10" y1="108" x2="27" y2="125" /&gt;
  &lt;line x1="10" y1="120" x2="27" y2="137" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="10" y2="120" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="17" x2="27" y2="137" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 27.014952,17.014952 27.014952,137.014952 10.000000,120.000000" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="46" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="17" x2="63" y2="17" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="27" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="46" y1="0" x2="63" y2="17" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 46.948234,0.000000 63.963186,17.014952 27.014952,17.014952" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="27" y1="17" x2="63" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="29" x2="63" y2="29" /&gt;
  &lt;line x1="27" y1="41" x2="63" y2="41" /&gt;
  &lt;line x1="27" y1="53" x2="63" y2="53" /&gt;
  &lt;line x1="27" y1="65" x2="63" y2="65" /&gt;
  &lt;line x1="27" y1="77" x2="63" y2="77" /&gt;
  &lt;line x1="27" y1="89" x2="63" y2="89" /&gt;
  &lt;line x1="27" y1="101" x2="63" y2="101" /&gt;
  &lt;line x1="27" y1="113" x2="63" y2="113" /&gt;
  &lt;line x1="27" y1="125" x2="63" y2="125" /&gt;
  &lt;line x1="27" y1="137" x2="63" y2="137" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="27" y1="17" x2="27" y2="137" style="stroke-width:2" /&gt;
  &lt;line x1="63" y1="17" x2="63" y2="137" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="27.014952,17.014952 63.963186,17.014952 63.963186,137.014952 27.014952,137.014952" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="45.489069" y="157.014952" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="83.963186" y="77.014952" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,83.963186,77.014952)"&gt;10240&lt;/text&gt;
&lt;text x="8.507476" y="148.507476" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,8.507476,148.507476)"&gt;201&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 3.16 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (201, 1024, 7680) &lt;/td&gt; &lt;td&gt; (201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 30 Tasks &lt;/td&gt;&lt;td&gt; 10 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="197" height="108" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="27" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="10" y1="40" x2="27" y2="58" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="10" y2="40" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="17" x2="27" y2="58" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 27.988258,17.988258 27.988258,58.112379 10.000000,40.124121" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="10" y1="0" x2="130" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="17" x2="147" y2="17" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="10" y1="0" x2="27" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="22" y1="0" x2="39" y2="17" /&gt;
  &lt;line x1="34" y1="0" x2="51" y2="17" /&gt;
  &lt;line x1="46" y1="0" x2="63" y2="17" /&gt;
  &lt;line x1="58" y1="0" x2="75" y2="17" /&gt;
  &lt;line x1="70" y1="0" x2="87" y2="17" /&gt;
  &lt;line x1="82" y1="0" x2="99" y2="17" /&gt;
  &lt;line x1="94" y1="0" x2="111" y2="17" /&gt;
  &lt;line x1="106" y1="0" x2="123" y2="17" /&gt;
  &lt;line x1="118" y1="0" x2="135" y2="17" /&gt;
  &lt;line x1="130" y1="0" x2="147" y2="17" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="10.000000,0.000000 130.000000,0.000000 147.988258,17.988258 27.988258,17.988258" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="27" y1="17" x2="147" y2="17" style="stroke-width:2" /&gt;
  &lt;line x1="27" y1="58" x2="147" y2="58" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="27" y1="17" x2="27" y2="58" style="stroke-width:2" /&gt;
  &lt;line x1="39" y1="17" x2="39" y2="58" /&gt;
  &lt;line x1="51" y1="17" x2="51" y2="58" /&gt;
  &lt;line x1="63" y1="17" x2="63" y2="58" /&gt;
  &lt;line x1="75" y1="17" x2="75" y2="58" /&gt;
  &lt;line x1="87" y1="17" x2="87" y2="58" /&gt;
  &lt;line x1="99" y1="17" x2="99" y2="58" /&gt;
  &lt;line x1="111" y1="17" x2="111" y2="58" /&gt;
  &lt;line x1="123" y1="17" x2="123" y2="58" /&gt;
  &lt;line x1="135" y1="17" x2="135" y2="58" /&gt;
  &lt;line x1="147" y1="17" x2="147" y2="58" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="27.988258,17.988258 147.988258,17.988258 147.988258,58.112379 27.988258,58.112379" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="87.988258" y="78.112379" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;7680&lt;/text&gt;
&lt;text x="167.988258" y="38.050318" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,167.988258,38.050318)"&gt;1024&lt;/text&gt;
&lt;text x="8.994129" y="69.118250" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,8.994129,69.118250)"&gt;201&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Or, if we wanted to make a new dimension, we would use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;da.stack&lt;/span&gt;&lt;/code&gt;. In this
case note that we’ve run out of easily visible dimensions, so you should take
note of the listed shape in the table input on the left more than the picture
on the right. Notice that we’ve stacked these 3d images into a 4d image.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 3.16 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (10, 201, 1024, 768) &lt;/td&gt; &lt;td&gt; (1, 201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 30 Tasks &lt;/td&gt;&lt;td&gt; 10 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="354" height="194" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="0" y1="0" x2="25" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="0" y1="25" x2="25" y2="25" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" style="stroke-width:2" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="12" y1="0" x2="12" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="20" y1="0" x2="20" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="0.000000,0.000000 25.412617,0.000000 25.412617,25.412617 0.000000,25.412617" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="12.706308" y="45.412617" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;10&lt;/text&gt;
&lt;text x="45.412617" y="12.706308" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(0,45.412617,12.706308)"&gt;1&lt;/text&gt;&lt;/p&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="95" y1="0" x2="119" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="95" y1="120" x2="119" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="95" y1="0" x2="95" y2="120" style="stroke-width:2" /&gt;
  &lt;line x1="119" y1="24" x2="119" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="95.000000,0.000000 119.664918,24.664918 119.664918,144.664918 95.000000,120.000000" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="95" y1="0" x2="185" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="119" y1="24" x2="209" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="95" y1="0" x2="119" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="185" y1="0" x2="209" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="95.000000,0.000000 185.000000,0.000000 209.664918,24.664918 119.664918,24.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="119" y1="24" x2="209" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="119" y1="144" x2="209" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="119" y1="24" x2="119" y2="144" style="stroke-width:2" /&gt;
  &lt;line x1="209" y1="24" x2="209" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="119.664918,24.664918 209.664918,24.664918 209.664918,144.664918 119.664918,144.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="164.664918" y="164.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="229.664918" y="84.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,229.664918,84.664918)"&gt;1024&lt;/text&gt;
&lt;text x="97.332459" y="152.332459" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,97.332459,152.332459)"&gt;201&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;These are the common case situations, where you have a single axis along which
you want to stitch images together.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="full-example"&gt;
&lt;h2&gt;Full example&lt;/h2&gt;
&lt;p&gt;This works fine for combining along a single axis. However if we need to
combine across multiple we need to perform multiple concatenate steps.
Fortunately there is a simpler option &lt;a class="reference external" href="https://docs.dask.org/en/latest/array-api.html#dask.array.block"&gt;da.block&lt;/a&gt;, which can
concatenate along multiple axes at once if you give it a nested list of dask
arrays.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="n"&gt;laxy_array_00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazy_array_01&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lazy_array_10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazy_array_11&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We now do the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Parse each filename to learn where it should live in the larger array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;See how many files are in each of our relevant dimensions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate a NumPy object-dtype array of the appropriate size, where each
element of this array will hold a single-chunk Dask array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go through our filenames and insert the proper Dask array into the right
position&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;da.block&lt;/span&gt;&lt;/code&gt; on the result&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This code is a bit complex, but shows what this looks like in a real-world
setting&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Get various dimensions&lt;/span&gt;

&lt;span class="n"&gt;fn_comp_sets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;splitext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="n"&gt;fn_comp_sets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;fn_comp_sets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fn_comp_sets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn_comp_sets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;

&lt;span class="n"&gt;remap_comps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn_comp_sets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]))),&lt;/span&gt;
    &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn_comp_sets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Create an empty object array to organize each chunk that loads a TIFF&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remap_comps&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filenames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazy_arrays&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_ch&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_stack&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="c1"&gt;# Stitch together the many blocks into a single array&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;table&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;th&gt; Array &lt;/th&gt;&lt;th&gt; Chunk &lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;th&gt; Bytes &lt;/th&gt;&lt;td&gt; 188.74 GB &lt;/td&gt; &lt;td&gt; 316.15 MB &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Shape &lt;/th&gt;&lt;td&gt; (3, 199, 201, 1024, 768) &lt;/td&gt; &lt;td&gt; (1, 1, 201, 1024, 768) &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Count &lt;/th&gt;&lt;td&gt; 2985 Tasks &lt;/td&gt;&lt;td&gt; 597 Chunks &lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;th&gt; Type &lt;/th&gt;&lt;td&gt; uint16 &lt;/td&gt;&lt;td&gt; numpy.ndarray &lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;svg width="386" height="194" style="stroke:rgb(0,0,0);stroke-width:1" &gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="0" y1="0" x2="41" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="0" y1="8" x2="41" y2="8" /&gt;
  &lt;line x1="0" y1="16" x2="41" y2="16" /&gt;
  &lt;line x1="0" y1="25" x2="41" y2="25" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" style="stroke-width:2" /&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" /&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" /&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" /&gt;
  &lt;line x1="0" y1="0" x2="0" y2="25" /&gt;
  &lt;line x1="1" y1="0" x2="1" y2="25" /&gt;
  &lt;line x1="1" y1="0" x2="1" y2="25" /&gt;
  &lt;line x1="1" y1="0" x2="1" y2="25" /&gt;
  &lt;line x1="1" y1="0" x2="1" y2="25" /&gt;
  &lt;line x1="1" y1="0" x2="1" y2="25" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="2" y1="0" x2="2" y2="25" /&gt;
  &lt;line x1="3" y1="0" x2="3" y2="25" /&gt;
  &lt;line x1="3" y1="0" x2="3" y2="25" /&gt;
  &lt;line x1="3" y1="0" x2="3" y2="25" /&gt;
  &lt;line x1="3" y1="0" x2="3" y2="25" /&gt;
  &lt;line x1="3" y1="0" x2="3" y2="25" /&gt;
  &lt;line x1="4" y1="0" x2="4" y2="25" /&gt;
  &lt;line x1="4" y1="0" x2="4" y2="25" /&gt;
  &lt;line x1="4" y1="0" x2="4" y2="25" /&gt;
  &lt;line x1="4" y1="0" x2="4" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="5" y1="0" x2="5" y2="25" /&gt;
  &lt;line x1="6" y1="0" x2="6" y2="25" /&gt;
  &lt;line x1="6" y1="0" x2="6" y2="25" /&gt;
  &lt;line x1="6" y1="0" x2="6" y2="25" /&gt;
  &lt;line x1="6" y1="0" x2="6" y2="25" /&gt;
  &lt;line x1="6" y1="0" x2="6" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="7" y1="0" x2="7" y2="25" /&gt;
  &lt;line x1="8" y1="0" x2="8" y2="25" /&gt;
  &lt;line x1="8" y1="0" x2="8" y2="25" /&gt;
  &lt;line x1="8" y1="0" x2="8" y2="25" /&gt;
  &lt;line x1="8" y1="0" x2="8" y2="25" /&gt;
  &lt;line x1="9" y1="0" x2="9" y2="25" /&gt;
  &lt;line x1="9" y1="0" x2="9" y2="25" /&gt;
  &lt;line x1="9" y1="0" x2="9" y2="25" /&gt;
  &lt;line x1="9" y1="0" x2="9" y2="25" /&gt;
  &lt;line x1="9" y1="0" x2="9" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="10" y1="0" x2="10" y2="25" /&gt;
  &lt;line x1="11" y1="0" x2="11" y2="25" /&gt;
  &lt;line x1="11" y1="0" x2="11" y2="25" /&gt;
  &lt;line x1="11" y1="0" x2="11" y2="25" /&gt;
  &lt;line x1="11" y1="0" x2="11" y2="25" /&gt;
  &lt;line x1="11" y1="0" x2="11" y2="25" /&gt;
  &lt;line x1="12" y1="0" x2="12" y2="25" /&gt;
  &lt;line x1="12" y1="0" x2="12" y2="25" /&gt;
  &lt;line x1="12" y1="0" x2="12" y2="25" /&gt;
  &lt;line x1="12" y1="0" x2="12" y2="25" /&gt;
  &lt;line x1="13" y1="0" x2="13" y2="25" /&gt;
  &lt;line x1="13" y1="0" x2="13" y2="25" /&gt;
  &lt;line x1="13" y1="0" x2="13" y2="25" /&gt;
  &lt;line x1="13" y1="0" x2="13" y2="25" /&gt;
  &lt;line x1="13" y1="0" x2="13" y2="25" /&gt;
  &lt;line x1="14" y1="0" x2="14" y2="25" /&gt;
  &lt;line x1="14" y1="0" x2="14" y2="25" /&gt;
  &lt;line x1="14" y1="0" x2="14" y2="25" /&gt;
  &lt;line x1="14" y1="0" x2="14" y2="25" /&gt;
  &lt;line x1="14" y1="0" x2="14" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="15" y1="0" x2="15" y2="25" /&gt;
  &lt;line x1="16" y1="0" x2="16" y2="25" /&gt;
  &lt;line x1="16" y1="0" x2="16" y2="25" /&gt;
  &lt;line x1="16" y1="0" x2="16" y2="25" /&gt;
  &lt;line x1="16" y1="0" x2="16" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="17" y1="0" x2="17" y2="25" /&gt;
  &lt;line x1="18" y1="0" x2="18" y2="25" /&gt;
  &lt;line x1="18" y1="0" x2="18" y2="25" /&gt;
  &lt;line x1="18" y1="0" x2="18" y2="25" /&gt;
  &lt;line x1="18" y1="0" x2="18" y2="25" /&gt;
  &lt;line x1="18" y1="0" x2="18" y2="25" /&gt;
  &lt;line x1="19" y1="0" x2="19" y2="25" /&gt;
  &lt;line x1="19" y1="0" x2="19" y2="25" /&gt;
  &lt;line x1="19" y1="0" x2="19" y2="25" /&gt;
  &lt;line x1="19" y1="0" x2="19" y2="25" /&gt;
  &lt;line x1="19" y1="0" x2="19" y2="25" /&gt;
  &lt;line x1="20" y1="0" x2="20" y2="25" /&gt;
  &lt;line x1="20" y1="0" x2="20" y2="25" /&gt;
  &lt;line x1="20" y1="0" x2="20" y2="25" /&gt;
  &lt;line x1="20" y1="0" x2="20" y2="25" /&gt;
  &lt;line x1="21" y1="0" x2="21" y2="25" /&gt;
  &lt;line x1="21" y1="0" x2="21" y2="25" /&gt;
  &lt;line x1="21" y1="0" x2="21" y2="25" /&gt;
  &lt;line x1="21" y1="0" x2="21" y2="25" /&gt;
  &lt;line x1="21" y1="0" x2="21" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="22" y1="0" x2="22" y2="25" /&gt;
  &lt;line x1="23" y1="0" x2="23" y2="25" /&gt;
  &lt;line x1="23" y1="0" x2="23" y2="25" /&gt;
  &lt;line x1="23" y1="0" x2="23" y2="25" /&gt;
  &lt;line x1="23" y1="0" x2="23" y2="25" /&gt;
  &lt;line x1="23" y1="0" x2="23" y2="25" /&gt;
  &lt;line x1="24" y1="0" x2="24" y2="25" /&gt;
  &lt;line x1="24" y1="0" x2="24" y2="25" /&gt;
  &lt;line x1="24" y1="0" x2="24" y2="25" /&gt;
  &lt;line x1="24" y1="0" x2="24" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" /&gt;
  &lt;line x1="25" y1="0" x2="25" y2="25" /&gt;
  &lt;line x1="26" y1="0" x2="26" y2="25" /&gt;
  &lt;line x1="26" y1="0" x2="26" y2="25" /&gt;
  &lt;line x1="26" y1="0" x2="26" y2="25" /&gt;
  &lt;line x1="26" y1="0" x2="26" y2="25" /&gt;
  &lt;line x1="26" y1="0" x2="26" y2="25" /&gt;
  &lt;line x1="27" y1="0" x2="27" y2="25" /&gt;
  &lt;line x1="27" y1="0" x2="27" y2="25" /&gt;
  &lt;line x1="27" y1="0" x2="27" y2="25" /&gt;
  &lt;line x1="27" y1="0" x2="27" y2="25" /&gt;
  &lt;line x1="27" y1="0" x2="27" y2="25" /&gt;
  &lt;line x1="28" y1="0" x2="28" y2="25" /&gt;
  &lt;line x1="28" y1="0" x2="28" y2="25" /&gt;
  &lt;line x1="28" y1="0" x2="28" y2="25" /&gt;
  &lt;line x1="28" y1="0" x2="28" y2="25" /&gt;
  &lt;line x1="29" y1="0" x2="29" y2="25" /&gt;
  &lt;line x1="29" y1="0" x2="29" y2="25" /&gt;
  &lt;line x1="29" y1="0" x2="29" y2="25" /&gt;
  &lt;line x1="29" y1="0" x2="29" y2="25" /&gt;
  &lt;line x1="29" y1="0" x2="29" y2="25" /&gt;
  &lt;line x1="30" y1="0" x2="30" y2="25" /&gt;
  &lt;line x1="30" y1="0" x2="30" y2="25" /&gt;
  &lt;line x1="30" y1="0" x2="30" y2="25" /&gt;
  &lt;line x1="30" y1="0" x2="30" y2="25" /&gt;
  &lt;line x1="30" y1="0" x2="30" y2="25" /&gt;
  &lt;line x1="31" y1="0" x2="31" y2="25" /&gt;
  &lt;line x1="31" y1="0" x2="31" y2="25" /&gt;
  &lt;line x1="31" y1="0" x2="31" y2="25" /&gt;
  &lt;line x1="31" y1="0" x2="31" y2="25" /&gt;
  &lt;line x1="31" y1="0" x2="31" y2="25" /&gt;
  &lt;line x1="32" y1="0" x2="32" y2="25" /&gt;
  &lt;line x1="32" y1="0" x2="32" y2="25" /&gt;
  &lt;line x1="32" y1="0" x2="32" y2="25" /&gt;
  &lt;line x1="32" y1="0" x2="32" y2="25" /&gt;
  &lt;line x1="33" y1="0" x2="33" y2="25" /&gt;
  &lt;line x1="33" y1="0" x2="33" y2="25" /&gt;
  &lt;line x1="33" y1="0" x2="33" y2="25" /&gt;
  &lt;line x1="33" y1="0" x2="33" y2="25" /&gt;
  &lt;line x1="33" y1="0" x2="33" y2="25" /&gt;
  &lt;line x1="34" y1="0" x2="34" y2="25" /&gt;
  &lt;line x1="34" y1="0" x2="34" y2="25" /&gt;
  &lt;line x1="34" y1="0" x2="34" y2="25" /&gt;
  &lt;line x1="34" y1="0" x2="34" y2="25" /&gt;
  &lt;line x1="34" y1="0" x2="34" y2="25" /&gt;
  &lt;line x1="35" y1="0" x2="35" y2="25" /&gt;
  &lt;line x1="35" y1="0" x2="35" y2="25" /&gt;
  &lt;line x1="35" y1="0" x2="35" y2="25" /&gt;
  &lt;line x1="35" y1="0" x2="35" y2="25" /&gt;
  &lt;line x1="35" y1="0" x2="35" y2="25" /&gt;
  &lt;line x1="36" y1="0" x2="36" y2="25" /&gt;
  &lt;line x1="36" y1="0" x2="36" y2="25" /&gt;
  &lt;line x1="36" y1="0" x2="36" y2="25" /&gt;
  &lt;line x1="36" y1="0" x2="36" y2="25" /&gt;
  &lt;line x1="37" y1="0" x2="37" y2="25" /&gt;
  &lt;line x1="37" y1="0" x2="37" y2="25" /&gt;
  &lt;line x1="37" y1="0" x2="37" y2="25" /&gt;
  &lt;line x1="37" y1="0" x2="37" y2="25" /&gt;
  &lt;line x1="37" y1="0" x2="37" y2="25" /&gt;
  &lt;line x1="38" y1="0" x2="38" y2="25" /&gt;
  &lt;line x1="38" y1="0" x2="38" y2="25" /&gt;
  &lt;line x1="38" y1="0" x2="38" y2="25" /&gt;
  &lt;line x1="38" y1="0" x2="38" y2="25" /&gt;
  &lt;line x1="38" y1="0" x2="38" y2="25" /&gt;
  &lt;line x1="39" y1="0" x2="39" y2="25" /&gt;
  &lt;line x1="39" y1="0" x2="39" y2="25" /&gt;
  &lt;line x1="39" y1="0" x2="39" y2="25" /&gt;
  &lt;line x1="39" y1="0" x2="39" y2="25" /&gt;
  &lt;line x1="39" y1="0" x2="39" y2="25" /&gt;
  &lt;line x1="40" y1="0" x2="40" y2="25" /&gt;
  &lt;line x1="40" y1="0" x2="40" y2="25" /&gt;
  &lt;line x1="40" y1="0" x2="40" y2="25" /&gt;
  &lt;line x1="40" y1="0" x2="40" y2="25" /&gt;
  &lt;line x1="41" y1="0" x2="41" y2="25" /&gt;
  &lt;line x1="41" y1="0" x2="41" y2="25" /&gt;
  &lt;line x1="41" y1="0" x2="41" y2="25" /&gt;
  &lt;line x1="41" y1="0" x2="41" y2="25" /&gt;
  &lt;line x1="41" y1="0" x2="41" y2="25" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="0.000000,0.000000 41.887587,0.000000 41.887587,25.412617 0.000000,25.412617" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="20.943793" y="45.412617" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;199&lt;/text&gt;
&lt;text x="61.887587" y="12.706308" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(0,61.887587,12.706308)"&gt;3&lt;/text&gt;&lt;/p&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="111" y1="0" x2="135" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="111" y1="120" x2="135" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="111" y1="0" x2="111" y2="120" style="stroke-width:2" /&gt;
  &lt;line x1="135" y1="24" x2="135" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="111.000000,0.000000 135.664918,24.664918 135.664918,144.664918 111.000000,120.000000" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="111" y1="0" x2="201" y2="0" style="stroke-width:2" /&gt;
  &lt;line x1="135" y1="24" x2="225" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="111" y1="0" x2="135" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="201" y1="0" x2="225" y2="24" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="111.000000,0.000000 201.000000,0.000000 225.664918,24.664918 135.664918,24.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Horizontal lines --&gt;
  &lt;line x1="135" y1="24" x2="225" y2="24" style="stroke-width:2" /&gt;
  &lt;line x1="135" y1="144" x2="225" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Vertical lines --&gt;
  &lt;line x1="135" y1="24" x2="135" y2="144" style="stroke-width:2" /&gt;
  &lt;line x1="225" y1="24" x2="225" y2="144" style="stroke-width:2" /&gt;
  &lt;!-- Colored Rectangle --&gt;
  &lt;polygon points="135.664918,24.664918 225.664918,24.664918 225.664918,144.664918 135.664918,144.664918" style="fill:#ECB172A0;stroke-width:0"/&gt;
  &lt;!-- Text --&gt;
&lt;p&gt;&lt;text x="180.664918" y="164.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" &gt;768&lt;/text&gt;
&lt;text x="245.664918" y="84.664918" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(-90,245.664918,84.664918)"&gt;1024&lt;/text&gt;
&lt;text x="113.332459" y="152.332459" font-size="1.0rem" font-weight="100" text-anchor="middle" transform="rotate(45,113.332459,152.332459)"&gt;201&lt;/text&gt;
&lt;/svg&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;That’s a 180 GB logical array, composed of around 600 chunks, each of size 300
MB. We can now do normal NumPy like computations on this array using &lt;a class="reference external" href="https://docs.dask.org/en/latest/array.html"&gt;Dask
Array&lt;/a&gt;, but we’ll save that for a
future post.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="c1"&gt;# array computations would work fine, and would run in low memory&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="c1"&gt;# but we&amp;#39;ll save actual computation for future posts&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 1056)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="save-data"&gt;
&lt;h1&gt;Save Data&lt;/h1&gt;
&lt;p&gt;To simplify data loading in the future, we store this in a large chunked
array format like &lt;a class="reference external" href="https://zarr.readthedocs.io/"&gt;Zarr&lt;/a&gt; using the &lt;a class="reference external" href="https://docs.dask.org/en/latest/array-api.html#dask.array.Array.to_zarr"&gt;to_zarr&lt;/a&gt;
method.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_zarr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mydata.zarr&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We may add additional information about the image data as &lt;a class="reference external" href="https://zarr.readthedocs.io/en/stable/tutorial.html#user-attributes"&gt;attributes&lt;/a&gt;. This
both makes things simpler for future users (they can read the full dataset with
a single line using &lt;a class="reference external" href="http://docs.dask.org/en/latest/array-api.html#dask.array.from_zarr"&gt;da.from_zarr&lt;/a&gt;) and much
more performant because Zarr is an &lt;em&gt;analysis ready format&lt;/em&gt; that is efficiently
encoded for computation.&lt;/p&gt;
&lt;p&gt;Zarr uses the &lt;a class="reference external" href="http://blosc.org/"&gt;Blosc&lt;/a&gt; library for compression by default.
For scientific imaging data, we can optionally pass compression options that provide
a good compression ratio to speed tradeoff and optimize compression
performance.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numcodecs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blosc&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_zarr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mydata.zarr&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compressor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Blosc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;zstd&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Blosc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BITSHUFFLE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: WARNING/2 (&lt;span class="docutils literal"&gt;/opt/build/repo/2019/06/20/load-image-data.md&lt;/span&gt;, line 1082)&lt;/p&gt;
&lt;p&gt;Document headings start at H2, not H1 [myst.header]&lt;/p&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="future-work"&gt;
&lt;h1&gt;Future Work&lt;/h1&gt;
&lt;p&gt;The workload above is generic and straightforward. It works well in simple
cases and also extends well to more complex cases, providing you’re willing to
write some for-loops and parsing code around your custom logic. It works on a
single small-scale laptop as well as a large HPC or Cloud cluster. If you have
a function that turns a filename into a NumPy array, you can generate large
lazy Dask array using that function, &lt;a class="reference external" href="https://docs.dask.org/en/latest/delayed.html"&gt;Dask
Delayed&lt;/a&gt; and &lt;a class="reference external" href="https://docs.dask.org/en/latest/array.html"&gt;Dask
Array&lt;/a&gt;.&lt;/p&gt;
&lt;section id="dask-image"&gt;
&lt;h2&gt;Dask Image&lt;/h2&gt;
&lt;p&gt;However, we can make things a bit easier for users if we specialize a bit. For
example the &lt;a class="reference external" href="https://image.dask.org/en/latest/"&gt;Dask Image&lt;/a&gt; library has a
parallel image reader function, which automates much of our work above in the
simple case.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;dask_image&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dask_image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;raw/*.tif&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Similarly libraries like &lt;a class="reference external" href="https://xarray.pydata.org/en/stable/"&gt;Xarray&lt;/a&gt; have
readers for other file formats, like GeoTIFF.&lt;/p&gt;
&lt;p&gt;As domains do more and more work like what we did above they tend to write down
common patterns into domain-specific libraries, which then increases the
accessibility and user base of these tools.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="gpus"&gt;
&lt;h2&gt;GPUs&lt;/h2&gt;
&lt;p&gt;If we have special hardware lying around like a few GPUs, we can move the data
over to it and perform computations with a library like CuPy, which mimics
NumPy very closely. Thus benefiting from the same operations listed above, but
with the added performance of GPUs behind them.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cupy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cp&lt;/span&gt;
&lt;span class="n"&gt;a_gpu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_blocks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asarray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="computation"&gt;
&lt;h2&gt;Computation&lt;/h2&gt;
&lt;p&gt;Finally, in future blogposts we plan to talk about how to compute on our large
Dask arrays using common image-processing workloads like overlapping stencil
functions, segmentation and deconvolution, and integrating with other libraries
like ITK.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://blog.dask.org/2019/06/20/load-image-data/"/>
    <summary>Document headings start at H2, not H1 [myst.header]</summary>
    <category term="dask-image" label="dask-image"/>
    <category term="python" label="python"/>
    <category term="scikit-image" label="scikit-image"/>
    <category term="scipy" label="scipy"/>
    <published>2019-06-20T00:00:00+00:00</published>
  </entry>
</feed>
