cuDDL
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | List of all members
cuddl::kmer_blacklist Class Reference

Immutable canonical k-mers excluded from construction, independent of sketch size. More...

Public Member Functions

 kmer_blacklist ()=default
 
 kmer_blacklist (uint32_t k, std::vector< uint64_t > keys)
 Validates packed canonical words and normalizes their order and duplicates.
 
uint32_t kmer_length () const noexcept
 
uint64_t identity () const noexcept
 
uint8_t version () const noexcept
 
std::vector< uint64_t > const & keys () const noexcept
 

Static Public Member Functions

static Result< kmer_blacklist > load (std::filesystem::path const &path, uint32_t k)
 Reads BBTools DDL FASTA/FASTQ, including gzip and fused records, or exact DNA lines.
 
static uint64_t canonical (uint64_t word, uint32_t k) noexcept
 

Detailed Description

Immutable canonical k-mers excluded from construction, independent of sketch size.

Definition at line 77 of file blacklist.cuh.

Constructor & Destructor Documentation

◆ kmer_blacklist() [1/2]

cuddl::kmer_blacklist::kmer_blacklist ( )
default

◆ kmer_blacklist() [2/2]

cuddl::kmer_blacklist::kmer_blacklist ( uint32_t  k,
std::vector< uint64_t >  keys 
)
inline

Validates packed canonical words and normalizes their order and duplicates.

Definition at line 82 of file blacklist.cuh.

82 : k_(k), keys_(std::move(keys)) {
83 if (k < 1 || k > 31 || keys_.size() > std::numeric_limits<uint32_t>::max()) {
84 throw std::invalid_argument("invalid blacklist k or entry count");
85 }
86
87 for (auto key : keys_) {
88 if ((key >> (2 * k)) != 0 || canonical(key, k) != key) {
89 throw std::invalid_argument("blacklist words must be canonical packed k-mers");
90 }
91 }
92
93 std::sort(keys_.begin(), keys_.end());
94 keys_.erase(std::unique(keys_.begin(), keys_.end()), keys_.end());
95
96 if (keys_.empty()) {
97 k_ = 0;
98 return;
99 }
100 // Explicit little-endian words make identity independent of host byte order.
101 std::vector<uint64_t> words;
102 words.reserve(keys_.size() + 3);
103 words.insert(words.end(), {uint64_t{1}, k, keys_.size()});
104 words.insert(words.end(), keys_.begin(), keys_.end());
105
106 if constexpr (std::endian::native != std::endian::little) {
107 for (auto& word : words) {
108 word = cuda::std::byteswap(word);
109 }
110 }
111
112 identity_ = detail::xxhash64(
113 reinterpret_cast<uint8_t const*>(words.data()),
114 words.size() * sizeof(uint64_t),
115 0x435544444c424c31ULL // CUDDLBL1
116 );
117
118 if (identity_ == 0) identity_ = 1;
119 }
static uint64_t canonical(uint64_t word, uint32_t k) noexcept
std::vector< uint64_t > const & keys() const noexcept
__host__ __device__ uint64_t xxhash64(const uint8_t *bytes, uint64_t size, uint64_t seed)
Computes xxHash-64 over a byte range without allocating or copying it.
Definition hash.cuh:63
auto const words
Definition top_k.cuh:204
auto const word
Definition top_k.cuh:241
Here is the call graph for this function:

Member Function Documentation

◆ canonical()

static uint64_t cuddl::kmer_blacklist::canonical ( uint64_t  word,
uint32_t  k 
)
inlinestaticnoexcept

Definition at line 189 of file blacklist.cuh.

189 {
190 return std::max(word, detail::reverse_complement(word, k));
191 }
constexpr uint64_t reverse_complement(uint64_t packed, uint32_t k) noexcept
Reverse-complements a packed k-mer (2 bits per base) with bit-parallel reversal.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ identity()

uint64_t cuddl::kmer_blacklist::identity ( ) const
inlinenoexcept

Definition at line 179 of file blacklist.cuh.

179 {
180 return identity_;
181 }
Here is the caller graph for this function:

◆ keys()

std::vector< uint64_t > const & cuddl::kmer_blacklist::keys ( ) const
inlinenoexcept

Definition at line 185 of file blacklist.cuh.

185 {
186 return keys_;
187 }
Here is the caller graph for this function:

◆ kmer_length()

uint32_t cuddl::kmer_blacklist::kmer_length ( ) const
inlinenoexcept

Definition at line 176 of file blacklist.cuh.

176 {
177 return k_;
178 }
Here is the caller graph for this function:

◆ load()

static Result< kmer_blacklist > cuddl::kmer_blacklist::load ( std::filesystem::path const &  path,
uint32_t  k 
)
inlinestatic

Reads BBTools DDL FASTA/FASTQ, including gzip and fused records, or exact DNA lines.

FASTX contributes every valid k-mer window; ambiguity and record boundaries reset it.

Definition at line 124 of file blacklist.cuh.

124 {
125 if (k < 1 || k > 31) return Err(Error::invalid_argument("invalid blacklist k"));
126
127 std::ifstream input(path);
128 if (!input) return Err(Error::resource("cannot open blacklist: " + path.string()));
129
130 input >> std::ws;
131 auto const first = input.peek();
132 if (first == '>' || first == '@' || first == 0x1f) {
133 auto parsed = parse_fasta_file(path.string(), k, 1);
134 if (!parsed) return Err(parsed.error());
135 return kmer_blacklist(k, std::move(parsed->kmers));
136 }
137 input.clear();
138 input.seekg(0);
139 std::vector<uint64_t> keys;
140 std::string line;
141 size_t number = 0;
142
143 while (std::getline(input, line)) {
144 ++number;
145 if (!line.empty() && line.back() == '\r') line.pop_back();
146 if (line.empty()) continue;
147 if (line.size() != k) {
148 return Err(
150 "invalid blacklist length at line " + std::to_string(number)
151 )
152 );
153 }
154 uint64_t word = 0;
155 for (char base : line) {
156 auto const code = detail::encode_base(base);
157 if (code == 0xffU) {
158 return Err(
160 "invalid blacklist base at line " + std::to_string(number)
161 )
162 );
163 }
164 word = (word << 2) | code;
165 }
166 keys.push_back(canonical(word, k));
167 }
168 if (!input.eof()) return Err(Error::resource("cannot read blacklist: " + path.string()));
169 return kmer_blacklist(k, std::move(keys));
170 } catch (std::invalid_argument const& error) {
171 return Err(Error::invalid_argument(error.what()));
172 } catch (std::bad_alloc const& error) {
173 return Err(Error::resource(error.what()));
174 }
constexpr uint8_t encode_base(char base) noexcept
Maps one DNA byte to its 2-bit symbol (A=0, C=1, T=2, G=3) or 0xff when invalid.
Definition dna.hpp:16
Result< fasta_parse_result > parse_fasta_file(std::string const &path, uint32_t k, unsigned threads=std::thread::hardware_concurrency())
Parses a FASTA/FASTQ file's sequence bases into packed canonical k-mers of length k.
Definition fastx.hpp:34
cuda::std::unexpected< Error > Err(Error error)
Failure return; converts to any Result<T> via cuda::std::unexpected.
Definition error.hpp:176
static Error invalid_argument(std::string message)
Definition error.hpp:99
static Error resource(std::string message)
Definition error.hpp:103
Here is the call graph for this function:

◆ version()

uint8_t cuddl::kmer_blacklist::version ( ) const
inlinenoexcept

Definition at line 182 of file blacklist.cuh.

182 {
183 return keys_.empty() ? 0U : 1U;
184 }
Here is the caller graph for this function:

The documentation for this class was generated from the following file: