Skip to content

Commit

Permalink
Split aux tag adjustment from read filtering
Browse files Browse the repository at this point in the history
Pull the part that implements the `--keep-tags` and `--remove-tags`
options out of process_aln() and put it in a new adjust_tags()
function.  This means the tag adjustment only has to be done when
actually needed - so for example it can be skipped in counting
mode.

Invalid aux tags detected in adjust_tags() are now reported
immediately as errors.  This just means they're trapped a bit
earlier, as before they would have caused the writer to fail.

Note that as this code used to come after all the process_aln()
filters had run, the tags were only ever edited if the read
passed filtering.  For compatibility the new version has been
made to work the same way, and notes have been added to the manual
page stating that the options only affect passed reads.
  • Loading branch information
daviesrob committed Jan 13, 2022
1 parent f792ea6 commit 28331fd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
4 changes: 4 additions & 0 deletions doc/samtools-view.1
Expand Up @@ -390,12 +390,16 @@ can be repeated multiple times.
If the list starts with a `^' then it is negated and treated as a
request to remove all tags except those in \fISTR\fR. The list may be
empty, so \fB-x ^\fR will remove all tags.

Note that tags will only be removed from reads that pass filtering.
.TP
.BI "--keep-tag " STR
This keeps \fIonly\fR tags listed in \fISTR\fR and is directly equivalent
to \fB--remove-tag ^\fR\fISTR\fR. Specifying an empty list will remove
all tags. If both \fB--keep-tag\fR and \fB--remove-tag\fR are
specified then \fB--keep-tag\fR has precedence.

Note that tags will only be removed from reads that pass filtering.
.TP
.BR -B ", " --remove-B
Collapse the backward CIGAR operation.
Expand Down
20 changes: 16 additions & 4 deletions sam_view.c
Expand Up @@ -206,6 +206,11 @@ static int process_aln(const sam_hdr_t *h, bam1_t *b, samview_settings_t* settin
const char *p = bam_get_library((sam_hdr_t*)h, b);
if (!p || strcmp(p, settings->library) != 0) return 1;
}
return 0;
}

static int adjust_tags(const sam_hdr_t *h, bam1_t *b,
samview_settings_t* settings) {
if (settings->keep_tag) {
uint8_t *s_from, *s_to, *end = b->data + b->l_data;
auxhash_t h = settings->keep_tag;
Expand All @@ -217,7 +222,7 @@ static int process_aln(const sam_hdr_t *h, bam1_t *b, samview_settings_t* settin
if (s == NULL) {
print_error("view", "malformed aux data for record \"%s\"",
bam_get_qname(b));
break;
return -1;
}

if (kh_get(aux_exists, h, x) != kh_end(h) ) {
Expand All @@ -239,7 +244,7 @@ static int process_aln(const sam_hdr_t *h, bam1_t *b, samview_settings_t* settin
if (s == NULL) {
print_error("view", "malformed aux data for record \"%s\"",
bam_get_qname(b));
break;
return -1;
}

if (kh_get(aux_exists, h, x) == kh_end(h) ) {
Expand Down Expand Up @@ -654,8 +659,13 @@ static int fetch_pairs_collect_mates(samview_settings_t *conf, hts_itr_multi_t *
k = kh_get(names,mate_names,bam_get_qname(rec));
if ( k != kh_end(mate_names) ) drop = 0;
}
if ( !drop && check_sam_write1(conf->out,conf->header,rec,conf->fn_out,&write_error) < 0 )
goto out;
if (!drop) {
if (adjust_tags(conf->header, rec, conf) != 0)
goto out;
if (check_sam_write1(conf->out, conf->header, rec, conf->fn_out,
&write_error) < 0)
goto out;
}
}

if (r < -1) {
Expand Down Expand Up @@ -685,6 +695,8 @@ static inline int process_one_record(samview_settings_t *conf, bam1_t *b,
if (!process_aln(conf->header, b, conf)) {
if (!conf->is_count) {
change_flag(b, conf);
if (adjust_tags(conf->header, b, conf) != 0)
return -1;
if (check_sam_write1(conf->out, conf->header,
b, conf->fn_out, write_error) < 0) {
return -1;
Expand Down

0 comments on commit 28331fd

Please sign in to comment.