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/ — a synthetic Flumina run.
| 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 exercises every control, and it includes reads, so the pile-up opens on it.
example_run/README.md describes the design.
example_run_nanopore/ — a synthetic FluPore run, with single-end ONT reads.
| 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 every gene product appears |
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 call at a very low frequency can sit
on high depth and still rest on few alt reads. A fixed call, with almost no reference
reads, is not penalised on strand balance, because there is no reference allele to
compare it against. Recent Flumina writes the verdict into the variant table (an assessment
column) and FluLens reads it from there, so the two always agree; without that column
FluLens derives the same verdict from the per-sample VCFs.
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. The variant table cannot show you how many reads a segment recovered. This strip can.
QC column. It gives a per-sample verdict. 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.
Four rules make the verdict: the number of calls, their median depth, the fraction of
them below the run's depth floor, and the number of segments that IRMA recovered. A
slider in the sidebar sets each rule. The segment rule needs
IRMA_results/<sample>/tables/READ_COUNTS.txt, and FluLens skips it if the run has no
read counts.
Samples with no calls also get a row. A sample can have no row in the variant table. FluLens finds it in the run's per-sample directories and shows it as an empty row, with the coverage strip and the QC verdict. Use hide samples with no calls to put these rows away.
FluMut markers, SNPGenie diversity layers, WFABC selection results, and export to CSV, TSV, TXT, JSON, Markdown, VCF, or FASTA.
Export writes any item, and not only the open view. The export dialog lists every item in the run. Tick the items you want. FluLens writes one file for each item. The dialog greys out an item the run does not have, and gives the reason.
| Item | File types | What it holds |
|---|---|---|
| Variant calls | table, VCF | One row per call, with 17 columns |
| Consensus residues | table | Each codon where a sample differs from the reference |
| Consensus proteins | FASTA | One record per sample and product, in amino acids |
| Consensus calls, nucleotide | table, VCF | The call that made each consensus codon |
| Consensus segments, nucleotide | FASTA | One record per sample and segment |
| IRMA consensus changes | table | The residues where IRMA differs from the reference |
| IRMA consensus proteins | FASTA | One record per frame IRMA placed |
| Sample summary and QC | table | The QC verdict, its inputs, and the metadata |
Each item picks its own file type. The menu beside an item gives the types that
item can write. table means CSV, TSV, TXT, JSON, or Markdown. The two call items also
give VCF 4.2, because they have a REF and an ALT to write. FluLens keeps your choice for
the session.
Set scope to as shown to write the filters, the sample order and the hidden
products of the display. Set scope to everything to write the full run. Each file
has a header with the scope and the filters that made it. A FASTA file carries the same
header in leading ; lines, and repeats the facts in each defline.
A consensus FASTA is the reference plus the calls above 50%. A product or a segment
that did not assemble therefore comes out as the reference. Read changes= on each
record. The IRMA proteins do not have this problem, because IRMA states a residue only
where it placed a contig.
The desktop app writes a folder. It asks for a folder one time. Then it writes all the files into that folder. The browser version downloads the files one at a time.
The first view is filtered. FluLens sets the depth, frequency and alt-read sliders
from the values in the run's config.cfg, and the nonsynonymous only control is on.
The sidebar gives the count of the calls on screen. Click Reset filters to show every
call in the table.
The assessment thresholds are fixed. They are not the sidebar sliders. The sliders change which calls you see. They never change a verdict. The panel shows where a call sits against your current filters, and the verdict stays the same.
LoFreq and GATK4 do not report the same quantity. LoFreq gives an allele fraction. GATK4 gives a genotype. FluLens reconciles the two at load. It gives a GATK4 row LoFreq's fraction where both callers found the same change, and marks the rest as genotypes. The consensus view leaves out genotype-only calls.
Each caller writes its own row for the same change. The table therefore holds more than one row per variant at most sites. Use the caller checkboxes to show one caller at a time.
FluMut HA and NA markers use H5/N1 numbering. HA1-5 means H5 HA1 numbering and
NA-1 means N1 NA numbering. FluLens reads the subtype from the reference segment names
and marks every HA or NA marker that it cannot confirm. A bare A_HA with no subtype
suffix counts as unconfirmed. The internal genes do not depend on the subtype.
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. See LICENSE.
AI-assisted coding tools, including Claude Code and OpenAI Codex, were used during development of this project.
The underlying ideas, scientific questions, project design, methodology, software architecture, and implementation decisions were developed by the author. AI tools were used primarily as development assistants for tasks such as creating the graphical user interface, code review, identifying bugs, suggesting fixes, improving code clarity, generating or refining documentation, and assisting with implementation of clearly specified functionality.
All AI-generated or AI-suggested changes were reviewed before inclusion in the project. Responsibility for the design, correctness, scientific validity, testing, maintenance, and final contents of the software remains with the author.
AI tools were not treated as independent authors or sources of scientific conclusions.


