71 template<
class BarcodePoolContainer>
73 my_forward(search_forward(options.strand)),
74 my_reverse(search_reverse(options.strand)),
75 my_max_mm(options.max_mismatches),
76 my_use_first(options.use_first),
77 my_constant_matcher(template_seq, template_length, options.strand)
79 const auto& regions = my_constant_matcher.forward_variable_regions();
80 if (regions.size() != num_variable_) {
81 throw std::runtime_error(
"expected " + std::to_string(num_variable_) +
" variable regions in the constant template");
83 if (barcode_pools.size() != num_variable_) {
84 throw std::runtime_error(
"length of 'barcode_pools' should be equal to the number of variable regions");
87 for (
int i = 0; i < num_variable_; ++i) {
88 SeqLength rlen = regions[i].second - regions[i].first;
89 SeqLength vlen = barcode_pools[i].length();
91 throw std::runtime_error(
"length of variable region " + std::to_string(i + 1) +
" (" + std::to_string(rlen) +
92 ") should be the same as its sequences (" + std::to_string(vlen) +
")");
97 for (
int i = 0; i < num_variable_; ++i) {
98 my_pool_size[i] = barcode_pools[i].pool().size();
107 for (
int i = 0; i < num_variable_; ++i) {
114 for (
int i = 0; i < num_variable_; ++i) {
138 std::array<SimpleBarcodeSearch, num_variable_> my_forward_lib, my_reverse_lib;
139 std::array<BarcodeIndex, num_variable_> my_pool_size;
152 std::array<BarcodeIndex, num_variable_> temp;
156 std::array<typename SimpleBarcodeSearch::State, num_variable_> forward_details, reverse_details;
163 std::pair<bool, int> find_match(
168 const std::array<SimpleBarcodeSearch, num_variable_>& libs,
169 std::array<typename SimpleBarcodeSearch::State, num_variable_>& states,
170 std::array<BarcodeIndex, num_variable_>& temp,
175 for (
int r = 0; r < num_variable_; ++r) {
176 const auto& range = regions[r];
177 auto start = seq + position;
179 buffer.insert(buffer.end(), start + range.first, start + range.second);
181 auto& curstate = states[r];
182 libs[r].search(buffer, curstate, my_max_mm - obs_mismatches);
184 return std::make_pair(
false, 0);
187 obs_mismatches += curstate.mismatches;
188 if (obs_mismatches > my_max_mm) {
189 return std::make_pair(
false, 0);
193 temp[num_variable_ - r - 1] = curstate.index;
195 temp[r] = curstate.index;
199 return std::make_pair(
true, obs_mismatches);
202 std::pair<bool, int> forward_match(
const char* seq,
const typename ScanTemplate<max_size_>::State& deets, State& state)
const {
203 return find_match(
false, seq, deets.position, deets.forward_mismatches, my_forward_lib, state.forward_details, state.temp, state.buffer);
206 std::pair<bool, int> reverse_match(
const char* seq,
const typename ScanTemplate<max_size_>::State& deets, State& state)
const {
207 return find_match(
true, seq, deets.position, deets.reverse_mismatches, my_reverse_lib, state.reverse_details, state.temp, state.buffer);
211 void process_first(State& state,
const std::pair<const char*, const char*>& x)
const {
212 auto deets = my_constant_matcher.
initialize(x.first, x.second - x.first);
214 while (!deets.finished) {
215 my_constant_matcher.
next(deets);
217 if (my_forward && deets.forward_mismatches <= my_max_mm) {
218 if (forward_match(x.first, deets, state).first) {
219 ++state.collected[state.temp];
224 if (my_reverse && deets.reverse_mismatches <= my_max_mm) {
225 if (reverse_match(x.first, deets, state).first) {
226 ++state.collected[state.temp];
233 void process_best(State& state,
const std::pair<const char*, const char*>& x)
const {
234 auto deets = my_constant_matcher.
initialize(x.first, x.second - x.first);
236 int best_mismatches = my_max_mm + 1;
237 std::array<BarcodeIndex, num_variable_> best_id;
239 auto update = [&](std::pair<bool, int> match) ->
void {
240 if (match.first && match.second <= best_mismatches) {
241 if (match.second == best_mismatches) {
242 if (best_id != state.temp) {
251 best_mismatches = match.second;
252 best_id = state.temp;
257 while (!deets.finished) {
258 my_constant_matcher.
next(deets);
260 if (my_forward && deets.forward_mismatches <= my_max_mm) {
261 update(forward_match(x.first, deets, state));
264 if (my_reverse && deets.reverse_mismatches <= my_max_mm) {
265 update(reverse_match(x.first, deets, state));
270 ++state.collected[best_id];
278 State initialize()
const {
282 void reduce(State& s) {
284 for (
int r = 0; r < num_variable_; ++r) {
285 my_forward_lib[r].reduce(s.forward_details[r]);
289 for (
int r = 0; r < num_variable_; ++r) {
290 my_reverse_lib[r].reduce(s.reverse_details[r]);
294 for (
const auto& col : s.collected) {
295 my_combinations[col.first] += col.second;
301 void process(State& state,
const std::pair<const char*, const char*>& x)
const {
303 process_first(state, x);
305 process_best(state, x);
310 static constexpr bool use_names =
false;
320 return my_combinations;