<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matt McCormick</title>
    <description>The latest articles on DEV Community by Matt McCormick (@thewtex).</description>
    <link>https://dev.to/thewtex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1006582%2F6d6774c7-c8b4-437c-9780-f6916310538f.jpeg</url>
      <title>DEV Community: Matt McCormick</title>
      <link>https://dev.to/thewtex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thewtex"/>
    <language>en</language>
    <item>
      <title>Embed interactive itkwidgets 3D renderings into JupyterLite deployments</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Wed, 15 Mar 2023 16:05:10 +0000</pubDate>
      <link>https://dev.to/thewtex/embed-interactive-itkwidgets-3d-renderings-into-jupyterlite-deployments-48in</link>
      <guid>https://dev.to/thewtex/embed-interactive-itkwidgets-3d-renderings-into-jupyterlite-deployments-48in</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick, Brianna Major, Jeremy Tuloup, Wei Ouyang, Stephen Aylward
&lt;/h6&gt;

&lt;p&gt;&lt;strong&gt;Zero-install&lt;/strong&gt; web applications have transformed the way we consume and deliver software. Browser-based interfaces facilitate rapid discovery, exploration, and universal access.&lt;/p&gt;

&lt;p&gt;However, for research software engineers (RSEs), developing traditional software stacks for web applications is not only onerous, but those stacks may limit essential future scalability and may be even more onerous to sustain. A RSE must face difficult questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who is going to pay to keep the servers online?&lt;/li&gt;
&lt;li&gt;Who is going to pay to scale the servers for many user or datasets?&lt;/li&gt;
&lt;li&gt;When are you going to find the time to learn and keep up-to-date with all the devops knowledge and skills required?&lt;/li&gt;
&lt;li&gt;Who is going to maintain the system and address security vulnerabilities as they arise?&lt;/li&gt;
&lt;li&gt;How is private data on the server managed and kept secure?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As one of my favorite professors used to say, in cases like this we can look to the advice offered by a wise doctor:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Patient: Oh, Doctor, it hurts badly when I move my knee like this.&lt;/p&gt;

&lt;p&gt;Doctor: Stop moving your knee like that!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In some cases, components of the traditional web application software stack are necessary, and some of those components are easier, more scalable, and more sustainable than others. However, for many RSE use cases, we now can create useful web applications while avoiding traditional server-related hardships altogether.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will demonstrate how to create a &lt;strong&gt;zero-server&lt;/strong&gt; JupyterLite deployment that embeds interactive 3D renderings into advanced scientific applications, such as for deep learning medical image analysis applications using &lt;a href="https://monai.io" rel="noopener noreferrer"&gt;MONAI&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jupyterlite.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;JupyterLite&lt;/a&gt; is a &lt;a href="https://jupyter.org" rel="noopener noreferrer"&gt;JupyterLab&lt;/a&gt; distribution that runs entirely in the browser built from the ground-up using JupyterLab components and extensions. JupyterLite uses a &lt;a href="//webassembly.org"&gt;WebAssembly&lt;/a&gt;-based distribution of scientific Python called &lt;a href="https://pyodide.org/en/stable/" rel="noopener noreferrer"&gt;Pyodide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itkwidgets.readthedocs.io/" rel="noopener noreferrer"&gt;ITKWidgets&lt;/a&gt; provides interactive widgets to visualize images, point sets, and 3D geometry on the web. ITKWidgets is powered by the same WebAssembly technology. It is built on &lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;ITK-Wasm&lt;/a&gt; and &lt;a href="https://imjoy.io/" rel="noopener noreferrer"&gt;ImJoy&lt;/a&gt;, a hybrid computing platform that communicates via symmetrical transparent remote procedure calls. ImJoy and ITKWidgets support browser-based Pyodide communication along with a number of additional server-client communication transport mechanisms.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will first demonstrate a zero-server, interactive 3D rendering notebook. Then, we walk through the quick and easy configuration that can be customized to your needs.  Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Preliminaries
&lt;/h2&gt;

&lt;p&gt;Reproduce the figure below, a rendering of medical imaging volume of an abdominal aortic stent, by &lt;a href="https://jupyterlite-itkwidgets-config-post.netlify.app/lab/index.html?path=Hello3DWorld.ipynb" rel="noopener noreferrer"&gt;running the notebook in your web browser&lt;/a&gt;! After the page has loaded, use the standard &lt;code&gt;Shift+Enter&lt;/code&gt; keys to execute the Jupyter notebook cells.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F8VilXUN.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F8VilXUN.gif" alt="a medical imaging volume of an abdominal aortic stent rendered in JupyterLite"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that unlike other Jupyter deployments, the python code runs on your system instead of a server.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create the JupyterLite environment
&lt;/h2&gt;

&lt;p&gt;To build our sustainable JupyterLite deployment, we will use &lt;a href="https://github.com/conda-forge/miniforge" rel="noopener noreferrer"&gt;a Python environment&lt;/a&gt; that contains Python packages for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;jupyterlite&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;imjoy_jupyterlab_extension&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Any other JupyterLab federated extensions (JupyterLab 3 extensions) that you want in your JupyterLab deployment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a &lt;em&gt;requirements.txt&lt;/em&gt; file with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jupyterlite[all]==0.1.0b17
imjoy_jupyterlab_extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And install the packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See also the related &lt;a href="https://jupyterlite.readthedocs.io/en/latest/howto/configure/simple_extensions.html" rel="noopener noreferrer"&gt;JupyterLite extension addition documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add itkwidgets and other Python packages
&lt;/h2&gt;

&lt;p&gt;Next, we will add &lt;em&gt;itkwidgets&lt;/em&gt;, its dependencies, and other Python packages and their dependencies, that we wish to include into the JupyterLite configuration for deployment. These packages, along with &lt;a href="https://github.com/pyodide/pyodide/tree/main/packages" rel="noopener noreferrer"&gt;the packages available in the Pyodide distribution&lt;/a&gt;, will be available in the deployed site.&lt;/p&gt;

&lt;p&gt;Create a &lt;em&gt;jupyterlite_config.json&lt;/em&gt; file, which specifies the locations of the itkwidgets wheel Python packages. Add other desired packages and their dependencies as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PipliteAddon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;piplite_urls&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://files.pythonhosted.org/packages/4c/ee/56f970ca26375176d3e4885f58471a12d5a6794bcefe8ad0ccb8d7158ca3/itkwasm-1.0b82-py3-none-any.whl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://files.pythonhosted.org/packages/6c/55/c3fc7e2b9671d15f0c0becdcb9fad6c330172988744ad6eaa17b71bace88/imjoy_rpc-0.5.16-py3-none-any.whl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://files.pythonhosted.org/packages/69/d9/5a6c8af2f4b4f49a809ae316ae4c12937d7dfda4e5b2f9e4167df5f15c0e/imjoy_utils-0.1.2-py3-none-any.whl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://files.pythonhosted.org/packages/c9/dc/3504845528418aff0b71f4b622bb0e8e12adec2d8f2c1ba21d695b9ac6e6/itkwidgets-1.0a24-py3-none-any.whl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://files.pythonhosted.org/packages/bb/3e/3667ac685ae83887b874896bcb55584797ba6b52a292df3e4b37736a9610/ngff_zarr-0.1.6-py3-none-any.whl&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find links to these URLs by browsing the package on &lt;a href="https://pypi.org" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; and copying the link from the &lt;em&gt;Download files&lt;/em&gt; page for a package.&lt;/p&gt;

&lt;p&gt;For packages that do not have a wheel on PyPI, you can provide one locally by placing them in the &lt;em&gt;pypi/&lt;/em&gt; directory of your JupyterLite configuration. For example, if you want to use a local version of itkwidgets instead of the version on PyPi, you could directly add &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets/raw/2baa8ec865d4c08a4749cc468579742448e524c7/docs/jupyterlite/pypi/dask_image-2022.9.0-py2.py3-none-any.whl" rel="noopener noreferrer"&gt;this &lt;code&gt;dask-image&lt;/code&gt; wheel&lt;/a&gt; to your &lt;em&gt;pypi/&lt;/em&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls &lt;/span&gt;pypi/
pypi/dask_image-2022.9.0-py2.py3-none-any.whl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Add notebooks and data
&lt;/h2&gt;

&lt;p&gt;Add notebooks and data you would like available in the deployment in the &lt;em&gt;files/&lt;/em&gt; directory. In this tutorial, we will add a &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets/raw/2baa8ec865d4c08a4749cc468579742448e524c7/docs/jupyterlite/files/Hello3DWorld.ipynb" rel="noopener noreferrer"&gt;&lt;em&gt;Hello3DWorld.ipynb&lt;/em&gt; notebook&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls &lt;/span&gt;files/
files/Hello3DWorld.ipynb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your notebook, install additional packages in the first cell with &lt;code&gt;piplite&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;piplite&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;piplite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;itkwidgets==1.0a24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Build and deploy
&lt;/h2&gt;

&lt;p&gt;Build your site with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyter lite build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Serve the site locally with &lt;code&gt;python -m http.server --directory ./_output&lt;/code&gt; or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyter lite serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The site can be deployed and shared with free static file hosting services such as &lt;a href="https://jupyterlite.readthedocs.io/en/latest/quickstart/deploy.html" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt;, &lt;a href="https://jupyterlite.readthedocs.io/en/latest/howto/deployment/vercel-netlify.html" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;, or &lt;a href="https://fleek.co/" rel="noopener noreferrer"&gt;Fleek&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;In this post, we learned how to create a scalable, sustainable, zero-server Jupyter deployment that uses ITKWidgets for 3D rendering. In subsequent posts, we will discuss how to create simple, zero-server, custom web applications written in Python with &lt;a href="https://pyscript.net/" rel="noopener noreferrer"&gt;PyScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>jupyter</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Debug WebAssembly Pipelines in Your Web Browser</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Wed, 08 Mar 2023 21:45:52 +0000</pubDate>
      <link>https://dev.to/thewtex/how-to-debug-webassembly-pipelines-in-your-web-browser-4gng</link>
      <guid>https://dev.to/thewtex/how-to-debug-webassembly-pipelines-in-your-web-browser-4gng</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick, Mary Elise Dedicke, Jean-Christophe Fillion-Robin, Will Schroeder
&lt;/h6&gt;

&lt;p&gt;Did you know that your web browser comes bundled with extremely powerful development tools?&lt;/p&gt;

&lt;p&gt;Modern web browsers are the foundation of the &lt;a href="https://en.wikipedia.org/wiki/Web_platform"&gt;The Web Platform&lt;/a&gt;, a full-featured computing environment. However, &lt;em&gt;full-featured platforms are not useful in and of themselves&lt;/em&gt;. A large community of software developers is required to program the applications on a platform that people love. And, &lt;a href="https://www.kitware.com/how-to-debug-wasi-pipelines-with-itk-wasm/"&gt;effective debugging results in effective programming&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will learn how to debug &lt;a href="https://wasm.itk.org"&gt;itk-wasm&lt;/a&gt; C++ data processing pipelines built to &lt;a href="https://webassembly.org"&gt;WebAssembly (wasm)&lt;/a&gt; with the full-featured graphical debugger built into Chromium-based browsers.&lt;/p&gt;

&lt;p&gt;In the following sections, we will first explain how to obtain a useful JavaScript backtrace in Node.js, then debug C++ code built to WebAssembly in a Chromium-based web browser. Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Preliminaries
&lt;/h2&gt;

&lt;p&gt;Before starting this tutorial, check out our &lt;a href="https://www.kitware.com/how-to-debug-wasi-pipelines-with-itk-wasm/"&gt;WASI WebAssembly command line debugging tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As with the previous tutorial, we will be debugging the following C++ code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Hello debugger world!"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;wasmDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"are no longer hidden"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&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;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&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;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;c&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;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Simulate a crash.&lt;/span&gt;
  &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples/debugging"&gt;The tutorial code&lt;/a&gt; provides npm scripts as a convenient way to execute debugging commands, which you may also invoke directly in a command line shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Node.js Backtrace
&lt;/h2&gt;

&lt;p&gt;When debugging WebAssembly built with the itk-wasm Emscripten toolchain, set the &lt;code&gt;CMAKE_BUILD_TYPE&lt;/code&gt; to &lt;code&gt;Debug&lt;/code&gt; just like with native binary debug builds.&lt;/p&gt;

