Precise removal of coordinate-labelled sites from NEXUS matrices.
NEXCISION is a dependency-free Python command-line tool for reproducibly removing matrix rows whose genomic coordinates fall within user-specified intervals, while preserving the remaining structure and content of the NEXUS file.
It is designed primarily for transposed NEXUS matrices in which each row represents a genomic site and the first token ends with its coordinate:
CP013831_180 01001101
In this example, 180 is the genomic coordinate used to determine whether the row should be retained or removed.
- Precise — removes only rows with coordinates inside defined genomic intervals.
- Reproducible — optionally records parameters, results, and SHA-256 checksums in a deterministic JSON report.
- Safe — validates input files and refuses to overwrite outputs unless explicitly instructed.
- Transparent — reports removal counts for every input region, including overlapping regions.
- Portable — requires only Python 3.10 or newer and has no runtime dependencies.
- NEXUS-aware — safely updates
ntaxor transposed-matrixncharvalues when appropriate.
python -m pip install git+https://github.com/RhysWhite/nexcision.gitAlternatively, clone the repository and install it locally:
git clone https://github.com/RhysWhite/nexcision.git
cd nexcision
python -m pip install .nexcise input.nex regions.tsv \
--output filtered.nex \
--counts removed_counts_per_region.tsv \
--report nexcision_report.jsonExisting outputs are not overwritten unless --force is supplied.
NEXCISION reads the genomic coordinate from the first token of each matrix row, compares it against the supplied intervals, and removes matching rows. Rows outside those intervals are retained unchanged.
By default, NEXCISION extracts the terminal integer following an underscore in the first token of each matrix row:
CP013831_160 01001101
CP013831_180 11000110
CP013831_200 01011001
The default coordinate pattern is:
_(\d+)$
A different identifier format can be handled with --position-regex. The expression must contain exactly one capture group representing the coordinate:
nexcise input.nex regions.tsv \
--position-regex 'site:(\d+)$'Matrix rows that cannot be parsed are rejected by default. Use --allow-unparsed only when unmatched rows should be retained unchanged.
The regions file is whitespace-delimited. Coordinates are 1-based and inclusive. A third name column is optional.
start end name
170 260 recombination_block_1
300 350 recombination_block_2
Blank lines and lines beginning with # are ignored. Reversed start and end coordinates are normalised automatically.
NEXCISION can produce three outputs:
| Output | Description |
|---|---|
filtered.nex |
NEXUS file with matching coordinate-labelled rows removed. |
removed_counts_per_region.tsv |
Number of removed rows associated with each supplied interval. |
nexcision_report.json |
Optional run metadata, parameters, results, warnings, and SHA-256 checksums. |
Overlapping regions are counted independently, but each matrix row is removed only once.
The optional JSON report can be checked programmatically before downstream analysis proceeds. Workflows can enforce analysis-specific criteria such as an expected removal count, absence of warnings, consistency of matrix-row totals, or agreement with recorded SHA-256 checksums.
A result of zero removed rows is not inherently an error. The appropriate acceptance rule depends on the supplied mask and analysis. See Workflow integration for shell and Snakemake examples, including a report-gated downstream step.
By default, NEXCISION automatically selects the appropriate NEXUS dimension to update:
ntaxfor an ordinary matrix;ncharwhen the precedingFORMATcommand declaresTRANSPOSE.
The selected value is changed only when it equals the original number of matrix rows. If it does not, NEXCISION issues a warning and leaves it unchanged rather than guessing.
This behaviour can be overridden explicitly:
--update-dimension ntax
--update-dimension nchar
--update-dimension nonepython -m pip install .
nexcise examples/input.nex examples/regions.tsv \
--output filtered.nex \
--counts removed_counts_per_region.tsv \
--report nexcision_report.json
diff -u examples/expected_filtered.nex filtered.nex
diff -u examples/expected_removed_counts_per_region.tsv \
removed_counts_per_region.tsvOn Windows, the generated files can be compared with the expected outputs using Git, PowerShell, or another text-comparison tool.
Run the full test suite with:
python -m unittest discover -s tests -vGitHub Actions tests NEXCISION on Python 3.10, 3.11, 3.12, and 3.13, reproduces the bundled example, and builds an installable wheel.
NEXCISION filters matrix rows, not alignment columns. It deliberately supports one standalone MATRIX block per file and is not intended to be a general-purpose NEXUS parser.
Use NEXCISION when genomic sites are represented as coordinate-labelled rows. Confirm the orientation and structure of the input matrix before filtering.
Please cite NEXCISION if it contributes to an analysis, publication, report, or reusable workflow.
White RT. NEXCISION: exact, validated, and scalable excision of genomic regions from phylogenomic NEXUS matrices. bioRxiv [Preprint]. 2026. doi: https://doi.org/10.64898/2026.07.26.740842
GitHub citation metadata are provided in CITATION.cff.
The complete validation and benchmarking materials are available in the NEXCISION benchmarking repository.
Development of NEXCISION was supported by Genomics Aotearoa and undertaken at Public Health and Forensic Science (PHF Science), Aotearoa New Zealand.
NEXCISION was developed and is maintained by Rhys White.
Bug reports, feature requests, and contributions are welcome. See CONTRIBUTING.md for guidance.
For security-related concerns, see SECURITY.md.
NEXCISION is distributed under the MIT License.

