Spaces:
Running
Running
Download index.html from SharpMeow/segment-lens: direct link, hf CLI and curl.
- Browser
- Download file 19.9 kB
-
https://huggingface.co/spaces/SharpMeow/segment-lens/resolve/main/index.html
- Command line
-
hf download hf://spaces/SharpMeow/segment-lens/index.html
-
curl -L -o index.html https://huggingface.co/spaces/SharpMeow/segment-lens/resolve/main/index.html
19.9 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> | |
| <title>Segment Lens · every published Herculaneum segment, measured</title> | |
| <meta name="description" content="Traced segments from the Vesuvius Challenge open data as 3D surfaces, with holes, folds and over-stretched grid edges painted on, beside the Segment Atlas numbers."> | |
| <meta name="theme-color" content="#05080b"> | |
| <meta name="color-scheme" content="dark"> | |
| <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%2305080b'/%3E%3Cpath d='M5 22c5-9 9 3 14-6s6-6 8-4' fill='none' stroke='%23d8e4ea' stroke-width='2'/%3E%3Ccircle cx='12' cy='17' r='2.4' fill='%23ff5c5c'/%3E%3Ccircle cx='22' cy='13' r='2.4' fill='%23ffa733'/%3E%3C/svg%3E"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="style.css?v=2"> | |
| <!-- space-onescroll:start --> | |
| <!-- one page scroll bar: written by python -m kit spaceconnect render; do not edit --> | |
| <style>iframe[srcdoc]{display:block;max-height:none}</style> | |
| <script> | |
| (function () { | |
| if (window.__oneScroll) return; | |
| window.__oneScroll = true; | |
| var CSS = 'html,body{height:auto!important;min-height:0!important}html{overflow:hidden!important}'; | |
| function size(f) { | |
| var d, st = f.__os; | |
| try { d = f.contentDocument; } catch (e) { return; } | |
| if (!d || !d.body || st.off) return; | |
| var de = d.documentElement, r = Math.ceil(de.getBoundingClientRect().height), over = de.scrollHeight; | |
| var ch = f.clientHeight, t = r; | |
| if (over > ch + 1) t = Math.max(r, over); | |
| else if (r >= st.r) t = Math.max(r, ch); | |
| st.r = r; | |
| if (Math.abs(t - ch) < 2) return; | |
| var now = Date.now(); | |
| st.n = now - st.t0 < 4000 ? st.n + 1 : 1; | |
| if (st.n === 1) st.t0 = now; | |
| if (st.n > 40) { st.off = true; f.removeAttribute('scrolling'); var g = d.getElementById('space-onescroll'); if (g) g.remove(); return; } | |
| f.style.setProperty('height', t + 'px', 'important'); | |
| } | |
| function attach(f) { | |
| var d, st = f.__os; | |
| try { d = f.contentDocument; } catch (e) { return; } | |
| if (!d || !d.documentElement || st.doc === d) return; | |
| st.doc = d; st.r = Infinity; st.n = 0; st.off = false; | |
| if (!d.getElementById('space-onescroll')) { | |
| var s = d.createElement('style'); s.id = 'space-onescroll'; s.textContent = CSS; | |
| (d.head || d.documentElement).appendChild(s); | |
| } | |
| f.setAttribute('scrolling', 'no'); | |
| f.style.setProperty('min-height', '0', 'important'); | |
| f.style.setProperty('max-height', 'none', 'important'); | |
| var w = d.defaultView, go = function () { size(f); }; | |
| if (w && w.ResizeObserver) { var ro = new w.ResizeObserver(go); ro.observe(d.documentElement); if (d.body) ro.observe(d.body); } | |
| d.addEventListener('load', go, true); | |
| go(); | |
| } | |
| function bind(f) { | |
| if (f.__os || f.getAttribute('data-scroll') === 'inner') return; | |
| try { if (!f.contentDocument) return; } catch (e) { return; } | |
| f.__os = {t0: 0, n: 0, r: 0}; | |
| f.addEventListener('load', function () { attach(f); }); | |
| if (f.contentDocument.readyState !== 'loading') attach(f); | |
| else f.contentDocument.addEventListener('DOMContentLoaded', function () { attach(f); }); | |
| } | |
| function scan() { var fs = document.getElementsByTagName('iframe'); for (var i = 0; i < fs.length; i++) bind(fs[i]); } | |
| function start() { | |
| scan(); | |
| new MutationObserver(scan).observe(document.documentElement, {childList: true, subtree: true}); | |
| window.addEventListener('resize', function () { | |
| var fs = document.getElementsByTagName('iframe'); | |
| for (var i = 0; i < fs.length; i++) if (fs[i].__os) size(fs[i]); | |
| }); | |
| } | |
| if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start(); | |
| })(); | |
| </script> | |
| <!-- space-onescroll:end --> | |
| <script type="importmap"> | |
| { "imports": { | |
| "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js", | |
| "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/" | |
| } } | |
| </script> | |
| </head> | |
| <body> | |
| <canvas id="gl" aria-label="3D view of the selected segment"></canvas> | |
| <header class="hud tl"> | |
| <div class="kicker mono dim"><span class="k-src">VESUVIUS CHALLENGE<span class="sep">/</span>OPEN DATA<span class="sep">/</span></span><span id="k-count">…</span> MESHES</div> | |
| <h1>Segment <em>Lens</em></h1> | |
| <p class="lede">Traced segments as surfaces, with the grid's problems painted on: <span class="c-hole">holes</span>, <span class="c-fold">folds</span> and <span class="c-str">over-stretched</span> edges. Numbers from the <a href="https://huggingface.co/datasets/SharpMeow/vesuvius-segment-atlas" target="_blank" rel="noopener">Segment Atlas</a>.</p> | |
| </header> | |
| <nav class="hud tr" aria-label="View"> | |
| <div class="seg" role="tablist"> | |
| <button class="chip on" data-mode="lens" role="tab">3D</button> | |
| <button class="chip" data-mode="table" role="tab">Table</button> | |
| </div> | |
| <button class="tbtn" id="b-about">Guide</button> | |
| </nav> | |
| <aside class="hud bl panel" id="picker" aria-label="Pick a segment"> | |
| <label class="mono small dim" for="sel-scroll">SCROLL</label> | |
| <select id="sel-scroll"></select> | |
| <label class="row mono small"><input type="checkbox" id="only-top" checked> top-level meshes only</label> | |
| <input id="filter" class="mono small" type="search" placeholder="filter segments" aria-label="Filter segments"> | |
| <ol id="list" class="list mono small"></ol> | |
| </aside> | |
| <aside class="hud br panel" id="card" aria-live="polite"> | |
| <div class="mono small dim" id="c-kicker">SELECT A SEGMENT</div> | |
| <h2 id="c-title">…</h2> | |
| <details id="c-more" class="more" open> | |
| <summary class="mono dim">NUMBERS</summary> | |
| <dl id="c-nums" class="nums mono small"></dl> | |
| </details> | |
| <div class="legend mono small"> | |
| <label><input type="checkbox" id="t-hole" checked> <span class="sw hole"></span>holes</label> | |
| <label><input type="checkbox" id="t-fold" checked> <span class="sw fold"></span>folds</label> | |
| <label><input type="checkbox" id="t-str" checked> <span class="sw str"></span>stretched</label> | |
| <label><input type="checkbox" id="t-wire"> grid</label> | |
| </div> | |
| <div class="actions mono small"> | |
| <button id="b-copy" class="lk">copy kit command</button> | |
| <a id="a-bucket" class="lk" target="_blank" rel="noopener">mesh folder</a> | |
| </div> | |
| <p class="mono tiny dim" id="c-note"></p> | |
| </aside> | |
| <section id="table-view" class="sheet" hidden> | |
| <div class="sheet-head"> | |
| <h2>Every mesh in the atlas</h2> | |
| <p class="mono small dim" id="t-meta"></p> | |
| <input id="t-filter" class="mono small" type="search" placeholder="filter by scroll or segment" aria-label="Filter the table"> | |
| </div> | |
| <div class="tablewrap"> | |
| <table class="mono small" id="tbl"> | |
| <thead><tr> | |
| <th data-k="scroll">scroll</th><th data-k="segment">segment</th><th data-k="voxel_um" class="n">voxel µm</th> | |
| <th data-k="area_cm2" class="n">area cm²</th><th data-k="filled_share" class="n">filled</th> | |
| <th data-k="within_10pct" class="n">edges ±10%</th><th data-k="holes_mm2" class="n">holes mm²</th> | |
| <th data-k="folds_mm2" class="n">folds mm²</th><th data-k="stretched_mm2" class="n">stretched mm²</th> | |
| <th data-k="lens">3D</th> | |
| </tr></thead> | |
| <tbody></tbody> | |
| </table> | |
| </div> | |
| </section> | |
| <dialog id="about" class="sheet-dialog"> | |
| <form method="dialog"><button class="x" aria-label="Close">×</button></form> | |
| <h2>Guide</h2> | |
| <p>A <b>segment</b> is a piece of the rolled papyrus surface that someone (or a program) traced through the X-ray CT of a scroll. It is stored as a <b>tifxyz</b> mesh: three images, x.tif, y.tif and z.tif, that together hold a grid of 3D points in the scan's voxels. The open data maps each segment onto several scan volumes, so one segment can have several meshes.</p> | |
| <p>The colors mark what <code>kit tifxyz check</code> flags on the full grid:</p> | |
| <ul> | |
| <li><span class="c-hole">Holes</span>: missing grid nodes inside the sheet (not joined to its border). The preview draws the rim around them.</li> | |
| <li><span class="c-fold">Folds</span>: neighboring cells whose surface normals turn by more than 90 degrees, where the surface doubles back.</li> | |
| <li><span class="c-str">Stretched</span>: grid edges more than 1.5 times longer or shorter than the spacing the mesh's meta.json promises.</li> | |
| </ul> | |
| <p>"Edges ±10%" is the share of grid edges within 10 percent of that spacing: how close the grid is to isometric, which matters for flattened renders. A clean mesh can still jump from one wrap of papyrus to the next; nothing here looks at the CT or judges ink, and none of it is an official villa or prize check.</p> | |
| <p>3D previews are shown only for scans on none of the prize lists (Grand Prize, First Letters, and the title prize's PHerc. Paris 4, from kit's dated snapshot); scrolls on a list appear in the table with numbers only. Previews keep every k-th node, at most 256 per side, with each flag pooled over the block it stands for.</p> | |
| <!-- space-connect:start --> | |
| <section class="scc" id="connect" aria-label="Connect your tool"><style>.scc{--a:var(--scc-accent,#4ea8de);color:inherit;font:inherit;line-height:1.5;max-width:60rem} | |
| .scc h2{font-size:1.15em;margin:.2em 0 .3em}.scc h3{font-size:1em;margin:0 0 .2em} | |
| .scc p{margin:.3em 0}.scc a{color:var(--a)} | |
| .scc .scc-src{border:1px solid color-mix(in srgb,currentColor 18%,transparent);border-radius:10px;padding:.7em .9em;margin:.7em 0;background:color-mix(in srgb,currentColor 4%,transparent)} | |
| .scc .scc-meta{font-size:.85em;opacity:.8} | |
| .scc details{border-top:1px solid color-mix(in srgb,currentColor 12%,transparent);padding:.35em 0} | |
| .scc summary{cursor:pointer;font-weight:600;list-style-position:inside} | |
| .scc .scc-b{font-weight:400;font-size:.75em;padding:.05em .5em;border-radius:99px;margin-left:.5em;border:1px solid currentColor;opacity:.75;white-space:nowrap} | |
| .scc .scc-b.ok{color:#3fb37f}.scc .scc-b.src{color:var(--a)}.scc .scc-b.warn{color:#e0a030} | |
| .scc .scc-code{position:relative;margin:.4em 0 .2em} | |
| .scc pre{margin:0;padding:.7em .8em;border-radius:8px;overflow:auto;font-size:.82em;background:color-mix(in srgb,currentColor 9%,transparent);white-space:pre} | |
| .scc code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace} | |
| .scc button.scc-copy{all:unset;box-sizing:border-box;position:absolute;top:.35em;right:.35em;font-size:.75em;line-height:1.4;padding:.1em .6em;border-radius:6px;border:1px solid color-mix(in srgb,currentColor 30%,transparent);background:color-mix(in srgb,currentColor 8%,transparent);color:inherit;cursor:pointer} | |
| .scc button.scc-copy:hover{border-color:var(--a)} | |
| .scc .scc-url{position:relative}.scc .scc-url pre{padding-right:4.5em;white-space:pre-wrap;word-break:break-all} | |
| .scc .scc-go{display:inline-block;margin:.3em 0;padding:.25em .8em;border-radius:6px;border:1px solid var(--a);text-decoration:none} | |
| .scc footer{font-size:.8em;opacity:.75;margin-top:.6em}</style> | |
| <h2>Connect your tool</h2> | |
| <p>Every number and preview on this page comes from the Segment Atlas dataset, and every mesh it measures is a tifxyz folder on the open-data bucket. Both read straight from these URLs, with no account.</p> | |
| <div class="scc-src" id="connect-atlas"><h3>Segment Atlas (one row per published mesh)</h3> | |
| <p class="scc-meta">CC BY-NC 4.0 (derived from Vesuvius Challenge open data) · Each row has the mesh's open-data url, its grid size, area, filled share, edge statistics and the holes, folds and stretched area that kit tifxyz check reports. lens/ holds the decimated 3D previews.</p> | |
| <div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://huggingface.co/datasets/SharpMeow/vesuvius-segment-atlas</code></pre></div> | |
| <details><summary>Python (huggingface_hub)<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install huggingface_hub | |
| from huggingface_hub import hf_hub_download, snapshot_download | |
| path = hf_hub_download("SharpMeow/vesuvius-segment-atlas", "atlas.jsonl", repo_type="dataset") # one file, cached | |
| folder = snapshot_download("SharpMeow/vesuvius-segment-atlas", repo_type="dataset")</code></pre></div></details> | |
| <details><summary>Python (datasets)<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install datasets | |
| from datasets import load_dataset | |
| default = load_dataset("SharpMeow/vesuvius-segment-atlas", "default", split="train")</code></pre></div></details> | |
| <details><summary>pandas<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install pandas huggingface_hub | |
| import pandas as pd | |
| df = pd.read_json("hf://datasets/SharpMeow/vesuvius-segment-atlas/atlas.jsonl", lines=True)</code></pre></div></details> | |
| <details><summary>Command line (hf)<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>pip install -U huggingface_hub | |
| hf download SharpMeow/vesuvius-segment-atlas atlas.jsonl --repo-type dataset --local-dir vesuvius-segment-atlas</code></pre></div></details> | |
| <details><summary>curl<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>curl -L -O https://huggingface.co/datasets/SharpMeow/vesuvius-segment-atlas/resolve/main/atlas.jsonl</code></pre></div></details> | |
| </div> | |
| <div class="scc-src" id="connect-mesh"><h3>A measured mesh (tifxyz), example PHerc0009B 20250510172639</h3> | |
| <p class="scc-meta">CC BY-NC 4.0 (Vesuvius Challenge open data) · Every row of the atlas names its mesh folder in url; the table's mesh folder link opens it. Read live from the open-data bucket, never copied here.</p> | |
| <div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0009B/segments/20250510172639/mesh/20250510172639-on-20250521125136-8.64um.tifxyz</code></pre></div> | |
| <details><summary>Python (numpy, tifffile)<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code># pip install numpy tifffile | |
| import io, json, urllib.request | |
| import numpy as np, tifffile | |
| T = "https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0009B/segments/20250510172639/mesh/20250510172639-on-20250521125136-8.64um.tifxyz" | |
| meta = json.load(urllib.request.urlopen(T + "/meta.json")) # scale, bbox, format | |
| get = lambda c: tifffile.imread(io.BytesIO(urllib.request.urlopen(f"{T}/{c}.tif").read())) | |
| xyz = np.stack([get(c) for c in "xyz"], -1) # xyz[i, j] = (x, y, z) in scan voxels; -1 = no surface</code></pre></div></details> | |
| </div> | |
| <div class="scc-src" id="connect-page"><h3>This page's code and data</h3> | |
| <p class="scc-meta">Page code Apache 2.0; data as above · python -m kit atlas show SCROLL and python -m kit tifxyz check MESH_URL reproduce the numbers from a clone of ChaseHendrick/Scrolls.</p> | |
| <div class="scc-url"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>https://sharpmeow-segment-lens.hf.space/</code></pre></div> | |
| <details><summary>Links and embed<span class="scc-b ok">tested 2026-10-24</span></summary> | |
| <div class="scc-code"><button type="button" class="scc-copy" data-testid="connect-copy" onclick="navigator.clipboard&&navigator.clipboard.writeText(this.parentNode.querySelector('code').innerText).then(()=>{this.textContent='Copied';setTimeout(()=>this.textContent='Copy',1200)})">Copy</button><pre><code>The whole atlas as one CSV: https://huggingface.co/datasets/SharpMeow/vesuvius-segment-atlas/resolve/main/atlas.csv | |
| API and MCP for agents (list_scrolls, list_segments, get_segment, segment_picture): https://sharpmeow-segment-lens.hf.space/agents/ | |
| Page source: https://github.com/ChaseHendrick/Scrolls/tree/main/spaces/segment-lens</code></pre></div></details> | |
| </div> | |
| <footer>Machine-readable: <a href="https://huggingface.co/spaces/SharpMeow/segment-lens/blob/main/connect.json" target="_blank" rel="noopener">connect.json</a> and <a href="https://huggingface.co/spaces/SharpMeow/segment-lens/blob/main/CONNECT.md" target="_blank" rel="noopener">CONNECT.md</a>. Checked 2026-10-24. "Tested" means the snippet ran against this public data on that date. Scan data keeps its own license (the Vesuvius Challenge open data is CC BY-NC 4.0).</footer></section> | |
| <!-- space-connect:end --> | |
| <h3>On your own machine</h3> | |
| <pre class="mono small">git clone https://github.com/ChaseHendrick/Scrolls && cd Scrolls | |
| python -m pip install numpy tifffile imagecodecs | |
| python -m kit atlas show PHerc0139 --top 10 | |
| python -m kit tifxyz check MESH_URL --png check.png</pre> | |
| <h3>Credits</h3> | |
| <ul class="small"> | |
| <li>Meshes: Vesuvius Challenge open data, CC BY-NC 4.0. The atlas numbers and previews carry the same license.</li> | |
| <li>This page: Apache 2.0, by Chase Hendrick (<a href="https://github.com/ChaseHendrick/Scrolls/tree/main/spaces/segment-lens" target="_blank" rel="noopener">source</a>). three.js is MIT.</li> | |
| </ul> | |
| </dialog> | |
| <div id="toast" class="toast mono small" role="status" hidden></div> | |
| <script type="module" src="app.js?v=2"></script> | |
| </body> | |
| </html> | |