11#include <btllib/bihash_hashing_internals.hpp>
12#include <btllib/hashing_internals.hpp>
13#include <btllib/nthash_kmer.hpp>
14#include <btllib/status.hpp>
18using hashing_internals::base_forward_hash;
19using hashing_internals::base_reverse_hash;
20using hashing_internals::extend_hashes;
21using hashing_internals::next_forward_hash;
22using hashing_internals::next_reverse_hash;
23using hashing_internals::prev_forward_hash;
24using hashing_internals::prev_reverse_hash;
25using hashing_internals::SEED_N;
26using hashing_internals::SEED_TAB;
27using hashing_internals::sub_hash;
29using hashing_internals::BI_CT_SEED_TAB;
30using hashing_internals::BI_GA_SEED_TAB;
32using hashing_internals::BI_CT_MS_TAB_33R;
33using hashing_internals::BI_GA_MS_TAB_33R;
35using hashing_internals::BI_CT_MS_TAB_31L;
36using hashing_internals::BI_GA_MS_TAB_31L;
38using hashing_internals::BI_CT_CONVERT_TAB;
39using hashing_internals::BI_GA_CONVERT_TAB;
41using hashing_internals::BI_CT_RC_CONVERT_TAB;
42using hashing_internals::BI_GA_RC_CONVERT_TAB;
44using hashing_internals::BI_CT_DIMER_TAB;
45using hashing_internals::BI_CT_TETRAMER_TAB;
46using hashing_internals::BI_CT_TRIMER_TAB;
47using hashing_internals::BI_GA_DIMER_TAB;
48using hashing_internals::BI_GA_TETRAMER_TAB;
49using hashing_internals::BI_GA_TRIMER_TAB;
70 hashing_internals::NUM_HASHES_TYPE num_hashes,
71 hashing_internals::K_TYPE k,
72 std::string conversion_type,
76 , num_hashes(num_hashes)
78 , conversion_type(conversion_type)
81 , hash_arr(new uint64_t[num_hashes])
83 check_error(k == 0,
"BiHash: k must be greater than 0");
85 check_error((k / 2) % 2 == 0,
"BiHash: k must have odd number of dimers");
87 "BiHash: sequence length (" + std::to_string(this->seq_len) +
88 ") is smaller than k (" + std::to_string(k) +
")");
90 "BiHash: passed position (" + std::to_string(pos) +
91 ") is larger than sequence length (" +
92 std::to_string(this->seq_len) +
")");
94 size_t num_dimers = k / 2;
95 size_t center_dimer_start = (num_dimers / 2) * 2;
96 if (conversion_type ==
"CT") {
97 meth_base_idx = center_dimer_start;
99 primitive_tab = BI_CT_SEED_TAB;
101 right_table = BI_CT_MS_TAB_33R;
102 left_table = BI_CT_MS_TAB_31L;
104 convert_tab = BI_CT_CONVERT_TAB;
105 rc_convert_tab = BI_CT_RC_CONVERT_TAB;
107 dimer_tab = BI_CT_DIMER_TAB;
108 rc_dimer_tab = BI_GA_DIMER_TAB;
109 trimer_tab = BI_CT_TRIMER_TAB;
110 rc_trimer_tab = BI_GA_TRIMER_TAB;
111 tetramer_tab = BI_CT_TETRAMER_TAB;
113 rc_tetramer_tab = BI_GA_TETRAMER_TAB;
114 }
else if (conversion_type ==
"GA") {
115 meth_base_idx = center_dimer_start + 1;
117 primitive_tab = BI_GA_SEED_TAB;
119 right_table = BI_GA_MS_TAB_33R;
120 left_table = BI_GA_MS_TAB_31L;
122 convert_tab = BI_GA_CONVERT_TAB;
123 rc_convert_tab = BI_GA_RC_CONVERT_TAB;
125 dimer_tab = BI_GA_DIMER_TAB;
126 rc_dimer_tab = BI_CT_DIMER_TAB;
127 trimer_tab = BI_GA_TRIMER_TAB;
128 rc_trimer_tab = BI_CT_TRIMER_TAB;
129 tetramer_tab = BI_GA_TETRAMER_TAB;
130 rc_tetramer_tab = BI_CT_TETRAMER_TAB;
133 true,
"Unsupported conversion_type. Must be CT or GA, as capitalized.");
147 hashing_internals::NUM_HASHES_TYPE num_hashes,
148 hashing_internals::K_TYPE k,
149 std::string conversion_type,
162 , seq_len(obj.seq_len)
163 , num_hashes(obj.num_hashes)
165 , conversion_type(obj.conversion_type)
167 , initialized(obj.initialized)
168 , fwd_hash(obj.fwd_hash)
169 , rev_hash(obj.rev_hash)
170 , hash_arr(new uint64_t[obj.num_hashes])
171 , primitive_tab(obj.primitive_tab)
172 , right_table(obj.right_table)
173 , left_table(obj.left_table)
174 , convert_tab(obj.convert_tab)
175 , rc_convert_tab(obj.rc_convert_tab)
176 , dimer_tab(obj.dimer_tab)
177 , rc_dimer_tab(obj.rc_dimer_tab)
178 , trimer_tab(obj.trimer_tab)
179 , rc_trimer_tab(obj.rc_trimer_tab)
180 , tetramer_tab(obj.tetramer_tab)
181 , rc_tetramer_tab(obj.rc_tetramer_tab)
184 hash_arr.get(), obj.hash_arr.get(), num_hashes *
sizeof(uint64_t));
205 if (pos >= seq_len - k) {
208 if (hashing_internals::SEED_TAB[(
unsigned char)seq[pos + k]] ==
209 hashing_internals::SEED_N) {
213 fwd_hash = next_forward_hash(fwd_hash,
220 rev_hash = next_reverse_hash(rev_hash,
227 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
244 if (SEED_TAB[(
unsigned char)seq[pos - 1]] == SEED_N && pos >= k) {
248 if (SEED_TAB[(
unsigned char)seq[pos - 1]] == SEED_N) {
251 fwd_hash = prev_forward_hash(fwd_hash,
258 rev_hash = prev_reverse_hash(rev_hash,
265 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
278 if (pos >= seq_len - k) {
281 return peek(seq[pos + k]);
307 if (SEED_TAB[(
unsigned char)char_in] == SEED_N) {
310 const uint64_t fwd = next_forward_hash(
311 fwd_hash, k, seq[pos], char_in, primitive_tab, right_table, left_table);
312 const uint64_t rev = next_reverse_hash(
313 rev_hash, k, seq[pos], char_in, primitive_tab, right_table, left_table);
314 extend_hashes(fwd, rev, k, num_hashes, hash_arr.get());
327 if (SEED_TAB[(
unsigned char)char_in] == SEED_N) {
330 const unsigned char char_out = seq[pos + k - 1];
331 const uint64_t fwd = prev_forward_hash(
332 fwd_hash, k, char_out, char_in, primitive_tab, right_table, left_table);
333 const uint64_t rev = prev_reverse_hash(
334 rev_hash, k, char_out, char_in, primitive_tab, right_table, left_table);
335 extend_hashes(fwd, rev, k, num_hashes, hash_arr.get());
350 char base = seq[pos + meth_base_idx];
352 if (conversion_type ==
"CT")
353 return base ==
'C' || base ==
'c';
355 return base ==
'G' || base ==
'g';
364 void sub(
const std::vector<unsigned>& positions,
365 const std::vector<unsigned char>& new_bases)
383 const uint64_t*
hashes()
const {
return hash_arr.get(); }
396 hashing_internals::NUM_HASHES_TYPE
get_hash_num()
const {
return num_hashes; }
402 hashing_internals::K_TYPE
get_k()
const {
return k; }
418 const size_t seq_len;
419 hashing_internals::NUM_HASHES_TYPE num_hashes;
420 hashing_internals::K_TYPE k;
421 std::string conversion_type;
423 size_t meth_base_idx;
425 uint64_t fwd_hash = 0;
426 uint64_t rev_hash = 0;
427 std::unique_ptr<uint64_t[]> hash_arr;
429 const uint64_t* primitive_tab;
431 const uint64_t*
const* right_table;
432 const uint64_t*
const* left_table;
434 const uint8_t* convert_tab;
435 const uint8_t* rc_convert_tab;
437 const uint64_t* dimer_tab;
438 const uint64_t* rc_dimer_tab;
439 const uint64_t* trimer_tab;
440 const uint64_t* rc_trimer_tab;
441 const uint64_t* tetramer_tab;
442 const uint64_t* rc_tetramer_tab;
451 while (pos <= seq_len - k + 1 && has_n) {
453 for (
unsigned i = 0; i < k && pos <= seq_len - k + 1; i++) {
454 if (SEED_TAB[(
unsigned char)seq[pos + k - i - 1]] == SEED_N) {
460 if (pos > seq_len - k) {
463 fwd_hash = base_forward_hash(seq + pos,
470 rev_hash = base_reverse_hash(seq + pos,
477 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
Definition bihash_kmer_directional.hpp:55
BiHashDirectional(const std::string &seq, hashing_internals::NUM_HASHES_TYPE num_hashes, hashing_internals::K_TYPE k, std::string conversion_type, size_t pos=0)
Definition bihash_kmer_directional.hpp:146
bool peek()
Definition bihash_kmer_directional.hpp:276
uint64_t get_forward_hash() const
Definition bihash_kmer_directional.hpp:408
bool peek_back()
Definition bihash_kmer_directional.hpp:288
hashing_internals::NUM_HASHES_TYPE get_hash_num() const
Definition bihash_kmer_directional.hpp:396
size_t get_pos() const
Definition bihash_kmer_directional.hpp:390
hashing_internals::K_TYPE get_k() const
Definition bihash_kmer_directional.hpp:402
bool peek_back(char char_in)
Definition bihash_kmer_directional.hpp:322
bool roll()
Definition bihash_kmer_directional.hpp:200
bool peek(char char_in)
Definition bihash_kmer_directional.hpp:302
bool is_methylated()
Definition bihash_kmer_directional.hpp:348
BiHashDirectional(const char *seq, size_t seq_len, hashing_internals::NUM_HASHES_TYPE num_hashes, hashing_internals::K_TYPE k, std::string conversion_type, size_t pos=0)
Definition bihash_kmer_directional.hpp:68
bool is_forward_higher() const
Definition bihash_kmer_directional.hpp:362
const uint64_t * hashes() const
Definition bihash_kmer_directional.hpp:383
uint64_t get_reverse_hash() const
Definition bihash_kmer_directional.hpp:414
bool roll_back()
Definition bihash_kmer_directional.hpp:236
void check_error(bool condition, const std::string &msg)