mafutils 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. mafutils-0.1.1/.codex +0 -0
  2. mafutils-0.1.1/.github/workflows/publish-pypi.yml +46 -0
  3. mafutils-0.1.1/AGENTS.md +93 -0
  4. mafutils-0.1.1/DEVELOPMENT.md +22 -0
  5. mafutils-0.1.1/LICENSE +21 -0
  6. mafutils-0.1.1/PKG-INFO +198 -0
  7. mafutils-0.1.1/README.md +161 -0
  8. mafutils-0.1.1/__pycache__/__init__.cpython-312.pyc +0 -0
  9. mafutils-0.1.1/__pycache__/__main__.cpython-312.pyc +0 -0
  10. mafutils-0.1.1/__pycache__/cli.cpython-312.pyc +0 -0
  11. mafutils-0.1.1/__pycache__/fetch.cpython-312.pyc +0 -0
  12. mafutils-0.1.1/__pycache__/index.cpython-312.pyc +0 -0
  13. mafutils-0.1.1/__pycache__/stats.cpython-312.pyc +0 -0
  14. mafutils-0.1.1/lib/__pycache__/__init__.cpython-311.pyc +0 -0
  15. mafutils-0.1.1/lib/__pycache__/__init__.cpython-312.pyc +0 -0
  16. mafutils-0.1.1/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  17. mafutils-0.1.1/lib/__pycache__/__init__.cpython-39.pyc +0 -0
  18. mafutils-0.1.1/lib/__pycache__/common.cpython-311.pyc +0 -0
  19. mafutils-0.1.1/lib/__pycache__/common.cpython-312.pyc +0 -0
  20. mafutils-0.1.1/lib/__pycache__/common.cpython-313.pyc +0 -0
  21. mafutils-0.1.1/lib/__pycache__/common.cpython-39.pyc +0 -0
  22. mafutils-0.1.1/lib/__pycache__/loginit.cpython-311.pyc +0 -0
  23. mafutils-0.1.1/lib/__pycache__/loginit.cpython-312.pyc +0 -0
  24. mafutils-0.1.1/lib/__pycache__/loginit.cpython-313.pyc +0 -0
  25. mafutils-0.1.1/lib/__pycache__/loginit.cpython-39.pyc +0 -0
  26. mafutils-0.1.1/mafutils/__init__.py +3 -0
  27. mafutils-0.1.1/mafutils/__main__.py +5 -0
  28. mafutils-0.1.1/mafutils/__pycache__/__init__.cpython-312.pyc +0 -0
  29. mafutils-0.1.1/mafutils/__pycache__/__main__.cpython-312.pyc +0 -0
  30. mafutils-0.1.1/mafutils/__pycache__/cli.cpython-312.pyc +0 -0
  31. mafutils-0.1.1/mafutils/__pycache__/fetch.cpython-312.pyc +0 -0
  32. mafutils-0.1.1/mafutils/__pycache__/index.cpython-312.pyc +0 -0
  33. mafutils-0.1.1/mafutils/__pycache__/stats.cpython-312.pyc +0 -0
  34. mafutils-0.1.1/mafutils/_version.py +24 -0
  35. mafutils-0.1.1/mafutils/cli.py +20 -0
  36. mafutils-0.1.1/mafutils/fetch.py +1311 -0
  37. mafutils-0.1.1/mafutils/index.py +102 -0
  38. mafutils-0.1.1/mafutils/lib/__init__.py +0 -0
  39. mafutils-0.1.1/mafutils/lib/__pycache__/__init__.cpython-312.pyc +0 -0
  40. mafutils-0.1.1/mafutils/lib/__pycache__/common.cpython-312.pyc +0 -0
  41. mafutils-0.1.1/mafutils/lib/__pycache__/loginit.cpython-312.pyc +0 -0
  42. mafutils-0.1.1/mafutils/lib/common.py +39 -0
  43. mafutils-0.1.1/mafutils/lib/loginit.py +169 -0
  44. mafutils-0.1.1/mafutils/stats.py +1312 -0
  45. mafutils-0.1.1/mafutils.egg-info/PKG-INFO +198 -0
  46. mafutils-0.1.1/mafutils.egg-info/SOURCES.txt +79 -0
  47. mafutils-0.1.1/mafutils.egg-info/dependency_links.txt +1 -0
  48. mafutils-0.1.1/mafutils.egg-info/entry_points.txt +2 -0
  49. mafutils-0.1.1/mafutils.egg-info/requires.txt +1 -0
  50. mafutils-0.1.1/mafutils.egg-info/top_level.txt +1 -0
  51. mafutils-0.1.1/pyproject.toml +32 -0
  52. mafutils-0.1.1/setup.cfg +4 -0
  53. mafutils-0.1.1/tests/__pycache__/test_fetch.cpython-312-pytest-8.4.1.pyc +0 -0
  54. mafutils-0.1.1/tests/crossblocks-missing-species.bed +1 -0
  55. mafutils-0.1.1/tests/crossblocks.bed +1 -0
  56. mafutils-0.1.1/tests/example.bed +10 -0
  57. mafutils-0.1.1/tests/example.maf +40 -0
  58. mafutils-0.1.1/tests/example.maf.block.idx +10 -0
  59. mafutils-0.1.1/tests/example.maf.scaffold.idx +6 -0
  60. mafutils-0.1.1/tests/example.maf.scaffold.regenerated.idx +6 -0
  61. mafutils-0.1.1/tests/expected-fasta/01-singleblock-gap.fa +4 -0
  62. mafutils-0.1.1/tests/expected-fasta/02-truncatedblock.fa +4 -0
  63. mafutils-0.1.1/tests/expected-fasta/03-crossblocks-missing.fa +4 -0
  64. mafutils-0.1.1/tests/expected-fasta/04-singleblock.fa +4 -0
  65. mafutils-0.1.1/tests/expected-fasta/05-crossblocks.fa +4 -0
  66. mafutils-0.1.1/tests/expected-fasta/06-noalign.fa +0 -0
  67. mafutils-0.1.1/tests/expected-fasta/07-negstrand.fa +4 -0
  68. mafutils-0.1.1/tests/expected-fasta/08-span-multiple-gaps.fa +4 -0
  69. mafutils-0.1.1/tests/expected-fasta/09-missingchrom.fa +0 -0
  70. mafutils-0.1.1/tests/expected-fasta/10-crossblocks-missing-species.fa +6 -0
  71. mafutils-0.1.1/tests/expected-maf/01-singleblock-gap.maf +7 -0
  72. mafutils-0.1.1/tests/expected-maf/02-truncatedblock.maf +7 -0
  73. mafutils-0.1.1/tests/expected-maf/03-crossblocks-missing.maf +11 -0
  74. mafutils-0.1.1/tests/expected-maf/04-singleblock.maf +7 -0
  75. mafutils-0.1.1/tests/expected-maf/05-crossblocks.maf +11 -0
  76. mafutils-0.1.1/tests/expected-maf/06-noalign.maf +0 -0
  77. mafutils-0.1.1/tests/expected-maf/07-negstrand.maf +7 -0
  78. mafutils-0.1.1/tests/expected-maf/08-span-multiple-gaps.maf +7 -0
  79. mafutils-0.1.1/tests/expected-maf/09-missingchrom.maf +0 -0
  80. mafutils-0.1.1/tests/expected-maf/10-crossblocks-missing-species.maf +11 -0
  81. mafutils-0.1.1/tests/test_fetch.py +100 -0
