Skip to content
cbg-innovPublic

About

Metabarcoding Analysis Pipeline

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

45 Commits

Folders and files

Repository files navigation

MAP — Metabarcoding Analysis Pipeline

MAP is a fully containerized metabarcoding pipeline that supports both Illumina paired‑end and Oxford Nanopore (ONT) / long‑read single‑end data. All tools (incl. R and Python packages, etc. ) and reference databases are baked into the container or automatically created upon running MAP. MAP is customizable using command line flags and a parameters file designed to accomodate different barcode markers, UMIs, and primers, if desired.


Contents


What MAP does

  • MAP designates OTUs, taxonomy and BIN classifications for use with BOLD (Barcode of Life Database) from one to several non-demultiplexed fastq.gz files. MAP handles demultiplexing, primer/UMI trimming, denoising/clustering, reference‑frame sequence correction (COI), chimera screening, contaminant removal, taxonomic assignment (SINTAX), and BOLD BIN matching.

  • MAP was specifically developed for use with COI barcodes and for BIN assignment for direct output to BOLD (Barcode of Life Database).


How MAP works

  1. Demultiplex & trim — assign reads to samples; remove primers/UMIs (cutadapt, seqkit). Illumina reads are merged (vsearch).
  2. Per‑sample clustering — denoise/cluster each sample into OTUs (vsearch); filter by Min reads per OTU.
  3. Run‑wide clustering — cluster per‑sample OTUs across the run into run‑wide OTUs.
  4. Sequence correction (COI) — reference‑frame indel/homopolymer correction to clean coding sequences.
  5. Chimera screening — vsearch --uchime_denovo.
  6. Taxonomy — SINTAX assignment against the bundled reference library.
  7. Contaminant removal — negative‑control‑aware filtering + replicate‑support checks.
  8. BIN matching (COI) — match OTUs to BOLD BINs.
  9. Report — Quarto renders the interactive HTML report; final tables written to Excel/TSV.

Requirements

  • Supported architectures: linux/amd64 and linux/arm64 (Apple Silicon).
  • Disk space and memory. Large intermediate files may be created during runtime.
  • Docker (Desktop or Engine).

Instructions for easy Docker setup

  • There are many ways to get Docker up and running, including:

Easiest Docker setup (Linux):

curl -fsSL https://get.docker.com | sh      # installs Docker Engine + compose plugin
sudo usermod -aG docker "$USER"             # so you don't need sudo
newgrp docker                               # apply group now (or just log out/in)
docker run hello-world                      # verify, no sudo

Easiest Docker setup (Mac/Windows with WSL):


To Install MAP: Quick start (run the included demo after Docker setup)

  • Runs the demo out of the box. Highly recommended. With no arguments, MAP runs the bundled PHAUS_1K test dataset, so you can confirm the whole pipeline works before touching your own data.

Note: The instructions are meant to be run from the '/workdir' directory, but can be run from any directory with the fastq.gz, parameters.xlsx, and compose.yaml files. These 3 files are required for MAP to run and they should be set up with the same structure as in the provided workdir directory.

Pull the image: This installs MAP.

docker pull ghcr.io/cbg-innov/map:latest

Demo data

Bundled inside the image (under /MAP/Metabarcoding/) and easily viewable from 'workdir' directory in Github repo:

  • PHAUS_1K_RawReads.fastq.gz — small COI test read set.
  • parameters.xlsx — matching parameters spreadsheet (use as your template).
  • compose.yaml - compose file to aid command line

All working directory files can be downloaded using git:

git clone --no-checkout --depth 1 --filter=blob:none https://github.com/cbg-innov/MAP.git
cd MAP
git sparse-checkout set workdir
git checkout main

These provide a template for running MAP on your own data. The compose.yaml file may be copied and re-used.

Running MAP with no --fastq/--params runs this demo end‑to‑end.

Run the bundled demo and write results to the directory — this single command runs the entire pipeline on the included PHAUS_1K test data. Note: The '/data/' directory name is used internally within the Docker container, but 'workdir' is how it will apppear on your device

cd <PATH>/workdir #or rename
docker compose -f compose.yaml run --rm map \
  bash /MAP/SCRIPTS/MAP.sh \
  --wd /data/run

Here, the fastq.gz and parameters files are internal and do not need to be named directly.

