<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Home on betolink</title><link>https://betolink.github.io/blog/</link><description>Recent content in Home on betolink</description><generator>Hugo</generator><language>en</language><lastBuildDate>Thu, 12 Nov 2026 11:00:00 -0600</lastBuildDate><atom:link href="https://betolink.github.io/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>dmrpp as a chunk reference format</title><link>https://betolink.github.io/blog/posts/dmrpp-is-a-proxy/</link><pubDate>Thu, 12 Nov 2026 11:00:00 -0600</pubDate><guid>https://betolink.github.io/blog/posts/dmrpp-is-a-proxy/</guid><description>&lt;p&gt;I keep coming back to DMR++. It is a good old idea: instead of making every&#10;client parse an HDF5 granule from scratch, publish the map ahead of time. A&#10;sidecar gives you dimensions, variables, chunk positions, offsets, and byte&#10;lengths. The client follows the references and only fetches what it needs.&lt;/p&gt;&#10;&lt;p&gt;That is a proxy. It is not a copy, and it is not a proof.&lt;/p&gt;&#10;&lt;p&gt;The &lt;a href="https://betolink.github.io/blog/notebooks/dmrpp-to-zarr/"&gt;reference notebook&lt;/a&gt; parses a&#10;small DMR++ document, turns the offsets into a VirtualiZarr chunk manifest, and&#10;puts the result next to an Icechunk-style manifest.&lt;/p&gt;</description></item><item><title>A reproducible technical blog with Hugo, Quarto, and Pixi</title><link>https://betolink.github.io/blog/posts/reproducible-technical-blog/</link><pubDate>Thu, 12 Nov 2026 09:00:00 -0600</pubDate><guid>https://betolink.github.io/blog/posts/reproducible-technical-blog/</guid><description>&lt;p&gt;This site is deliberately boring infrastructure: static files generated in CI,&#10;deployed to GitHub Pages, with no application server and no database.&lt;/p&gt;&#10;&lt;h2 id="the-pieces"&gt;The pieces&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Layer&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Tool&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Responsibility&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Site generator&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hugo&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pages, taxonomies, RSS, HTML&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Theme&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;rewired&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Layouts and retro terminal visual identity&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Notebooks&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Quarto&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Execute and convert &lt;code&gt;.qmd&lt;/code&gt;/&lt;code&gt;.ipynb&lt;/code&gt; to Markdown&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Environment&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pixi&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pinned Python and tooling&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Search&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pagefind&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static, client-side index&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Comments&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Giscus&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Discussions&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="render-pipeline"&gt;Render pipeline&lt;/h2&gt;&#10;&lt;p&gt;Quarto writes Hugo-compatible Markdown into &lt;code&gt;content/notebooks/&lt;/code&gt;, Hugo builds the&#10;site into &lt;code&gt;public/&lt;/code&gt;, and Pagefind indexes the generated HTML.&lt;/p&gt;</description></item><item><title>Apache Nutch crawler</title><link>https://betolink.github.io/blog/projects/nutch-crawler/</link><pubDate>Thu, 12 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/nutch-crawler/</guid><description>&lt;p&gt;A fork of Apache Nutch tuned for web services and data discovery.&lt;/p&gt;</description></item><item><title>DMR++ as a virtual chunk manifest</title><link>https://betolink.github.io/blog/notebooks/dmrpp-to-zarr/</link><pubDate>Thu, 12 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/notebooks/dmrpp-to-zarr/</guid><description>&lt;p&gt;DMR++ is a metadata sidecar used by OPeNDAP/Hyrax. For an HDF5 granule, it&#10;describes the dataset structure and, importantly, the byte ranges of each chunk&#10;inside the original file. A client can therefore build a virtual view of the&#10;dataset without parsing the granule from scratch.&lt;/p&gt;&#10;&lt;p&gt;This notebook makes the mapping explicit with a small synthetic DMR++ document.&#10;It then builds a VirtualiZarr &lt;code&gt;ChunkManifest&lt;/code&gt; from the same references and&#10;compares the result with the shape of an Icechunk-style manifest.&lt;/p&gt;</description></item><item><title>pyLDAvis</title><link>https://betolink.github.io/blog/projects/pyldavis/</link><pubDate>Wed, 11 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/pyldavis/</guid><description>&lt;p&gt;A Python port of the R LDAvis package for interactive topic model visualization.&lt;/p&gt;</description></item><item><title>A small numerical check: orbital period from Kepler's third law</title><link>https://betolink.github.io/blog/posts/kepler-third-law/</link><pubDate>Tue, 10 Nov 2026 14:30:00 -0600</pubDate><guid>https://betolink.github.io/blog/posts/kepler-third-law/</guid><description>&lt;p&gt;Kepler&amp;rsquo;s third law relates the orbital period \(T\) to the semi-major axis \(a\)&#10;for a body orbiting a mass \(M\):&lt;/p&gt;&#10;$$&#10;T = 2\pi \sqrt{\frac{a^3}{GM}}.&#10;$$&lt;p&gt;For Earth around the Sun, using \(a = 1.496 \times 10^{11}\,\mathrm{m}\) and&#10;\(GM = 1.327 \times 10^{20}\,\mathrm{m^3\,s^{-2}}\), we expect roughly one year.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; math&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GM &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;1.32712440018e20&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;1.495978707e11&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;period_seconds &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;2&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;*&lt;/span&gt; math&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;pi &lt;span style="color:#ff79c6"&gt;*&lt;/span&gt; math&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;sqrt(a&lt;span style="color:#ff79c6"&gt;**&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;3&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;/&lt;/span&gt; GM)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(period_seconds &lt;span style="color:#ff79c6"&gt;/&lt;/span&gt; (&lt;span style="color:#bd93f9"&gt;365.25&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;*&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;24&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;*&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;3600&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.0000&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="reference-values"&gt;Reference values&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Body&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: right"&gt;Semi-major axis (AU)&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: right"&gt;Period (years)&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Mercury&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;0.387&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;0.241&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Earth&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;1.000&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;1.000&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Mars&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;1.524&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;1.881&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Jupiter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;5.203&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: right"&gt;11.862&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;The point is not the arithmetic. The point is that a notebook can carry the&#10;claim, the code, and the output together.&lt;/p&gt;</description></item><item><title>filesystem_spec</title><link>https://betolink.github.io/blog/projects/filesystem-spec/</link><pubDate>Tue, 10 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/filesystem-spec/</guid><description>&lt;p&gt;The shared specification behind Python&amp;rsquo;s fsspec filesystem implementations.&lt;/p&gt;</description></item><item><title>ipyleaflet</title><link>https://betolink.github.io/blog/projects/ipyleaflet/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/ipyleaflet/</guid><description>&lt;p&gt;Interactive Leaflet maps inside Jupyter notebooks and JupyterLab.&lt;/p&gt;</description></item><item><title>xarray in a Jupyter notebook</title><link>https://betolink.github.io/blog/notebooks/xarray-ipynb-demo/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/notebooks/xarray-ipynb-demo/</guid><description>&lt;h2 id="a-tiny-labeled-array"&gt;A tiny labeled array&lt;/h2&gt;&#10;&lt;p&gt;This page starts life as a standard &lt;code&gt;.ipynb&lt;/code&gt; file. Quarto executes it and writes&#10;Hugo-compatible Markdown, so the output stays readable without a Jupyter server.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; numpy &lt;span style="color:#ff79c6"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; xarray &lt;span style="color:#ff79c6"&gt;as&lt;/span&gt; xr&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;da &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; xr&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;DataArray(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;arange(&lt;span style="color:#bd93f9"&gt;6&lt;/span&gt;)&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;reshape(&lt;span style="color:#bd93f9"&gt;2&lt;/span&gt;, &lt;span style="color:#bd93f9"&gt;3&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dims&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;, &lt;span style="color:#f1fa8c"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; coords&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#f1fa8c"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;: [&lt;span style="color:#bd93f9"&gt;10&lt;/span&gt;, &lt;span style="color:#bd93f9"&gt;20&lt;/span&gt;], &lt;span style="color:#f1fa8c"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;: [&lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;, &lt;span style="color:#bd93f9"&gt;2&lt;/span&gt;, &lt;span style="color:#bd93f9"&gt;3&lt;/span&gt;]},&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(da)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;xarray.DataArray 'value' (y: 2, x: 3)&amp;gt; Size: 48B&#10;array([[0, 1, 2],&#10; [3, 4, 5]])&#10;Coordinates:&#10; * y (y) int64 16B 10 20&#10; * x (x) int64 24B 1 2 3&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;f&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;mean = &lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;{&lt;/span&gt;da&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;mean()&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;item()&lt;span style="color:#f1fa8c"&gt;:&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;.1f&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;}&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;mean = 2.5&#10;&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>earthaccess</title><link>https://betolink.github.io/blog/projects/earthaccess/</link><pubDate>Sun, 08 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/earthaccess/</guid><description>&lt;p&gt;Authentication, search, and access for NASA Earth science data collections.&lt;/p&gt;</description></item><item><title>itslive-py</title><link>https://betolink.github.io/blog/projects/itslive-py/</link><pubDate>Sat, 07 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/itslive-py/</guid><description>&lt;p&gt;A Python client for discovering and working with ITS_LIVE glacier ice velocity data.&lt;/p&gt;</description></item><item><title>earthcatalog</title><link>https://betolink.github.io/blog/projects/earthcatalog/</link><pubDate>Fri, 06 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/earthcatalog/</guid><description>&lt;p&gt;A GeoParquet-backed STAC catalog for making Earth data collections easier to query and use.&lt;/p&gt;</description></item><item><title>Earth observation data is a software problem</title><link>https://betolink.github.io/blog/posts/earth-observation-is-software/</link><pubDate>Thu, 05 Nov 2026 09:15:00 -0600</pubDate><guid>https://betolink.github.io/blog/posts/earth-observation-is-software/</guid><description>&lt;p&gt;Earth observation archives are often described as data problems. In practice,&#10;most of the friction is software: metadata that does not agree with itself,&#10;formats that require whole-file downloads, and access patterns that assume a&#10;local filesystem.&lt;/p&gt;&#10;&lt;h2 id="what-cloud-native-changes"&gt;What cloud-native changes&lt;/h2&gt;&#10;&lt;p&gt;Chunked, self-describing arrays make partial reads practical. A workflow can&#10;open a dataset, inspect coordinates, and request one time slice without&#10;downloading the archive.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; xarray &lt;span style="color:#ff79c6"&gt;as&lt;/span&gt; xr&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ds &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; xr&lt;span style="color:#ff79c6"&gt;.&lt;/span&gt;open_zarr(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#34;https://example.com/store.zarr&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; consolidated&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;True&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chunks&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{},&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;print&lt;/span&gt;(ds)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hard part is not the API. The hard part is consistency across collections,&#10;clear provenance, and clients that fail gracefully.&lt;/p&gt;</description></item><item><title>Cloud-optimized ICESat-2</title><link>https://betolink.github.io/blog/projects/cloud-optimized-icesat2/</link><pubDate>Thu, 05 Nov 2026 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/projects/cloud-optimized-icesat2/</guid><description>&lt;p&gt;A project and paper evaluating paged aggregation, chunk sizes, and access patterns for cloud-hosted ICESat-2 HDF5 data.&lt;/p&gt;</description></item><item><title>Joshua Tree National Park</title><link>https://betolink.github.io/blog/travel/joshua-tree/</link><pubDate>Sat, 17 Oct 2026 09:00:00 -0700</pubDate><guid>https://betolink.github.io/blog/travel/joshua-tree/</guid><description>&lt;p&gt;Joshua Tree had been on my bucket list for a while. We finally went a month ago,&#10;kept the visit short, and packed in as much desert as we could.&lt;/p&gt;&#10;&lt;p&gt;I’ve always liked deserts, and seeing petroglyphs there makes me think that people have&#10;been reading this landscape and its skies for a very long time. The night skies were&#10;impressive even without a new moon. I got to use my Dwarf 3 telescope again and captured&#10;Barnard 33, the Horsehead Nebula. 🌵🌌&lt;/p&gt;</description></item><item><title>About</title><link>https://betolink.github.io/blog/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://betolink.github.io/blog/about/</guid><description>&lt;h2 id="hello"&gt;Hello&lt;/h2&gt;&#10;&lt;p&gt;I am Luis López (&lt;a href="https://github.com/betolink"&gt;@betolink&lt;/a&gt;). I work on open-source&#10;scientific software, Earth observation data systems, and reproducible computing.&lt;/p&gt;&#10;&lt;p&gt;This site is a personal technical notebook. It collects articles, executable&#10;notebooks, project notes, and experiments that are useful enough to write down.&lt;/p&gt;&#10;&lt;h2 id="what-you-will-find-here"&gt;What you will find here&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Blog posts&lt;/strong&gt; about software engineering, Python, data systems, and research software.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Amateur astronomy&lt;/strong&gt;, mostly dark skies, desert trips, and what I manage to see.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;My political views&lt;/strong&gt;, when I have something worth writing down.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Notebooks&lt;/strong&gt; rendered with Quarto, including code, plots, equations, and tables.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Projects&lt;/strong&gt; that I maintain or contribute to.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="elsewhere"&gt;Elsewhere&lt;/h2&gt;&#10;&lt;div class="social-list" aria-label="Social links"&gt;&lt;a class="social-list__link" href="https://github.com/betolink" rel="me noopener" target="_blank"&gt;&#10;&#9;&#9;&#9;&#9;&lt;span class="social-list__icon" aria-hidden="true"&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;i class="fa-brands fa-github"&gt;&lt;/i&gt;&#10;&#9;&#9;&#9;&#9;&lt;/span&gt;&#10;&#9;&#9;&#9;&#9;&lt;span&gt;GitHub&lt;/span&gt;&#10;&#9;&#9;&#9;&lt;/a&gt;&lt;a class="social-list__link" href="https://x.com/betolink" rel="me noopener" target="_blank"&gt;&#10;&#9;&#9;&#9;&#9;&lt;span class="social-list__icon" aria-hidden="true"&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;i class="fa-brands fa-x-twitter"&gt;&lt;/i&gt;&#10;&#9;&#9;&#9;&#9;&lt;/span&gt;&#10;&#9;&#9;&#9;&#9;&lt;span&gt;X&lt;/span&gt;&#10;&#9;&#9;&#9;&lt;/a&gt;&lt;a class="social-list__link" href="https://keybase.io/betolink" rel="me noopener" target="_blank"&gt;&#10;&#9;&#9;&#9;&#9;&lt;span class="social-list__icon" aria-hidden="true"&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;i class="fa-brands fa-keybase"&gt;&lt;/i&gt;&#10;&#9;&#9;&#9;&#9;&lt;/span&gt;&#10;&#9;&#9;&#9;&#9;&lt;span&gt;Keybase&lt;/span&gt;&#10;&#9;&#9;&#9;&lt;/a&gt;&lt;a class="social-list__link" href="https://www.linkedin.com/in/betolink/" rel="me noopener" target="_blank"&gt;&#10;&#9;&#9;&#9;&#9;&lt;span class="social-list__icon" aria-hidden="true"&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;i class="fa-brands fa-linkedin"&gt;&lt;/i&gt;&#10;&#9;&#9;&#9;&#9;&lt;/span&gt;&#10;&#9;&#9;&#9;&#9;&lt;span&gt;LinkedIn&lt;/span&gt;&#10;&#9;&#9;&#9;&lt;/a&gt;&lt;a class="social-list__link" href="https://betolink.github.io/blog/index.xml" rel="me noopener" target="_blank"&gt;&#10;&#9;&#9;&#9;&#9;&lt;span class="social-list__icon" aria-hidden="true"&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;i class="fa-solid fa-rss"&gt;&lt;/i&gt;&#10;&#9;&#9;&#9;&#9;&lt;/span&gt;&#10;&#9;&#9;&#9;&#9;&lt;span&gt;RSS&lt;/span&gt;&#10;&#9;&#9;&#9;&lt;/a&gt;&lt;/div&gt;</description></item></channel></rss>