FluLens is a viewer for influenza variant calls. You can inspect and filter them. The grid shows samples × codons, one cell per call. FluLens colours each cell by allele frequency, or shows it as a consensus.
FluLens reads the output of Flumina (Illumina) and FluPore (Nanopore). It helps you answer two questions more quickly than a spreadsheet: is this variant real? and is this sample good enough to keep?
▶ Try it in your browser — no installation, with example data.
There are three ways to run FluLens. They are the same application. Use the one you like.
| Use when | |
|---|---|
| 1. In a browser | Simplest. Nothing to install, works on any OS |
| 2. As a single file | You want it offline, or on a machine with no internet |
| 3. As a desktop app | macOS (Apple Silicon & Intel), remembers your last run |
Open https://flu-crew.github.io/FluLens/. Click Open run folder…. Then select a Flumina or FluPore output folder.
FluLens uploads nothing. The page reads the folder on your machine through the browser's file picker. See Your data stays on your machine.
FluLens is one HTML file. It has no dependencies and no build step.
Download flulens.html from the
latest release and open it.
open flulens.html # macOS
xdg-open flulens.html # LinuxDownload FluLens_<version>_<arch>.dmg (e.g. FluLens_1.0.0_aarch64.dmg) from the
latest release. Open it and
drag FluLens to Applications.
The desktop app is signed and notarized by Apple. It reopens your last run directory automatically across launches and provides direct native filesystem access for fast byte-range reads over BAM alignments.
You do not need a pipeline run to see FluLens. The repository ships two synthetic examples — one from each supported pipeline.
example_run/ — twelve samples, 1,378 calls, all twelve gene products.
| Get it | How |
|---|---|
| Browse it on GitHub | see the file layout a run must have |
example_run.zip |
attached to every release |
| Download the whole repository | example_run/ is inside it |
The example gives the controls something to act on. It contains a library that
fails QC, two segments that did not assemble, GATK4 genotype calls with no LoFreq
counterpart, and skewed strand balance on some of the calls. All twelve samples
include reads, so the pile-up opens on the example. example_run/README.md
explains the design.
example_run_nanopore/ — five samples, single-end ONT reads at ~60–80× depth.
| Get it | How |
|---|---|
| Browse it on GitHub | FluPore output converted for FluLens |
| Download the whole repository | example_run_nanopore/ is inside it |
This is synthetic data. Do not interpret the variant calls as real observations.
example_run_nanopore/README.md has more detail.
git clone https://github.com/flu-crew/FluLens.git
# then in FluLens: Open run folder… -> FluLens/example_run
# or FluLens/example_run_nanoporeLoad a Flumina or FluPore output folder — the one that contains variant_analysis/.
Only the first file is required; the rest are optional. The sidebar reports which files
FluLens found:
| Path | What it adds |
|---|---|
variant_analysis/all_sample_amino_acids.txt |
required — the grid itself |
reference.fa |
the translated reference row |
reference_gtf/*.gtf |
true protein lengths and CDS intervals, so all twelve products appear |
variant_analysis/curated_amino_acids.txt |
▲ ticks marking curated sites |
variant_analysis/flumut/markers.tsv |
FluMut marker screening |
variant_analysis/flumut_lowfreq/ |
markers present below consensus |
vcf_files/<sample>/lofreq-called-variants.vcf |
strand balance and read counts (Flumina) |
vcf_files/<sample>/ivar-called-variants.tsv |
strand balance and read counts (FluPore) |
IRMA_results/<sample>/tables/READ_COUNTS.txt |
the per-segment coverage strip |
BAM_files/<sample>/final_mapped_reads.bam |
read pile-up |
wfabc*/FIT_results.csv |
selection coefficients and drift tests |
You can load a metadata CSV on its own if the run had no metadata. The sidebar reports how many samples the join matched. That number is the one to read: a join that matched half your samples looks the same as a join that matched all of them.
If you have no run of your own, the example datasets above fill most of these.
The matrix. It shows every call in the run, placed by product and codon. Use the wheel to zoom and drag to pan. Click a sample name to highlight its row. Drag a name to move it. Click any header to sort; shift-click to add a second sort key.
Variant detail. Click a cell. FluLens loads that one sample's VCF. It shows the amino-acid change, the raw numbers, the allele frequency on a linear or log axis, the strand balance against the reference allele, and a verdict.
Variant assessment. There are four verdicts — Looks real, Treat with caution, Likely artefact, and Cannot assess. Each verdict lists its reasons. It weighs strand balance, depth, allele frequency, and the number of reads that support the call. Supporting reads are not the same as depth: a 0.5% call on 15,000× has high depth but may rest on only a few alt reads.
Consensus view. It shows each sample's own residue at every codon. It draws only the differences from the reference, not a full field of colour.
Coverage strip. It shows the reads recovered per segment, per sample, by decade. The variant table cannot tell you that a segment recovered 5,455 reads and not 509,426; this strip can.
QC column. It gives a per-sample verdict from the raw variant table. The verdict does not change with your filters, because QC is a fact about the library and not about the view. Click the mark to override it.
FluMut markers, SNPGenie diversity layers, WFABC selection results, and export to CSV, TSV, TXT, JSON, Markdown, or VCF. Each file has a header that records the filters that made it.
These are properties of the data, not of this viewer. You cannot see them in the tables themselves.
LoFreq and GATK4 do not report the same quantity. LoFreq's allele frequency is an allele fraction. GATK4's is a genotype — a hom-alt call reads 1.0 whatever the reads say. At one measured site, LoFreq said 85.98%, GATK4 said 100%, and the reads said 85.44%. FluLens reconciles this at load. It gives GATK4 rows LoFreq's fraction where both callers found the same change. It flags the rest as genotypes. The consensus excludes genotype-only calls, because you cannot read a genotype as "above 50%".
Both callers emit a row for the same change, so the table has two rows per variant at most sites. To count calls per codon, first remove the duplicates by position and alternative.
FluMut's HA and NA markers use H5/N1 numbering. HA1-5 means H5 HA1 numbering
and NA-1 means N1 NA numbering. So on an H3N2 run, those positions use the wrong
numbering. The internal genes — PB2, PB1, PA, NP, and NS — do not depend on subtype and
are correct. FluLens finds the subtype from the reference segment
names. It marks the HA and NA findings that it cannot confirm. A bare A_HA with no
subtype suffix counts as unconfirmable, not as a pass.
Depth below 100 makes false fixed differences. With low template input, both callers
report false fixed differences. This is why Flumina defaults to min_depth 100 and
FluPore to min_depth 20, and why FluLens downgrades any verdict below the run's own
floor.
The assessment thresholds are absolute. They are not the sidebar sliders. If they were the sliders, a slider would change the verdict that the same slider then filters on. The panel shows where a call sits against your current filters, but the filters do not change the verdict.
In the SNPGenie layer, 99.1% of cells have πN or πS at zero. At one codon in one sample, the value mostly reports which kind of difference it found, not which one is larger. The result is the pattern across many codons.
FluLens has no server and makes no network requests. The browser version reads
your run folder through the file picker. The desktop version reads it from disk.
It uploads nothing. The hosted page at flu-crew.github.io is a static file. You could
save it and run it offline with no change in behaviour.
The browser version needs no build: flulens.html is the
application. Edit it and reload.
The desktop app is a Tauri shell around that same file:
cargo install tauri-cli --version "^2" --locked
rustup target add aarch64-apple-darwin x86_64-apple-darwin
cd desktop && cargo tauri build --target universal-apple-darwinThe binary contains the compiled frontend. If you edit
flulens.html, the desktop app shows no change until you rebuild. People forget this often and lose time.
More reading, all of it for maintainers:
docs/CONTRIBUTING.md— how the two run loaders work, how to regenerate the example, and the mistakes that often cost people timedocs/RELEASING.md— how to sign, notarise, and cut a release. Read the DMG section before you ship one: Tauri notarises the app but not the disk image, so a good build can still make a download that macOS blocksdesktop/README.md— the design of the Tauri shell
If FluLens helped your published work, please cite it — see
CITATION.cff. Please cite
Flumina or
FluPore too if you used one of those
pipelines to make the data.
GPL-3.0-or-later, the same as Flumina. See LICENSE.


