Skip to content

Commit e4d3f3b

Browse files
authored
feat/report header (#36)
* feat(report parser): Detect a header line in the report file and skip. If the first line of a kraken report is all strings and 6 fields - assume its a header line and skip with a warning. * feat(report parser): More informative error messages Adds line number and line context to errors bumps version to 3.1.0 * docs: update readme and changelog with 3.1.0 features * build: update kractor version to 3.1.0
1 parent 731a17d commit e4d3f3b

8 files changed

Lines changed: 218 additions & 54 deletions

File tree

CHANGELOG.md

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,118 +5,160 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.1.0] - 2025-12-12
9+
10+
### Added
11+
12+
- Attempt to detect headers in kraken report files and skip if it looks like a header. It does this by checking if there
13+
are 6 fields that are all strings (or more precisely if each field returns an error when parsing into an int/float).
14+
If so,
15+
it is assumed that this line is a header and is skipped. A warning message is printed in this case.
16+
- `--no-header-detect` flag to force parsing Kraken reports from the first line without auto-skipping headers, disabling
17+
the new header detection behaviour described above
18+
19+
### Changed
20+
21+
- Kraken report/output parsing errors now include the line number and o line for easier debugging.
22+
823
## [3.0.1] - 2025-10-16
924

1025
### Fixed
26+
1127
- Prevent a panic when writing to output paths without an extension.
1228

1329
## [3.0.0] - 2025-09-26
1430

1531
### Added
16-
- Able to specifiy taxon ids that are not present, without kractor stopping. These are instead logged to stderr with a warning. This may be useful when running kractor in a wrapper script for several fastq files and just want to extract a set of taxonids from them all - without caring if they are present or not.
32+
33+
- Able to specifiy taxon ids that are not present, without kractor stopping. These are instead logged to stderr with a
34+
warning. This may be useful when running kractor in a wrapper script for several fastq files and just want to extract
35+
a set of taxonids from them all - without caring if they are present or not.
1736
- Include a new field `missing_taxon_ids` in the summary output.
1837

1938
### Changed
20-
- Under the hood refactoring, introducing structs for the processed kraken outputs and processed kraken trees to simplify the returned data.
39+
40+
- Under the hood refactoring, introducing structs for the processed kraken outputs and processed kraken trees to
41+
simplify the returned data.
2142

2243
### Fixed
23-
- Unclassified reads being skipped in the tree building stage, meaning they were unable to be extracted
44+
45+
- Unclassified reads being skipped in the tree building stage, meaning they were unable to be extracted
2446

2547
## [2.0.0] - 2025-08-12
2648

