minibwa 0.0.0 → 0.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d54a100aaa8439c2dc2fb9b686ca60f4898ea0873370f3dc5b58bfd5af1b7fa
4
- data.tar.gz: 17911037009111f945b2f2621ccdc1e6b51928748585cc3753d6341250cca51e
3
+ metadata.gz: d3a36a760e0ac6885ee19e57ee672350abc63ee679541f757f9aca1bf2d1336b
4
+ data.tar.gz: 85da4f46eceba36f840a89207b91ae34a5bac5825a8f02cdb0e92bce0d4a38cc
5
5
  SHA512:
6
- metadata.gz: 0e3a98d1f7e2652f16d3537bbbe7a2e3b89ff05dad6b5f1c166db505a465cdb1f854bbd2970bca0c1c0152f8f5fa4bc10bf7ef4a716a4c9001663bf35ec77743
7
- data.tar.gz: 0c99b08294dcaaff5f896da4516c4c52df07cb74e879e58c7eea40f795235ac95b92535e7a86dec93cd900ee6257d4ea4e5e42b199fe4705fe1faa851d0cdb39
6
+ metadata.gz: 955d5ad73d6016241507b1f1b8b72aaa36cf7fd4004c5586c3ec943aa3d24a3bb47b6a333c84efdf1394c55a9f3bccc0726ef74d7c59e6811d5f44430db79dad
7
+ data.tar.gz: c3a4359e47da6b147e65c23afe0efb7407a04960c493cd8883dac9ca4a8b4edad7a766a1b225cf6aadf2f02f55643c1cd7f24f861f8f7294a8d6f4cb70c667c6
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![Gem Version](https://img.shields.io/gem/v/minibwa?color=brightgreen)](https://rubygems.org/gems/minibwa)
4
4
  [![Test](https://github.com/kojix2/ruby-minibwa/actions/workflows/test.yml/badge.svg)](https://github.com/kojix2/ruby-minibwa/actions/workflows/test.yml)
5
5
  [![Lines of Code](https://img.shields.io/endpoint?url=https%3A%2F%2Ftokei.kojix2.net%2Fbadge%2Fgithub%2Fkojix2%2Fruby-minibwa%2Flines)](https://tokei.kojix2.net/github/kojix2/ruby-minibwa)
6
+ [![DOI](https://zenodo.org/badge/1319741104.svg)](https://doi.org/10.5281/zenodo.21753646)
6
7
 
7
8
  Ruby bindings for [minibwa](https://github.com/lh3/minibwa), a short-read
8
9
  aligner combining bwa-mem seeding with minimap2 chaining and alignment.
@@ -254,8 +254,13 @@ void mb_fmt_sam(void *km, kstring_t *s, const l2b_t *l2b, const mb_bseq1_t *t, i
254
254
  kom_sprintf_lite(s, "%d\t", r_next->ts + 1);
255
255
  } else if (r_next) { // && this_tid < 0
256
256
  kom_sprintf_lite(s, "\t%s\t%d\t", l2b->ctg[r_next->tid].name, r_next->ts + 1);
257
- } else if (this_tid >= 0) { // && r_next == NULL
258
- kom_sprintf_lite(s, "\t=\t%d\t", this_pos + 1); // next segment will take r's coordinate
257
+ } else if (this_tid >= 0) { // && r_next == NULL. In this case, mate is unmapped and placed at this segment's primary alignment
258
+ const mb_hit_t *r_pri;
259
+ r_pri = get_sam_pri(n_h, h);
260
+ if (r->tid == r_pri->tid)
261
+ kom_sprintf_lite(s, "\t=\t%d\t", r_pri->ts + 1);
262
+ else
263
+ kom_sprintf_lite(s, "\t%s\t%d\t", l2b->ctg[r_pri->tid].name, r_pri->ts + 1);
259
264
  } else kom_sprintf_lite(s, "\t*\t0\t"); // neither has coordinates
260
265
  if (tlen > 0) ++tlen;
261
266
  else if (tlen < 0) --tlen;
@@ -12,6 +12,7 @@ typedef struct {
12
12
  int opt; /* equivalent to optopt */
13
13
  char *arg; /* equivalent to optarg */
14
14
  int longidx; /* index of a long option; or -1 if short */
15
+ int erri; /* offset of the wrong option */
15
16
  /* private variables not intended for external uses */
16
17
  int i, pos, n_args;
17
18
  } ketopt_t;
@@ -22,7 +23,7 @@ typedef struct {
22
23
  int val;
23
24
  } ko_longopt_t;
24
25
 
25
- static ketopt_t KETOPT_INIT = { 1, 0, 0, -1, 1, 0, 0 };
26
+ static ketopt_t KETOPT_INIT = { 1, 0, 0, -1, -1, 1, 0, 0 };
26
27
 
27
28
  static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
28
29
  {
@@ -60,7 +61,7 @@ static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *
60
61
  while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
61
62
  ++s->i, ++s->n_args;
62
63
  }
63
- s->arg = 0, s->longidx = -1, i0 = s->i;
64
+ s->arg = 0, s->longidx = -1, s->erri = -1, i0 = s->i;
64
65
  if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
65
66
  s->ind = s->i - s->n_args;
66
67
  return -1;
@@ -82,7 +83,7 @@ static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *
82
83
  else ++n_partial, o_partial = &longopts[k];
83
84
  }
84
85
  if (n_exact > 1 || (n_exact == 0 && n_partial > 1)) {
85
- s->i++;
86
+ s->erri = s->i++;
86
87
  return '?';
87
88
  }
88
89
  o = n_exact == 1? o_exact : n_partial == 1? o_partial : 0;
@@ -93,7 +94,7 @@ static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *
93
94
  if (s->i < argc - 1) s->arg = argv[++s->i];
94
95
  else opt = ':'; /* missing option argument */
95
96
  }
96
- }
97
+ } else s->erri = s->i;
97
98
  }
98
99
  } else { /* a short option */
99
100
  char *p;
@@ -101,7 +102,7 @@ static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *
101
102
  opt = s->opt = argv[s->i][s->pos++];
102
103
  p = strchr((char*)ostr, opt);
103
104
  if (p == 0) {
104
- opt = '?'; /* unknown option */
105
+ s->erri = s->i, opt = '?'; /* unknown option */
105
106
  } else if (p[1] == ':') {
106
107
  if (argv[s->i][s->pos] == 0) {
107
108
  if (s->i < argc - 1) s->arg = argv[++s->i];
@@ -115,6 +116,7 @@ static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *
115
116
  if (s->n_args > 0) /* permute */
116
117
  for (j = i0; j < s->i; ++j)
117
118
  ketopt_permute(argv, j, s->n_args);
119
+ if (s->erri >= 0) s->erri -= s->n_args; /* permutation moved the option left by n_args */
118
120
  }
119
121
  s->ind = s->i - s->n_args;
120
122
  return opt;
@@ -363,10 +363,10 @@ add_primary:
363
363
  kfree(km, w);
364
364
  }
365
365
 
366
- void mb_set_sam_pri(int32_t n, mb_hit_t *r, int32_t is_primary5)
366
+ int32_t mb_set_sam_pri(int32_t n, mb_hit_t *r, int32_t is_primary5)
367
367
  {
368
- int32_t i, n_pri = 0, min_i = -1, min_qs = -1, first_i = -1;
369
- if (n <= 0) return;
368
+ int32_t i, new_pri, n_pri = 0, min_i = -1, min_qs = -1, first_i = -1;
369
+ if (n <= 0) return -1;
370
370
  for (i = 0; i < n; ++i) {
371
371
  r[i].sam_pri = 0;
372
372
  if (r[i].id != r[i].parent) continue;
@@ -375,8 +375,9 @@ void mb_set_sam_pri(int32_t n, mb_hit_t *r, int32_t is_primary5)
375
375
  min_i = i, min_qs = r[i].qs;
376
376
  }
377
377
  assert(n_pri > 0);
378
- if (is_primary5) r[min_i].sam_pri = 1;
379
- else r[first_i].sam_pri = 1;
378
+ new_pri = is_primary5? min_i : first_i;
379
+ r[new_pri].sam_pri = 1;
380
+ return new_pri;
380
381
  }
381
382
 
382
383
  void mb_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int *n_, mb_hit_t *r)
@@ -751,7 +752,7 @@ mb_hit_t **mb_map_batch(const mb_opt_t *opt, const mb_idx_t *idx, int32_t n_seq,
751
752
  kfree(km, seq4);
752
753
 
753
754
  // paired-end processing
754
- if (is_pe && n_seq >= 2) {
755
+ if (is_pe && n_seq >= 2 && !(opt->flag & (MB_F_NO_PAIRING|MB_F_NO_ALN))) {
755
756
  mb_pestat_t pes[4];
756
757
  for (i = 0; i < 4; ++i) pes[i].failed = 1;
757
758
  pes[1].failed = 0;
@@ -68,7 +68,7 @@ int32_t mb_cal_mblen(int32_t n, const mb_anchor_t *a, int32_t *blen_);
68
68
  mb_hit_t *mb_gen_hit(void *km, uint32_t hash, int qlen, const l2b_t *l2b, int n_u, uint64_t *u, mb_anchor_t *a);
69
69
  void mb_sync_high_cov(int32_t n, mb_hit_t *h);
70
70
  void mb_set_parent(void *km, float mask_level, int mask_len, int n, mb_hit_t *r, int sub_diff, int hard_mask_level);
71
- void mb_set_sam_pri(int32_t n, mb_hit_t *r, int32_t is_primary5);
71
+ int32_t mb_set_sam_pri(int32_t n, mb_hit_t *r, int32_t is_primary5);
72
72
  void mb_hit_sort(void *km, int *n_regs, mb_hit_t *r);
73
73
  void mb_sync_hits(void *km, int n_regs, mb_hit_t *regs);
74
74
  void mb_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int *n_, mb_hit_t *r);
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include <stdint.h>
5
5
 
6
- #define MB_VERSION "0.6-r416"
6
+ #define MB_VERSION "0.7-r421"
7
7
 
8
8
  #define MB_F_PAF (0x1LL) // output in the PAF format
9
9
  #define MB_F_NO_UNMAP (0x2LL) // output unmapped query sequences
@@ -461,7 +461,7 @@ static int32_t mb_matesw(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_
461
461
  void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2], mb_hit_t *hit[2], const mb_pestat_t pes[4], int32_t qlen[2], char *const qseq[2])
462
462
  {
463
463
  const int32_t pe_bonus = 4;
464
- int32_t r, i, dp_max_se[2], score_se, dp_max_se2[2], score_se2, do_matesw, is_meth = !!(opt->flag & MB_F_METH);
464
+ int32_t r, i, dp_max_se[2], score_se, dp_max_se2[2], score_se2, do_matesw, is_meth = !!(opt->flag & MB_F_METH), reset_sam_pri = 1;
465
465
  mb_pairaux_t paux;
466
466
  int32_t seed_ratio[2], min_seed_ratio;
467
467
 
@@ -487,7 +487,7 @@ void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2],
487
487
  mb_pair_hits(km, opt, l2b, n_hit, hit, pes, &paux); // pair again if new hits rescued
488
488
  }
489
489
  }
490
- if (paux.n_pp == 0) goto end_pairing;
490
+ if (paux.n_pp == 0) goto end_pairing; // skip the rest if there are no properly paired hits
491
491
 
492
492
  for (r = 0; r < 2; ++r) {
493
493
  for (dp_max_se[r] = dp_max_se2[r] = 0, i = 0; i < n_hit[r]; ++i) {
@@ -502,6 +502,9 @@ void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2],
502
502
 
503
503
  mb_sync_high_cov(n_hit[0], hit[0]);
504
504
  mb_sync_high_cov(n_hit[1], hit[1]);
505
+ for (r = 0; r < 2; ++r) // clear 0x2 as these will be re-evaluated and set in the following
506
+ for (i = 0; i < n_hit[r]; ++i)
507
+ hit[r][i].proper_pair = 0;
505
508
  if (paux.score >= score_se - opt->pen_unpair * opt->a) { // choose the paired hits
506
509
  int32_t mapq_pe, score2 = paux.sub_sc, diff;
507
510
  double identity;
@@ -534,7 +537,8 @@ void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2],
534
537
  p->mapq = 0;
535
538
  }
536
539
  for (i = 0; i < n_hit[r]; ++i) { // handle other chimeric hits
537
- mb_hit_t *p = &hit[r][i], *q = h[r];
540
+ const mb_hit_t *q = h[r];
541
+ mb_hit_t *p = &hit[r][i];
538
542
  if (q != p && p->id == p->parent) { // p is a chimeric hit that is not h[r]
539
543
  int32_t j, ol = p->qe <= q->qs || p->qs >= q->qe? 0 : (p->qe < q->qe? p->qe : q->qe) - (p->qs > q->qs? p->qs : q->qs);
540
544
  if (ol > opt->mask_level * (p->qe - p->qs)) { // if p overlaps with h[r] a lot, make it a secondary hit
@@ -545,7 +549,24 @@ void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2],
545
549
  }
546
550
  }
547
551
  }
