countmut 0.0.2__tar.gz → 0.0.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: countmut
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Ultra-fast strand-aware mutation counter
5
5
  Author-email: Ye Chang <yech1990@gmail.com>
6
6
  License-Expression: MIT
@@ -41,13 +41,13 @@ Dynamic: license-file
41
41
  [![Downloads](https://img.shields.io/pepy/dt/countmut)](https://pepy.tech/project/countmut)
42
42
  [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/y9c/countmut)
43
43
 
44
- **Ultra-fast strand-aware mutation counter**
44
+ > **Ultra-fast strand-aware mutation counter for bisulfite sequencing analysis**
45
45
 
46
- CountMut counts mutations from bisulfite sequencing / CAM-seq / GLORI-seq / eTAM-seq BAM files with parallel processing, quality-based mate overlap deduplication, and optimized file I/O.
46
+ CountMut is a high-performance tool for counting mutations from bisulfite sequencing BAM files (BS-seq, CAM-seq, GLORI-seq, eTAM-seq). It features parallel processing, quality-based mate overlap deduplication, and optimized file I/O for maximum speed.
47
47
 
48
48
  ## Features
49
49
 
50
- - 🚀 **Ultra-Fast**: Direct FASTA index reading, shared file handles, BGZF multi-threading
50
+ - 🚀 **Ultra-Fast**: Call mutation without pileup reads
51
51
  - 🧬 **Bisulfite Support**: NS, Zf, Yf tag filtering for conversion analysis
52
52
  - 🎯 **Accurate**: Quality-based mate overlap deduplication prevents double-counting
53
53
  - ⚡ **Parallel**: Multi-threaded genomic window processing
@@ -72,51 +72,68 @@ countmut -i input.bam -r reference.fa -o mutations.tsv --ref-base T --mut-base C
72
72
  countmut -i input.bam -r reference.fa -o mutations.tsv -t 8 --max-unc 5 --min-con 2
73
73
  ```
74
74
 
75
- ## Key Options
75
+ ## Options
76
76
 
77
+ **Input/Output**
77
78
  ```bash
78
- Required:
79
- -i, --input PATH Input BAM file
80
- -r, --reference PATH Reference FASTA file
81
-
82
- Output:
83
- -o, --output PATH Output TSV file (default: stdout)
84
-
85
- Mutation:
86
- --ref-base TEXT Reference base [default: A]
87
- --mut-base TEXT Mutation base [default: G]
88
- --strand [both|forward|reverse] Strand processing [default: both]
89
- --region TEXT Specific region (e.g., 'chr1:1000000-2000000')
90
-
91
- Performance:
92
- -t, --threads INTEGER Number of threads [default: auto]
93
- -b, --bin-size INTEGER Genomic bin size [default: 10000]
94
-
95
- Filtering (Bisulfite):
96
- --pad INTEGER Motif window padding [default: 15]
97
- --trim-start INTEGER Trim 5' bases [default: 2]
98
- --trim-end INTEGER Trim 3' bases [default: 2]
99
- --max-unc INTEGER Max unconverted (Zf) [default: 3]
100
- --min-con INTEGER Min converted (Yf) [default: 1]
101
- --max-sub INTEGER Max substitutions (NS) [default: 1]
102
- --min-baseq INTEGER Min base quality (Phred) [default: 20]
103
- --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
79
+ -i, --input PATH Input BAM file (coordinate-sorted) [required]
80
+ -r, --reference PATH Reference FASTA file [required]
81
+ -o, --output PATH Output TSV file (default: stdout)
82
+ -f, --force Overwrite output without prompting
104
83
  ```
105
84
 
106
- **Note**: BAM must have NS, Zf, and Yf tags for bisulfite analysis.
85
+ **Mutation Analysis**
86
+ ```bash
87
+ --ref-base TEXT Reference base to count from [default: A]
88
+ --mut-base TEXT Mutation base to count [default: G]
89
+ --strand TEXT Strand: both/forward/reverse [default: both]
90
+ --region TEXT Genomic region (e.g., 'chr1:1000000-2000000')
91
+ ```
107
92
 
108
- ## Output Format
93
+ **Performance**
94
+ ```bash
95
+ -t, --threads INTEGER Number of parallel threads [default: auto]
96
+ -b, --bin-size INTEGER Genomic bin size in bp [default: 10000]
97
+ ```
109
98
 
110
- TSV file with columns:
111
- - `chrom`, `pos`, `strand`, `motif` - Position and sequence context
112
- - `u0`, `u1`, `u2` - Unconverted (reference base) counts [drop, clean, unconverted]
113
- - `m0`, `m1`, `m2` - Mutation (mutation base only) counts [drop, clean, unconverted]
114
- - `o0`, `o1`, `o2` - Other bases counts [drop, clean, unconverted] (only with `--save-rest`)
99
+ **Quality Filters**
100
+ ```bash
101
+ --min-baseq INTEGER Min base quality (Phred score) [default: 20]
102
+ --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
103
+ --max-sub INTEGER Max substitutions (NS tag) [default: 1]
104
+ --trim-start INTEGER Trim 5' bases from reads [default: 2]
105
+ --trim-end INTEGER Trim 3' bases from reads [default: 2]
106
+ --max-unc INTEGER Max unconverted (Zf tag) [default: 3]
107
+ --min-con INTEGER Min converted (Yf tag) [default: 1]
108
+ ```
109
+
110
+ **Output Records**
111
+ ```bash
112
+ -p, --pad INTEGER Motif window half-size [default: 15]
113
+ -s, --save-rest Include other bases (o0, o1, o2 columns)
114
+ ```
115
+
116
+ > **Note**: BAM files must have **NS**, **Zf**, and **Yf** tags (essential for bisulfite analysis).
117
+ > Indices (.bai, .fai) are created automatically if missing.
118
+
119
+ ## Output Format
115
120
 
116
- Where:
117
- - **drop** (x0): Bases failing quality filters (internal position, mismatch, mapq, baseq)
118
- - **clean** (x1): High-quality bases passing all filters
119
- - **unconverted** (x2): Bases in unconverted reads (high Zf or low Yf)
121
+ TSV file with the following columns:
122
+
123
+ | Column | Description |
124
+ |--------|-------------|
125
+ | `chrom` | Chromosome name |
126
+ | `pos` | Genomic position (1-based) |
127
+ | `strand` | Strand (+ or -) |
128
+ | `motif` | Sequence context (2×pad+1 bp window) |
129
+ | `u0`, `u1`, `u2` | **Unconverted** (reference base) counts |
130
+ | `m0`, `m1`, `m2` | **Mutation** (mutation base only) counts |
131
+ | `o0`, `o1`, `o2` | **Other bases** counts (with `--save-rest`) |
132
+
133
+ **Count categories** (x0, x1, x2):
134
+ - **x0 (low quality)**: Bases failing quality filters (trim region, max-sub, min-mapq, min-baseq)
135
+ - **x1 (high conversion)**: Bases from reads with high conversion efficiency (low Zf and high Yf)
136
+ - **x2 (insufficient conversion)**: Bases from reads with insufficient conversion efficiency (high Zf or low Yf)
120
137
 
121
138
 
122
139
  &nbsp;
@@ -0,0 +1,117 @@
1
+ # CountMut
2
+
3
+ [![Pypi Releases](https://img.shields.io/pypi/v/countmut.svg)](https://pypi.python.org/pypi/countmut)
4
+ [![Downloads](https://img.shields.io/pepy/dt/countmut)](https://pepy.tech/project/countmut)
5
+ [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/y9c/countmut)
6
+
7
+ > **Ultra-fast strand-aware mutation counter for bisulfite sequencing analysis**
8
+
9
+ CountMut is a high-performance tool for counting mutations from bisulfite sequencing BAM files (BS-seq, CAM-seq, GLORI-seq, eTAM-seq). It features parallel processing, quality-based mate overlap deduplication, and optimized file I/O for maximum speed.
10
+
11
+ ## Features
12
+
13
+ - 🚀 **Ultra-Fast**: Call mutation without pileup reads
14
+ - 🧬 **Bisulfite Support**: NS, Zf, Yf tag filtering for conversion analysis
15
+ - 🎯 **Accurate**: Quality-based mate overlap deduplication prevents double-counting
16
+ - ⚡ **Parallel**: Multi-threaded genomic window processing
17
+ - 🔧 **Flexible**: Configurable filtering, strand-specific processing, auto-indexing
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install countmut
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ # Basic usage - auto-creates indices if needed
29
+ countmut -i input.bam -r reference.fa -o mutations.tsv
30
+
31
+ # Count T→C mutations (common in bisulfite sequencing)
32
+ countmut -i input.bam -r reference.fa -o mutations.tsv --ref-base T --mut-base C
33
+
34
+ # With custom threads and filtering
35
+ countmut -i input.bam -r reference.fa -o mutations.tsv -t 8 --max-unc 5 --min-con 2
36
+ ```
37
+
38
+ ## Options
39
+
40
+ **Input/Output**
41
+ ```bash
42
+ -i, --input PATH Input BAM file (coordinate-sorted) [required]
43
+ -r, --reference PATH Reference FASTA file [required]
44
+ -o, --output PATH Output TSV file (default: stdout)
45
+ -f, --force Overwrite output without prompting
46
+ ```
47
+
48
+ **Mutation Analysis**
49
+ ```bash
50
+ --ref-base TEXT Reference base to count from [default: A]
51
+ --mut-base TEXT Mutation base to count [default: G]
52
+ --strand TEXT Strand: both/forward/reverse [default: both]
53
+ --region TEXT Genomic region (e.g., 'chr1:1000000-2000000')
54
+ ```
55
+
56
+ **Performance**
57
+ ```bash
58
+ -t, --threads INTEGER Number of parallel threads [default: auto]
59
+ -b, --bin-size INTEGER Genomic bin size in bp [default: 10000]
60
+ ```
61
+
62
+ **Quality Filters**
63
+ ```bash
64
+ --min-baseq INTEGER Min base quality (Phred score) [default: 20]
65
+ --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
66
+ --max-sub INTEGER Max substitutions (NS tag) [default: 1]
67
+ --trim-start INTEGER Trim 5' bases from reads [default: 2]
68
+ --trim-end INTEGER Trim 3' bases from reads [default: 2]
69
+ --max-unc INTEGER Max unconverted (Zf tag) [default: 3]
70
+ --min-con INTEGER Min converted (Yf tag) [default: 1]
71
+ ```
72
+
73
+ **Output Records**
74
+ ```bash
75
+ -p, --pad INTEGER Motif window half-size [default: 15]
76
+ -s, --save-rest Include other bases (o0, o1, o2 columns)
77
+ ```
78
+
79
+ > **Note**: BAM files must have **NS**, **Zf**, and **Yf** tags (essential for bisulfite analysis).
80
+ > Indices (.bai, .fai) are created automatically if missing.
81
+
82
+ ## Output Format
83
+
84
+ TSV file with the following columns:
85
+
86
+ | Column | Description |
87
+ |--------|-------------|
88
+ | `chrom` | Chromosome name |
89
+ | `pos` | Genomic position (1-based) |
90
+ | `strand` | Strand (+ or -) |
91
+ | `motif` | Sequence context (2×pad+1 bp window) |
92
+ | `u0`, `u1`, `u2` | **Unconverted** (reference base) counts |
93
+ | `m0`, `m1`, `m2` | **Mutation** (mutation base only) counts |
94
+ | `o0`, `o1`, `o2` | **Other bases** counts (with `--save-rest`) |
95
+
96
+ **Count categories** (x0, x1, x2):
97
+ - **x0 (low quality)**: Bases failing quality filters (trim region, max-sub, min-mapq, min-baseq)
98
+ - **x1 (high conversion)**: Bases from reads with high conversion efficiency (low Zf and high Yf)
99
+ - **x2 (insufficient conversion)**: Bases from reads with insufficient conversion efficiency (high Zf or low Yf)
100
+
101
+
102
+ &nbsp;
103
+
104
+ <p align="center">
105
+ <img
106
+ src="https://raw.githubusercontent.com/y9c/y9c/master/resource/footer_line.svg?sanitize=true"
107
+ />
108
+ </p>
109
+ <p align="center">
110
+ Copyright &copy; 2025-present
111
+ <a href="https://github.com/y9c" target="_blank">Chang Y</a>
112
+ </p>
113
+ <p align="center">
114
+ <a href="https://github.com/y9c/countmut/blob/main/LICENSE">
115
+ <img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=282a36&colorB=c678dd" />
116
+ </a>
117
+ </p>
@@ -40,12 +40,8 @@ click.rich_click.TEXT_EMOJIS = True
40
40
  click.rich_click.OPTION_GROUPS = {
41
41
  "countmut": [
42
42
  {
43
- "name": "Required Options",
44
- "options": ["--input", "--reference"],
45
- },
46
- {
47
- "name": "Output Options",
48
- "options": ["--output", "--save-rest", "--force"],
43
+ "name": "Input/Output Options",
44
+ "options": ["--input", "--reference", "--output", "--force"],
49
45
  },
50
46
  {
51
47
  "name": "Mutation Analysis",
@@ -64,8 +60,12 @@ click.rich_click.OPTION_GROUPS = {
64
60
  ],
65
61
  },
66
62
  {
67
- "name": "Sequence Context",
68
- "options": ["--pad"],
63
+ "name": "Output Records",
64
+ "options": ["--pad", "--save-rest"],
65
+ },
66
+ {
67
+ "name": "Performance Options",
68
+ "options": ["--threads", "--bin-size"],
69
69
  },
70
70
  {
71
71
  "name": "Help & Version",
@@ -181,7 +181,7 @@ countmut -i input.bam -r reference.fa --region chr1:1000000-2000000
181
181
  "-s",
182
182
  "--save-rest",
183
183
  is_flag=True,
184
- help="[bold]Save additional statistics[/bold] including y0, y1, y2 columns",
184
+ help="[bold]Save other bases[/bold] statistics (o0, o1, o2 columns)",
185
185
  )
186
186
  @click.option(
187
187
  "--region",
@@ -202,6 +202,7 @@ countmut -i input.bam -r reference.fa --region chr1:1000000-2000000
202
202
  help="[bold]Strand processing[/bold]: 'both' (default), 'forward' (+ only), or 'reverse' (- only)",
203
203
  )
204
204
  @click.option(
205
+ "-p",
205
206
  "--pad",
206
207
  type=int,
207
208
  default=15,
@@ -255,14 +255,14 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
255
255
  for pos in target_sites_list:
256
256
  position_data[pos] = {
257
257
  "+": {
258
- "clean_count": Counter(),
259
- "unc_count": Counter(),
260
- "drop_count": Counter(),
258
+ "high_conversion_count": Counter(),
259
+ "insufficient_conversion_count": Counter(),
260
+ "low_quality_count": Counter(),
261
261
  },
262
262
  "-": {
263
- "clean_count": Counter(),
264
- "unc_count": Counter(),
265
- "drop_count": Counter(),
263
+ "high_conversion_count": Counter(),
264
+ "insufficient_conversion_count": Counter(),
265
+ "low_quality_count": Counter(),
266
266
  },
267
267
  }
268
268
 
@@ -310,10 +310,10 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
310
310
  ns = read.get_tag("NS")
311
311
  passes_mismatch_filter = ns <= max_sub
312
312
 
313
- # Check conversion status
313
+ # Check conversion filter (reads passing are sufficiently converted)
314
314
  zf = read.get_tag("Zf")
315
315
  yf = read.get_tag("Yf")
316
- is_converted = (zf <= max_unc) and (yf >= min_con)
316
+ passes_conversion_filter = (zf <= max_unc) and (yf >= min_con)
317
317
 
318
318
  # Process each position in the read
319
319
  query_sequence = read.query_sequence
@@ -363,7 +363,7 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
363
363
  bool(passes_mismatch_filter),
364
364
  bool(passes_mapq_filter),
365
365
  bool(passes_baseq_filter),
366
- bool(is_converted),
366
+ bool(passes_conversion_filter),
367
367
  )
368
368
 
369
369
  except (KeyError, AttributeError) as e:
@@ -380,28 +380,34 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
380
380
  passes_mismatch_filter,
381
381
  passes_mapq_filter,
382
382
  passes_baseq_filter,
383
- is_converted,
383
+ passes_conversion_filter,
384
384
  ) in best_obs.items():
385
385
  # Skip positions that are not in our target sites (safety)
386
386
  if ref_pos not in position_data:
387
387
  continue
388
388
 
389
- # Count in drop_count if ANY quality filter fails
389
+ # Count in low_quality if ANY quality filter fails
390
390
  if not (
391
391
  is_internal
392
392
  and passes_mismatch_filter
393
393
  and passes_mapq_filter
394
394
  and passes_baseq_filter
395
395
  ):
396
- position_data[ref_pos][strand_symbol]["drop_count"][query_base] += 1
397
- # Count in clean_count/unc_count only if ALL quality filters pass
396
+ position_data[ref_pos][strand_symbol]["low_quality_count"][
397
+ query_base
398
+ ] += 1
399
+ # Count in high_conversion/insufficient_conversion only if ALL quality filters pass
398
400
  else:
399
- if is_converted:
400
- position_data[ref_pos][strand_symbol]["clean_count"][
401
+ if passes_conversion_filter:
402
+ # High conversion efficiency (pass quality + conversion filters)
403
+ position_data[ref_pos][strand_symbol]["high_conversion_count"][
401
404
  query_base
402
405
  ] += 1
403
406
  else:
404
- position_data[ref_pos][strand_symbol]["unc_count"][query_base] += 1
407
+ # Insufficient conversion efficiency (pass quality but fail conversion)
408
+ position_data[ref_pos][strand_symbol][
409
+ "insufficient_conversion_count"
410
+ ][query_base] += 1
405
411
 
406
412
  # Calculate total skipped
407
413
  total_skipped = (
@@ -433,9 +439,15 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
433
439
  if process_reverse_only and strand_symbol != "-":
434
440
  continue
435
441
 
436
- clean_count = position_data[pos][strand_symbol]["clean_count"]
437
- unc_count = position_data[pos][strand_symbol]["unc_count"]
438
- drop_count = position_data[pos][strand_symbol]["drop_count"]
442
+ high_conversion_count = position_data[pos][strand_symbol][
443
+ "high_conversion_count"
444
+ ]
445
+ insufficient_conversion_count = position_data[pos][strand_symbol][
446
+ "insufficient_conversion_count"
447
+ ]
448
+ low_quality_count = position_data[pos][strand_symbol][
449
+ "low_quality_count"
450
+ ]
439
451
 
440
452
  # Get motif
441
453
  motif = extended_target_seq[
@@ -448,15 +460,15 @@ def parse_region_worker(args: tuple) -> dict[str, Any]:
448
460
 
449
461
  # Calculate counts
450
462
  # u = unconverted (reference base), m = mutation (mutation base only), o = others
451
- u0 = drop_count[ref_base]
452
- m0 = drop_count[mut_base]
453
- o0 = drop_count.total() - u0 - m0
454
- u1 = clean_count[ref_base]
455
- m1 = clean_count[mut_base]
456
- o1 = clean_count.total() - u1 - m1
457
- u2 = unc_count[ref_base]
458
- m2 = unc_count[mut_base]
459
- o2 = unc_count.total() - u2 - m2
463
+ u0 = low_quality_count[ref_base]
464
+ m0 = low_quality_count[mut_base]
465
+ o0 = low_quality_count.total() - u0 - m0
466
+ u1 = high_conversion_count[ref_base]
467
+ m1 = high_conversion_count[mut_base]
468
+ o1 = high_conversion_count.total() - u1 - m1
469
+ u2 = insufficient_conversion_count[ref_base]
470
+ m2 = insufficient_conversion_count[mut_base]
471
+ o2 = insufficient_conversion_count.total() - u2 - m2
460
472
 
461
473
  if u1 + m1 + u2 + m2 > 0:
462
474
  site_info = [region_chrom, pos + 1, strand_symbol, motif]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: countmut
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Ultra-fast strand-aware mutation counter
5
5
  Author-email: Ye Chang <yech1990@gmail.com>
6
6
  License-Expression: MIT
@@ -41,13 +41,13 @@ Dynamic: license-file
41
41
  [![Downloads](https://img.shields.io/pepy/dt/countmut)](https://pepy.tech/project/countmut)
42
42
  [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/y9c/countmut)
43
43
 
44
- **Ultra-fast strand-aware mutation counter**
44
+ > **Ultra-fast strand-aware mutation counter for bisulfite sequencing analysis**
45
45
 
46
- CountMut counts mutations from bisulfite sequencing / CAM-seq / GLORI-seq / eTAM-seq BAM files with parallel processing, quality-based mate overlap deduplication, and optimized file I/O.
46
+ CountMut is a high-performance tool for counting mutations from bisulfite sequencing BAM files (BS-seq, CAM-seq, GLORI-seq, eTAM-seq). It features parallel processing, quality-based mate overlap deduplication, and optimized file I/O for maximum speed.
47
47
 
48
48
  ## Features
49
49
 
50
- - 🚀 **Ultra-Fast**: Direct FASTA index reading, shared file handles, BGZF multi-threading
50
+ - 🚀 **Ultra-Fast**: Call mutation without pileup reads
51
51
  - 🧬 **Bisulfite Support**: NS, Zf, Yf tag filtering for conversion analysis
52
52
  - 🎯 **Accurate**: Quality-based mate overlap deduplication prevents double-counting
53
53
  - ⚡ **Parallel**: Multi-threaded genomic window processing
@@ -72,51 +72,68 @@ countmut -i input.bam -r reference.fa -o mutations.tsv --ref-base T --mut-base C
72
72
  countmut -i input.bam -r reference.fa -o mutations.tsv -t 8 --max-unc 5 --min-con 2
73
73
  ```
74
74
 
75
- ## Key Options
75
+ ## Options
76
76
 
77
+ **Input/Output**
77
78
  ```bash
78
- Required:
79
- -i, --input PATH Input BAM file
80
- -r, --reference PATH Reference FASTA file
81
-
82
- Output:
83
- -o, --output PATH Output TSV file (default: stdout)
84
-
85
- Mutation:
86
- --ref-base TEXT Reference base [default: A]
87
- --mut-base TEXT Mutation base [default: G]
88
- --strand [both|forward|reverse] Strand processing [default: both]
89
- --region TEXT Specific region (e.g., 'chr1:1000000-2000000')
90
-
91
- Performance:
92
- -t, --threads INTEGER Number of threads [default: auto]
93
- -b, --bin-size INTEGER Genomic bin size [default: 10000]
94
-
95
- Filtering (Bisulfite):
96
- --pad INTEGER Motif window padding [default: 15]
97
- --trim-start INTEGER Trim 5' bases [default: 2]
98
- --trim-end INTEGER Trim 3' bases [default: 2]
99
- --max-unc INTEGER Max unconverted (Zf) [default: 3]
100
- --min-con INTEGER Min converted (Yf) [default: 1]
101
- --max-sub INTEGER Max substitutions (NS) [default: 1]
102
- --min-baseq INTEGER Min base quality (Phred) [default: 20]
103
- --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
79
+ -i, --input PATH Input BAM file (coordinate-sorted) [required]
80
+ -r, --reference PATH Reference FASTA file [required]
81
+ -o, --output PATH Output TSV file (default: stdout)
82
+ -f, --force Overwrite output without prompting
104
83
  ```
105
84
 
106
- **Note**: BAM must have NS, Zf, and Yf tags for bisulfite analysis.
85
+ **Mutation Analysis**
86
+ ```bash
87
+ --ref-base TEXT Reference base to count from [default: A]
88
+ --mut-base TEXT Mutation base to count [default: G]
89
+ --strand TEXT Strand: both/forward/reverse [default: both]
90
+ --region TEXT Genomic region (e.g., 'chr1:1000000-2000000')
91
+ ```
107
92
 
108
- ## Output Format
93
+ **Performance**
94
+ ```bash
95
+ -t, --threads INTEGER Number of parallel threads [default: auto]
96
+ -b, --bin-size INTEGER Genomic bin size in bp [default: 10000]
97
+ ```
109
98
 
110
- TSV file with columns:
111
- - `chrom`, `pos`, `strand`, `motif` - Position and sequence context
112
- - `u0`, `u1`, `u2` - Unconverted (reference base) counts [drop, clean, unconverted]
113
- - `m0`, `m1`, `m2` - Mutation (mutation base only) counts [drop, clean, unconverted]
114
- - `o0`, `o1`, `o2` - Other bases counts [drop, clean, unconverted] (only with `--save-rest`)
99
+ **Quality Filters**
100
+ ```bash
101
+ --min-baseq INTEGER Min base quality (Phred score) [default: 20]
102
+ --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
103
+ --max-sub INTEGER Max substitutions (NS tag) [default: 1]
104
+ --trim-start INTEGER Trim 5' bases from reads [default: 2]
105
+ --trim-end INTEGER Trim 3' bases from reads [default: 2]
106
+ --max-unc INTEGER Max unconverted (Zf tag) [default: 3]
107
+ --min-con INTEGER Min converted (Yf tag) [default: 1]
108
+ ```
109
+
110
+ **Output Records**
111
+ ```bash
112
+ -p, --pad INTEGER Motif window half-size [default: 15]
113
+ -s, --save-rest Include other bases (o0, o1, o2 columns)
114
+ ```
115
+
116
+ > **Note**: BAM files must have **NS**, **Zf**, and **Yf** tags (essential for bisulfite analysis).
117
+ > Indices (.bai, .fai) are created automatically if missing.
118
+
119
+ ## Output Format
115
120
 
116
- Where:
117
- - **drop** (x0): Bases failing quality filters (internal position, mismatch, mapq, baseq)
118
- - **clean** (x1): High-quality bases passing all filters
119
- - **unconverted** (x2): Bases in unconverted reads (high Zf or low Yf)
121
+ TSV file with the following columns:
122
+
123
+ | Column | Description |
124
+ |--------|-------------|
125
+ | `chrom` | Chromosome name |
126
+ | `pos` | Genomic position (1-based) |
127
+ | `strand` | Strand (+ or -) |
128
+ | `motif` | Sequence context (2×pad+1 bp window) |
129
+ | `u0`, `u1`, `u2` | **Unconverted** (reference base) counts |
130
+ | `m0`, `m1`, `m2` | **Mutation** (mutation base only) counts |
131
+ | `o0`, `o1`, `o2` | **Other bases** counts (with `--save-rest`) |
132
+
133
+ **Count categories** (x0, x1, x2):
134
+ - **x0 (low quality)**: Bases failing quality filters (trim region, max-sub, min-mapq, min-baseq)
135
+ - **x1 (high conversion)**: Bases from reads with high conversion efficiency (low Zf and high Yf)
136
+ - **x2 (insufficient conversion)**: Bases from reads with insufficient conversion efficiency (high Zf or low Yf)
120
137
 
121
138
 
122
139
  &nbsp;
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "countmut"
7
- version = "0.0.2"
7
+ version = "0.0.3"
8
8
  description = "Ultra-fast strand-aware mutation counter"
9
9
  readme = "README.md"
10
10
  license = "MIT"
countmut-0.0.2/README.md DELETED
@@ -1,100 +0,0 @@
1
- # CountMut
2
-
3
- [![Pypi Releases](https://img.shields.io/pypi/v/countmut.svg)](https://pypi.python.org/pypi/countmut)
4
- [![Downloads](https://img.shields.io/pepy/dt/countmut)](https://pepy.tech/project/countmut)
5
- [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/y9c/countmut)
6
-
7
- **Ultra-fast strand-aware mutation counter**
8
-
9
- CountMut counts mutations from bisulfite sequencing / CAM-seq / GLORI-seq / eTAM-seq BAM files with parallel processing, quality-based mate overlap deduplication, and optimized file I/O.
10
-
11
- ## Features
12
-
13
- - 🚀 **Ultra-Fast**: Direct FASTA index reading, shared file handles, BGZF multi-threading
14
- - 🧬 **Bisulfite Support**: NS, Zf, Yf tag filtering for conversion analysis
15
- - 🎯 **Accurate**: Quality-based mate overlap deduplication prevents double-counting
16
- - ⚡ **Parallel**: Multi-threaded genomic window processing
17
- - 🔧 **Flexible**: Configurable filtering, strand-specific processing, auto-indexing
18
-
19
- ## Installation
20
-
21
- ```bash
22
- pip install countmut
23
- ```
24
-
25
- ## Quick Start
26
-
27
- ```bash
28
- # Basic usage - auto-creates indices if needed
29
- countmut -i input.bam -r reference.fa -o mutations.tsv
30
-
31
- # Count T→C mutations (common in bisulfite sequencing)
32
- countmut -i input.bam -r reference.fa -o mutations.tsv --ref-base T --mut-base C
33
-
34
- # With custom threads and filtering
35
- countmut -i input.bam -r reference.fa -o mutations.tsv -t 8 --max-unc 5 --min-con 2
36
- ```
37
-
38
- ## Key Options
39
-
40
- ```bash
41
- Required:
42
- -i, --input PATH Input BAM file
43
- -r, --reference PATH Reference FASTA file
44
-
45
- Output:
46
- -o, --output PATH Output TSV file (default: stdout)
47
-
48
- Mutation:
49
- --ref-base TEXT Reference base [default: A]
50
- --mut-base TEXT Mutation base [default: G]
51
- --strand [both|forward|reverse] Strand processing [default: both]
52
- --region TEXT Specific region (e.g., 'chr1:1000000-2000000')
53
-
54
- Performance:
55
- -t, --threads INTEGER Number of threads [default: auto]
56
- -b, --bin-size INTEGER Genomic bin size [default: 10000]
57
-
58
- Filtering (Bisulfite):
59
- --pad INTEGER Motif window padding [default: 15]
60
- --trim-start INTEGER Trim 5' bases [default: 2]
61
- --trim-end INTEGER Trim 3' bases [default: 2]
62
- --max-unc INTEGER Max unconverted (Zf) [default: 3]
63
- --min-con INTEGER Min converted (Yf) [default: 1]
64
- --max-sub INTEGER Max substitutions (NS) [default: 1]
65
- --min-baseq INTEGER Min base quality (Phred) [default: 20]
66
- --min-mapq INTEGER Min mapping quality (MAPQ) [default: 0]
67
- ```
68
-
69
- **Note**: BAM must have NS, Zf, and Yf tags for bisulfite analysis.
70
-
71
- ## Output Format
72
-
73
- TSV file with columns:
74
- - `chrom`, `pos`, `strand`, `motif` - Position and sequence context
75
- - `u0`, `u1`, `u2` - Unconverted (reference base) counts [drop, clean, unconverted]
76
- - `m0`, `m1`, `m2` - Mutation (mutation base only) counts [drop, clean, unconverted]
77
- - `o0`, `o1`, `o2` - Other bases counts [drop, clean, unconverted] (only with `--save-rest`)
78
-
79
- Where:
80
- - **drop** (x0): Bases failing quality filters (internal position, mismatch, mapq, baseq)
81
- - **clean** (x1): High-quality bases passing all filters
82
- - **unconverted** (x2): Bases in unconverted reads (high Zf or low Yf)
83
-
84
-
85
- &nbsp;
86
-
87
- <p align="center">
88
- <img
89
- src="https://raw.githubusercontent.com/y9c/y9c/master/resource/footer_line.svg?sanitize=true"
90
- />
91
- </p>
92
- <p align="center">
93
- Copyright &copy; 2025-present
94
- <a href="https://github.com/y9c" target="_blank">Chang Y</a>
95
- </p>
96
- <p align="center">
97
- <a href="https://github.com/y9c/countmut/blob/main/LICENSE">
98
- <img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=282a36&colorB=c678dd" />
99
- </a>
100
- </p>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes