Answers.Body: <p>You're just looking in the wrong header file. The BCF stuff will be in <code>vcf.h</code> (you'll see the two functions you mentioned there).</p>
  <p>With BAM files one doesn't typically need to add/remove headers, which is why there are not convenience functions for them. To add a header:</p>
  <ol>
  <li>Increment <code>hdr-&gt;ntargets</code></li>
  <li><code>realloc(hdr-&gt;target_len, ...)</code> and <code>hdr-&gt;target_name</code>.</li>
  <li>You likely want to append the name/length to the end of <code>hdr-&gt;target_name</code> and <code>hdr-&gt;target_len</code>, respectively.</li>
  </ol>
  <p>I don't think you need to update the dictionary or plain text for most uses (or at least I've never needed to).</p>
  <p>Removing a chromosome would follow the reverse instructions, (you'd need to shift everything in the name and length arrays if you remove entries in the middle.</p>
  <h1>WARNING, doing this is prone to error!</h1>
  <p>I would strongly cautious you to be very careful when doing this. Please remember that the chromosome that entries are mapped to isn't actually stored in alignment entries themselves. Rather, they simply have an index into <code>hdr-&gt;target_name</code>, which saves space. Consequently, if you start adding/removing headers to/from a BAM file with alignments then you're going to have to modify <strong>all</strong> of the alignments to keep the correct alignment:chromosome associations. Otherwise you'll end up with completely useless results (this is the same caveat as with <code>samtools reheader</code>).</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-09-04T08:12:16.353Z
Answers.LastActivityDate: 2017-09-04T08:12:16.353Z
Answers.LastEditDate: 2020-06-18T08:30:41.743Z
Answers.UserDisplayName: Devon Ryan
Body: <p>I'd like to use C++ to generate a new BAM file programmatically. This is an example how to use htslib to generate a new BCF file on the fly.</p>
  
  <blockquote>
    <p><a href="https://github.com/samtools/htslib/blob/develop/test/test-bcf-translate.c" rel="noreferrer">https://github.com/samtools/htslib/blob/develop/test/test-bcf-translate.c</a></p>
  </blockquote>
  
  <p>The two key functions are:</p>
  
  <ul>
  <li><code>bcf_hdr_append</code></li>
  <li><code>bcf_hdr_add_sample</code></li>
  </ul>
  
  <p>Now when I navigate to the header file for SAM/BAM functions:</p>
  
  <blockquote>
    <p><a href="https://github.com/samtools/htslib/blob/develop/htslib/sam.h" rel="noreferrer">https://github.com/samtools/htslib/blob/develop/htslib/sam.h</a></p>
  </blockquote>
  
  <p>The only "append" function is <code>bam_aux_append</code>. But that's for optional fields. </p>
  
  <p>My questions:</p>
  
  <ul>
  <li>Given a <code>bam_hdr_t</code> header (potentially empty), how to add a new chromosome reference? (For example, add a new chrAB to the BAM file)</li>
  <li>Given a non-empty <code>bam_hdr_t *</code> header, how to remove a chromosome? (For example, remove chr4 from the BAM header)</li>
  </ul>
  
  <p>My sample code:</p>
  
  <pre><code>// Empty BAM header, nothing inside
  bam_hdr_t * hdr = bam_hdr_init();
  
  // I'd like to add a new synthetic `chrAB` into the header, how?  
  </code></pre>
  
Tags: <samtools><c++>
Title: How to build a BAM header file with htslib in C++?
ThreadText: # How to build a BAM header file with htslib in C++?
  
  (Asked by: username_0 on 2017-09-04)
  
  I'd like to use C++ to generate a new BAM file programmatically. This is an example how to use htslib to generate a new BCF file on the fly.
  
  > <https://github.com/samtools/htslib/blob/develop/test/test-bcf-translate.c>
  
  The two key functions are:
  
  * `bcf_hdr_append`
  * `bcf_hdr_add_sample`
  
  Now when I navigate to the header file for SAM/BAM functions:
  
  > <https://github.com/samtools/htslib/blob/develop/htslib/sam.h>
  
  The only "append" function is `bam_aux_append`. But that's for optional fields.
  
  My questions:
  
  * Given a `bam_hdr_t` header (potentially empty), how to add a new chromosome reference? (For example, add a new chrAB to the BAM file)
  * Given a non-empty `bam_hdr_t *` header, how to remove a chromosome? (For example, remove chr4 from the BAM header)
  
  My sample code:
  
  ```
  // Empty BAM header, nothing inside
  bam_hdr_t * hdr = bam_hdr_init();
  
  // I'd like to add a new synthetic `chrAB` into the header, how?  
  
  ```
  
  **Tags:** samtools, c++
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-09-04. Score: 4 | Accepted answer
  
  You're just looking in the wrong header file. The BCF stuff will be in `vcf.h` (you'll see the two functions you mentioned there).
  
  With BAM files one doesn't typically need to add/remove headers, which is why there are not convenience functions for them. To add a header:
  
  1. Increment `hdr->ntargets`
  2. `realloc(hdr->target_len, ...)` and `hdr->target_name`.
  3. You likely want to append the name/length to the end of `hdr->target_name` and `hdr->target_len`, respectively.
  
  I don't think you need to update the dictionary or plain text for most uses (or at least I've never needed to).
  
  Removing a chromosome would follow the reverse instructions, (you'd need to shift everything in the name and length arrays if you remove entries in the middle.
  
  # WARNING, doing this is prone to error!
  
  I would strongly cautious you to be very careful when doing this. Please remember that the chromosome that entries are mapped to isn't actually stored in alignment entries themselves. Rather, they simply have an index into `hdr->target_name`, which saves space. Consequently, if you start adding/removing headers to/from a BAM file with alignments then you're going to have to modify **all** of the alignments to keep the correct alignment:chromosome associations. Otherwise you'll end up with completely useless results (this is the same caveat as with `samtools reheader`).
  
  
  ---
  
  