&lt;p&gt;As with native builds, this build configuration adds debugging symbols, the human-readable names of functions, variables, etc., into the binary.  This also adds support for C++ exceptions and retrieving the string name associated with exceptions. Without this itk-wasm instrumentation, a C++ exception will throw an error with an opaque integer value. And, Emscripten JavaScript WebAssembly bindings will not be minified, which facilitates debugging.&lt;/p&gt;

&lt;p&gt;When built with the default &lt;code&gt;Release&lt;/code&gt; build type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2kL0kIn6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/8DKAnqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2kL0kIn6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/8DKAnqQ.png" alt="Emscripten build Release" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the JavaScript support code is minified, and difficult to debug:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ITCRcCJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/QwMl2SK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ITCRcCJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/QwMl2SK.png" alt="Run Node Release" width="880" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, when built with the &lt;code&gt;Debug&lt;/code&gt; build type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Muc6WsoX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/63tC2wC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Muc6WsoX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/63tC2wC.png" alt="Emscripten build Debug" width="880" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you can obtain a useful backtrace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_0x5zTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/8tUmqRd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_0x5zTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/8tUmqRd.png" alt="Run Node Debug" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is helpful for debugging issues that occur in the Emscripten JavaScript interface. The next section describes how to debug issues inside the Emscripten-generated WebAssembly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Debugging in Chromium-based Browsers
&lt;/h2&gt;

&lt;p&gt;Recent Chromium-based browsers have support for debugging C++ -based WebAssembly in the browser. With a few extra steps described in this section, it is possible to interactively step through and inspect WebAssembly that is compiled with C++ running in the browser.&lt;/p&gt;

&lt;p&gt;WebAssembly debugging in DevTools requires a few extra setup steps compared to a default browser installation.&lt;/p&gt;

&lt;p&gt;First, &lt;a href="https://goo.gle/wasm-debugging-extension"&gt;install the Chrome WebAssembly Debugging extension&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, enable it in DevTools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;  In DevTools, click the &lt;em&gt;gear (⚙)&lt;/em&gt; icon in the top-right corner.&lt;/li&gt;
&lt;li&gt;  Go to the &lt;em&gt;Experiments&lt;/em&gt; panel.&lt;/li&gt;
&lt;li&gt;  Select &lt;em&gt;WebAssembly Debugging: Enable DWARF support&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q0Pe0DmD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/L5zyBlJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q0Pe0DmD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/L5zyBlJ.png" alt="Enable Wasm Debugging" width="880" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exit Settings, then reload DevTools as prompted.&lt;/p&gt;

&lt;p&gt;Next, open the options for the Chrome WebAssembly Debugging extension:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yYFpEIZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Gbe53Fz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yYFpEIZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Gbe53Fz.png" alt="Wasm Debugging Options" width="527" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since itk-wasm builds in a clean Docker environment, the debugging source paths in the Docker environment are different from the paths on the host system. The debugging extension has a path substitution system that can account for these differences. In the Docker image, the directory where &lt;code&gt;itk-wasm&lt;/code&gt; is invoked is mounted as &lt;code&gt;/work&lt;/code&gt;. Substitute &lt;code&gt;/work&lt;/code&gt; with the directory where the &lt;code&gt;itk-wasm&lt;/code&gt; CLI is invoked. For example, if &lt;code&gt;itk-wasm&lt;/code&gt; was invoked at &lt;code&gt;/home/matt/src/itk-wasm/examples/Debugging&lt;/code&gt;, then set the path substitution as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a7bCoul_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YuUp7rP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a7bCoul_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YuUp7rP.png" alt="Path substitution" width="880" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build the project with itk-wasm and the &lt;code&gt;Debug&lt;/code&gt; &lt;code&gt;CMAKE_BUILD_TYPE&lt;/code&gt; to include DWARF debugging information:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fex5-wfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/d36DmGJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fex5-wfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/d36DmGJ.png" alt="Emscripten build Debug" width="880" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we load and run the WebAssembly with a simple HTML file and server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/itk-wasm@1.0.0-a.11/dist/umd/itk-wasm.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is an example to demonstrate browser-based debugging of
    C++-generated WebAssembly. For more information, please see the
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://wasm.itk.org/examples/debugging.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;associated
      documentation&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;emscripten-build-debug/DebugMe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;itk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wv5jBlb_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/bZsm9lG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wv5jBlb_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/bZsm9lG.png" alt="HTTP Server" width="880" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we can debug the C++ code in Chrome's DevTools debugger alongside the executing JavaScript!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yR2wt2PE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/iO8QhDz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yR2wt2PE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/iO8QhDz.png" alt="Debug C++ DevTools" width="880" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;In our next post, we will provide a tutorial on how to generate JavaScript and TypeScript bindings for Node.js and the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webassembly</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Extending ITK for C++ and Python: Build and Test ITK External Modules in a GitHub Action</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Fri, 03 Mar 2023 18:12:28 +0000</pubDate>
      <link>https://dev.to/thewtex/extending-itk-for-c-and-python-build-and-test-itk-external-modules-in-a-github-action-4f9p</link>
      <guid>https://dev.to/thewtex/extending-itk-for-c-and-python-build-and-test-itk-external-modules-in-a-github-action-4f9p</guid>
      <description>&lt;h6&gt;
  
  
  By: Tom Birdsong, Matt McCormick, Lucas Gandel, Simon Rit, Jean-Christophe Fillion-Robin, Stephen Aylward
&lt;/h6&gt;

&lt;p&gt;Medical imaging is an ever-changing domain, with technological advances introducing exciting new data and processing techniques every year. In a rapidly evolving landscape, the open-source &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;Insight Toolkit (ITK)&lt;/a&gt; continues to provide essential and cutting-edge tools for medical image processing to aid researchers and practitioners alike. ITK keeps up with rapid advances in the field through the contributions of its community members and their commitment to open science. To support these contributions, ITK provides a robust framework for the development and inclusion of external modules. Recent updates that leverage &lt;a href="https://docs.github.com/en/actions/using-workflows" rel="noopener noreferrer"&gt;GitHub Actions workflows&lt;/a&gt; have made external module maintenance easier than ever. Any ITK developer can now quickly create and disseminate external modules that enhance ITK's capabilities on multiple Mac, Linux, and Windows platforms, in C++ and for python versions 3.7-3.11 via pip.  Furthermore, if an external module is deemed to add sufficient value to the ITK community, then it can be distributed as a “remote module” of ITK, allowing it to be easily enabled and built as part of the ITK C++ library and Python package.&lt;/p&gt;

&lt;p&gt;An individual might create a new external module for any of several reasons, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To add domain-specific tools, such as ultrasound despeckle techniques provided in the &lt;a href="https://github.com/KitwareMedical/ITKUltrasound" rel="noopener noreferrer"&gt;ITKUltrasound&lt;/a&gt; external module or tomographic reconstruction in the &lt;a href="https://www.openrtk.org" rel="noopener noreferrer"&gt;reconstruction toolkit (RTK)&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;To wrap an existing library for medical imaging so that it can be used in the ITK ecosystem, such as wrapping the &lt;a href="https://elastix.lumc.nl/" rel="noopener noreferrer"&gt;Elastix&lt;/a&gt; registration library in the &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix" rel="noopener noreferrer"&gt;ITKElastix&lt;/a&gt; external module;&lt;/li&gt;
&lt;li&gt;To add support for an emerging data formatting standard, such as support for reading from and writing to the &lt;a href="https://doi.org/10.1101/2023.02.17.528834" rel="noopener noreferrer"&gt;OME-Zarr&lt;/a&gt; spatial array chunking standard in the &lt;a href="https://github.com/InsightSoftwareConsortium/ITKIOOMEZarrNGFF" rel="noopener noreferrer"&gt;ITKIOOMEZarrNGFF&lt;/a&gt; external module.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A notable challenge in creating an external module is the learning curve required for new contributors. In order to fully leverage the building blocks that ITK provides, it is generally necessary to have basic knowledge of C++ programming, CMake, and the ITK pipelining system, the latter of which is covered in detail in the &lt;a href="https://itk.org/ItkSoftwareGuide.pdf" rel="noopener noreferrer"&gt;ITK Software Guide&lt;/a&gt;. Fortunately, new users can make use of the &lt;a href="https://github.com/InsightSoftwareConsortium/ITKModuleTemplate" rel="noopener noreferrer"&gt;ITKModuleTemplate cookiecutter&lt;/a&gt; discussed in the &lt;a href="https://www.kitware.com/python-packages-for-itk-modules/" rel="noopener noreferrer"&gt;Python Packages for ITK Modules&lt;/a&gt; article, rather than starting from scratch. In the past, another significant barrier to entry was familiarity with good software practices, namely setting up continuous integration and continuous deployment (CI/CD) pipelines, so that modules are tested and remain compatible as ITK's core is updated. Initial pipelines populated by the cookiecutter template had limited support for good software practices. This article introduces recent updates that take advantage of Github Action Workflows and make it easy for most ITK modules to follow CI/CD best practices and minimize maintenance requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing an ITK Module Reusable Workflow
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction" rel="noopener noreferrer"&gt;ITKRemoteModuleBuildTestPackageAction GitHub Action&lt;/a&gt; is a central repository to collect common procedures for building, testing, and packaging ITK open source external modules that are hosted on GitHub. Scripts leverage the CI/CD framework provided by GitHub Actions to automatically run pipelines on certain events, such as when a user opens a pull request or when a maintainer merges new changes. The repository currently offers two yaml pipeline files that lay out steps for building an external module for C++ or Python targets. These steps can be used by the majority of ITK external modules (a) to verify that the module compiles across platforms with proposed changes; (b) to run and report results from module tests; and (c) to package and deploy cross-platform Python wheels for users to easily install and run.&lt;/p&gt;

&lt;p&gt;In most cases community members can leverage ITKRemoteModuleBuildTestPackageAction in their external module projects for several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build procedures are provided as GitHub Actions (GHA) reusable workflow &lt;code&gt;.yml&lt;/code&gt; files which integrate directly with GHA runners. These can be invoked for a given external module in its GitHub repository with minimal code.&lt;/li&gt;
&lt;li&gt;Build procedure updates are centralized. Rather than replicating build step updates directly in a custom build procedure for each external module, developers may simply update workflow commit tags to include process updates in external module CI. For example, an update to a runner platform version from Ubuntu 18.04 to Ubuntu 20.04 would be introduced to ITKRemoteModuleBuildTestPackageAction once and then consumed by a variety of external modules by simply updating the ITKRemoteModuleBuildTestPackageAction commit hash accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ITK reusable workflows are best leveraged by ITK external modules that are implemented primarily in C++ and have a simple build process. If a developer wants to distribute their filters without requiring that users have prerequisites to build the module, then they can invoke the Python reusable workflow to easily package and distribute the module when new versions of the module are released. If the external module has a more complex build process with one or more external dependencies, but those dependencies can be fetched with CMake and included in the module build process, then the module will likewise be able to leverage external pipelines.&lt;/p&gt;

&lt;p&gt;Unfortunately, at this time, external modules that require certain system dependencies in place before the build starts cannot easily leverage the reusable workflows. Pure Python external modules are also unable to be packaged with ITK reusable workflows at this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Developers can take advantage of ITK reusable workflows with just a few lines of code. GitHub Actions will automatically detect and run any yaml pipeline files inside a project’s &lt;code&gt;.github/workflows&lt;/code&gt; directory. Here is an example of a basic file to run C++ and Python CI/CD pipelines from an ITK external module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build, test, package&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cxx-build-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-cxx.yml@d4a5ce4f219b66b78269a15392e15c95f90e7e00&lt;/span&gt;

  &lt;span class="na"&gt;python-build-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package-python.yml@d4a5ce4f219b66b78269a15392e15c95f90e7e00&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;pypi_password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.pypi_password }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code example above tells GitHub Actions to find and run reusable workflows in the ITKRemoteModuleBuildTestPackageAction repository. &lt;code&gt;cxx-build-workflow&lt;/code&gt; is a job that exists to fetch and run the &lt;code&gt;build-test-cxx&lt;/code&gt; reusable workflow, while &lt;code&gt;python-build-workflow&lt;/code&gt; is a job that fetches and runs the &lt;code&gt;build-test-package-python&lt;/code&gt; reusable workflow. Each workflow itself subsequently handles scheduling runners, performing environment setup, and then building the ITK external module.&lt;/p&gt;

