nthash_lowlevel.hpp
/*
* nthash_lowlevel.hpp
* Author: Hamid Mohamadi
* Genome Sciences Centre,
* British Columbia Cancer Agency
*/
#ifndef BTLLIB_NTHASH_LOWLEVEL_HPP
#define BTLLIB_NTHASH_LOWLEVEL_HPP
#include "btllib/nthash_consts.hpp"
#include <array>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <vector>
namespace btllib {
template<typename T>
inline T
canonical(const T fwd, const T rev)
{
return fwd + rev;
}
static_assert(std::numeric_limits<unsigned>::max() + 1 == 0,
"Integers don't overflow on this platform which is necessary for "
"ntHash canonical hash computation.");
// Data structures for spaced seeds
// List of don't care positions
using SpacedSeed = std::vector<unsigned>;
// Bx2 array representing block start and end positions.
using SpacedSeedBlocks = std::vector<std::array<unsigned, 2>>;
// List of blocks with sizes of one.
using SpacedSeedMonomers = std::vector<unsigned>;
inline uint64_t
srol(const uint64_t x)
{
uint64_t m = ((x & 0x8000000000000000ULL) >> 30) | // NOLINT
((x & 0x100000000ULL) >> 32); // NOLINT
return ((x << 1) & 0xFFFFFFFDFFFFFFFFULL) | m; // NOLINT
}
inline uint64_t
srol(const uint64_t x, const unsigned d)
{
uint64_t v = (x << d) | (x >> (64 - d)); // NOLINT
uint64_t y = (v ^ (v >> 33)) & // NOLINT
(std::numeric_limits<uint64_t>::max() >> (64 - d)); // NOLINT
return v ^ (y | (y << 33)); // NOLINT
}
inline uint64_t
sror(const uint64_t x)
{
uint64_t m = ((x & 0x200000000ULL) << 30) | ((x & 1ULL) << 32); // NOLINT
return ((x >> 1) & 0xFFFFFFFEFFFFFFFFULL) | m; // NOLINT
}
uint64_t
ntf64(const char* kmer_seq, unsigned k);
uint64_t
ntr64(const char* kmer_seq, unsigned k);
uint64_t
ntf64(uint64_t fh_val,
unsigned k,
unsigned char char_out,
unsigned char char_in);
uint64_t
ntr64(uint64_t rh_val,
unsigned k,
unsigned char char_out,
unsigned char char_in);
uint64_t
ntc64(const char* kmer_seq, unsigned k);
uint64_t
ntc64(const char* kmer_seq, unsigned k, uint64_t& fh_val, uint64_t& rh_val);
uint64_t
ntc64(unsigned char char_out,
unsigned char char_in,
unsigned k,
uint64_t& fh_val,
uint64_t& rh_val);
uint64_t
ntf64l(uint64_t rh_val,
unsigned k,
unsigned char char_out,
unsigned char char_in);
uint64_t
ntr64l(uint64_t fh_val,
unsigned k,
unsigned char char_out,
unsigned char char_in);
uint64_t
ntc64l(unsigned char char_out,
unsigned char char_in,
unsigned k,
uint64_t& fh_val,
uint64_t& rh_val);
void
nte64(uint64_t bh_val, unsigned k, unsigned h, uint64_t* h_val);
void
ntmc64(const char* kmer_seq, unsigned k, unsigned m, uint64_t* h_val);
void
ntmc64(const char* kmer_seq,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
uint64_t* h_val);
void
ntmc64(unsigned char char_out,
unsigned char char_in,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
uint64_t* h_val);
void
ntmc64l(unsigned char char_out,
unsigned char char_in,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
uint64_t* h_val);
bool
ntc64(const char* kmer_seq, unsigned k, uint64_t& h_val, unsigned& loc_n);
bool
ntmc64(const char* kmer_seq,
unsigned k,
unsigned m,
unsigned& loc_n,
uint64_t* h_val);
bool
ntc64(const char* kmer_seq,
unsigned k,
uint64_t& fh_val,
uint64_t& rh_val,
uint64_t& h_val,
unsigned& loc_n);
bool
ntmc64(const char* kmer_seq,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
unsigned& loc_n,
uint64_t* h_val);
bool
ntmc64(const char* kmer_seq,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
unsigned& loc_n,
uint64_t* h_val,
bool& h_stn);
void
ntmc64(unsigned char char_out,
unsigned char char_in,
unsigned k,
unsigned m,
uint64_t& fh_val,
uint64_t& rh_val,
uint64_t* h_val,
bool& h_stn);
uint64_t
mask_hash(uint64_t& fk_val,
uint64_t& rk_val,
const char* seed_seq,
const char* kmer_seq,
unsigned k);
void
sub_hash(uint64_t fh_val,
uint64_t rh_val,
const char* kmer_seq,
const std::vector<unsigned>& positions,
const std::vector<unsigned char>& new_bases,
unsigned k,
unsigned m,
uint64_t* h_val);
bool
ntmsm64(const char* kmer_seq,
const std::vector<SpacedSeedBlocks>& seeds_blocks,
const std::vector<SpacedSeedMonomers>& seeds_monomers,
unsigned k,
unsigned m,
unsigned m2,
uint64_t* fh_nomonos,
uint64_t* rh_nomonos,
uint64_t* fh_val,
uint64_t* rh_val,
unsigned& loc_n,
uint64_t* h_val);
#define NTMSM64(ROL_HANDLING, IN_HANDLING, OUT_HANDLING, ROR_HANDLING) \
unsigned char char_out, char_in; \
uint64_t fh_seed, rh_seed; \
unsigned i_out, i_in, i_base; \
for (unsigned i_seed = 0; i_seed < m; i_seed++) { \
ROL_HANDLING /* NOLINT(bugprone-macro-parentheses) */ \
for (const auto& block : seeds_blocks[i_seed]) \
{ \
IN_HANDLING \
OUT_HANDLING \
fh_seed ^= MS_TAB(char_out, k - i_out); \
fh_seed ^= MS_TAB(char_in, k - i_in); \
rh_seed ^= MS_TAB(char_out & CP_OFF, i_out); \
rh_seed ^= MS_TAB(char_in & CP_OFF, i_in); \
} \
ROR_HANDLING /* NOLINT(bugprone-macro-parentheses) */ \
fh_nomonos[i_seed] = fh_seed; \
rh_nomonos[i_seed] = rh_seed; \
for (const auto& pos : seeds_monomers[i_seed]) { \
fh_seed ^= MS_TAB((unsigned char)kmer_seq[pos + 1], k - 1 - pos); \
rh_seed ^= MS_TAB((unsigned char)kmer_seq[pos + 1] & CP_OFF, pos); \
} \
fh_val[i_seed] = fh_seed; \
rh_val[i_seed] = rh_seed; \
i_base = i_seed * m2; \
h_val[i_base] = canonical(fh_seed, rh_seed); \
for (unsigned i_hash = 1; i_hash < m2; i_hash++) { \
h_val[i_base + i_hash] = h_val[i_base] * (i_hash ^ k * MULTISEED); \
h_val[i_base + i_hash] ^= h_val[i_base + i_hash] >> MULTISHIFT; \
} \
}
void
ntmsm64(const char* kmer_seq,
const std::vector<SpacedSeedBlocks>& seeds_blocks,
const std::vector<SpacedSeedMonomers>& seeds_monomers,
unsigned k,
unsigned m,
unsigned m2,
uint64_t* fh_nomonos,
uint64_t* rh_nomonos,
uint64_t* fh_val,
uint64_t* rh_val,
uint64_t* h_val);
void
ntmsm64l(const char* kmer_seq,
const std::vector<SpacedSeedBlocks>& seeds_blocks,
const std::vector<SpacedSeedMonomers>& seeds_monomers,
unsigned k,
unsigned m,
unsigned m2,
uint64_t* fh_nomonos,
uint64_t* rh_nomonos,
uint64_t* fh_val,
uint64_t* rh_val,
uint64_t* h_val);
void
ntmsm64(const char* kmer_seq,
char in,
const std::vector<SpacedSeedBlocks>& seeds_blocks,
const std::vector<SpacedSeedMonomers>& seeds_monomers,
unsigned k,
unsigned m,
unsigned m2,
uint64_t* fh_nomonos,
uint64_t* rh_nomonos,
uint64_t* fh_val,
uint64_t* rh_val,
uint64_t* h_val);
void
ntmsm64l(const char* kmer_seq,
char in,
const std::vector<SpacedSeedBlocks>& seeds_blocks,
const std::vector<SpacedSeedMonomers>& seeds_monomers,
unsigned k,
unsigned m,
unsigned m2,
uint64_t* fh_nomonos,
uint64_t* rh_nomonos,
uint64_t* fh_val,
uint64_t* rh_val,
uint64_t* h_val);
} // namespace btllib
#endif
btllib
Definition: bloom_filter.hpp:16
btllib::ntf64l
uint64_t ntf64l(uint64_t rh_val, unsigned k, unsigned char char_out, unsigned char char_in)
btllib::sub_hash
void sub_hash(uint64_t fh_val, uint64_t rh_val, const char *kmer_seq, const std::vector< unsigned > &positions, const std::vector< unsigned char > &new_bases, unsigned k, unsigned m, uint64_t *h_val)
btllib::ntr64l
uint64_t ntr64l(uint64_t fh_val, unsigned k, unsigned char char_out, unsigned char char_in)
btllib::srol
uint64_t srol(const uint64_t x)
Definition: nthash_lowlevel.hpp:51
btllib::mask_hash
uint64_t mask_hash(uint64_t &fk_val, uint64_t &rk_val, const char *seed_seq, const char *kmer_seq, unsigned k)
btllib::ntc64l
uint64_t ntc64l(unsigned char char_out, unsigned char char_in, unsigned k, uint64_t &fh_val, uint64_t &rh_val)
btllib::sror
uint64_t sror(const uint64_t x)
Definition: nthash_lowlevel.hpp:85
btllib::ntc64
uint64_t ntc64(const char *kmer_seq, unsigned k)
btllib::ntr64
uint64_t ntr64(const char *kmer_seq, unsigned k)
btllib::nte64
void nte64(uint64_t bh_val, unsigned k, unsigned h, uint64_t *h_val)
btllib::ntf64
uint64_t ntf64(const char *kmer_seq, unsigned k)