552
+ for (i = 0; i < n_hit[r]; ++i) {
553
+ mb_hit_t *p = &hit[r][i];
554
+ p->sam_pri = p->proper_pair = 0;
555
+ if (p->id == p->parent)
556
+ p->proper_pair = 1;
557
+ }
558
+ h[r]->sam_pri = 1;
559
+ }
560
+ if (opt->flag & MB_F_PRIMARY5) {
561
+ int32_t pri[2];
562
+ pri[0] = mb_set_sam_pri(n_hit[0], hit[0], 1);
563
+ pri[1] = mb_set_sam_pri(n_hit[1], hit[1], 1);
564
+ if (&hit[0][pri[0]] != h[0] || &hit[1][pri[1]] != h[1]) // if sam_pri is changed, clear flag 0x2
565
+ for (r = 0; r < 2; ++r)
566
+ for (i = 0; i < n_hit[r]; ++i)
567
+ hit[r][i].proper_pair = 0;
548
568
  }
569
+ reset_sam_pri = 0;
549
570
  } else { // choose the unpaired hits
550
571
  int32_t diff = score_se - opt->pen_unpair * opt->a - paux.score;
551
572
  int32_t mapq_pe = 6 * diff / opt->a;
@@ -554,6 +575,8 @@ void mb_pair(void *km, const mb_opt_t *opt, const l2b_t *l2b, int32_t n_hit[2],
554
575
  hit[r][i].mapq = hit[r][i].mapq < mapq_pe? hit[r][i].mapq : mapq_pe;
555
576
  }
556
577
  end_pairing:
557
- mb_set_sam_pri(n_hit[0], hit[0], !!(opt->flag & MB_F_PRIMARY5));
558
- mb_set_sam_pri(n_hit[1], hit[1], !!(opt->flag & MB_F_PRIMARY5));
578
+ if (reset_sam_pri) {
579
+ mb_set_sam_pri(n_hit[0], hit[0], !!(opt->flag & MB_F_PRIMARY5));
580
+ mb_set_sam_pri(n_hit[1], hit[1], !!(opt->flag & MB_F_PRIMARY5));
581
+ }
559
582
  }
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Minibwa
4
4
  # Gem version.
5
- VERSION = '0.0.0'
5
+ VERSION = '0.0.1'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minibwa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  requirements: []
85
- rubygems_version: 4.0.16
85
+ rubygems_version: 3.6.9
86
86
  specification_version: 4
87
87
  summary: Ruby bindings for minibwa, a short-read aligner
88
88
  test_files: []