&lt;p&gt;The example workflow file above is broken down line by line in the ITKRemoteModuleBuildTestPackageAction &lt;a href="https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction#example-usage" rel="noopener noreferrer"&gt;README file on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  C++ Workflow
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;build-test-cxx&lt;/code&gt; workflow provides a common process to build and test a given ITK external module. The workflow offers cross-platform testing on Windows, Ubuntu, and macOS images as provided by GitHub Actions. First, build tools and prerequisites such as CMake and Python are installed, then the Insight Toolkit is built from scratch, and finally the ITK external module is built. Any tests that are defined for CTest are run as part of the procedure and uploaded to the ITK CDash dashboard at &lt;a href="https://open.cdash.org/index.php?project=Insight" rel="noopener noreferrer"&gt;https://open.cdash.org/index.php?project=Insight&lt;/a&gt; under the &lt;em&gt;Experimental&lt;/em&gt; header.&lt;/p&gt;

&lt;p&gt;Users can specify a number of input arguments to direct the external module build process, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ITK C++ version to use;&lt;/li&gt;
&lt;li&gt;CMake variables for the ITK build or external module build;&lt;/li&gt;
&lt;li&gt;Test options and warnings to ignore in reporting results to the ITK dashboard;&lt;/li&gt;
&lt;li&gt;Other ITK external modules to build first and include as build prerequisites for the current module.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More information on the C++ workflow can be found in the &lt;a href="https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction" rel="noopener noreferrer"&gt;project README&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python Workflow
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;build-test-package-python&lt;/code&gt; workflow provides a common process to build, package, and deploy ITK external module Python wheels to the Python Package Index. A fixed version of ITK is used with cached Python build results in order to avoid long build times.&lt;/p&gt;

&lt;p&gt;Several input arguments are available to direct the Python wheel build process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ITK Python build cache version to use, which roughly corresponds to ITK minor release versions;&lt;/li&gt;
&lt;li&gt;CMake variables for the external module build (but not the underlying ITK build);&lt;/li&gt;
&lt;li&gt;The remote reference for build scripts to use, which allows developers to build their modules with custom scripts in a development branch;&lt;/li&gt;
&lt;li&gt;Linux toolsets and architectures to target, including building Python wheels for ARM platforms;&lt;/li&gt;
&lt;li&gt;Other ITK external modules to build first and include as build prerequisites for the current module.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More information on the Python workflow can be found in the &lt;a href="https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction" rel="noopener noreferrer"&gt;project README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Reusable workflows are being actively adopted to streamline ITK external module builds. Developers can reference a number of open source projects to get started with leveraging reusable workflows in a number of ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/KitwareMedical/ITKUltrasound" rel="noopener noreferrer"&gt;ITKUltrasound&lt;/a&gt; uses ITK reusable workflows to minimize complicated build maintenance to track changes in its five prerequisite external modules;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix" rel="noopener noreferrer"&gt;ITKElastix&lt;/a&gt; uses reusable workflows to deploy Python wheels for ARM architectures;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/RTKConsortium/RTK" rel="noopener noreferrer"&gt;RTK&lt;/a&gt;, The Reconstruction Toolkit, uses reusable workflows to build Python packages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the reusable workflow is not directly usable because the workflow environment must be tuned to the needs of the module, it can serve as a basis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/RTKConsortium/ITKCudaCommon" rel="noopener noreferrer"&gt;ITKCudaCommon&lt;/a&gt; workflows are used to distribute Python packages with CUDA compatibilty for accelerated computing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/RTKConsortium/RTK" rel="noopener noreferrer"&gt;RTK&lt;/a&gt; has CUDA specific workflows for distributing &lt;a href="https://pypi.org/project/itk-rtk-cuda116" rel="noopener noreferrer"&gt;Python packages using CUDA 11.6&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;ITK reusable workflows continue to expand due to user contributions. Future workflows may aim to tackle additional challenges that face the ITK community, such as packaging and testing pure Python modules that leverage ITK processing pipelines. &lt;a href="https://vtk.org" rel="noopener noreferrer"&gt;VTK&lt;/a&gt; remote modules like the &lt;a href="https://github.com/Kitware/LookingGlassVTKModule" rel="noopener noreferrer"&gt;LookingGlassVTKModule&lt;/a&gt; aim to adopt similar reusable workflows. Additional planned features will address common build issues such as Windows path lengths for modules with long names, large build sizes on GitHub runners, and cross-compiled builds for ARM to improve build times. Longer term, with upgrades to our &lt;a href="https://scikit-build.org" rel="noopener noreferrer"&gt;scikit-build&lt;/a&gt; Python package configuration, the action will further build on community tools like &lt;a href="https://cibuildwheel.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;cibuildwheel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to Debug WASI Pipelines with ITK-Wasm</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Thu, 02 Mar 2023 18:16:41 +0000</pubDate>
      <link>https://dev.to/thewtex/how-to-debug-wasi-pipelines-with-itk-wasm-4fbi</link>
      <guid>https://dev.to/thewtex/how-to-debug-wasi-pipelines-with-itk-wasm-4fbi</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick &lt;a href="https://orcid.org/0000-0001-9475-3756"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iD22Ovmw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://info.orcid.org/wp-content/uploads/2020/12/orcid_16x16.gif" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;, Mary Elise Dedicke &lt;a href="https://orcid.org/0000-0001-8848-3235"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IzYOR_b7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i0.wp.com/info.orcid.org/wp-content/uploads/2020/12/orcid_16x16.gif%3Fresize%3D16%252C16%26ssl%3D1" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;, Jean-Christophe Fillion-Robin &lt;a href="https://orcid.org/0000-0002-9688-8950"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IzYOR_b7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i0.wp.com/info.orcid.org/wp-content/uploads/2020/12/orcid_16x16.gif%3Fresize%3D16%252C16%26ssl%3D1" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;, Will Schroeder &lt;a href="https://orcid.org/0000-0003-3815-9386"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IzYOR_b7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i0.wp.com/info.orcid.org/wp-content/uploads/2020/12/orcid_16x16.gif%3Fresize%3D16%252C16%26ssl%3D1" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;
&lt;/h6&gt;

&lt;p&gt;Effective debugging results in effective programming; &lt;a href="https://wasm.itk.org"&gt;itk-wasm&lt;/a&gt; makes effective debugging of WebAssembly possible. In this tutorial, adapted from the &lt;a href="https://wasm.itk.org"&gt;itk-wasm documentation&lt;/a&gt;, we walk through how to debug a C++ data processing pipeline with the mature, native binary debugging tools that are comfortable for developers. This is a fully featured way to ensure the base correctness of a processing pipeline. Next, we will walk through an interactive debugging experience for &lt;a href="https://wasi.dev/"&gt;WASI WebAssembly&lt;/a&gt;. With itk-wasm, we can debug the same source code in either context with an interactive debugger. We also have a convenvient way to pass data from our local filesystem into a WebAssembly (Wasm) processing pipeline.&lt;/p&gt;

&lt;p&gt;Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Preliminaries
&lt;/h2&gt;

&lt;p&gt;Before starting this tutorial, check out our &lt;a href="https://www.kitware.com/hello-wasm-world/"&gt;Hello Wasm World&lt;/a&gt; tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Native Debugging
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples/debugging"&gt;The tutorial code&lt;/a&gt; provides npm scripts as a convenient way to execute debugging commands, which you may also invoke directly in a command line shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Hello debugger world!"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;wasmDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"are no longer hidden"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&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;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&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;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;c&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;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Simulate a crash.&lt;/span&gt;
  &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run these examples, first &lt;a href="https://www.kitware.com/hello-wasm-world/"&gt;install and test&lt;/a&gt; Docker and Node/NPM. Then, install the package dependencies and run the example commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd itk-wasm/examples/Debugging/
npm install
npm run &amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; is the npm script. Available names can be found by calling &lt;code&gt;npm run&lt;/code&gt; without any arguments.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://cmake.org"&gt;CMake&lt;/a&gt;-based, itk-wasm build system tooling enables the same C++ build system configuration and code to be reused when building a native system binary or a WebAssembly binary. As a result, native binary debugging tools, such as &lt;a href="https://sourceware.org/gdb/"&gt;GDB&lt;/a&gt;, &lt;a href="https://lldb.llvm.org/"&gt;LLDB&lt;/a&gt;, or the &lt;a href="https://docs.microsoft.com/en-us/visualstudio/debugger/?view=vs-2022"&gt;Visual Studio debugger&lt;/a&gt; can be utilized.&lt;/p&gt;

&lt;p&gt;We can build the project's standard CMake build configuration,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 3.10&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;DebuggingWebAssemblyExample&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;DebugMe DebugMe.cxx&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with standard CMake commands:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jG-euxj2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/vEA9Cwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jG-euxj2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/vEA9Cwq.png" alt="Native build" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The native binary can then be debugged in the standard way. For example, with &lt;code&gt;gdb&lt;/code&gt; on Linux:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C6ln_fRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/BJ1H8E3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C6ln_fRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/BJ1H8E3.png" alt="Native debug Linux" width="880" height="766"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. WASI Debugging
&lt;/h2&gt;

&lt;p&gt;The most direct way to debug WebAssembly is through the &lt;a href="https://wasi.dev/"&gt;WebAssembly System Interface (WASI)&lt;/a&gt;. In itk-wasm, we can build to WASI with the &lt;a href="https://github.com/WebAssembly/wasi-sdk"&gt;WASI SDK&lt;/a&gt; by specifying the &lt;code&gt;itkwasm/wasi&lt;/code&gt; toolchain image. A backtrace can quickly be obtained with the &lt;code&gt;itk-wasm&lt;/code&gt; CLI. Or, a fully fledged debugger session can be started with LLDB.&lt;/p&gt;

&lt;p&gt;First, build to WASI WebAssembly with debugging symbols available:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iLkfEn8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wbGpRWC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iLkfEn8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wbGpRWC.png" alt="WASI debug build" width="880" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, the &lt;code&gt;itk-wasm&lt;/code&gt; CLI can conveniently run the Wasm binary with the included WASI runtime:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wLcTWKmX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/agxGSt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wLcTWKmX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/agxGSt9.png" alt="Run WASI debug" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that &lt;code&gt;abort&lt;/code&gt; is called in the &lt;code&gt;main&lt;/code&gt; function at line 13 in &lt;code&gt;DebugMe.cxx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A full debugging session is also possible after &lt;a href="https://lldb.llvm.org/"&gt;LLDB&lt;/a&gt; &amp;gt;= 13 and &lt;a href="https://wasmtime.dev/"&gt;Wasmtime&lt;/a&gt; are installed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zA8zFlup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/EhSg8Ay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zA8zFlup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/EhSg8Ay.png" alt="LLDB WASI debug" width="880" height="704"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;In our next post, we will provide a tutorial on how to debug C++ WebAssembly processing pipelines in a web browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>cpp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Leverage the powerful Insight Toolkit (ITK) in MATLAB via Python</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Fri, 24 Feb 2023 16:22:12 +0000</pubDate>
      <link>https://dev.to/thewtex/leverage-the-powerful-insight-toolkit-itk-in-matlab-via-python-2cjo</link>
      <guid>https://dev.to/thewtex/leverage-the-powerful-insight-toolkit-itk-in-matlab-via-python-2cjo</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick, Tom Birdsong, Brad Moore, Jake McCall, Stephen Aylward
&lt;/h6&gt;

