Unconfigured Ad

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • jdrum00
    Member
    • Dec 2009
    • 16

    Duplicates in samtools view when using ranges

    Well, I continue to ask newbie questions, but hopefully they're getting at least a little more interesting over time....

    The docs for "samtools view" say quite clearly that "An alignment may be given multiple times if it is overlapping several regions", and indeed that's true. Even when the regions don't themselves overlap, as in this example:

    samtools view -b full.bam chr1:23995228-23995342 chr1:23995353-23995376 > filtered.bam

    ...if the ranges are close enough together, the space between them will be spanned by certain reads. Any read that touches both ranges gets included twice.

    In this particular case, that's 25 duplicated reads. The entire sorted block of 25 reads gets included twice, which means that the resulting BAM has out-of-order reads. If it's out of order, it can't be indexed until it's resorted, which takes as much time as the filtering did in the first place. Even once you re-sort, you've still got duplicates. Alas, rmdup doesn't seem to have a mode for removing completely identical reads!

    So how do you eliminate true read duplicates in your BAMs? I could "just" stream it through a UNIX-level command, but it would have to go through SAM and back to BAM, which requires a reference list and, presumably, a lot more time.
  • nilshomer
    Nils Homer
    • Nov 2008
    • 1283

    #2
    Originally posted by jdrum00 View Post
    Well, I continue to ask newbie questions, but hopefully they're getting at least a little more interesting over time....

    The docs for "samtools view" say quite clearly that "An alignment may be given multiple times if it is overlapping several regions", and indeed that's true. Even when the regions don't themselves overlap, as in this example:

    samtools view -b full.bam chr1:23995228-23995342 chr1:23995353-23995376 > filtered.bam

    ...if the ranges are close enough together, the space between them will be spanned by certain reads. Any read that touches both ranges gets included twice.

    In this particular case, that's 25 duplicated reads. The entire sorted block of 25 reads gets included twice, which means that the resulting BAM has out-of-order reads. If it's out of order, it can't be indexed until it's resorted, which takes as much time as the filtering did in the first place. Even once you re-sort, you've still got duplicates. Alas, rmdup doesn't seem to have a mode for removing completely identical reads!

    So how do you eliminate true read duplicates in your BAMs? I could "just" stream it through a UNIX-level command, but it would have to go through SAM and back to BAM, which requires a reference list and, presumably, a lot more time.
    A solution would be to write a program that reads in BAMs using the samtools library. If you assume the ranges are non-overlapping and in ascending order, you can store the chr/pos of the previous alignment outputted by the above and then discard any with a smaller chr/pos than the previous, otherwise update the previous. For an example in C (you can use the Java library, Perl library, python library, etc):

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <zlib.h>
    
    // Change these to point to your the samtools source files
    #include "../samtools/bam.h"
    #include "../samtools/sam.h"
    
    #define Name "dbamtest"
    
    int main(int argc, char *argv[])
    {
        samfile_t *fp_in = NULL, *fp_out = NULL;
        bam1_t *b=NULL;
    
        if(2 == argc) {
            fp_in = samopen(argv[1], "rb", 0); 
            if(NULL == fp_in) {
                perror("Could not open file for reading");
                return 1;
            }   
            fp_out = samopen("-", "wb", fp_in->header);
            if(NULL == fp_out) {
                perror("Could not open stdout for writing");
                return 1;
            }
    
            int32_t prev_tid=-1, prev_pos=-1;
            b = bam_init1();
            while(0 < samread(fp_in, b)) {
                if(prev_tid < b->core.tid || (prev_tid == b->core.tid && prev_pos <= b->core.pos)) {
                    if(samwrite(fp_out, b) <= 0) {
                        perror("Could not write sam entry");
                        return 1;
                    }
                    prev_tid = b->core.tid;
                    prev_pos = b->core.pos;
                }
     // Destroy bam
                bam_destroy1(b);
                // Reinitialize
                b = bam_init1();
            }
            // Free
            bam_destroy1(b);
    
            /* Close the file */
            samclose(fp_in);
            samclose(fp_out);
        }
        else {
            fprintf(stderr, "Usage: %s [OPTIONS]\n", Name);
            fprintf(stderr, "\t<bam file>\n");
        }
    
        return 0;
    }
    You will have to compile against the samtools source code (here's a snippet from my Makefile.am):
    Code:
                            
                            ../samtools/bam_import.c \
                            ../samtools/bam_aux.c \
                            ../samtools/bam_pileup.c \
                            ../samtools/bam.c ../samtools/bam.h \
                            ../samtools/sam.c ../samtools/sam.h \
                            ../samtools/faidx.c ../samtools/faidx.h \
                            ../samtools/razf.c ../samtools/razf.h \
                            ../samtools/bgzf.c    ../samtools/bgzf.h \
                            ../samtools/kstring.c ../samtools/kstring.h \
                            ../samtools/bam_color.c
    Note: The above code has not been tested and there is no warranty either explicit or implied.

    Comment

    • jdrum00
      Member
      • Dec 2009
      • 16

      #3
      Originally posted by nilshomer View Post
      A solution would be to write a program that reads in BAMs using the samtools library.
      Wow; yes, that's definitely taking it to the next level! I've seen that there are Python bindings; I'll give that a shot, using your code as a guide.

      Originally posted by nilshomer View Post
      Note: The above code has not been tested and there is no warranty either explicit or implied.
      Understood. I'll post my version, if I manage to make it work, to see if I can help the next guy. Thanks a bunch for the pointer; I have a feeling I'm going to need this sort of thing more and more, so it's probably good to get to know the libraries sooner rather than later.

      Comment

      • lh3
        Senior Member
        • Feb 2008
        • 686

        #4
        The simpler way is to merge adjacent regions close to each other. This will grab a little bit more reads in the output, but I believe this does not matter too much.

        Comment

        • lh3
          Senior Member
          • Feb 2008
          • 686

          #5
          In addition, here shows the preferred way to link against samtools:

          Download SAM tools for free. SAM (Sequence Alignment/Map) is a flexible generic format for storing nucleotide sequence alignment. SAMtools provide efficient utilities on manipulating alignments in the SAM format.

          Comment

          • jdrum00
            Member
            • Dec 2009
            • 16

            #6
            Originally posted by lh3 View Post
            The simpler way is to merge adjacent regions close to each other. This will grab a little bit more reads in the output, but I believe this does not matter too much.
            I started to do this, but I wasn't sure how rigorous I needed to be with the data, and the person I would need to ask is out of town.

            Though, actually.... If two ranges are close enough to be spanned by a read, then there's no possible read that could fall between them and be considered outside the set of ranges.

            So, closing gaps of the read length or less between ranges can't actually introduce extraneous reads, only eliminate duplicates. Thanks for helping me think that through!

            Comment

            Latest Articles

            Collapse

            • SEQadmin2
              Advanced Sequencing Platforms Tackle Neuroscience’s Toughest Genomics Problems
              by SEQadmin2



              Genomics studies in neuroscience face a special challenge due to the brain’s complexity and scarcity of samples. Mapping changes in cell type and state using conventional next-generation sequencing methods remains challenging. Advances in technologies like single-cell sequencing, spatial transcriptomics, and long-read sequencing have opened the door to deeper studies of the brain and diseases like Alzheimer’s, amyotrophic lateral sclerosis (ALS), and schizophrenia.
              ...
              07-09-2026, 11:10 AM
            • SEQadmin2
              Cancer Drug Resistance: The Lingering Barrier to Rising Survival
              by SEQadmin2



              Cancer survival rates have significantly increased in the last few decades in the United States, reaching a combined 70% 5-year survival rate by 2021. Behind this number, there are years of research to find new therapies, drug targets, and early detection methods. But there is one core challenge that keeps slowing down these advances, and it’s about drug resistance.

              There is no single reason why many patients don’t respond to treatment as expected. Cancer is...
              07-08-2026, 05:17 AM
            • GATTACAT
              Reply to Nine Things a Sample Prep Scientist Thinks About Before Sequencing
              by GATTACAT
              Love this - good data definitely starts from good input, and poor input can only give relatively poor data. I particularly like the mention of Nanodrop/absorbance based methods for quantification. It's such a toss up if you'll get an accurate reading or what amounts to a randomly generated number, and a lot of library/sequencing related issues can be traced back to poor quant.
              07-01-2026, 11:43 AM

            ad_right_rmr

            Collapse

            News

            Collapse

            Topics Statistics Last Post
            Started by SEQadmin2, 07-13-2026, 10:26 AM
            0 responses
            26 views
            0 reactions
            Last Post SEQadmin2  
            Started by SEQadmin2, 07-09-2026, 10:04 AM
            0 responses
            36 views
            0 reactions
            Last Post SEQadmin2  
            Started by SEQadmin2, 07-08-2026, 10:08 AM
            0 responses
            23 views
            0 reactions
            Last Post SEQadmin2  
            Started by SEQadmin2, 07-07-2026, 11:05 AM
            0 responses
            34 views
            0 reactions
            Last Post SEQadmin2  
            Working...