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.
Key features
- 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.
Quick start
Install with Bioconda
conda install -c conda-forge -c bioconda nexcision
Install from GitHub
python -m pip install git+https://github.com/RhysWhite/nexcision.git
Alternatively, clone the repository and install it locally:
git clone https://github.com/RhysWhite/nexcision.git
cd nexcision
python -m pip install .
Run NEXCISION
nexcise input.nex regions.tsv \
--output filtered.nex \
--counts removed_counts_per_region.tsv \
--report nexcision_report.json
Existing outputs are not overwritten unless --force is supplied.
How it works
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.
Input files
NEXUS matrix
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.
Regions file
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.
Outputs
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.
Workflow integration
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.
For a detailed plain-English explanation of how the program works, see the Code walkthrough.
Dimension handling
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 none
Reproduce the bundled example
python -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.tsv
On Windows, the generated files can be compared with the expected outputs using Git, PowerShell, or another text-comparison tool.
Testing
Run the full test suite with:
python -m unittest discover -s tests -v
GitHub Actions tests NEXCISION on Python 3.10, 3.11, 3.12, and 3.13, reproduces the bundled example, and builds an installable wheel.
Scope and limitations
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.
Citation
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.
Funding and affiliation
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.
Contributing
Bug reports, feature requests, and contributions are welcome. See CONTRIBUTING.md for guidance.
For security-related concerns, see SECURITY.md.
License
NEXCISION is distributed under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nexcision-0.1.1.tar.gz.
File metadata
- Download URL: nexcision-0.1.1.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed446312295dd417dce8df2298b9f42e003e9ea8e68cc287f5c8dc5573f6295f
|
|
| MD5 |
f8b570b1d6df2485009d6692bee115b3
|
|
| BLAKE2b-256 |
69bd814a1f70812528b4b086f288d9b803288f1229779aa35b869addb7cfe6b2
|
Provenance
The following attestation bundles were made for nexcision-0.1.1.tar.gz:
Publisher:
publish-pypi.yml on RhysWhite/nexcision
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nexcision-0.1.1.tar.gz -
Subject digest:
ed446312295dd417dce8df2298b9f42e003e9ea8e68cc287f5c8dc5573f6295f - Sigstore transparency entry: 2472526964
- Sigstore integration time:
-
Permalink:
RhysWhite/nexcision@918cfbad4360f6394eae8a44bde9ff5f5b95e4ef -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RhysWhite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@918cfbad4360f6394eae8a44bde9ff5f5b95e4ef -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file nexcision-0.1.1-py3-none-any.whl.
File metadata
- Download URL: nexcision-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb53b7a949d8a00744910d242a37cf9ecc476e9b6f9d861486a43d21cb9a6771
|
|
| MD5 |
444c842e3e79690b373682fec3cba873
|
|
| BLAKE2b-256 |
44314e9c7387c12166742dc661d0fee323d1ddd1172c136577946ccc9ed028fc
|
Provenance
The following attestation bundles were made for nexcision-0.1.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on RhysWhite/nexcision
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nexcision-0.1.1-py3-none-any.whl -
Subject digest:
eb53b7a949d8a00744910d242a37cf9ecc476e9b6f9d861486a43d21cb9a6771 - Sigstore transparency entry: 2472526982
- Sigstore integration time:
-
Permalink:
RhysWhite/nexcision@918cfbad4360f6394eae8a44bde9ff5f5b95e4ef -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RhysWhite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@918cfbad4360f6394eae8a44bde9ff5f5b95e4ef -
Trigger Event:
workflow_dispatch
-
Statement type: