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.
- What MAP does
- How MAP works
- Requirements
- Quick start (run the included demo after Docker setup)
- Run on your own data
- Run with your own reference library
- Interactive container
- Parameters
- Outputs
- Build the image yourself
- Offline use & reusing the reference library
- Demo data
- Troubleshooting
- Citation
-
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).
- Demultiplex & trim — assign reads to samples; remove primers/UMIs (
cutadapt,seqkit). Illumina reads are merged (vsearch). - Per‑sample clustering — denoise/cluster each sample into OTUs (
vsearch); filter by Min reads per OTU. - Run‑wide clustering — cluster per‑sample OTUs across the run into run‑wide OTUs.
- Sequence correction (COI) — reference‑frame indel/homopolymer correction to clean coding sequences.
- Chimera screening —
vsearch --uchime_denovo. - Taxonomy — SINTAX assignment against the bundled reference library.
- Contaminant removal — negative‑control‑aware filtering + replicate‑support checks.
- BIN matching (COI) — match OTUs to BOLD BINs.
- Report — Quarto renders the interactive HTML report; final tables written to Excel/TSV.
- 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).
- 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 sudoEasiest Docker setup (Mac/Windows with WSL):
- Download Docker Desktop from their website and follow their guidelines. https://www.docker.com/products/docker-desktop/
- Runs the demo out of the box. Highly recommended. With no arguments, MAP runs the bundled
PHAUS_1Ktest 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:latestBundled 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
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 mainThese 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/runWhen it finishes, your results are in ./data/run/output/ (Excel + TSV tables, an interactive HTML report, and demultiplexing summaries). See Outputs.
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/runUse 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_readsThe 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 /dataResults appear in ./data/run/output/.
- Illumina paired‑end: Include
--pe_readsflag 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_readsflag 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).
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 hereNote: 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.
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). |
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.
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
--componentreadsis passed.
For COI markers ≥ ~300 bp, results include BOLD BIN matches (BIN hit, % identity, BIN taxonomy).
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.
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:latesthas already been run once (workdir/compose.yamlwon't try to re-pull it otherwise). - The
reflibvolume 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/runEach 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- No output on the host? Set working directory
--wdto 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/Metabarcodinginside 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.
mapenvironment not active. Usebash -lc "…", or run insidemicromamba run -n map bash -c "…".
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