File: htslib_util.c

package info (click to toggle)
python-pysam 0.15.4%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 27,992 kB
  • sloc: ansic: 140,738; python: 7,881; sh: 265; makefile: 223; perl: 41
file content (159 lines) | stat: -rw-r--r-- 3,294 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <ctype.h>
#include <assert.h>
#include "htslib/khash.h"
#include "htslib/ksort.h"
#include "htslib/sam.h"
#include "htslib/hts.h"
#include "htslib/knetfile.h"
#include "htslib/kseq.h"
#include "htslib_util.h"
#include <stdio.h>

#ifndef inline
#define inline __inline
#endif

// set htslib verbosity level
extern int hts_verbose;
int hts_set_verbosity(int verbosity)
{
  int old_verbosity = hts_verbose;
  hts_verbose = verbosity;
  return old_verbosity;
}

int hts_get_verbosity(void)
{
  return hts_verbose;
}


// taken from samtools/bam_import.c
static inline uint8_t * alloc_data(bam1_t *b, size_t size)
{
  if (b->m_data < size)
    {
      b->m_data = size;
      kroundup32(b->m_data);
      b->data = (uint8_t*)realloc(b->data, b->m_data);
    }
  return b->data;
}

// update the variable length data within a bam1_t entry.
// Adds *nbytes_new* - *nbytes_old* into the variable length data of *src* at *pos*.
// Data within the bam1_t entry is moved so that it is
// consistent with the data field lengths.
// Return NULL on error (memory allocation)
bam1_t * pysam_bam_update(bam1_t * b,
			  const size_t nbytes_old,
			  const size_t nbytes_new, 
			  uint8_t * field_start)
{
  int d = nbytes_new - nbytes_old;
  int new_size;
  size_t nbytes_before;
  uint8_t * retval = NULL;
    
  // no change
  if (d == 0)
    return b;

  // new size of total data
  new_size = d + b->l_data;
  
  // fields before field in data
  nbytes_before = field_start - b->data;

  if (b->l_data != 0)
    {
      assert(nbytes_before >= 0);
      assert(nbytes_before <= b->l_data);
    }

  // increase memory if required
  if (d > 0)
    {
      retval = alloc_data(b, new_size);
      if (retval == NULL)
	return NULL;
      field_start = b->data + nbytes_before;
    }
  
  // move data after field to new location
  memmove(field_start + nbytes_new,
	  field_start + nbytes_old,
	  b->l_data - (nbytes_before + nbytes_old));

  // adjust l_data
  b->l_data = new_size;
      
  return b;
}

// translate a nucleotide character to binary code
unsigned char pysam_translate_sequence(const unsigned char s)
{
  return seq_nt16_table[s];
}

// Auxiliary functions for B support
void bam_aux_appendB(bam1_t *b,
		     const char tag[2],
		     char type,
		     char subtype,
		     int len,
		     uint8_t *data)
{

  int ori_len;
  int l_data;

  // check that type is 'B'
  if('B' != type) return;

  ori_len = b->l_data;

  l_data = len * aux_type2size(subtype);
  // infer the data length from the sub-type
  b->l_data += 8 + l_data;

  // htslib: obsolete?
  // b->l_aux += 8 + l_data;
  if (b->m_data < b->l_data) 
    {
      b->m_data = b->l_data;
      kroundup32(b->m_data);
      b->data = (uint8_t*)realloc(b->data, b->m_data);
    }

  b->data[ori_len] = tag[0];
  b->data[ori_len + 1] = tag[1];
  // tag
  b->data[ori_len + 2] = type;
  // type
  b->data[ori_len + 3] = subtype;
  // subtype
  (*(int32_t*)(b->data + ori_len + 4)) = len;
  // size
  memcpy(b->data + ori_len + 8, data, l_data);
  // data
}

int aux_type2size(uint8_t type)
{
	switch (type) {
	case 'A': case 'c': case 'C':
		return 1;
	case 's': case 'S':
		return 2;
	case 'i': case 'I': case 'f':
		return 4;
	case 'd':
		return 8;
	case 'Z': case 'H': case 'B':
		return type;
	default:
		return 0;
	}
}