When it finishes, your results are in ./data/run/output/ (Excel + TSV tables, an interactive HTML report, and demultiplexing summaries). See Outputs.


Run on your own data

Put your reads (*.fastq.gz) and a filled‑in parameters spreadsheet into the data directory, and point MAP at them. Use --wd so all outputs land in your mounted folder:

# host folder containing: reads.fastq.gz,  parameters.xlsx, and compose.yaml
cd <PATH>/workdir
cp <DATA_FASTQ.GZ> <PATH>/workdir/data/
cp <PARAMETERS.XLSX> <PATH>/workdir/data/
docker compose -f compose.yaml run --rm map \
  bash /MAP/SCRIPTS/MAP.sh \
  --fastq /data/*.fastq.gz \
  --params /data/my_parameters.xlsx \
  --wd /data/run

Running paired-end reads?

Use the same command as for "Run on your own data" (above). The --pe_reads flag must be present while running the command. For the --fastq input, use a name with a wildcard [ * ] that can apply to both files. Make sure only 2 files match the --fastq input; otherwise only the first 2 files will be used.

# host folder containing: Illumina_R1_001.fastq.gz,  Illumina_R2_001.fastq.gz, parameters.xlsx, and compose.yaml
cd <PATH>/workdir
cp <DATA_FASTQ.GZ> <PATH>/workdir/data/
cp <PARAMETERS.XLSX> <PATH>/workdir/data/
docker compose -f compose.yaml run --rm map \
  bash /MAP/SCRIPTS/MAP.sh \
  --fastq /data/Illumina_R*_001.fastq.gz \
  --params /data/my_parameters_illumina.xlsx \
  --wd /data/run \
  --pe_reads

Run with your own reference library

The latest BOLDdistilled COI SINTAX reference set is downloaded and unpacked into /MAP/REFS at first run time and needs an internet connection, and may prolong the MAP demo runtime slightly. The COI correction reference set is provided at first build time — no manual download needed. REFS is mounted as a named volume (reflib) so it persists across runs and can be shared between containers (see Offline use & reusing the reference library for details on how that persistence works). If you wish to change the reference library, make sure that the parameters.xlsx sheet reflects the new name and copy your vsearch reference file into your working directory.

--refs points at a folder containing your custom reference library (e.g. refs), and must be independent of the run directory. We recommend <PATH>/workdir/data/refs. The files should be sintax-formatted .fasta files (e.g., 'ITS_eukaryotes_ref_sintax.fasta'):

# host folder containing: reads.fastq.gz,  parameters.xlsx, and compose.yaml
mkdir <PATH>/workdir/data/refs
cp <REF_FILES_FASTA> <PATH>/workdir/data/refs/
cd <PATH>/workdir
docker compose -f compose.yaml run --rm map \
  bash /MAP/SCRIPTS/MAP.sh \
  --refs /data/refs \
  --wd /data

Results appear in ./data/run/output/.

  • Illumina paired‑end: Include --pe_reads flag when running MAP on the command line. Use the common prefix and/or suffix for both files, with '*' where names diverge.
  • ONT / long‑read: Do not include --pe_reads flag on the command line. MAP's default is individual reads.
  • Start from the bundled spreadsheet as a template (in 'workdir' directory in Github repo) (see Demo data).

Interactive container

For exploring intermediate files or running repeatedly, keep a container alive. compose.yaml also persists the reference library in a named volume so it survives container recreation.

docker compose up -d            # start a long‑running 'map' container
docker compose exec map bash    # drop into a shell (the 'map' env auto‑activates)

# inside the container:
bash SCRIPTS/MAP.sh        # runs the demo, or add --fastq/--params/--wd

# copy results out to your Desktop:
docker compose cp map:/MAP/Metabarcoding/output ~/Desktop/MAP_results

docker compose down             # stop & remove the container (volume persists)

To make your own data visible inside the interactive container, add a bind mount under the map service in compose.yaml, e.g.:

    volumes:
      - reflib:/MAP/REFS
      - ~/Desktop/my_run:/data        # <-- your data here

Parameters

Note: UMI map and primers are provided by the user in an Excel (.xlsx) file, using the template provided. The 'UMIs and Primers', 'Bulk Sample Metadata', and 'Dictionary Update' tabs must be filled out.

The parameters spreadsheet

Important parameters are set in the .xlsx parameters file. Start from the bundled parameters.xlsx in the workdir directory on Github to understand formatting. Key fields:

Tab Field Meaning
UMIs and Primers Many Primer and UMI information
Run Name Name used for outputs
Plate Indicate plate name or number (e.g, Plate06)
Well Indicate well number (e.g., B09)
Sample Indicate sample name corresponding to well (e.g., GMP-58226_Rep1). Any replicate should be denoted with '_Rep#', but the first does not require this suffix.
Forward / Reverse UMI UMI sequences corresponding to sample (e.g., ACAGATTTTTA)
Forward / Reverse Primer Name Use the names that match the sequences as defined in the Dictionary Update tab (see below) (e.g., PHAUS_F2, PHAUS_R3)
Negative Control indicate whether it is a Negative control (e.g., yes). Otherwise, leave blank.
Bulk Sample Metadata Sample collection information Per‑sample metadata for the report
Sample Should match Sample in 'UMIs and Primers' tab, minus any replicate denotion (e.g., should be GMP-58226, not GMP-58226_Rep2)
Collection Site Any name (e.g., Australia)
Latitude/Longitude Please enter separately in respective fields in decimal format (e.g., -134.5544)
Collection Start Date/Collection End Date Please enter separately in respective fields in this format: DD-Mon-YY (e.g., 20-Dec-24)
Dictionary Update Many Parameter informaton to be used with each primer combination
Forward / Reverse Primer Name This is where you indicate the name you will use for the corresponding Forward / Reverse Primer Sequences that are used in the 'UMIs and Primers' tab (e.g., PHAUS_F2, PHAUS_R3)
Forward / Reverse Primer Sequence This is where you indicate the sequence that corresponds with the primer name you provided (e.g., AYATRGCHTTYCCHCG)
Marker Locus name (e.g. COI-5P)
Reference Library SINTAX‑formatted reference DB name (e.g., BOLDistilled_COI_Apr2026 or BOLDistilled_COI_ for BOLDistilled_COI_Apr2026_sintax.fasta). Note: BOLDistilled_COI_ can be used to allow for updated/different libraries to be used without errors.
Min / Max Amplicon Length Length filter WITHOUT UMIs or primers or single reads (e.g., ONT).
Target amplicon length Expected amplicon length (no primers/UMIs)
Reverse Complement (optional) Yes for a primer pair whose reads come off the sequencer from the reverse-primer end — i.e. plates built with the primer/UMI layout reversed, so this row's "forward" primer is really the reverse primer (e.g. F2 = GRTGNCCRAARAAYCA, R2 = AYATRGCHTTYCCHCG). Those reads are demultiplexed exactly as sequenced, then reverse-complemented after trimming so every sample is clustered, classified and BIN-matched on the plus strand. Leave blank, or omit the column entirely, for normal pairs. Not supported with symmetrical UMIs.
Min reads per OTU OTUs below this read count are discarded (e.g., 2)
Replicates per sample Number of replicates per sample (e.g., 8)
Intra-OTU Clustering Threshold Threshold for clustering OTUs within samples (i.e., across replicates of the same sample) (e.g., 2.5). Somewhat akin to denoising ASVs.
Inter-OTU Clustering Threshold Threshold for final OTU clustering across samples (e.g., 2.3).
Reverse Complement Default is 'No' or [blank] and it is unlikely that you will need to change this. Set 'Yes' only for a primer row with reads that come off the sequencer starting from the reverse-primer end (e.g., plates built with the layout reversed so UMIs can be reused). That row's primer sequences must also be entered swapped (the reverse primer in the Forward Primer Sequence column).

Command‑line flags

Override paths and advanced parameters at run time (defaults shown):

Flag Default Description
--fastq /MAP/Metabarcoding/PHAUS_1K_RawReads.fastq.gz Input reads: one or more files. A wildcard works with or without quotes (e.g., --fastq /data/PHAUS_Illumina_*.fastq.gz), as does listing files explicitly; give related files a similar prefix. Paired-end R1/R2 files must follow the _R1_/_R2_ or _1.fastq/_2.fastq naming convention. File paths cannot contain spaces.
--params /MAP/Metabarcoding/parameters.xlsx Parameters spreadsheet
--refs /MAP/REFS Reference library directory
--wd /MAP/Metabarcoding Working directory (outputs go to <wd>/output)
--pe_reads [off] Include flag if using paired-end reads. Older parameters files with a Paired-End Reads column still work if column agrees with flag
--scripts /MAP/SCRIPTS Pipeline scripts directory
--sintax_cutoff 0.6 SINTAX confidence cutoff (0–1)
--componentreads [off] Save per‑OTU component reads. Default is off; component reads not saved.
--cores_to_leave 2 How many cores to leave free. MAP will use the rest.
--mem_to_leave 2 How many GB left free inside the container. MAP will use the rest.
--mem_per_job auto This may be edited to manually change the max GB of memory used per job
--ref_seq_corr /MAP/REFS/reference_seqs_327K.fasta File used for sequence correction
--umi_overlap_min 0.75 Multiplier applied to UMI lengths during demultiplexing. We recommend 0.75 for UMIs ≥12 nucleotides, and 1.0 for UMIs <12 nucleotides.
--primer_overlap_min 0.75 Multiplier applied to primer lengths. We recommend 0.75.
--error_umi1 0.125 Max error rate (Cutadapt) for the forward UMI; could be lower for shorter UMI sequences (e.g., <10bp)
--error_umi2 0.125 Max error rate (Cutadapt) for the reverse UMI; could be lower for shorter UMI sequences (e.g., <10bp)
--error_primer1 0.2 Max error rate (Cutadapt) for the forward primer
--error_primer2 0.2 Max error rate (Cutadapt) for the reverse primer
--maxee 1 (Illumina paired‑end only) Max expected error value permitted
--minqual 10 Min quality score permitted with Chopper (ONT/long‑read). We recommend 10 for long‑read sequences with lower overall predicted quality for better retention; a score closer to 20 is likely more useful for higher‑quality sequences (e.g., HiFi PacBio).
--min_read_and_primer_length 100 Min length of sequence+primers kept by Chopper. Kept loose to account for variable markers with variable polymorphic lengths.
--max_read_and_primer_length 1000 Max length of sequence+primers kept by Chopper. Kept loose to account for variable markers with variable polymorphic lengths.
--no_Ill_chimera_check [off] (Paired‑end/Illumina only) Skips the per‑sample uchime_denovo chimera screen, which otherwise runs by default. Dereplication still runs either way, as cluster_unoise requires it.
--Ill_abskew 2 (Paired‑end/Illumina only) VSEARCH uchime_denovo abskew parameter
--Ill_mindiv 0.8 (Paired‑end/Illumina only) VSEARCH uchime_denovo mindiv parameter
--LR_abskew 10 (Long‑read/ONT only) VSEARCH uchime_denovo abskew parameter
--LR_mindiv 0.0005 (Long‑read/ONT only) VSEARCH uchime_denovo mindiv parameter
--minsize_unoise 2 Min cluster size (within samples) for paired‑end reads using VSEARCH cluster_unoise
--min_rep_prop 0.65 Min proportion of replicate samples an OTU must be present in to be retained
--high_dens_prop 0.65 Min proportion of replicates (where the OTU is present) whose sequence count falls within the high kernel‑density area, for the OTU to be retained. For Illumina, we recommend 0.15
--alpha_default 0.001 Default contamination rate; only used if alpha_quantile is not defined.
--alpha_quantile 0.9 Quantile of the calculated alpha (contaminated‑reads floor estimate) to use. For Illumina, we recommend 0.8
--k_multiplier 1 Contaminant‑floor multiplier (<1 permissive, >1 strict). Note: we do not recommend changing this unless widespread contamination occurred. Values over 1 are likely to remove a lot of good data.
--BIN_percent_ID 0.85 We recommend 0.85 for short‑read data. Threshold to keep matches to BINs in the final database, regardless of 'formal' BIN assignment. Matches below this threshold are labeled "NO MATCH" in the final data.
--BIN_maxaccepts 3 Parameter fed to VSEARCH's usearch_global command.
--BIN_maxhits 3 Parameter fed to VSEARCH's usearch_global command.
--overwrite [off] Include flag if you want to replace the contents of the output/ directory

Tip (ONT): raising Min reads per OTU is an effective lever for trimming low‑read long‑read error variants and tightening per‑sample richness.


Outputs

All results are written to <working_dir>/output/<marker>_<len>bp/:

  • Metabarcoding Results - <run>.xlsx — main results workbook (By Sample, By Replicate, Sample Metadata sheets).
  • 2-TSV Versions of Results/ — the same tables as plain TSV (…_BySample.tsv, …_ByReplicate.tsv).
  • 1-Results and Report/MAP Report - <run>.html — interactive report (richness, maps, treemaps, BIN matches).
  • Demultiplexing_Results_<run>.pdf — per‑sample/plate read‑count summaries.
  • <run>_<marker>_<len>bp_NegativeControlOTUs.tsv — OTUs detected in negative controls.
  • OTU component reads (zipped) when --componentreads is passed.

For COI markers ≥ ~300 bp, results include BOLD BIN matches (BIN hit, % identity, BIN taxonomy).


Build the image yourself

Locally (single-arch, matches your own machine):

From the Docker/ directory (the build context):

cd Docker
docker build -t map .

This installs the full environment via micromamba, lays out SCRIPTS/, Metabarcoding/, and REFS/, installs Quarto and iNEXT, and unpacks the reference library used for sequence correction of COI.

Run a locally‑built image by replacing ghcr.io/cbg-innov/map:latest with map:latest in any command above.

Multi‑arch (published to ghcr.io): the published ghcr.io/cbg-innov/map:latest image is a single multi‑arch manifest (linux/amd64 + linux/arm64), built by the .github/workflows/docker-publish.yml GitHub Actions workflow. amd64 builds natively on the GitHub runner and arm64 is built via QEMU emulation under docker buildx, so Docker automatically pulls the right layer whether you're on Apple Silicon or an x86 Linux.


Offline use & reusing the reference library

The first run needs internet access — MAP downloads the BOLDdistilled reference library (~1GB) into /MAP/REFS the first time it doesn't find one already there. Every run after that can be fully offline, as long as two things are already in place from a prior run:

  • The image itself: docker pull ghcr.io/cbg-innov/map:latest has already been run once (workdir/compose.yaml won't try to re-pull it otherwise).
  • The reflib volume already has the reference library downloaded into it. Note: the reference library will not update unless re-downloaded.

Using the same reference library across multiple datasets/directories: workdir/compose.yaml pins its Compose project name (name: map), so the reflib volume (with and the reference library inside it) is automatically reused no matter which directory you run from. Set up each dataset the standard way:

# first, run commands specified in 'Demo data' section.

# later run, different directory, different dataset — fully offline, no re-download
cd ~/map_runs/dataset2              # contains: reads2.fastq.gz, params2.xlsx, compose.yaml
docker compose -f compose.yaml run --rm map \
  bash /MAP/SCRIPTS/MAP.sh --fastq /data/<NEW>.fastq.gz --params /data/<DIFFERENT_params>.xlsx --wd /data/run

Each dataset folder needs its own copy of compose.yaml and the customized fastq/parameters files. Note: compose.yaml file content is identical every time, it just needs to be present so docker compose has something to read.

Verifying you're set up for offline use, before disconnecting from the internet:

docker images | grep cbg-innov/map        # confirm the image is present locally
docker volume ls | grep map_reflib        # confirm the reflib volume exists

Troubleshooting

  • No output on the host? Set working directory --wd to the mounted folder, e.g., --wd /data/run, which will write results to ./data/run/output/on your machine. Without --wd, MAP writes to /MAP/Metabarcoding inside the container. If you ran MAP in a long-running container (docker compose up -d), you can copy results out using: docker compose cp map:/MAP/Metabarcoding/output ./MAP_results
  • Disk space. Large/deep runs (especially ONT) can generate many intermediate files; ensure adequate free disk on the Docker host.
  • map environment not active. Use bash -lc "…", or run inside micromamba run -n map bash -c "…".

Citation

Sean WJ Prosser, Nicholas W Bard, Ken A Thompson, Robin M Floyd, Sameer Padhye, Emine Ozsahin, Saeideh Jafarpour, and Paul DN Hebert (2026). The Metabarcoding Analysis Pipeline (MAP): Simple, accurate, and flexible metabarcoding. BioRxiv . https://doi.org/10.64898/2026.07.22.740107

About

Metabarcoding Analysis Pipeline

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages