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_BI_SEED_TAB;
31using hashing_internals::BI_BI_MS_TAB_33R;
33using hashing_internals::BI_BI_MS_TAB_31L;
35using hashing_internals::BI_BI_CONVERT_TAB;
37using hashing_internals::BI_BI_RC_CONVERT_TAB;
39using hashing_internals::BI_BI_DIMER_TAB;
40using hashing_internals::BI_BI_TETRAMER_TAB;
41using hashing_internals::BI_BI_TRIMER_TAB;
60 hashing_internals::NUM_HASHES_TYPE num_hashes,
61 hashing_internals::K_TYPE k,
65 , num_hashes(num_hashes)
69 , hash_arr(new uint64_t[num_hashes])
71 check_error(k == 0,
"BiHash: k must be greater than 0");
73 check_error((k / 2) % 2 == 0,
"BiHash: k must have odd number of dimers");
75 "BiHash: sequence length (" + std::to_string(this->seq_len) +
76 ") is smaller than k (" + std::to_string(k) +
")");
78 "BiHash: passed position (" + std::to_string(pos) +
79 ") is larger than sequence length (" +
80 std::to_string(this->seq_len) +
")");
82 size_t num_dimers = k / 2;
83 size_t center_dimer_start = (num_dimers / 2) * 2;
84 meth_base_idx = center_dimer_start;
86 primitive_tab = BI_BI_SEED_TAB;
88 right_table = BI_BI_MS_TAB_33R;
89 left_table = BI_BI_MS_TAB_31L;
91 convert_tab = BI_BI_CONVERT_TAB;
92 rc_convert_tab = BI_BI_RC_CONVERT_TAB;
94 dimer_tab = BI_BI_DIMER_TAB;
95 trimer_tab = BI_BI_TRIMER_TAB;
96 tetramer_tab = BI_BI_TETRAMER_TAB;
107 hashing_internals::NUM_HASHES_TYPE num_hashes,
108 hashing_internals::K_TYPE k,
110 :
BiHashBi(seq.data(), seq.size(), num_hashes, k, pos)
116 , seq_len(obj.seq_len)
117 , num_hashes(obj.num_hashes)
120 , initialized(obj.initialized)
121 , fwd_hash(obj.fwd_hash)
122 , rev_hash(obj.rev_hash)
123 , hash_arr(new uint64_t[obj.num_hashes])
124 , primitive_tab(obj.primitive_tab)
125 , right_table(obj.right_table)
126 , left_table(obj.left_table)
127 , convert_tab(obj.convert_tab)
128 , rc_convert_tab(obj.rc_convert_tab)
129 , dimer_tab(obj.dimer_tab)
130 , trimer_tab(obj.trimer_tab)
131 , tetramer_tab(obj.tetramer_tab)
134 hash_arr.get(), obj.hash_arr.get(), num_hashes *
sizeof(uint64_t));
155 if (pos >= seq_len - k) {
158 if (hashing_internals::SEED_TAB[(
unsigned char)seq[pos + k]] ==
159 hashing_internals::SEED_N) {
163 fwd_hash = next_forward_hash(fwd_hash,
170 rev_hash = next_reverse_hash(rev_hash,
177 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
194 if (SEED_TAB[(
unsigned char)seq[pos - 1]] == SEED_N && pos >= k) {
198 if (SEED_TAB[(
unsigned char)seq[pos - 1]] == SEED_N) {
201 fwd_hash = prev_forward_hash(fwd_hash,
208 rev_hash = prev_reverse_hash(rev_hash,
215 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
228 if (pos >= seq_len - k) {
231 return peek(seq[pos + k]);
257 if (SEED_TAB[(
unsigned char)char_in] == SEED_N) {
260 const uint64_t fwd = next_forward_hash(
261 fwd_hash, k, seq[pos], char_in, primitive_tab, right_table, left_table);
262 const uint64_t rev = next_reverse_hash(
263 rev_hash, k, seq[pos], char_in, primitive_tab, right_table, left_table);
264 extend_hashes(fwd, rev, k, num_hashes, hash_arr.get());
277 if (SEED_TAB[(
unsigned char)char_in] == SEED_N) {
280 const unsigned char char_out = seq[pos + k - 1];
281 const uint64_t fwd = prev_forward_hash(
282 fwd_hash, k, char_out, char_in, primitive_tab, right_table, left_table);
283 const uint64_t rev = prev_reverse_hash(
284 rev_hash, k, char_out, char_in, primitive_tab, right_table, left_table);
285 extend_hashes(fwd, rev, k, num_hashes, hash_arr.get());
301 constexpr size_t DIMER_LEN = 2;
302 const size_t center_idx = pos + (k / 4) * DIMER_LEN;
303 return std::string_view(seq + center_idx, DIMER_LEN);
317 char base = seq[pos + meth_base_idx + offset];
319 return base ==
'C' || base ==
'c';
321 return base ==
'G' || base ==
'g';
331 void sub(
const std::vector<unsigned>& positions,
332 const std::vector<unsigned char>& new_bases)
350 const uint64_t*
hashes()
const {
return hash_arr.get(); }
363 hashing_internals::NUM_HASHES_TYPE
get_hash_num()
const {
return num_hashes; }
369 hashing_internals::K_TYPE
get_k()
const {
return k; }
385 const size_t seq_len;
386 hashing_internals::NUM_HASHES_TYPE num_hashes;
387 hashing_internals::K_TYPE k;
389 size_t meth_base_idx;
391 uint64_t fwd_hash = 0;
392 uint64_t rev_hash = 0;
393 std::unique_ptr<uint64_t[]> hash_arr;
395 const uint64_t* primitive_tab;
397 const uint64_t*
const* right_table;
398 const uint64_t*
const* left_table;
400 const uint8_t* convert_tab;
401 const uint8_t* rc_convert_tab;
403 const uint64_t* dimer_tab;
404 const uint64_t* trimer_tab;
405 const uint64_t* tetramer_tab;
414 while (pos <= seq_len - k + 1 && has_n) {
416 for (
unsigned i = 0; i < k && pos <= seq_len - k + 1; i++) {
417 if (SEED_TAB[(
unsigned char)seq[pos + k - i - 1]] == SEED_N) {
423 if (pos > seq_len - k) {
426 fwd_hash = base_forward_hash(seq + pos,
433 rev_hash = base_reverse_hash(seq + pos,
440 extend_hashes(fwd_hash, rev_hash, k, num_hashes, hash_arr.get());
Definition bihash_kmer_bi.hpp:47
bool peek(char char_in)
Definition bihash_kmer_bi.hpp:252
size_t get_pos() const
Definition bihash_kmer_bi.hpp:357
bool roll()
Definition bihash_kmer_bi.hpp:150
bool roll_back()
Definition bihash_kmer_bi.hpp:186
BiHashBi(const std::string &seq, hashing_internals::NUM_HASHES_TYPE num_hashes, hashing_internals::K_TYPE k, size_t pos=0)
Definition bihash_kmer_bi.hpp:106
bool is_methylated(int offset)
Definition bihash_kmer_bi.hpp:315
bool peek_back(char char_in)
Definition bihash_kmer_bi.hpp:272
BiHashBi(const char *seq, size_t seq_len, hashing_internals::NUM_HASHES_TYPE num_hashes, hashing_internals::K_TYPE k, size_t pos=0)
Definition bihash_kmer_bi.hpp:58
hashing_internals::NUM_HASHES_TYPE get_hash_num() const
Definition bihash_kmer_bi.hpp:363
hashing_internals::K_TYPE get_k() const
Definition bihash_kmer_bi.hpp:369
bool is_forward_higher() const
Definition bihash_kmer_bi.hpp:329
std::string_view center_dimer() const
Definition bihash_kmer_bi.hpp:299
uint64_t get_forward_hash() const
Definition bihash_kmer_bi.hpp:375
const uint64_t * hashes() const
Definition bihash_kmer_bi.hpp:350
bool peek_back()
Definition bihash_kmer_bi.hpp:238
bool peek()
Definition bihash_kmer_bi.hpp:226
uint64_t get_reverse_hash() const
Definition bihash_kmer_bi.hpp:381
void check_error(bool condition, const std::string &msg)