&lt;p&gt;In recent years, &lt;a href="https://www.mathworks.com/products/matlab.html" rel="noopener noreferrer"&gt;MathWork's MATLAB&lt;/a&gt; added &lt;a href="https://www.mathworks.com/help/matlab/call-python-libraries.html" rel="noopener noreferrer"&gt;Python support&lt;/a&gt;. This unlocks the capabilities of the powerful open source scientific Python ecosystem inside MATLAB. This post provides a tutorial on how to use &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;Insight Toolkit (ITK)&lt;/a&gt; version 5.3 and newer and &lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;itkwasm&lt;/a&gt; Python packages in MATLAB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itk.org" rel="noopener noreferrer"&gt;ITK&lt;/a&gt; is an open-source, cross-platform library that provides developers with an extensive suite of software tools for image analysis.  Developed through extreme programming methodologies, ITK builds on a proven, spatially-oriented architecture for processing, segmentation, and registration of scientific images in two, three, or more dimensions.&lt;/p&gt;

&lt;p&gt;To interactively reproduce this tutorial, run the corresponding &lt;a href="https://www.mathworks.com/matlabcentral/fileexchange/125300-itk-matlab-python-tutorial" rel="noopener noreferrer"&gt;MATLAB Live Script&lt;/a&gt; (&lt;a href="https://github.com/InsightSoftwareConsortium/itk-matlab-python-tutorial" rel="noopener noreferrer"&gt;source&lt;/a&gt;, &lt;a href="https://insightsoftwareconsortium.github.io/itk-matlab-python-tutorial/" rel="noopener noreferrer"&gt;html&lt;/a&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;This section walks through how to install the &lt;code&gt;itk&lt;/code&gt; Python package into the PythonEnvironment available in the MATLAB Online environment.&lt;/p&gt;

&lt;p&gt;In general, you can install &lt;code&gt;itk&lt;/code&gt; into your local Python environment by simply calling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!python -m pip install itk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since MATLAB Online uses Linux, we will use &lt;code&gt;python3&lt;/code&gt;to specify the MATLAB Python version. On Windows, you may want to specify a version with&lt;code&gt;'Version', '3.10'&lt;/code&gt;or similar. For more information, see the &lt;a href="https://www.mathworks.com/help/matlab/ref/pyenv.html" rel="noopener noreferrer"&gt;pyenv&lt;/a&gt; documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pyenv("Version","python3")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ans = 
  PythonEnvironment with properties:

          Version: "3.8"
       Executable: "/usr/bin/python3"
          Library: "libpython3.8.so.1.0"
             Home: "/usr"
           Status: Loaded
    ExecutionMode: InProcess
        ProcessID: "5004"
      ProcessName: "MATLAB"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will Install &lt;code&gt;itk&lt;/code&gt; via the Python package manager, &lt;code&gt;pip&lt;/code&gt;. A standard Linux Python distribution is unusal in that it does not ship with &lt;code&gt;pip&lt;/code&gt;, so we will download a self-contained version in this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;websave("pip.pyz", "https://bootstrap.pypa.io/pip/pip.pyz");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For MATLAB Online, install the package into set the &lt;code&gt;user&lt;/code&gt; packages and the &lt;code&gt;setuptools&lt;/code&gt; package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!python3 pip.pyz install --user itk setuptools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Collecting itk
  Downloading itk-5.3.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (8.3 kB)
Collecting setuptools
  Downloading setuptools-67.4.0-py3-none-any.whl (1.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 80.0 MB/s eta 0:00:00

Collecting numpy
  Downloading numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.3/17.3 MB 109.4 MB/s eta 0:00:00

Collecting itk-filtering==5.3.0
  Downloading itk_filtering-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (75.9 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 75.9/75.9 MB 39.0 MB/s eta 0:00:00

Collecting itk-registration==5.3.0
  Downloading itk_registration-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (27.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 27.3/27.3 MB 84.0 MB/s eta 0:00:00

Collecting itk-io==5.3.0
  Downloading itk_io-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (26.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 26.2/26.2 MB 73.7 MB/s eta 0:00:00

Collecting itk-numerics==5.3.0
  Downloading itk_numerics-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 60.0/60.0 MB 48.3 MB/s eta 0:00:00

Collecting itk-core==5.3.0
  Downloading itk_core-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (83.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 83.6/83.6 MB 35.1 MB/s eta 0:00:00

Collecting itk-segmentation==5.3.0
  Downloading itk_segmentation-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.2/17.2 MB 106.7 MB/s eta 0:00:00

Installing collected packages: setuptools, numpy, itk-core, itk-numerics, itk-io, itk-filtering, itk-segmentation, itk-registration, itk
  WARNING: The scripts f2py, f2py3 and f2py3.8 are installed in '/home/mluser/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed itk-5.3.0 itk-core-5.3.0 itk-filtering-5.3.0 itk-io-5.3.0 itk-numerics-5.3.0 itk-registration-5.3.0 itk-segmentation-5.3.0 numpy-1.24.2 setuptools-67.4.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For MATLAB Online, we need to add the user site packages to &lt;code&gt;sys.path&lt;/code&gt; so Python will find them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usp = py.site.getusersitepackages();
pyrun(["import sys", "if usp not in sys.path: sys.path.append(usp)"], usp=usp);
py.sys.path;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the Python interpreter has already been started, we would need to &lt;a href="https://www.mathworks.com/help/matlab/matlab_external/call-user-defined-custom-module.html?searchHighlight=importlib&amp;amp;s_tid=srchtitle_importlib_7" rel="noopener noreferrer"&gt;manually import the Python package for MATLAB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Again, these steps are unnecessary for local installations where the &lt;code&gt;itk&lt;/code&gt; Python package is simply installed before starting MATLAB.&lt;/p&gt;

&lt;h1&gt;
  
  
  ITK to MATLAB
&lt;/h1&gt;

&lt;p&gt;In this section, we will show how to load an image with ITK and display it with MATLAB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% download a test image
websave("cthead1.png", "https://bafybeigja4wbultavomsvai433hln7uqabzl2mg24frxzqblx4y4cvd5am.ipfs.w3s.link/ipfs/bafybeigja4wbultavomsvai433hln7uqabzl2mg24frxzqblx4y4cvd5am/cthead1.png");

% load the image with itk
pyrun(["import itk", "image = itk.imread('cthead1.png')"])

% transfer python dict to matlab
image_dict = pyrun(["image_dict = itk.dict_from_image(image)"], "image_dict")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image_dict = 
  Python dict with no properties.

    {'imageType': {'dimension': 2, 'componentType': 'uint8', 'pixelType': 'Scalar', 'components': 1}, 'name': '', 'origin': (0.0, 0.0), 'spacing': (1.0, 1.0), 'size': (256, 256), 'direction': array([[1., 0.],
           [0., 1.]]), 'data': array([[0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           ...,
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% matlab struct
image_struct = struct(image_dict)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image_struct = 
    imageType: [1x1 py.dict]
         name: [1x0 py.str]
       origin: [1x2 py.tuple]
      spacing: [1x2 py.tuple]
         size: [1x2 py.tuple]
    direction: [1x1 py.numpy.ndarray]
         data: [1x1 py.numpy.ndarray]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spacing = double(image_struct.spacing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spacing = 1x2    
     1     1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% equivalent
spacing = double(image_dict{'spacing'})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spacing = 1x2    
     1     1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pixels = double(image_struct.data);
imshow(pixels, [0, 255])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276a1qoffw9a1ihjzk1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276a1qoffw9a1ihjzk1r.png" width="577" height="433"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image_dict{'imageType'}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ans = 
  Python dict with no properties.

    {'dimension': 2, 'componentType': 'uint8', 'pixelType': 'Scalar', 'components': 1}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% Keep pixel type
pixels = uint8(image_struct.data);
imshow(pixels)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcriewzsxmgki73w97n7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcriewzsxmgki73w97n7b.png" width="577" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  MATLAB to ITK
&lt;/h1&gt;

&lt;p&gt;In this section, we will show how to load an image with MATLAB and transfer it to ITK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pixels = imread("cthead1.png")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning: PNG library warning: sCAL: invalid unit.
pixels = 256x256 uint8 matrix    
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pyrun(["import numpy as np", "array = np.asarray(pixels)"], pixels=pixels)
pyrun(["image = itk.image_view_from_array(array)", "print(image)"])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image (0x7f3aec3261e0)
  RTTI typeinfo:   itk::Image&amp;lt;unsigned char, 2u&amp;gt;
  Reference Count: 1
  Modified Time: 402
  Debug: Off
  Object Name: 
  Observers: 
    none
  Source: (none)
  Source output name: (none)
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 0
  UpdateMTime: 0
  RealTimeStamp: 0 seconds 
  LargestPossibleRegion: 
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  BufferedRegion: 
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  RequestedRegion: 
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  Spacing: [1, 1]
  Origin: [0, 0]
  Direction: 
1 0
0 1

  IndexToPointMatrix: 
1 0
0 1

  PointToIndexMatrix: 
1 0
0 1

  Inverse Direction: 
1 0
0 1

  PixelContainer: 
    ImportImageContainer (0x7f3aec3219f0)
      RTTI typeinfo:   itk::ImportImageContainer&amp;lt;unsigned long, unsigned char&amp;gt;
      Reference Count: 1
      Modified Time: 397
      Debug: Off
      Object Name: 
      Observers: 
        none
      Pointer: 0x7f3aec2a0d80
      Container manages memory: false
      Size: 65536
      Capacity: 65536
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Call ITK filters
&lt;/h1&gt;

&lt;p&gt;Let's call an &lt;code&gt;itk&lt;/code&gt; filter and look at the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pyrun(["smoothed = itk.discrete_gaussian_image_filter(image, sigma=sigma)"], sigma=3.0);
smoothed = pyrun(["smoothed = itk.dict_from_image(smoothed)"], "smoothed");
imshow(uint8(smoothed{"data"}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zk5ogh110707klpqa0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zk5ogh110707klpqa0t.png" width="577" height="433"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% equivalent
smoothed = py.itk.discrete_gaussian_image_filter(py.itk.image_from_dict(image_dict), sigma=3.0);
smoothed = py.itk.dict_from_image(smoothed);
imshow(uint8(smoothed{"data"}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk73r87r8ezs81zv03t20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk73r87r8ezs81zv03t20.png" width="577" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Beyond images
&lt;/h1&gt;

&lt;p&gt;ITK supports other data structures beyond images, including &lt;code&gt;Mesh&lt;/code&gt;'s, &lt;code&gt;PointSet&lt;/code&gt;'s, and spatial &lt;code&gt;Transform&lt;/code&gt;'s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;websave("cow.vtk", "https://bafybeihqh2e2xyff5fzwygx4m2lmgqmnm3kv7gyzjgtcgv7kpfvvjy4rty.ipfs.w3s.link/ipfs/bafybeihqh2e2xyff5fzwygx4m2lmgqmnm3kv7gyzjgtcgv7kpfvvjy4rty/cow.vtk");

% load the mesh with itk
% pyrun(["mesh = itk.meshread('cow.vtk')"])
mesh = py.itk.meshread("cow.vtk")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mesh = 
  Python itkMeshF3 with properties:

    thisown: 1
       this: [1x1 py.SwigPyObject]

    Mesh (0x7f3aee68b400)
      RTTI typeinfo:   itk::Mesh&amp;lt;float, 3u, itk::DefaultStaticMeshTraits&amp;lt;float, 3u, 3u, float, float, float&amp;gt; &amp;gt;
      Reference Count: 1
      Modified Time: 10117
      Debug: Off
      Object Name: 
      Observers: 
        none
      Source: (none)
      Source output name: (none)
      Release Data: Off
      Data Released: False
      Global Release Data: Off
      PipelineMTime: 669
      UpdateMTime: 10116
      RealTimeStamp: 0 seconds 
      Number Of Points: 2903
      Requested Number Of Regions: 1
      Requested Region: 0
      Buffered Region: 0
      Maximum Number Of Regions: 1
      Point Data Container pointer: 0
      Size of Point Data Container: 0
      Number Of Points: 2903
      Number Of Cell Links: 0
      Number Of Cells: 3263
      Cell Data Container pointer: 0
      Size of Cell Data Container: 0
      Number of explicit cell boundary assignments: 3
      CellsAllocationMethod: itk::MeshEnums::MeshClassCellsAllocationMethod::CellsAllocatedDynamicallyCellByCell


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
% transfer python dict to matlab
mesh_dict = py.itk.dict_from_mesh(mesh)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mesh_dict = 
  Python dict with no properties.

    {'meshType': {'dimension': 3, 'pointComponentType': 'float32', 'pointPixelComponentType': 'float32', 'pointPixelType': 'Scalar', 'pointPixelComponents': 1, 'cellComponentType': 'uint64', 'cellPixelComponentType': 'float32', 'cellPixelType': 'Scalar', 'cellPixelComponents': 1}, 'name': '', 'numberOfPoints': 2903, 'points': array([3.71636 , 2.34339 , 0.      , ..., 4.23234 , 1.90308 , 0.534362],
          dtype=float32), 'numberOfPointPixels': 0, 'pointData': array([], dtype=float32), 'numberOfCells': 3263, 'cells': array([  4,   4, 250, ..., 966, 961, 970], dtype=uint64), 'numberOfCellPixels': 0, 'cellData': array([], dtype=float32), 'cellBufferSize': 18856}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% x,y,z point positions
points = double(mesh_dict{"points"})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;points = 1x8709    
    3.7164    2.3434         0    4.1266    0.6420         0    3.4550    2.1699         0    3.9293    0.4117         0    3.2474    2.0733         0    3.7317    0.1864         0    2.9854    1.9827         0    3.4860   -0.1417         0    2.7235    1.8988         0    3.3352   -0.3758         0    2.3396    1.8077         0    3.1181   -0.7039         0    2.1281    1.7884         0    2.0422    1.7772         0    1.4567    1.7859         0    2.9709   -0.9597         0    2.9318   -1.1297

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  WebAssembly packages with itkwasm
&lt;/h1&gt;

&lt;p&gt;In addition to native Python packages, &lt;a href="https://wasm.itk.org/" rel="noopener noreferrer"&gt;&lt;code&gt;itkwasm&lt;/code&gt;&lt;/a&gt; Python packages can be used, which leverage universal &lt;a href="https://webassembly.org" rel="noopener noreferrer"&gt;WebAssembly&lt;/a&gt; binaries.&lt;/p&gt;

&lt;p&gt;Calls are similar, but we use Python's builtin &lt;code&gt;dataclasses.asdict&lt;/code&gt; for conversion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!python3 pip.pyz install --user itkwasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Collecting itkwasm
  Downloading itkwasm-1.0b74-py3-none-any.whl (18 kB)
Collecting wasmer
  Downloading wasmer-1.1.0-cp38-cp38-manylinux_2_24_x86_64.whl (1.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 89.3 MB/s eta 0:00:00

Requirement already satisfied: numpy in /home/mluser/.local/lib/python3.8/site-packages (from itkwasm) (1.24.2)
Collecting wasmer-compiler-cranelift
  Downloading wasmer_compiler_cranelift-1.1.0-cp38-cp38-manylinux_2_24_x86_64.whl (1.9 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.9/1.9 MB 115.2 MB/s eta 0:00:00

Collecting typing-extensions
  Downloading typing_extensions-4.5.0-py3-none-any.whl (27 kB)
Installing collected packages: wasmer-compiler-cranelift, wasmer, typing-extensions, itkwasm
Successfully installed itkwasm-1.0b74 typing-extensions-4.5.0 wasmer-1.1.0 wasmer-compiler-cranelift-1.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itk_image = py.itk.imread("cthead1.png");
itk_image_dict = py.itk.dict_from_image(itk_image)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itk_image_dict = 
  Python dict with no properties.

    {'imageType': {'dimension': 2, 'componentType': 'uint8', 'pixelType': 'Scalar', 'components': 1}, 'name': '', 'origin': (0.0, 0.0), 'spacing': (1.0, 1.0), 'size': (256, 256), 'direction': array([[1., 0.],
           [0., 1.]]), 'data': array([[0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           ...,
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itkwasm_image = pyrun(["from itkwasm import Image", "itkwasm_image = Image(**itk_image_dict)"], "itkwasm_image", itk_image_dict=itk_image_dict)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itkwasm_image = 
  Python Image with properties:

         data: [1x1 py.numpy.ndarray]
         size: [1x2 py.tuple]
       origin: [1x2 py.tuple]
    imageType: [1x1 py.itkwasm.image.ImageType]
         name: [1x0 py.str]
      spacing: [1x2 py.tuple]
     metadata: [1x1 py.dict]
    direction: [1x1 py.numpy.ndarray]

    Image(imageType=ImageType(dimension=2, componentType='uint8', pixelType='Scalar', components=1), name='', origin=(0.0, 0.0), spacing=(1.0, 1.0), direction=array([[1., 0.],
           [0., 1.]]), size=(256, 256), metadata={}, data=array([[0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           ...,
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0]], dtype=uint8))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itkwasm_image_dict = py.dataclasses.asdict(itkwasm_image)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;itkwasm_image_dict = 
  Python dict with no properties.

    {'imageType': {'dimension': 2, 'componentType': 'uint8', 'pixelType': 'Scalar', 'components': 1}, 'name': '', 'origin': (0.0, 0.0), 'spacing': (1.0, 1.0), 'direction': array([[1., 0.],
           [0., 1.]]), 'size': (256, 256), 'metadata': {}, 'data': array([[0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           ...,
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0],
           [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;imshow(uint8(itkwasm_image_dict{"data"}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s2cofkejx4i2wu98do1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s2cofkejx4i2wu98do1.png" width="577" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ITKElastix 0.16.0 has been released!</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Tue, 21 Feb 2023 17:32:07 +0000</pubDate>
      <link>https://dev.to/thewtex/itkelastix-0160-has-been-released-pfa</link>
      <guid>https://dev.to/thewtex/itkelastix-0160-has-been-released-pfa</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick, Niels Dekker, Konstantinos Ntatsis, Marius Staring
&lt;/h6&gt;

&lt;p&gt;We are exceedingly pleased to announce the release of &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix/releases/tag/v0.16.0"&gt;ITKElastix 0.16.0&lt;/a&gt;, an &lt;a href="https://itk.org"&gt;ITK&lt;/a&gt; module that provides Python and C++ interfaces to &lt;a href="https://elastix.lumc.nl/"&gt;elastix&lt;/a&gt;, a toolbox for rigid and nonrigid registration of N-dimensional images. 🎉 🗺️🧠🙌&lt;/p&gt;

&lt;p&gt;Registration is the task of finding a spatial transformation that aligns one image to another by optimizing relevant image similarity metrics.&lt;/p&gt;

&lt;p&gt;For more information on how to register scientific images, see the &lt;a href="https://mybinder.org/v2/gh/InsightSoftwareConsortium/ITKElastix/main?urlpath=lab/tree/examples%2FITK_Example01_SimpleRegistration.ipynb"&gt;itk-elastix jupyter notebooks&lt;/a&gt; and the &lt;a href="https://github.com/SuperElastix/elastix/releases/download/5.1.0/elastix-5.1.0-manual.pdf"&gt;elastix manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4lnAErnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/AS6xJ7L.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4lnAErnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/AS6xJ7L.png" alt="monai-elastix hand registration" width="880" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MONAI deep learning registration with elastix pre-alignment &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_Example17_MONAIWithPreregistration.ipynb"&gt;(jupyter notebook)&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💾 Download
&lt;/h2&gt;

&lt;p&gt;To install the binary Python packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install itk-elastix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✨ Highlights
&lt;/h2&gt;

&lt;p&gt;ITKElastix 0.16.0 is released in conjunction with &lt;a href="https://github.com/SuperElastix/elastix/releases/tag/5.1.0"&gt;elastix 5.1.0&lt;/a&gt;. Features added include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐍 Cross-platform binary Python packages are now 80% smaller&lt;/li&gt;
&lt;li&gt;💪 macOS, Linux ARM Python packages&lt;/li&gt;
&lt;li&gt;🗣️ Updated example notebook on &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_Example17_MONAIWithPreregistration.ipynb"&gt;MONAI deep learning registration with affine pre-alignment using itk-elastix&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 Major performance improvements in the calculation of metrics; accelerates registration for some cases by 40% or more&lt;/li&gt;
&lt;li&gt;C++14 modernization&lt;/li&gt;
&lt;li&gt;Upgraded to &lt;a href="https://github.com/InsightSoftwareConsortium/ITK/releases/tag/v5.3.0"&gt;ITK 5.3.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Support ITK Transform types: Translation, Affine, Euler (2D and 3D), Similarity (2D and 3D), and BSpline&lt;/li&gt;
&lt;li&gt;Add &lt;em&gt;GetCombinationTransform()&lt;/em&gt;, &lt;em&gt;GetNumberOfTransforms()&lt;/em&gt;, &lt;em&gt;GetNthTransform(n)&lt;/em&gt;, &lt;em&gt;ConvertToItkTransform(transform)&lt;/em&gt; to &lt;code&gt;itk::ElastixRegistrationMethod&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;em&gt;SetCombinationTransform(transform)&lt;/em&gt; to &lt;code&gt;itk::TransformixFilter&lt;/code&gt;, for access and use of transform objects through the library interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details, see the full &lt;a href="https://github.com/SuperElastix/elastix/releases/tag/5.1.0"&gt;elastix 5.1.0 release notes&lt;/a&gt; and &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix/releases/tag/v0.16.0"&gt;ITKElastix 0.16.0 release notes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗣️ What's Next
&lt;/h2&gt;

&lt;p&gt;In the next release, we will publish additional notebooks on how to support medical image deep learning artificial intelligence (AI) with &lt;a href="https://monai.io/"&gt;Project MONAI&lt;/a&gt;. These improvement are made in collaboration with the MONAI community as &lt;code&gt;itk&lt;/code&gt; Python package spatial metadata improvements in &lt;code&gt;monai&lt;/code&gt; harden and extend MONAI's medical image registration capabilities. We will update the current &lt;a href="https://github.com/SuperElastix/elastix_napari"&gt;elastix_napari&lt;/a&gt; for &lt;a href="https://github.com/napari/napari"&gt;napari&lt;/a&gt; integration. Also, &lt;a href="https://webassembly.org/"&gt;WebAssembly&lt;/a&gt; builds will be created via &lt;a href="https://wasm.itk.org"&gt;itk-wasm&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🙏 Acknowledgments
&lt;/h2&gt;

&lt;p&gt;ITKElastix was developed in part with support from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://braininitiative.nih.gov/"&gt;NIH NIMH BRAIN Initiative&lt;/a&gt; under award 1RF1MH126732.&lt;/li&gt;
&lt;li&gt;Chan Zuckerberg Initiative (CZI) Essential Open Source Software for Science award for &lt;a href="https://chanzuckerberg.com/eoss/proposals/open-source-image-registration-the-elastix-toolbox/"&gt;Open Source Image Registration: The elastix Toolbox&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Enjoy ITK and elastix!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>jupyter</category>
      <category>opensource</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Create Elegant C++ Spatial Processing Pipelines in WebAssembly</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Fri, 10 Feb 2023 21:22:03 +0000</pubDate>
      <link>https://dev.to/thewtex/create-elegant-c-spatial-processing-pipelines-in-webassembly-7lg</link>
      <guid>https://dev.to/thewtex/create-elegant-c-spatial-processing-pipelines-in-webassembly-7lg</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick &lt;a href="https://orcid.org/0000-0001-9475-3756" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycpvj6nbwcv46f56uxa1.gif" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;, Mary Elise Dedicke &lt;a href="https://orcid.org/0000-0001-8848-3235" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycpvj6nbwcv46f56uxa1.gif" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;, Henry Schreiner &lt;a href="https://orcid.org/0000-0002-7833-783X" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycpvj6nbwcv46f56uxa1.gif" alt="ORCID" width="16" height="16"&gt;&lt;/a&gt;
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://webassembly.org/" rel="noopener noreferrer"&gt;WebAssembly&lt;/a&gt;'s origins date back to &lt;a href="https://emscripten.org" rel="noopener noreferrer"&gt;Alon Zakai&lt;/a&gt;'s  incredible effort to build C++ to JavaScript. In 2015, we demonstrated the power of this technology to make scientific computational sustainable and accessible. &lt;a href="https://insightsoftwareconsortium.github.io/ITKAnisotropicDiffusionLBR/" rel="noopener noreferrer"&gt;Try it&lt;/a&gt; -- reproducibility is still possible all these years later, with no installation (or maintenance!) required. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://insightsoftwareconsortium.github.io/ITKAnisotropicDiffusionLBR/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfwkl45hm5osxwgggah5.png" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;An interactive, accessible and sustainable open science publication on anisotropic diffusion where C++ is built into JavaScript for browser execution.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Since that time, Emscripten's capabilities have advanced and been standardized with WebAssembly (Wasm) in the &lt;a href="https://en.wikipedia.org/wiki/Web_platform" rel="noopener noreferrer"&gt;Web Platform&lt;/a&gt;. Moreover, Wasm's scope has expanded dramatically with the advent of the &lt;a href="https://github.com/WebAssembly/WASI" rel="noopener noreferrer"&gt;WebAssembly System Interface, WASI&lt;/a&gt;, and &lt;a href="https://github.com/WebAssembly/component-model" rel="noopener noreferrer"&gt;The Component Model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, there was a &lt;strong&gt;significant gap&lt;/strong&gt; in capabilites for research software developers who aimed to create &lt;strong&gt;data and computationally intense scientific processing pipelines&lt;/strong&gt; for applications like spatial analysis and visualization. Namely,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;An elegant, simple way to write processing pipelines in C++.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Handling of non-trivial spatial data structures (Wasm natively only supports integers and floats 😮).&lt;/li&gt;
&lt;li&gt;Easy-to-use, reproducible tools to build Wasm modules.&lt;/li&gt;
&lt;li&gt;Safe and efficient memory handling.&lt;/li&gt;
&lt;li&gt;Parallelism, whether multi-module, multi-threading, or SIMD.&lt;/li&gt;
&lt;li&gt;Provide bindings for the command line and functional interfaces for languages like JavaScript, Typescript, Python, Rust, C#, R, and Java.&lt;/li&gt;
&lt;li&gt;Debugging support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, adapted from &lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;itk-wasm&lt;/a&gt;'s documentation, we provide a C++ Wasm processing pipeline tutorial that demonstrates how we can &lt;strong&gt;write elegant processing pipelines in C++ via itk-wasm's &lt;a href="https://github.com/CLIUtils/CLI11" rel="noopener noreferrer"&gt;CLI11&lt;/a&gt; command line parser, which provides a rich feature set with a simple and intuitive interface&lt;/strong&gt;. At the end of this tutorial, you will have built and executed C++ code to Wasm for standalone execution on the command line and in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;&lt;em&gt;itk-wasm&lt;/em&gt;&lt;/a&gt; combines &lt;a href="https://www.itk.org/" rel="noopener noreferrer"&gt;the Insight Toolkit (ITK)&lt;/a&gt; and WebAssembly to enable &lt;em&gt;high-performance spatial analysis&lt;/em&gt; in a web browser, Node.js, and reproducible execution across programming languages and hardware architectures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cliutils.github.io/CLI11/book/" rel="noopener noreferrer"&gt;CLI11&lt;/a&gt; provides all the features you expect in a powerful command line parser, with a beautiful, minimal syntax and no dependencies beyond C++11. itk-wasm enhances CLI11 with a &lt;code&gt;itk::wasm::Pipeline&lt;/code&gt; wrapper to support efficient execution in multiple Wasm contexts, scientific data structures, and lovely colorized help output 🥰. &lt;/p&gt;

&lt;p&gt;Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Preliminaries
&lt;/h2&gt;

&lt;p&gt;Before starting this tutorial, check out our &lt;a href="https://www.kitware.com/hello-wasm-world/" rel="noopener noreferrer"&gt;Hello Wasm World&lt;/a&gt; tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Write the code
&lt;/h2&gt;

&lt;p&gt;First, let's create a new directory to house our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;hello-pipeline
&lt;span class="nb"&gt;cd &lt;/span&gt;hello-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write some code! Populate &lt;em&gt;hello-pipeline.cxx&lt;/em&gt; first with the headers we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"itkPipeline.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"itkInputImage.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"itkImage.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;itkPipeline.h&lt;/em&gt; and &lt;em&gt;itkInputImage.h&lt;/em&gt; headers come from the itk-wasm &lt;em&gt;WebAssemblyInterface&lt;/em&gt; &lt;a href="https://www.kitware.com/advance-itk-with-modules/" rel="noopener noreferrer"&gt;ITK module&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;itkImage.h&lt;/em&gt; header is &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;ITK&lt;/a&gt;'s standard n-dimensional image data structure.&lt;/p&gt;

&lt;p&gt;Next, create a standard &lt;code&gt;main&lt;/code&gt; C command line interface function and an &lt;code&gt;itk::wasm::Pipeline&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&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 the pipeline for parsing arguments. Provide a description.&lt;/span&gt;
  &lt;span class="n"&gt;itk&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;wasm&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pipeline&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello-pipeline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"A hello world itk::wasm::Pipeline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;itk::wasm::Pipeline&lt;/code&gt; extends the &lt;a href="https://github.com/CLIUtils/CLI11" rel="noopener noreferrer"&gt;CLI11 modern C++ command line parser&lt;/a&gt;. In addition to all of CLI11's functionality, &lt;code&gt;itk::wasm::Pipeline&lt;/code&gt;'s adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support for execution in Wasm modules along with command line execution&lt;/li&gt;
&lt;li&gt;Support for spatial data structures such as &lt;code&gt;Image&lt;/code&gt;, &lt;code&gt;Mesh&lt;/code&gt;, &lt;code&gt;PolyData&lt;/code&gt;, and &lt;code&gt;Transform&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Support for multiple dimensions and pixel types&lt;/li&gt;
&lt;li&gt;Colored help output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add a standard CLI11 flag to the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;  &lt;span class="n"&gt;itk&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;wasm&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pipeline&lt;/span&gt; &lt;span class="nf"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello-pipeline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"A hello world itk::wasm::Pipeline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_flag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-q,--quiet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Do not print image information"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add an input image argument to the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;  &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_flag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-q,--quiet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Do not print image information"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="k"&gt;constexpr&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Dimension&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;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;PixelType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;ImageType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itk&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PixelType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dimension&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Add a input image argument.&lt;/span&gt;
  &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;InputImageType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itk&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;wasm&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InputImage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ImageType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;InputImageType&lt;/span&gt; &lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input-image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"The input image"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INPUT_IMAGE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;inputImage&lt;/code&gt; variable is populated from the filesystem if built as a native executable or a WASI binary run from the command line. When running in the browser or in a wrapped language, &lt;code&gt;inputImage&lt;/code&gt; is read from WebAssembly memory without file IO.&lt;/p&gt;

&lt;p&gt;Parse the command line arguments with the &lt;code&gt;ITK_WASM_PARSE&lt;/code&gt; macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;  &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"InputImage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"The input image"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INPUT_IMAGE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="n"&gt;ITK_WASM_PARSE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;-q&lt;/code&gt; or &lt;code&gt;--quiet&lt;/code&gt; is set, the &lt;code&gt;quiet&lt;/code&gt; variable will be set to &lt;code&gt;true&lt;/code&gt;. Missing or invalid arguments will print an error and exit. The &lt;code&gt;-h&lt;/code&gt; and &lt;code&gt;--help&lt;/code&gt; flags are automatically generated from pipeline arguments to print usage information.&lt;/p&gt;

&lt;p&gt;Finally, run the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Hello pipeline world!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;quiet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Obtain the itk::Image * from the itk::wasm::InputImage with `.Get()`.&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Input image: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, provide a &lt;a href="https://cmake.org/" rel="noopener noreferrer"&gt;CMake&lt;/a&gt; build configuration in &lt;em&gt;CMakeLists.txt&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 3.16&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;hello-pipeline&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Use C++17 or newer with itk-wasm&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_CXX_STANDARD 17&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# We always want to build against the WebAssemblyInterface module.&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;itk_components
  WebAssemblyInterface
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# WASI or native binaries&lt;/span&gt;
&lt;span class="nb"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;NOT EMSCRIPTEN&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# WebAssemblyInterface supports the .iwi, .iwi.cbor itk-wasm format.&lt;/span&gt;
  &lt;span class="c1"&gt;# We can list other ITK IO modules to build against to support other&lt;/span&gt;
  &lt;span class="c1"&gt;# formats when building native executable or WASI WebAssembly.&lt;/span&gt;
  &lt;span class="c1"&gt;# However, this will bloat the size of the WASI WebAssembly binary, so&lt;/span&gt;
  &lt;span class="c1"&gt;# add them judiciously.&lt;/span&gt;
  &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;itk_components
    WebAssemblyInterface
    ITKIOPNG
    &lt;span class="c1"&gt;# ITKImageIO # Adds support for all available image IO modules&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;ITK REQUIRED
  COMPONENTS &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;itk_components&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ITK_USE_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;hello-pipeline hello-pipeline.cxx&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;hello-pipeline PUBLIC &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ITK_LIBRARIES&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create and Run WebAssembly binary
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kitware.com/hello-wasm-world/" rel="noopener noreferrer"&gt;Build the WASI binary&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx itk-wasm@1.0.0-b.70 &lt;span class="nt"&gt;-i&lt;/span&gt; itkwasm/wasi build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And check the generated help output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx itk-wasm@1.0.0-b.70 run hello-pipeline.wasi.wasm &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuc5mzpzkjf07h8040ti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuc5mzpzkjf07h8040ti.png" alt="Hello pipeline help" width="644" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two &lt;code&gt;--&lt;/code&gt;'s are to separate arguments for the Wasm module from arguments to the &lt;code&gt;itk-wasm&lt;/code&gt; CLI and the WebAssembly interpreter.&lt;/p&gt;

&lt;p&gt;Try running on an &lt;a href="https://data.kitware.com/api/v1/file/63041ac8f64de9b9501e5a22/download" rel="noopener noreferrer"&gt;example image&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npx itk-wasm@1.0.0-b.65 run hello-pipeline.wasi.wasm -- -- cthead1.png

Hello pipeline world!

Input image: Image (0x2b910)
  RTTI typeinfo:   itk::Image&amp;lt;unsigned char, 2u&amp;gt;
  Reference Count: 1
  Modified Time: 54
  Debug: Off
  Object Name:
  Observers:
    none
  Source: (none)
  Source output name: (none)
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 22
  UpdateMTime: 53
  RealTimeStamp: 0 seconds
  LargestPossibleRegion:
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  BufferedRegion:
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  RequestedRegion:
    Dimension: 2
    Index: [0, 0]
    Size: [256, 256]
  Spacing: [1, 1]
  Origin: [0, 0]
  Direction:
1 0
0 1

  IndexToPointMatrix:
1 0
0 1

  PointToIndexMatrix:
1 0
0 1

  Inverse Direction:
1 0
0 1

  PixelContainer:
    ImportImageContainer (0x2ba60)
      RTTI typeinfo:   itk::ImportImageContainer&amp;lt;unsigned long, unsigned char&amp;gt;
      Reference Count: 1
      Modified Time: 50
      Debug: Off
      Object Name:
      Observers:
        none
      Pointer: 0x2c070
      Container manages memory: true
      Size: 65536
      Capacity: 65536
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with the &lt;code&gt;--quiet&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npx itk-wasm@1.0.0-b.65 run hello-pipeline.wasi.wasm -- -- --quiet cthead1.png

Hello pipeline world!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You just executed a C++ pipeline capable of processsing a scientific image in WebAssembly. 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;We created a processing pipeline that works with real data -- exciting! When creating these pipelines, however, we will sometimes need a more detailed understanding of their execution. In our next post, we will address this need by describing how to debug itk-wasm WASI modules.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>software</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Hello Wasm World!</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Sat, 14 Jan 2023 14:42:44 +0000</pubDate>
      <link>https://dev.to/thewtex/hello-wasm-world-59a3</link>
      <guid>https://dev.to/thewtex/hello-wasm-world-59a3</guid>
      <description>&lt;p&gt;In modern computing, the &lt;a href="https://en.wikipedia.org/wiki/Web_platform" rel="noopener noreferrer"&gt;Web Platform&lt;/a&gt; has transformed &lt;em&gt;web browsers&lt;/em&gt; into a &lt;strong&gt;powerful&lt;/strong&gt; and &lt;strong&gt;accessible&lt;/strong&gt; &lt;em&gt;application interface&lt;/em&gt;. Applications built on open web standards work, with no installation, across operating system and hardware platforms. &lt;a href="https://en.wikipedia.org/wiki/WebAssembly" rel="noopener noreferrer"&gt;WebAssembly&lt;/a&gt;, also known as &lt;em&gt;Wasm&lt;/em&gt;, is a portable, binary format for high-performance applications on the web. Wasm has additional properties critical for the web: tiny binary sizes and strong, security-driven sandboxed execution. Wasm's capabilities became even more universal with with the creation of the &lt;a href="https://github.com/WebAssembly/WASI" rel="noopener noreferrer"&gt;WebAssembly System Interface, WASI&lt;/a&gt;, open standard. WASI enables Wasm to run outside the browser in contexts such as the command line, embedded environments, and within higher level programming languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;&lt;em&gt;itk-wasm&lt;/em&gt;&lt;/a&gt; combines &lt;a href="https://www.itk.org/" rel="noopener noreferrer"&gt;the Insight Toolkit (ITK)&lt;/a&gt; and WebAssembly to enable &lt;em&gt;high-performance spatial analysis&lt;/em&gt; in a web browser, Node.js, and reproducible execution across programming languages and hardware architectures.&lt;/p&gt;

&lt;p&gt;In this post, adapted from itk-wasm's documentation, we provide a C++ Wasm &lt;a href="https://en.wikipedia.org/wiki/%22Hello,_World!%22_program" rel="noopener noreferrer"&gt;Hello World&lt;/a&gt; tutorial. At the end of this tutorial you will have built and executed C++ code to Wasm for standalone execution on the command line and in the browser.&lt;/p&gt;

&lt;p&gt;Let's get started! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Preliminaries
&lt;/h2&gt;

&lt;p&gt;Before getting started, make sure &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://docs.docker.com/install/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; are installed. On Linux, make sure you can run &lt;a href="https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo" rel="noopener noreferrer"&gt;&lt;code&gt;docker&lt;/code&gt; without &lt;code&gt;sudo&lt;/code&gt;&lt;/a&gt;. On Windows, we recommend &lt;a href="https://docs.docker.com/desktop/windows/wsl/" rel="noopener noreferrer"&gt;WSL 2 with Docker enabled&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While we recommend following along step-by-step, the complete example can also be found in the &lt;a href="https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples" rel="noopener noreferrer"&gt;&lt;code&gt;examples/&lt;/code&gt; directory of the project repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write the code
&lt;/h2&gt;

&lt;p&gt;First, let's create a new directory to house our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;HelloWorld
&lt;span class="nb"&gt;cd &lt;/span&gt;HelloWorld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write some code! Populate &lt;em&gt;hello.cxx&lt;/em&gt; with our Hello World program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Hello Wasm world!"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, provide a &lt;a href="https://cmake.org/" rel="noopener noreferrer"&gt;CMake&lt;/a&gt; build configuration at &lt;em&gt;CMakeLists.txt&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 3.16&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;HelloWorld&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;hello hello.cxx&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install itk-wasm
&lt;/h2&gt;

&lt;p&gt;We use the &lt;code&gt;add_executable&lt;/code&gt; command to build executables with itk-wasm. The &lt;a href="https://kripken.github.io/emscripten-site/" rel="noopener noreferrer"&gt;Emscripten&lt;/a&gt; and &lt;a href="https://github.com/WebAssembly/wasi-sdk" rel="noopener noreferrer"&gt;WASI&lt;/a&gt; toolchains along with itk-wasm build and execution configurations are contained in itk-wasm &lt;a href="https://github.com/dockcross/dockcross" rel="noopener noreferrer"&gt;dockcross&lt;/a&gt; Docker images invoked by the itk-wasm command line interface (CLI).  Note that the same code can also be built and tested with native operating system toolchains. This is useful for development and debugging.&lt;/p&gt;

&lt;p&gt;Build the program with the itk-wasm CLI, &lt;code&gt;itk-wasm&lt;/code&gt;. This is shipped with the &lt;code&gt;itk-wasm&lt;/code&gt; Node.js package. First install &lt;em&gt;itk-wasm&lt;/em&gt; with the Node Package Manager, &lt;code&gt;npm&lt;/code&gt;, the CLI that ships with Node.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize an empty project in the current directory&lt;/span&gt;
❯ npm init &lt;span class="nt"&gt;--yes&lt;/span&gt;
❯ npm &lt;span class="nb"&gt;install &lt;/span&gt;itk-wasm@1.0.0-b.70
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run on the command line
&lt;/h2&gt;

&lt;p&gt;Build the project with the WASI &lt;code&gt;itkwasm/wasi&lt;/code&gt; toolchain in the &lt;code&gt;./wasi-build/&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ npx itk-wasm &lt;span class="nt"&gt;-i&lt;/span&gt; itkwasm/wasi &lt;span class="nt"&gt;-b&lt;/span&gt; ./wasi-build/ build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;hello.wasi.wasm&lt;/code&gt; WebAssembly binary is built in the &lt;code&gt;./wasi-build/&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;ls &lt;/span&gt;wasi-build
build.ninja          CMakeFiles          libwasi-exception-shim.a
cmake_install.cmake  hello.wasi.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute the binary with the &lt;code&gt;run&lt;/code&gt; &lt;code&gt;itk-wasm&lt;/code&gt; subcommand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ npx itk-wasm &lt;span class="nt"&gt;-b&lt;/span&gt; ./wasi-build/ run hello.wasi.wasm
Hello Wasm world!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You just executed a C++ program compiled to WebAssembly. 🎉&lt;/p&gt;

&lt;p&gt;The binary can also be executed with other &lt;a href="https://github.com/mbasso/awesome-wasm#non-web-embeddings" rel="noopener noreferrer"&gt;WASI runtimes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run in the browser
&lt;/h2&gt;

&lt;p&gt;For Node.js or the Browser, build the project with the default &lt;a href="https://emscripten.org/" rel="noopener noreferrer"&gt;Emscripten&lt;/a&gt; toolchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ npx itk-wasm &lt;span class="nt"&gt;-b&lt;/span&gt; ./emscripten-build build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same Emscripten Wasm module can be executed in a web browser.&lt;/p&gt;

&lt;p&gt;Create an HTML file that will call the Wasm module through JavaScript and display&lt;br&gt;
its output in the HTML DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;itk-wasm Browser Hello World!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/itk-wasm@1.0.0-b.53/dist/umd/itk-wasm.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;readonly&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;WebAssembly output...&lt;span class="nt"&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputTextArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textarea&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;outputTextArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Loading...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wasmURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;emscripten-build/hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
      &lt;span class="nx"&gt;itk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wasmURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;webWorker&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;webWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="nx"&gt;outputTextArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Serve the web page and Wasm module with an http server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ npm &lt;span class="nb"&gt;install &lt;/span&gt;http-server
❯ npx http-server &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And point your browser to &lt;code&gt;http://127.0.0.1:8080/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtm6kbvqy49kpuv55pv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtm6kbvqy49kpuv55pv9.png" alt="Hello Wasm World!" width="390" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You just executed a C++ program in your web browser. 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Well done!&lt;/p&gt;

&lt;p&gt;As you build more advanced C++ projects into WebAssembly, you will find that many CMake-configured projects will &lt;em&gt;just work&lt;/em&gt; with &lt;a href="https://wasm.itk.org" rel="noopener noreferrer"&gt;itk-wasm&lt;/a&gt; since it handles details required for CMake &lt;code&gt;try_run&lt;/code&gt; commands, C++ exception handling, optimization of Wasm binary size, etc.&lt;/p&gt;

&lt;p&gt;In the next tutorial, we will introduces itk-wasm's ability to elegantly transform standalone C++ command line programs into powerful Wasm modules with a simple, efficient interface.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Welcome and guide first-time contributors with a GitHub Action</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Thu, 12 Jan 2023 16:50:32 +0000</pubDate>
      <link>https://dev.to/thewtex/welcome-and-guide-first-time-contributors-with-a-github-action-2i29</link>
      <guid>https://dev.to/thewtex/welcome-and-guide-first-time-contributors-with-a-github-action-2i29</guid>
      <description>&lt;p&gt;Back in the day, before open source won the Closed vs. Open Wars (&lt;a href="https://www.kitware.com//why-open-source-will-rule-scientific-computing/" rel="noopener noreferrer"&gt;especially in scientific computing&lt;/a&gt;),&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RTFM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;was a common first response when a new developer sought to contribute to an open source project. RTFM stands for &lt;em&gt;Read the Fine Manual&lt;/em&gt;, although there is also another, more crass, interpretation.&lt;/p&gt;

&lt;p&gt;We can do better!&lt;/p&gt;

&lt;p&gt;And in modern times, we must do better as a pragmatic imperative. In our overloaded, hectic lives, few have the time to read every project's manual before they submit a small fix. Moreover, as a new generation of developers are impatient with interactions beyond swiping a screen, they are not going to proactively sign up for a GNU Mailman mailing list, seek out and read all associated manuals, search mailing list archives, and &lt;em&gt;then&lt;/em&gt; post to the list according to the conventions of the community. While forking and maintaining patches should be avoided when possible in the interest of long-term maintainability, modern tooling for version control and testing makes it slightly more feasible. In general, a potential contributor's time, attention, and energy are in short supply, and we need to make their introduction to the contribution process as painless as possible.&lt;/p&gt;

&lt;p&gt;At the same time, as community-driven maintainers of open source projects, we must limit our time, which is in even shorter supply, while upholding the project's culture, quality, and sustainability.&lt;/p&gt;

&lt;p&gt;In this post, we review how the &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;Insight Toolkit (ITK)&lt;/a&gt; leverages the &lt;a href="https://github.com/marketplace/actions/first-interaction" rel="noopener noreferrer"&gt;first-interaction GitHub Action&lt;/a&gt; to communicate our appreciation of the efforts of first-time contributors, establish norms for behavior, and provide civil pointers on where to find more information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffs9msbrqctm34sb9rqkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffs9msbrqctm34sb9rqkw.png" alt="First interaction welcome" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example first interaction welcome message&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated outreach on first interaction
&lt;/h2&gt;

&lt;p&gt;While GitHub has made many improvements that facilitate social coding, including resources to &lt;a href="https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/setting-guidelines-for-repository-contributors" rel="noopener noreferrer"&gt;automate pointers to contributing guidelines&lt;/a&gt; that are put forward and easily discoverable using &lt;a href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#relative-links" rel="noopener noreferrer"&gt;relative links&lt;/a&gt; and a project's code of conduct for new contributors, configuration of the first-interaction GitHub Action is another mechanism that can be customized to a project's needs.&lt;/p&gt;

&lt;p&gt;The first-interaction GitHub Action adds a comment whenever a first-time contributor opens their first issue or pull request. This automated message connects with contributors where their attention is already directed.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note of welcome and appreciation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/InsightSoftwareConsortium/ITK/blob/master/.github/workflows/first-interaction.yml" rel="noopener noreferrer"&gt;Our comment starts&lt;/a&gt; with a note of welcome to the community and gratitude for the effort made to contribute back to the project. Software development, regardless of the cold and mechanical nature of computers, is a social endeavor; we respect and acknowledge this by beginning with our gratitude.&lt;/p&gt;

&lt;p&gt;Recently, &lt;a href="https://github.com/InsightSoftwareConsortium/ITK/pull/3859" rel="noopener noreferrer"&gt;emojis were added&lt;/a&gt; to the message to communicate a welcoming culture. 🤗&lt;/p&gt;

&lt;h2&gt;
  
  
  Communicate mission, values, and culture
&lt;/h2&gt;

&lt;p&gt;Next, we provide a link to our &lt;a href="https://github.com/InsightSoftwareConsortium/ITK/blob/master/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;community participation guidelines / Code of Conduct&lt;/a&gt;. This establishes culture and communicates behavioral expectations, along with the project's mission:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ITK is one of the largest and long-lived open-source projects within the scientific community. ITK is made by hundreds of community members around the globe with a diverse set of skills, personalities, and experiences working for open and reproducible research in image analysis.&lt;/p&gt;

&lt;p&gt;We work to build a great image analysis tool that serves a broad range of applications and environments, from research and education, to industry and beyond, by trying to contribute with amazing features, and teaching and helping our fellows for such a honorable intention. We seek no explicit recognition for this. Hence a sense of additional responsibility is part of why we do what we do.&lt;/p&gt;

&lt;p&gt;We want a successful, friendly, agile and growing community that can welcome new ideas in a complex field, continuously improve our community software process, and foster collaboration between groups with very different needs, interests and skills. Openness, collaboration and participation are core aspects of our work - from development of new amazing image analysis features, to collaboratively shaping the necessary tools to make it an ever easier and joyful experience for both developers and end-users. Such an environment enriches the surrounding community and other open communities as well.&lt;/p&gt;

&lt;p&gt;We put people first and do our best to recognize, appreciate and respect the diversity of our global contributors. The ITK project welcomes contributions from everyone who shares our goals and strives to contribute in a healthy and constructive manner within our community. This implies diversity of ideas and perspectives on often complex problems. We gain strength from diversity and actively seek participation from those who enhance it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And our values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;be open&lt;/li&gt;
&lt;li&gt;be welcoming&lt;/li&gt;
&lt;li&gt;be inclusive&lt;/li&gt;
&lt;li&gt;be civil and considerate&lt;/li&gt;
&lt;li&gt;be respectful&lt;/li&gt;
&lt;li&gt;be collaborative&lt;/li&gt;
&lt;li&gt;be careful in the words that we choose&lt;/li&gt;
&lt;li&gt;take responsibility for our words and our actions&lt;/li&gt;
&lt;li&gt;be concise&lt;/li&gt;
&lt;li&gt;be inquisitive&lt;/li&gt;
&lt;li&gt;moderate your expectations&lt;/li&gt;
&lt;li&gt;ask for help when unsure&lt;/li&gt;
&lt;li&gt;lead by example&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Share where to find more information
&lt;/h2&gt;

&lt;p&gt;Finally, we provide guidance on where to find more information for contributors with issues or those that would like to integrate a patch. For issues, we point contributors to prior issues and the discussion forum. For pull requests, we point to &lt;a href="https://github.com/InsightSoftwareConsortium/ITK/blob/master/CONTRIBUTING.md" rel="noopener noreferrer"&gt;documentation on our contribution process&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Configuration of a first-interaction GitHub Action is a relatively small step, but it has large impact in the greater battle to &lt;a href="https://www.kitware.com//how-sustainable-is-your-software/" rel="noopener noreferrer"&gt;achieve software sustainability&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will continue our aim to move beyond RTFM to WYBC (Welcome Your Brilliant Contributors), CMVC (Communicate Mission, Values, and Culture), SYCD (Share Your Contributor Documentation), and CUBA (Come Up with Better Acronyms) 😊.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>security</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to raise the quality of scientific Jupyter notebooks</title>
      <dc:creator>Matt McCormick</dc:creator>
      <pubDate>Thu, 12 Jan 2023 04:21:44 +0000</pubDate>
      <link>https://dev.to/thewtex/how-to-raise-the-quality-of-scientific-jupyter-notebooks-17d5</link>
      <guid>https://dev.to/thewtex/how-to-raise-the-quality-of-scientific-jupyter-notebooks-17d5</guid>
      <description>&lt;h6&gt;
  
  
  By: Matt McCormick,  Mary Elise Dedicke, Alex Remedios
&lt;/h6&gt;

&lt;h2&gt;
  
  
  Reproducibility in Computational Experiments
&lt;/h2&gt;

&lt;p&gt;Jupyter has emerged as a fundamental component in artificial intelligence (AI) solution development and scientific inquiry. &lt;a href="https://jupyter.org/" rel="noopener noreferrer"&gt;Jupyter notebooks&lt;/a&gt; are prevelant in modern education, commercial applications, and academic research. The &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;Insight Toolkit (ITK)&lt;/a&gt; is an open source, cross-platform toolkit for N-dimensional  processing, segmentation, and registration used to obtain quantitative insights from medical, biomicroscopy, material science, and geoscience images. The ITK community highly values scientific reproducibility and software sustainability. As a result, advanced computational methods in the toolkit have a dramatically larger impact because they can be reproducibly applied in derived research or commercial applications.&lt;/p&gt;

&lt;p&gt;Since ITK's inception in 1999, there has been a focus on engineering practices that result in high-quality software. High-quality scientific software is driven by regression testing. The ITK project supported the development of &lt;a href="https://cmake.org/cmake/help/latest/manual/ctest.1.html" rel="noopener noreferrer"&gt;CTest&lt;/a&gt; and &lt;a href="https://www.cdash.org/" rel="noopener noreferrer"&gt;CDash&lt;/a&gt; unit testing and software quality dashboard tools for use with the &lt;a href="https://cmake.org" rel="noopener noreferrer"&gt;CMake&lt;/a&gt; build system. In the Python programming language, the &lt;a href="https://pytest.org" rel="noopener noreferrer"&gt;pytest&lt;/a&gt; test driver helps developers write small, readable scripts that ensure their software will continue to work as expected. However, pytest can only test Python scripts by default, and errors in untested computational notebooks are more common than well-tested Python code. &lt;/p&gt;

&lt;p&gt;In this post, we describe how ITK's Python interface leverages &lt;a href="https://github.com/treebeardtech/nbmake" rel="noopener noreferrer"&gt;nbmake&lt;/a&gt;, a simple, powerful tool that increases the quality of Jupyter notebooks through testing with the pytest test driver.&lt;/p&gt;

&lt;h2&gt;
  
  
  nbmake
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/treebeardtech/nbmake" rel="noopener noreferrer"&gt;nbmake&lt;/a&gt; is a pytest plugin that enables developers to verify that Jupyter notebook files run without error. This lets teams keep notebook-based documents and research up to date in an evolving project.&lt;/p&gt;

&lt;p&gt;Quite a few libraries exist that relate to unit testing and notebooks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/computationalmodelling/nbval" rel="noopener noreferrer"&gt;nbval&lt;/a&gt; is a strong fit for developers who want to check that cells always render to the same value&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nteract/testbook" rel="noopener noreferrer"&gt;testbook&lt;/a&gt; is maintained by the nteract community, and is good for testing functions written inside notebooks&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/treebeardtech/nbmake" rel="noopener noreferrer"&gt;nbmake&lt;/a&gt; is popular for those maintaining documentation and research material; it programmatically runs notebooks from top to bottom to validate the contents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We used nbmake because of the simplicity of its adoption, integration with pytest, and the ability to test locally and in continuous integration (CI) testing systems like GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;A great first step for testing notebooks is to run nbmake with its default settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;nbmake &lt;span class="c"&gt;# install the python library&lt;/span&gt;

pytest &lt;span class="nt"&gt;--nbmake&lt;/span&gt; my_notebook.ipynb &lt;span class="c"&gt;# Invoke pytest with nbmake on a notebook&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple command will detect a majority of common issues, such as import errors, in the notebook.&lt;/p&gt;

&lt;p&gt;To add more detail on expected notebook content, simply add assertions in two notebook cells like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# my_notebook.ipynb
&lt;/span&gt;
&lt;span class="c1"&gt;# %% Cell 1
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;

&lt;span class="c1"&gt;# %% Cell 2
&lt;/span&gt;&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use assertions to check your notebook is working as expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you want to present a cleaner version of the notebook without assertions, you can use &lt;a href="https://jupyterbook.org/" rel="noopener noreferrer"&gt;Jupyter book&lt;/a&gt; to render it into a site and use the &lt;a href="https://jupyterbook.org/en/stable/interactive/hiding.html?highlight=tag#remove-an-entire-code-cell" rel="noopener noreferrer"&gt;remove-cell tag&lt;/a&gt; to omit assertions from the output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips for using nbmake
&lt;/h3&gt;

&lt;p&gt;Starting to test any software package is always difficult, but once begun it becomes easier to maintain quality software.&lt;/p&gt;

&lt;p&gt;If your directory contains an assortment of notebooks, you will find different blockers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some require kernels with different types and names&lt;/li&gt;
&lt;li&gt;some raise errors, expectedly or unexpectedly&lt;/li&gt;
&lt;li&gt;some require authentication and network dependencies&lt;/li&gt;
&lt;li&gt;some will take hours to run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our advice is to start small.&lt;/p&gt;

&lt;p&gt;Try running nbmake locally from your development environment on a single short notebook. If&lt;br&gt;
that is a challenge, use the &lt;code&gt;--nbmake-find-import-errors&lt;/code&gt; flag to only check for missing dependencies.&lt;/p&gt;

&lt;p&gt;Once you have a minimal quality bar, you can think about what's next for your testing&lt;br&gt;
approach.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run software quality checks on CI&lt;/li&gt;
&lt;li&gt;Test more notebooks&lt;/li&gt;
&lt;li&gt;Reduce the test time by using &lt;a href="https://pypi.org/project/pytest-xdist/" rel="noopener noreferrer"&gt;&lt;code&gt;pytest-xdist&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;--overwrite&lt;/code&gt; flag to write the output notebooks to disk to build documentation or
commit to version control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For complete docs and troubleshooting guides, see the &lt;a href="https://github.com/treebeardtech/nbmake" rel="noopener noreferrer"&gt;nbmake GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ITK Use Cases
&lt;/h2&gt;

&lt;p&gt;When creating spatial analysis processing pipelines, example code, notebook visualization tools, and documents, &lt;a href="https://itk.org" rel="noopener noreferrer"&gt;ITK&lt;/a&gt; leverages nbmake to ensure high-quality, easy-to-maintain documentation without common import errors or unexpected errors.&lt;/p&gt;

&lt;p&gt;In ITK extensions such as &lt;a href="https://github.com/KitwareMedical/ITKIOScanco" rel="noopener noreferrer"&gt;ITKIOScanco&lt;/a&gt; (a module to work with 3D microtomography volumes) or &lt;a href="https://github.com/InsightSoftwareConsortium/ITKElastix" rel="noopener noreferrer"&gt;ITKElastix&lt;/a&gt; (a toolbox for rigid and nonrigid registration of images), nbmake runs notebooks in &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; CI tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lzdivb9yf9jev2olua9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lzdivb9yf9jev2olua9.png" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ITKElastix GitHub Actions notebook test output, displaying standard pytest status information.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ne08d142gl25pp5ts4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ne08d142gl25pp5ts4d.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;CI testing catching an error and displaying traceback information via pytest&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itkwidgets.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;itkwidgets&lt;/a&gt;, a next-generation, simple 3D visualization tool for Python notebooks, uses nbmake to check its functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts2lop69rlhaup0ti6wf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts2lop69rlhaup0ti6wf.png" width="800" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;An &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets/blob/main/examples/integrations/itk/3DImage.ipynb" rel="noopener noreferrer"&gt;itkwidgets visualization notebook&lt;/a&gt; tested with nbmake.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In ITK's &lt;a href="https://examples.itk.org/" rel="noopener noreferrer"&gt;Sphinx examples&lt;/a&gt;, notebooks are embedded into HTML documentation and continuously tested.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscrpp9vzcgjx54pf3yue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscrpp9vzcgjx54pf3yue.png" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;An &lt;a href="https://examples.itk.org/src/registration/common/mutualinformation/mutualinformation" rel="noopener noreferrer"&gt;explanation of optimization&lt;/a&gt; during image registration. The notebook is rendered in Sphinx and tested with nbmake.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;While notebooks have been around for some time, we are still learning how to integrate them into rigorous engineering processes. The nbmake project is continuing to develop ways to remove friction associated with maintaining quality notebooks in many organizations.&lt;/p&gt;

&lt;p&gt;Over the next year, there will be updates to both the missing imports checker (to keep virtual environments up to date) and the mocking system (to skip slow and complex cells during testing).&lt;/p&gt;

&lt;p&gt;Nbmake is maintained by &lt;a href="https://treebeard.io" rel="noopener noreferrer"&gt;treebeard.io&lt;/a&gt;, a machine learning infrastructure company based in&lt;br&gt;
the UK. ITK is a &lt;a href="https://numfocus.org" rel="noopener noreferrer"&gt;NumFOCUS&lt;/a&gt; project with commercial support offered by &lt;a href="https://www.kitware.com" rel="noopener noreferrer"&gt;Kitware&lt;/a&gt;, an open source scientific computing company headquartered in the USA.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>code</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
