A DICOM viewer that never uploads a scan
A browser platform that puts radiotherapy scans from a 73-patient pancreatic-cancer cohort in the same view as tumor variant data from 26 sequenced samples.
- 73
- patients in the pancreatic-cancer cohort
- 12,877
- DICOM files cross-checked against a second reader
- 1,283 × 26
- variant matrix synced to the imaging planes
- Zero
- bytes of patient imaging uploaded anywhere

At a glance
- Role
- Undergraduate Research Developer
- Organization
- Holland Computing Center, University of Nebraska–Lincoln
- Dates
- July 2023 – present
- Status
- In active research use
- Stack
- JavaScript · React 18 · JBrowse 2 · Python · pydicom
- Hard skills
- JavaScript · Python · DICOM parsing from scratch · React 18 · JBrowse 2 · Cross-checking with pydicom
- Soft skills
- Designing around a privacy rule · Checking against a second reader
- Why it matters
- Researchers can compare imaging and tumor variant data in one place without patient scans leaving their computer.
Problem
Radiotherapy planning produces imaging. Tumor sequencing produces variant calls. For a 73-patient pancreatic-cancer cohort, the interesting questions sit between the two, but each is read in its own tool. Putting them side by side usually means moving patient scans onto someone else’s server first.
One rule came first: patient imaging does not leave the machine it is opened on. That settled the architecture. Parsing, volume assembly, reslicing and rendering all had to happen in the browser, with no upload step and no server-side compute.
What I built
I wrote a DICOM parser from scratch in JavaScript. With no imaging library, it decodes the format’s byte layout and tags. It reads a patient’s file set, assembles the slices into a volume and renders the three standard planes from it: axial, coronal and sagittal.
The genomics half sits on top. I used React 18 and JBrowse 2 to keep a matrix of 1,283 variants across 26 sequenced samples in sync with the imaging planes. For a patient with sequencing data, moving through the scan moves through their variants at the same time, and the JBrowse 2 genome view follows whichever mutation is selected.
How I checked it
I didn’t want to trust my parser just because I wrote it. So every one of the cohort’s 12,877 files was read twice: once by the browser parser and once by a Python reader built on pydicom, the standard Python DICOM library. Then I compared the two outputs field by field.
The comparison also surfaced metadata inconsistencies across the cohort that had been quietly blocking automated tumor-volume selection.
What happened
Once those inconsistencies were visible they could be fixed, and automated tumor-volume selection worked after that.
The viewer is in active research use at the Holland Computing Center, and I’m still developing it.