2749
### Added
50+
2851
- Added a `reads_extracted_per_taxon` field to to summary report (#28)
2952
- Added a `proportion_extracted` field to summary report (#28)
3053
- Added the version to summary report (#28)
3154
- Added an output format (`fasta` or `fastq`) field to the summary report (#28)
3255
- Added a `--verbose` flag (in addition to the existing `-v`)
3356

3457
### Changed
58+
3559
- Removed `-O` for compression type, now uses `--compression-format` for clarity.
3660
- Removed `-l` for compression level, now uses `--compression-level` for clarity.
3761
- Renamed `--json-report` to `--summary`
38-
- Improved the JSON report format to make it easier to read by removing `Paired` and `Single` fields and instead having a simple `total_reads_in` and `total_reads_out` field.
62+
- Improved the JSON report format to make it easier to read by removing `Paired` and `Single` fields and instead having
63+
a simple `total_reads_in` and `total_reads_out` field.
3964

4065
### Fixed
66+
4167
- Removed duplicate log message for taxon IDs identified
4268
- Clippy warnings
4369

4470
## [1.0.1] - 2025-06-28
4571

4672
### Fixed
73+
4774
- Create subdirectories specified in output path if they don't exist (#24)
4875
- Add output validation to prevent overwriting existing files (#25)
4976

5077
## [1.0.0] - 2025-04-16
5178

5279
### Added
80+
5381
- Better error handling with color-eyre (#16)
5482
- Proper panic handling (#16)
5583
- Tests for most functions
5684
- JSON report with accurate read count information (#15)
5785

5886
### Changed
87+
5988
- Keep fastq parsing in bytes instead of converting to String (#17)
6089
- Optimized functions to take `&str` instead of `String` (#21)
6190
- Migrated to crossbeam scoped channels and refactored threading code
6291
- Refactored JSON output and removed lazy_static dependency
6392

6493
### Fixed
94+
6595
- Root node no longer added to tree twice (#22)
6696

6797
## [0.4.0] - 2023-10-06
6898

6999
### Added
100+
70101
- JSON report included in stdout upon successful completion (can be disabled with `--no-json`)
71102

72103
### Changed
104+
73105
- Project renamed
74106

75107
## [0.3.0] - 2023-09-22
76108

77109
### Added
110+
78111
- Support for paired-end files
79112
- Output FASTA file with `--output-fasta` option
80113

81114
### Changed
115+
82116
- Major refactor to use Noodles for fastq parsing
83117
- Switched to Niffler for compression handling
84118
- Streamlined arguments related to compression types/level
85119

86120
### Improved
121+
87122
- Logging functionality
88123

89124
## [0.2.3] - 2023-09-02
90125

91126
### Changed
127+
92128
- Code optimizations
93129

94130
## [0.2.2]
95131

96132
### Added
133+
97134
- `--no-compress` flag to output standard plaintext fastq files
98135
- `--exclude` option to exclude specified reads (works with `--children` and `--parents`)
99136
- Internal documentation (docstrings)
100137

101138
### Improved
139+
102140
- Increased verbosity of user outputs
103141

104142
## [0.2.1]
105143

106144
### Fixed
145+
107146
- Reduced memory usage
108147

109148
## [0.2.0]
110149

111150
### Added
151+
112152
- Automatic detection and handling of gz and plain files
113153
- `--compression` argument to select compression type
114154
- `--children` and `--parents` options to save children and parents based on kraken report
115155

116156
### Changed
157+
117158
- Integrated zlib-ng for faster gzip handling
118159

119160
## [0.1.0]
120161

121162
### Added
163+
122164
- Initial release

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "kractor"
3-
version = "3.0.1"
3+
version = "3.1.0"
44
edition = "2021"
55
authors = ["Samuel Sims"]
66
description = "Extract reads from a FASTQ file based on taxonomic classification via Kraken2."

README.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,29 @@
1010

1111
**kra**ken extr**actor**
1212

13-
Kractor extracts reads from fastq `[.gz/.bz2]` files using taxonomic classifications obtained via Kraken2.
14-
It supports single or paired-end reads, can optionally include taxonomic parents or children, and uses minimal memory (~4.5 MB for a 17 GB FASTQ file).
13+
Kractor extracts reads from fastq `[.gz/.bz2]` files using taxonomic classifications obtained via Kraken2.
14+
It supports single or paired-end reads, can optionally include taxonomic parents or children, and uses minimal memory (~
15+
4.5 MB for a 17 GB FASTQ file).
1516

1617
The end result is a `fast[q/a]` file containing all reads classified as the specified taxon(s).
1718

1819
Kractor significantly enhances processing speed compared to KrakenTools for both paired and unpaired reads.
1920

2021
Performance vs KrakenTools:
21-
- Paired compressed FASTQ: ~21× faster
22-
- Paired uncompressed FASTQ: ~10× faster
22+
23+
- Paired compressed FASTQ: ~21× faster
24+
- Paired uncompressed FASTQ: ~10× faster
2325
- Unpaired: ~4× faster (compressed or uncompressed)
2426

2527
For additional details, refer to the [benchmarks](benchmarks/benchmarks.md)
2628

2729
## Motivation
2830

29-
Provides similar functionality to the [KrakenTools](https://github.com/jenniferlu717/KrakenTools) `extract_kraken_reads` python script.
31+
Provides similar functionality to the [KrakenTools](https://github.com/jenniferlu717/KrakenTools) `extract_kraken_reads`
32+
python script.
3033

31-
However the main motivation was to enhance speed when processing multiple, large FASTQ files - and as a way to learn Rust.
34+
However the main motivation was to enhance speed when processing multiple, large FASTQ files - and as a way to learn
35+
Rust.
3236

3337
## Installation
3438

@@ -115,6 +119,8 @@ Options:
115119
Output results in FASTA format
116120
--summary
117121
Enable a JSON summary output written to stdout
122+
--no-header-detect
123+
Disable detection and skipping of header lines in the Kraken2 report
118124
-v, --verbose
119125
Enable verbose output
120126
-h, --help
@@ -146,7 +152,9 @@ kractor -i sample.fastq -o extracted.fasta -k kraken_output.txt -t 562 --output-
146152
```
147153

148154
### Summary statistics
155+
149156
Use `--summary` to get summary statistics (output to stdout on completion)
157+
150158
```json
151159
{
152160
"total_taxon_count": 2,
@@ -162,7 +170,7 @@ Use `--summary` to get summary statistics (output to stdout on completion)
162170
"proportion_extracted": 0.2140419091180432,
163171
"input_format": "single",
164172
"output_format": "fastq",
165-
"kractor_version": "2.0.0"
173+
"kractor_version": "3.1.0"
166174
}
167175
```
168176

@@ -174,7 +182,7 @@ Use `--summary` to get summary statistics (output to stdout on completion)
174182

175183
`-i, --input`
176184

177-
Specifies one or two input FASTQ files to extract reads from. Files may be uncompressed or compressed (`gz`, `bz2`).
185+
Specifies one or two input FASTQ files to extract reads from. Files may be uncompressed or compressed (`gz`, `bz2`).
178186
Paired end reads can be specified by:
179187

180188
Using `--input` twice: `-i <R1_fastq_file> -i <R2_fastq_file>`
@@ -185,47 +193,53 @@ Using `--input` once but passing both files: `-i <R1_fastq_file> <R2_fastq_file>
185193

186194
`-o, --output`
187195

188-
Specifies the output file(s) for extracted reads, matching the order of the input files.
196+
Specifies the output file(s) for extracted reads, matching the order of the input files.
189197
Compression type is inferred from the file extension (.gz, .bz2). If not recognised, output will be uncompressed.
190198

191199
#### Kraken Output
192200

193201
`-k, --kraken`
194202

195-
Path to the [Standard Kraken Output Format file](https://github.com/DerrickWood/kraken2/wiki/Manual#standard-kraken-output-format), containing taxonomic classification of read IDs.
203+
Path to
204+
the [Standard Kraken Output Format file](https://github.com/DerrickWood/kraken2/wiki/Manual#standard-kraken-output-format),
205+
containing taxonomic classification of read IDs.
196206

197207
#### Taxid
198208

199209
`-t, --taxid`
200210

201-
One or more taxonomic IDs to extract.
211+
One or more taxonomic IDs to extract.
202212

203213
For example: `-t 1 2 10`
204214

205215
Each taxonomic id is affected by `--exclude`, `--parents`, and `--children` if those options are used.
206216

207-
Taxonomic ids do not need to be present in a given report. This may be useful when running kractor in a wrapper script for several fastq files and just want to extract a set of taxon ids from them all - without caring if they are present or not.
217+
Taxonomic ids do not need to be present in a given report. This may be useful when running kractor in a wrapper script
218+
for several fastq files and just want to extract a set of taxon ids from them all - without caring if they are present
219+
or not.
208220

209221
### Optional:
210222

211223
#### Output type
212224

213225
`--compression-format`
214226

215-
Manually set output compression format, overriding what is inferred from file names.
227+
Manually set output compression format, overriding what is inferred from file names.
216228

217229
Valid values:
218-
- `gz` – gzip compression
219-
- `bz2` – bzip2 compression
230+
231+
- `gz` – gzip compression
232+
- `bz2` – bzip2 compression
220233
- `none` – no compression
221234

222235
#### Compression level
223236

224237
`--compression-level`
225238

226-
Set compression level (1–9).
227-
- 1 = fastest, largest file
228-
- 9 = slowest, smallest file
239+
Set compression level (1–9).
240+
241+
- 1 = fastest, largest file
242+
- 9 = slowest, smallest file
229243

230244
Default: 2 (balance of speed and size)
231245

@@ -239,7 +253,12 @@ Output sequences in FASTA format instead of FASTQ.
239253

240254
`-r, --report`
241255

242-
Path to the [Kraken2 report file](https://github.com/DerrickWood/kraken2/wiki/Manual#sample-report-output-format). Required if using `--parents` or `--children`.
256+
Path to the [Kraken2 report file](https://github.com/DerrickWood/kraken2/wiki/Manual#sample-report-output-format).
257+
Required if using `--parents` or `--children`.
258+
259+
The first line is automatically treated as a header if it looks non-numeric; use `--no-header-detect` to force parsing
260+
from the very first line. Parsing errors will include the report line number and offending line to help spot format
261+
issues.
243262

244263
#### Parents
245264

@@ -265,8 +284,10 @@ Extract all reads except those matching the given taxids. Can be combined with `
265284

266285
Write a JSON report to stdout after processing.
267286

268-
## Citation
287+
## Citation
288+
269289
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15761837.svg)](https://doi.org/10.5281/zenodo.15761837)
290+
270291
```
271292
Sam Sims. (2025). Sam-Sims/kractor. Zenodo. https://doi.org/10.5281/zenodo.15761837
272-
```
293+
```

src/cli.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ pub struct Cli {
4848
/// Enable a JSON summary output written to stdout.
4949
#[arg(long = "summary")]
5050
pub summary: bool,
51+
/// Disable detection and skipping of any header lines in the Kraken2 report.
52+
#[arg(long = "no-header-detect", action)]
53+
pub no_report_header_detect: bool,
5154
/// Enable verbose output.
5255
#[arg(short, long)]
5356
pub verbose: bool,

0 commit comments

Comments
 (0)