You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

160 lines
3.2 KiB

  1. #include <ctype.h>
  2. #include <assert.h>
  3. #include "htslib/khash.h"
  4. #include "htslib/ksort.h"
  5. #include "htslib/sam.h"
  6. #include "htslib/hts.h"
  7. #include "htslib/knetfile.h"
  8. #include "htslib/kseq.h"
  9. #include "htslib_util.h"
  10. #include <stdio.h>
  11. #ifndef inline
  12. #define inline __inline
  13. #endif
  14. // set htslib verbosity level
  15. extern int hts_verbose;
  16. int hts_set_verbosity(int verbosity)
  17. {
  18. int old_verbosity = hts_verbose;
  19. hts_verbose = verbosity;
  20. return old_verbosity;
  21. }
  22. int hts_get_verbosity(void)
  23. {
  24. return hts_verbose;
  25. }
  26. // taken from samtools/bam_import.c
  27. static inline uint8_t * alloc_data(bam1_t *b, size_t size)
  28. {
  29. if (b->m_data < size)
  30. {
  31. b->m_data = size;
  32. kroundup32(b->m_data);
  33. b->data = (uint8_t*)realloc(b->data, b->m_data);
  34. }
  35. return b->data;
  36. }
  37. // update the variable length data within a bam1_t entry.
  38. // Adds *nbytes_new* - *nbytes_old* into the variable length data of *src* at *pos*.
  39. // Data within the bam1_t entry is moved so that it is
  40. // consistent with the data field lengths.
  41. // Return NULL on error (memory allocation)
  42. bam1_t * pysam_bam_update(bam1_t * b,
  43. const size_t nbytes_old,
  44. const size_t nbytes_new,
  45. uint8_t * field_start)
  46. {
  47. int d = nbytes_new - nbytes_old;
  48. int new_size;
  49. size_t nbytes_before;
  50. uint8_t * retval = NULL;
  51. // no change
  52. if (d == 0)
  53. return b;
  54. // new size of total data
  55. new_size = d + b->l_data;
  56. // fields before field in data
  57. nbytes_before = field_start - b->data;
  58. if (b->l_data != 0)
  59. {
  60. assert(nbytes_before >= 0);
  61. assert(nbytes_before <= b->l_data);
  62. }
  63. // increase memory if required
  64. if (d > 0)
  65. {
  66. retval = alloc_data(b, new_size);
  67. if (retval == NULL)
  68. return NULL;
  69. field_start = b->data + nbytes_before;
  70. }
  71. // move data after field to new location
  72. memmove(field_start + nbytes_new,
  73. field_start + nbytes_old,
  74. b->l_data - (nbytes_before + nbytes_old));
  75. // adjust l_data
  76. b->l_data = new_size;
  77. return b;
  78. }
  79. // translate a nucleotide character to binary code
  80. unsigned char pysam_translate_sequence(const unsigned char s)
  81. {
  82. return seq_nt16_table[s];
  83. }
  84. // Auxiliary functions for B support
  85. void bam_aux_appendB(bam1_t *b,
  86. const char tag[2],
  87. char type,
  88. char subtype,
  89. int len,
  90. uint8_t *data)
  91. {
  92. int ori_len;
  93. int l_data;
  94. // check that type is 'B'
  95. if('B' != type) return;
  96. ori_len = b->l_data;
  97. l_data = len * aux_type2size(subtype);
  98. // infer the data length from the sub-type
  99. b->l_data += 8 + l_data;
  100. // htslib: obsolete?
  101. // b->l_aux += 8 + l_data;
  102. if (b->m_data < b->l_data)
  103. {
  104. b->m_data = b->l_data;
  105. kroundup32(b->m_data);
  106. b->data = (uint8_t*)realloc(b->data, b->m_data);
  107. }
  108. b->data[ori_len] = tag[0];
  109. b->data[ori_len + 1] = tag[1];
  110. // tag
  111. b->data[ori_len + 2] = type;
  112. // type
  113. b->data[ori_len + 3] = subtype;
  114. // subtype
  115. (*(int32_t*)(b->data + ori_len + 4)) = len;
  116. // size
  117. memcpy(b->data + ori_len + 8, data, l_data);
  118. // data
  119. }
  120. int aux_type2size(uint8_t type)
  121. {
  122. switch (type) {
  123. case 'A': case 'c': case 'C':
  124. return 1;
  125. case 's': case 'S':
  126. return 2;
  127. case 'i': case 'I': case 'f':
  128. return 4;
  129. case 'd':
  130. return 8;
  131. case 'Z': case 'H': case 'B':
  132. return type;
  133. default:
  134. return 0;
  135. }
  136. }