TMA-Grid

One glass slide can hold tissue from hundreds of patients. TMA-Grid finds every core, rebuilds the grid, and labels each one, in your browser.

Client
National Cancer Institute, Division of Cancer Epidemiology and Genetics (Episphere)
Years
Built 2021 to 2024 (NCI fellowship); published 2026
Role
First author. Conceived the design, implemented most of the application, built the segmentation and de-arraying workflow
Part of
A set of browser-local research tools with FastImpute and mSigSDK

An open-source web app that de-arrays tissue microarrays in the browser: it finds every core, rebuilds the grid, and exports the map, with no install and no upload.

Try it: de-array this slide

This is the real TMA-Grid app running on this page, not a mock-up and not a recording. It opens with the app's own built-in demo slide: an H&E Hamamatsu tissue microarray, served from the app's public bucket. That is the demo slide's provenance, stated plainly. No slide from the paper's study set is shown here.

Loading the real app and its demo slide. The first load fetches the segmentation model and the slide itself, so it can take a minute on a slow connection.

Open the full app at episphere.github.io/tma-grid

  1. The slide is already there. The app below loads its demo slide on its own and moves to the Segment stage. What you see is a real stained array, visibly imperfect: cores sit at varying positions and some are damaged. The full-resolution OpenSeadragon viewer, where you drag to pan and scroll or pinch to zoom into real cellular detail, is the Grid stage in step 3.
  2. Find the cores. In the Segment stage, press Apply. If you cannot see Apply or the presets, open the collapsed menu at the top of the Segment stage first: the menu hides Apply and the presets until you open it. The presets (default, dense, sparse, damaged, noisy) and the sensitivity slider are live. Before you press Apply, the diagnostics line under the image reads “Detected: --”. In plain words, that means not run yet. After Apply, read the diagnostics line under the image: Detected / Rescued / Removed artifacts / Recentered, now showing real counts. The tool found the cores itself, including the ones a person would argue about. Click the image to add a core, shift-click a core to remove one.
  3. Fix one core. Press Proceed to the Grid stage, then press Apply in the Grid stage to build the grid from the cores you just found. Nothing is gridded until that Apply runs. The Review Queue flags problem cores: click an issue in the queue and the viewer flies to that core, then correct it with the app's editing grammar. Drag a core to move it, drag its corner anchors to resize it, double-click it to edit its metadata, shift-click it to toggle it between real and imaginary. The grid rebuilds on the edit. This correction step is what desktop tools made painful, and what this tool exists to make easy.
  4. See the virtual grid. Press Proceed to the Export stage. The virtual grid is the same slide as data: an idealized grid where each cell is addressed by its row and column. This portfolio writes positions in the letter-and-number style, like C7; the app prints the row and column numbers on the grid itself, and the real slide's grid is larger than the A1 to F10 example size. Click a cell to edit its metadata, with Add Field and Update Metadata.
  5. Download the map. Export the de-arraying table as CSV or JSON from the virtual grid. That table is the artifact the whole tool exists to produce: the map that links every core position to its patient metadata. You just de-arrayed a real slide. Evidence from the paper, beside the payoff: segmentation AUC 0.966, about half a second to segment, grid accuracy 1.00 on 9 of 10 head-to-head slides against QuPath.
  6. Want your own slide? The full app takes your own .svs, .tif/.tiff, and .ndpi images, read in place with nothing uploaded to a server: episphere.github.io/tma-grid.

Provenance: TMA-Grid is open source under the MIT license. The app above is a self-hosted copy of github.com/episphere/tma-grid at commit f7ed551645f52f51dbe0c11e9e97d3c88ed90035, carried in this site at /projects/tma-grid/app/, unmodified. Its demo slide is the app's own built-in demo image, the H&E Hamamatsu TMA from its public bucket, viewed in the app's own OpenSeadragon viewer.

A tissue microarray puts tissue from hundreds of patients on a single slide, which is only useful if you can say which core belongs to which patient. I built TMA-Grid at the National Cancer Institute to do that matching step in a web browser: it detects the cores with a neural network, rebuilds the row and column grid even when cores are missing or out of place, flags the spots a human should check, and exports the result as a table. It was published in BMC Bioinformatics in 2026, and it is free for anyone to use.

Evidence

Paper: Ge A et al., “TMA-Grid: An open-source, zero-footprint web application for FAIR Tissue MicroArray De-arraying,” BMC Bioinformatics 2026, DOI 10.1186/s12859-026-06638-2. Coverage listed on my resume: Scienmag and Bioengineer.org. Live app: episphere.github.io/tma-grid. Code (MIT): github.com/episphere/tma-grid. Video tutorial: youtu.be/miajqyw4BVk.

Headline numbers from the paper: segmentation AUC 0.966 across 10-fold cross-validation on 121 TMA whole slide images; segmentation runs in about half a second and grid construction in about 0.2 seconds on ordinary laptops; grid accuracy 1.00 on 9 of 10 head-to-head slides against QuPath, and 0.94 on the hardest slide.

The setup

A tissue microarray (TMA) packs many small round tissue samples, called cores, from many patients onto one glass slide, so one scan holds a whole study. De-arraying is the step that finds each core in the scanned slide image, assigns it its row and column, and links it to the patient and study data for that position. Without it, the scan is a picture with no map.

The problem

Real slides are messy. Cores end up misaligned, damaged, missing, overlapping, or rotated during assembly, sectioning, and scanning, and conventional de-arraying tools are desktop programs with limited room to correct those errors by hand. A wrong assignment is not a cosmetic error; it attaches one patient's tissue to another patient's data.

What I built

TMA-Grid runs entirely in the browser. No install, no server, and the source image never has to be uploaded anywhere; it can sit on the user's disk or in remote or cloud storage and is read in place. It treats the user as a reviewer rather than a bystander.

Finding cores

A U-Net style convolutional neural network (TensorFlow.js, separable convolutions to keep it small) segments tissue from background. Image processing steps (OpenCV.js) turn the mask into core detections, split merged cores, rescue missed ones, and remove artifacts and debris. The user can move a sensitivity slider, pick presets (default, dense, sparse, damaged, noisy), and add or remove detections by clicking.

Building the grid

Detected cores are assigned row and column positions using Delaunay triangulation plus a traveling row-building algorithm, with rotation correction, imaginary cores inserted for missing positions, marker cores kept out of the main grid, and a review queue that flags problem cores (missing, misaligned, damaged, marker) and flies the viewer to each one. Any edit rebuilds the grid at once. The app then shows an idealized virtual grid of the de-arrayed cores, supports per-core metadata editing, and exports the de-arraying table as JSON or CSV.

Discharge summary

Published, open source, and running as a public web app with a video tutorial. In a head-to-head on 10 lymphoma TMA slides, TMA-Grid matched or beat QuPath on grid and core accuracy, without needing the user to type in core diameter or grid dimensions first.

What I would do differently

Spend less effort on fully automatic correction and more on the review queue earlier, since the human check turned out to be the feature users trusted; and plan the public sample datasets from the start, because governance on the main study images limits what can be shown.