mafutils-0.1.1/.codex ADDED
File without changes
@@ -0,0 +1,46 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ pypi-publish:
10
+ name: Build and publish
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Check out source
14
+ uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.11"
22
+
23
+ - name: Build distributions
24
+ run: |
25
+ python -m pip install --upgrade build
26
+ python -m build
27
+
28
+ - name: Publish distributions
29
+ uses: pypa/gh-action-pypi-publish@release/v1
30
+ with:
31
+ user: __token__
32
+ password: ${{ secrets.PYPI_API_TOKEN }}
33
+
34
+ github-release:
35
+ name: Create GitHub release
36
+ runs-on: ubuntu-latest
37
+ needs: pypi-publish
38
+ permissions:
39
+ contents: write
40
+ steps:
41
+ - name: Create release from tag
42
+ uses: softprops/action-gh-release@v2
43
+ with:
44
+ tag_name: ${{ github.ref_name }}
45
+ name: ${{ github.ref_name }}
46
+ generate_release_notes: true
@@ -0,0 +1,93 @@
1
+ # LLM Agent rules and guardrails
2
+
3
+ ## Project information
4
+
5
+ - This directory contains development of a program to interact with MAF (Multiple Alignment Format) files in the context of comparative genomics.
6
+ - The current project directory is `/n/holylfs05/LABS/informatics/Lab/projects/gwct/dev/mafutils/`, referred to as `<project directory>` in this file.
7
+ - The current project conda environment is `phyloacc-workflows`, referred to as `<project env>` in this file.
8
+ - For commands that require the R programming language, use the conda environment `<renv>`, but follow all the same rules and guardrails outlined throughout.
9
+
10
+ ## Project directory guardrails
11
+
12
+ - At the beginning of every session, confirm that you are working in the `<project directory>` listed above.
13
+ - In plain text, this is referred to as the "project directory", or one of the synoyms listed below.
14
+ - Synonyms for the term project directory include "project directory", "current directory", "working directory", "project workspace", "workspace", "repository", "repo". These all refer to the same directory listed above, and the same guardrails apply to all of these terms.
15
+ - Only run commands or modify files within the project directory, and never ever run commands or modify files in parent directories or other locations on the filesystem.
16
+ - Treat this project directory as a secure, private, and confidential workspace, and do not share any information about it without explicit user permission.
17
+ - Treat this project directory as a completely isolated environment, and do not interact with or affect any other part of the filesystem or external systems without explicit user permission.
18
+ - If you ever need to create diagnostic scripts or files that are used only by the LLM and not meant for the user, place them in a `.llm-tmp/` dir so they are not cluttering the project directories.
19
+ - If `.llm-tmp/` is ever needed and does not exist, create it. If the project is a git repository, also add `.llm-tmp/` to `.gitignore`.
20
+
21
+ ## Environment
22
+
23
+ - This project assumes the use of a conda environment named `<project env>` that is activated at the beginning of every session. Always try to activate this environment at the beginning of every session.
24
+ - If the `<project env>` environment cannot be activated, run all commands except `echo`, `ls`, `cd`, `grep`, `sed`, `cat`, and `awk` with the conda environment by using `conda run -n <project env> <command>`.
25
+ - Do not install any packages or dependencies outside of this conda environment, and do not modify the environment in any way without explicit user permission. Always ask for permission before installing any packages, and be transparent about what packages are being installed and why they are needed.
26
+ - Do not modify any system-level configurations or settings, and do not run any commands that could affect the system or other users without explicit user permission. Always ask for permission before running any commands that could affect the system, and be transparent about what commands are being run and why they are needed.
27
+
28
+ ## Command execution guardrails
29
+
30
+ Allowed without prompt:
31
+ - read files
32
+ - list files
33
+ - modify scripts
34
+ - modify config files
35
+
36
+ Ask for permission:
37
+ - software/package installation
38
+ - network access
39
+ - git push or pull
40
+ - chmod
41
+ - API access
42
+ - modification of any non-script or non-config files
43
+ - any command that could delete files, or any script that has the potential to delete files
44
+
45
+ ### Specific rules
46
+
47
+ - Do not run destructive file deletion commands such as `rm`, `find -delete`, or scripted equivalents.
48
+ - Do not run git-destructive commands such as `git reset --hard`, `git clean -fd`, or `git checkout --`.
49
+ - If deletion is required, ask the user first and wait for explicit confirmation.
50
+ - Never ever delete a file without asking permission.
51
+
52
+ #### Sandbox / bwrap troubleshooting
53
+
54
+ - For simple read-only shell commands, pass the plain command directly to the terminal tool.
55
+ - Do not manually wrap simple commands in `bash -lc ...`; the terminal tool already provides the shell wrapper.
56
+ - Do not wrap simple read-only commands in `conda run -n <project env> bash -lc ...`.
57
+ - In this project, simple read-only commands include:
58
+ - `ls`
59
+ - `sed`
60
+ - `awk`
61
+ - `cat`
62
+ - `grep`
63
+ - `rg`
64
+ - `echo`
65
+ - For commands that actually require the conda environment, use `conda run -n <project env> ...` directly.
66
+ - If you encounter an error like `bwrap: Unknown option --argv0`, first simplify the command to the plain direct form above rather than retrying nested wrapper forms.
67
+ - Never fabricate a repository summary or workflow description when local file reads are failing.
68
+
69
+ ## Coding rules
70
+
71
+ - Never insert silent fallbacks or error handling that could hide errors or issues from the user. Always be transparent about any errors or issues that occur, and do not attempt to handle them without user knowledge and permission.
72
+ - Never insert silent fallbacks that do not achieve the stated objective of the code.
73
+ - Never hide errors in scripts or workflows. If there is an error the script should fail. Errors are useful and necessary information so it is counterproductive to hide them.
74
+ - Never modify tests in any way without explicit user permission.
75
+
76
+ ## Data analysis rules
77
+
78
+ - Never modify notebooks or parts of notebooks that are not related to the user's request.
79
+ - Notebooks should contain sections the clearly define all filtering, assumptions, and definitions of terms relevant for understanding the results of the analysis.
80
+ - Always be explicit about how data is categorized/binned/clustered by adding text to the notebook or plot. This text should both be plain for interpretation and technical to understand the underlying code.
81
+ - Accompanying every plot or analysis should be plain text that aids in the interpretation of said plot or analysis.
82
+
83
+ ## Network access guardrails
84
+
85
+ - Never send or share any data outside of the project directory, and never share any data with third parties without explicit user permission.
86
+ - Never send data via any network, API, or external service without explicit user permission.
87
+ - Always ask for permission before sharing any data, and be transparent about what data is being shared.
88
+
89
+ ## Code of conduct
90
+
91
+ - Never ever make up, mock, simulate, fabricate, or lie about input data or outputs.
92
+ - If simulated data is needed, always ask the user for permission to create it, and be transparent about the fact that it is simulated.
93
+ - Never hide errors in scripts or workflows. If there is an error the script should fail. Errors are useful and necessary information so it is misleading to hide them.
@@ -0,0 +1,22 @@
1
+ # mafutils Development Notes
2
+
3
+ - `tests/example.maf.scaffold.idx` is preserved as an older scaffold-index
4
+ fixture for comparison.
5
+ - `tests/example.maf.scaffold.regenerated.idx` is the scaffold index produced
6
+ by the current `mafutils index` implementation.
7
+ - The real production scaffold indexes checked so far match the regenerated
8
+ convention, not the preserved older fixture.
9
+
10
+ ## Releasing to PyPI
11
+
12
+ - Publishing is triggered by pushing a Git tag that matches `v*` (for example
13
+ `v0.1.1`).
14
+ - Ensure the GitHub repository secret `PYPI_API_TOKEN` is set before releasing.
15
+ - Commit release-related changes first, then create and push the tag:
16
+
17
+ ```bash
18
+ git add .github/workflows/publish-pypi.yml pyproject.toml README.md DEVELOPMENT.md
19
+ git commit -m "release: prepare v0.1.1"
20
+ git tag -a v0.1.1 -m "v0.1.1"
21
+ git push origin main v0.1.1
22
+ ```
mafutils-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harvard Informatics
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.4
2
+ Name: mafutils
3
+ Version: 0.1.1
4
+ Summary: Utilities for indexing, fetching, and summarizing MAFs.
5
+ Author: Gregg Thomas
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Harvard Informatics
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://informatics.fas.harvard.edu/
29
+ Project-URL: Repository, https://github.com/harvardinformatics/mafutils
30
+ Project-URL: Issues, https://github.com/harvardinformatics/mafutils/issues
31
+ Keywords: maf,comparative-genomics,bioinformatics
32
+ Requires-Python: >=3.9
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Requires-Dist: typer
36
+ Dynamic: license-file
37
+
38
+ # mafutils
39
+
40
+ `mafutils` is a command-line toolkit for indexing, extracting, and summarizing
41
+ MAF (Multiple Alignment Format) files.
42
+
43
+ It currently provides three commands:
44
+
45
+ - `mafutils index`
46
+ - `mafutils fetch`
47
+ - `mafutils stats`
48
+
49
+ ## Disclaimer
50
+
51
+ This project was developed with significant assistance from a large language model (GPT-5 / Codex).
52
+
53
+ ## Installation
54
+
55
+ From this `mafutils/` directory:
56
+
57
+ ```bash
58
+ pip install -e .
59
+ ```
60
+
61
+ If you are using the current shared workflow environment instead of a separate
62
+ package environment, you can also run it directly with:
63
+
64
+ ```bash
65
+ python -m mafutils --help
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ Show top-level help:
71
+
72
+ ```bash
73
+ python -m mafutils --help
74
+ ```
75
+
76
+ Create block and scaffold indexes for a MAF:
77
+
78
+ ```bash
79
+ python -m mafutils index input.maf output.block.idx output.scaffold.idx
80
+ ```
81
+
82
+ Fetch trimmed MAF regions from a BED file:
83
+
84
+ ```bash
85
+ python -m mafutils fetch input.maf input.block.idx regions.bed -o outdir
86
+ ```
87
+
88
+ Fetch FASTA output instead of MAF:
89
+
90
+ ```bash
91
+ python -m mafutils fetch input.maf input.block.idx regions.bed -o outdir -f -fh species-coords-id
92
+ ```
93
+
94
+ Extract full scaffolds using a scaffold index:
95
+
96
+ ```bash
97
+ python -m mafutils fetch input.maf input.scaffold.idx scaffolds.bed -m scaffold -o outdir
98
+ ```
99
+
100
+ Summarize an indexed MAF:
101
+
102
+ ```bash
103
+ python -m mafutils stats input.maf input.block.idx -o summary/example
104
+ ```
105
+
106
+ ## Commands
107
+
108
+ ### `mafutils index`
109
+
110
+ Create block and scaffold indexes for a MAF file.
111
+
112
+ ```bash
113
+ python -m mafutils index MAF_FILE BLOCK_INDEX SCAFFOLD_INDEX
114
+ ```
115
+
116
+ Arguments:
117
+
118
+ | Argument | Description |
119
+ |---|---|
120
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
121
+ | `BLOCK_INDEX` | Output block index path |
122
+ | `SCAFFOLD_INDEX` | Output scaffold index path |
123
+
124
+ ### `mafutils fetch`
125
+
126
+ Fetch regions or scaffolds from a MAF using an existing index.
127
+
128
+ ```bash
129
+ python -m mafutils fetch [OPTIONS] MAF_FILE INDEX_FILE BED_FILE
130
+ ```
131
+
132
+ Arguments:
133
+
134
+ | Argument | Description |
135
+ |---|---|
136
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
137
+ | `INDEX_FILE` | Block-level or scaffold-level index |
138
+ | `BED_FILE` | BED file with regions or scaffold names |
139
+
140
+ Options:
141
+
142
+ | Option | Description |
143
+ |---|---|
144
+ | `--basename`, `-b` | Output basename strategy: `id`, `coords`, or `count` |
145
+ | `--output`, `-o` | Output directory or output filename in single-output mode |
146
+ | `--fasta`, `-f` | Write FASTA instead of MAF |
147
+ | `--fasta-header`, `-fh` | FASTA header format: `species-coords-id`, `species-coords`, or `species-only` |
148
+ | `--expected-species` | Comma-separated expected species list for FASTA filling |
149
+ | `--expected-species-file` | File with one expected species name per line |
150
+ | `--fasta-dedupe` | FASTA duplicate handling: `none` or `most-seq` |
151
+ | `--processes`, `-p` | Number of worker processes |
152
+ | `--mode`, `-m` | Fetch mode: `block` or `scaffold` |
153
+ | `--verbose` | Emit warning lines from each completed batch |
154
+ | `--profile` | Log internal timing breakdowns |
155
+
156
+ ### `mafutils stats`
157
+
158
+ Summarize an indexed MAF at overall, species, and block levels.
159
+
160
+ ```bash
161
+ python -m mafutils stats [OPTIONS] MAF_FILE INDEX_FILE
162
+ ```
163
+
164
+ Arguments:
165
+
166
+ | Argument | Description |
167
+ |---|---|
168
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
169
+ | `INDEX_FILE` | Block index produced by `mafutils index` |
170
+
171
+ Options:
172
+
173
+ | Option | Description |
174
+ |---|---|
175
+ | `--output-prefix`, `-o` | Output prefix/path |
176
+ | `--processes`, `-p` | Number of worker processes |
177
+ | `--chunk-size` | Blocks per worker task |
178
+ | `--no-block-table` | Skip writing the per-block table |
179
+ | `--expected-species` | Comma-separated species names for exact missing lists |
180
+ | `--expected-species-file` | File with one species name per line |
181
+ | `--log-level` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
182
+ | `--html-dashboard` | Write an HTML summary dashboard |
183
+ | `--dashboard-top-species` | Number of species shown in dashboard bar plots |
184
+ | `--dashboard-max-block-points` | Maximum block rows sampled for dashboard plots |
185
+
186
+ ## Testing
187
+
188
+ From inside this `mafutils/` directory:
189
+
190
+ ```bash
191
+ pytest tests/test_fetch.py
192
+ ```
193
+
194
+ ## Notes
195
+
196
+ - `python -m mafutils ...` is the supported invocation from a source checkout.
197
+ - The installed console entrypoint is `mafutils ...` once the package is
198
+ installed.
@@ -0,0 +1,161 @@
1
+ # mafutils
2
+
3
+ `mafutils` is a command-line toolkit for indexing, extracting, and summarizing
4
+ MAF (Multiple Alignment Format) files.
5
+
6
+ It currently provides three commands:
7
+
8
+ - `mafutils index`
9
+ - `mafutils fetch`
10
+ - `mafutils stats`
11
+
12
+ ## Disclaimer
13
+
14
+ This project was developed with significant assistance from a large language model (GPT-5 / Codex).
15
+
16
+ ## Installation
17
+
18
+ From this `mafutils/` directory:
19
+
20
+ ```bash
21
+ pip install -e .
22
+ ```
23
+
24
+ If you are using the current shared workflow environment instead of a separate
25
+ package environment, you can also run it directly with:
26
+
27
+ ```bash
28
+ python -m mafutils --help
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ Show top-level help:
34
+
35
+ ```bash
36
+ python -m mafutils --help
37
+ ```
38
+
39
+ Create block and scaffold indexes for a MAF:
40
+
41
+ ```bash
42
+ python -m mafutils index input.maf output.block.idx output.scaffold.idx
43
+ ```
44
+
45
+ Fetch trimmed MAF regions from a BED file:
46
+
47
+ ```bash
48
+ python -m mafutils fetch input.maf input.block.idx regions.bed -o outdir
49
+ ```
50
+
51
+ Fetch FASTA output instead of MAF:
52
+
53
+ ```bash
54
+ python -m mafutils fetch input.maf input.block.idx regions.bed -o outdir -f -fh species-coords-id
55
+ ```
56
+
57
+ Extract full scaffolds using a scaffold index:
58
+
59
+ ```bash
60
+ python -m mafutils fetch input.maf input.scaffold.idx scaffolds.bed -m scaffold -o outdir
61
+ ```
62
+
63
+ Summarize an indexed MAF:
64
+
65
+ ```bash
66
+ python -m mafutils stats input.maf input.block.idx -o summary/example
67
+ ```
68
+
69
+ ## Commands
70
+
71
+ ### `mafutils index`
72
+
73
+ Create block and scaffold indexes for a MAF file.
74
+
75
+ ```bash
76
+ python -m mafutils index MAF_FILE BLOCK_INDEX SCAFFOLD_INDEX
77
+ ```
78
+
79
+ Arguments:
80
+
81
+ | Argument | Description |
82
+ |---|---|
83
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
84
+ | `BLOCK_INDEX` | Output block index path |
85
+ | `SCAFFOLD_INDEX` | Output scaffold index path |
86
+
87
+ ### `mafutils fetch`
88
+
89
+ Fetch regions or scaffolds from a MAF using an existing index.
90
+
91
+ ```bash
92
+ python -m mafutils fetch [OPTIONS] MAF_FILE INDEX_FILE BED_FILE
93
+ ```
94
+
95
+ Arguments:
96
+
97
+ | Argument | Description |
98
+ |---|---|
99
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
100
+ | `INDEX_FILE` | Block-level or scaffold-level index |
101
+ | `BED_FILE` | BED file with regions or scaffold names |
102
+
103
+ Options:
104
+
105
+ | Option | Description |
106
+ |---|---|
107
+ | `--basename`, `-b` | Output basename strategy: `id`, `coords`, or `count` |
108
+ | `--output`, `-o` | Output directory or output filename in single-output mode |
109
+ | `--fasta`, `-f` | Write FASTA instead of MAF |
110
+ | `--fasta-header`, `-fh` | FASTA header format: `species-coords-id`, `species-coords`, or `species-only` |
111
+ | `--expected-species` | Comma-separated expected species list for FASTA filling |
112
+ | `--expected-species-file` | File with one expected species name per line |
113
+ | `--fasta-dedupe` | FASTA duplicate handling: `none` or `most-seq` |
114
+ | `--processes`, `-p` | Number of worker processes |
115
+ | `--mode`, `-m` | Fetch mode: `block` or `scaffold` |
116
+ | `--verbose` | Emit warning lines from each completed batch |
117
+ | `--profile` | Log internal timing breakdowns |
118
+
119
+ ### `mafutils stats`
120
+
121
+ Summarize an indexed MAF at overall, species, and block levels.
122
+
123
+ ```bash
124
+ python -m mafutils stats [OPTIONS] MAF_FILE INDEX_FILE
125
+ ```
126
+
127
+ Arguments:
128
+
129
+ | Argument | Description |
130
+ |---|---|
131
+ | `MAF_FILE` | Input MAF file (`.maf` or `.maf.gz`) |
132
+ | `INDEX_FILE` | Block index produced by `mafutils index` |
133
+
134
+ Options:
135
+
136
+ | Option | Description |
137
+ |---|---|
138
+ | `--output-prefix`, `-o` | Output prefix/path |
139
+ | `--processes`, `-p` | Number of worker processes |
140
+ | `--chunk-size` | Blocks per worker task |
141
+ | `--no-block-table` | Skip writing the per-block table |
142
+ | `--expected-species` | Comma-separated species names for exact missing lists |
143
+ | `--expected-species-file` | File with one species name per line |
144
+ | `--log-level` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
145
+ | `--html-dashboard` | Write an HTML summary dashboard |
146
+ | `--dashboard-top-species` | Number of species shown in dashboard bar plots |
147
+ | `--dashboard-max-block-points` | Maximum block rows sampled for dashboard plots |
148
+
149
+ ## Testing
150
+
151
+ From inside this `mafutils/` directory:
152
+
153
+ ```bash
154
+ pytest tests/test_fetch.py
155
+ ```
156
+
157
+ ## Notes
158
+
159
+ - `python -m mafutils ...` is the supported invocation from a source checkout.
160
+ - The installed console entrypoint is `mafutils ...` once the package is
161
+ installed.
@@ -0,0 +1,3 @@
1
+ """Reusable MAF toolkit package for indexing, fetching, and summarizing MAFs."""
2
+
3
+ __all__ = ["cli", "fetch", "index", "stats"]
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.1'
22
+ __version_tuple__ = version_tuple = (0, 1, 1)
23
+
24
+ __commit_id__ = commit_id = 'gd532d75e9'
@@ -0,0 +1,20 @@
1
+ import typer
2
+
3
+ from . import fetch as fetch_mod
4
+ from . import index as index_mod
5
+ from . import stats as stats_mod
6
+
7
+
8
+ app = typer.Typer(
9
+ help="MAF toolkit for indexing, fetching, and summarizing MAF alignments.",
10
+ no_args_is_help=True,
11
+ pretty_exceptions_show_locals=False,
12
+ context_settings={"help_option_names": ["-h", "--help"]},
13
+ )
14
+ app.command("fetch", help="Fetch alignment blocks from a MAF using a BED file and an existing index.")(fetch_mod.fetch_command)
15
+ app.command("index", help="Create block and scaffold indexes for a MAF file.")(index_mod.index_command)
16
+ app.command("stats", help="Summarize an indexed MAF at overall, species, and block levels.")(stats_mod.stats_command)
17
+
18
+
19
+ def main() -> None:
20
+ app()