69 my_forward(search_forward(options.strand)),
70 my_reverse(search_reverse(options.strand)),
71 my_max_mm(options.max_mismatches),
72 my_use_first(options.use_first),
73 my_constant_matcher(template_seq, template_length, options.strand)
75 const auto& regions = my_constant_matcher.forward_variable_regions();
76 my_num_variable = regions.size();
77 if (barcode_pools.size() != my_num_variable) {
78 throw std::runtime_error(
"length of 'barcode_pools' should equal the number of variable regions");
81 for (
decltype(my_num_variable) i = 0; i < my_num_variable; ++i) {
82 SeqLength rlen = regions[i].second - regions[i].first;
83 SeqLength vlen = barcode_pools[i].length();
85 throw std::runtime_error(
"length of variable region " + std::to_string(i + 1) +
" (" + std::to_string(rlen) +
86 ") should be the same as its sequences (" + std::to_string(vlen) +
")");
91 if (my_num_variable) {
92 num_choices = barcode_pools[0].size();
93 for (
decltype(my_num_variable) i = 1; i < my_num_variable; ++i) {
94 if (num_choices != barcode_pools[i].size()) {
95 throw std::runtime_error(
"all entries of 'barcode_pools' should have the same length");
99 my_counts.resize(num_choices);
102 std::vector<std::string> combined(num_choices);
103 for (
decltype(my_num_variable) v = 0; v < my_num_variable; ++v) {
104 const auto& curpool = barcode_pools[v];
107 auto ptr = curpool[c];
108 combined[c].insert(combined[c].end(), ptr, ptr + n);
134 std::size_t my_num_variable;
137 std::vector<Count > my_counts;
146 State(
typename std::vector<Count>::size_type n) : counts(n) {}
148 std::vector<Count> counts;
154 typename SimpleBarcodeSearch::State forward_details, reverse_details;
161 std::pair<BarcodeIndex, int> find_match(
166 const SimpleBarcodeSearch& lib,
167 typename SimpleBarcodeSearch::State state,
173 for (
decltype(my_num_variable) r = 0; r < my_num_variable; ++r) {
174 auto start = seq + position;
175 buffer.insert(buffer.end(), start + regions[r].first, start + regions[r].second);
178 lib.search(buffer, state, my_max_mm - obs_mismatches);
179 return std::make_pair(state.index, obs_mismatches + state.mismatches);
182 std::pair<BarcodeIndex, int> forward_match(
const char* seq,
const typename ScanTemplate<max_size_>::State& deets, State& state)
const {
183 return find_match(
false, seq, deets.position, deets.forward_mismatches, my_forward_lib, state.forward_details, state.buffer);
186 std::pair<BarcodeIndex, int> reverse_match(
const char* seq,
const typename ScanTemplate<max_size_>::State& deets, State& state)
const {
187 return find_match(
true, seq, deets.position, deets.reverse_mismatches, my_reverse_lib, state.reverse_details, state.buffer);
191 bool process_first(State& state,
const std::pair<const char*, const char*>& x)
const {
192 auto deets = my_constant_matcher.
initialize(x.first, x.second - x.first);
194 while (!deets.finished) {
195 my_constant_matcher.
next(deets);
197 if (my_forward && deets.forward_mismatches <= my_max_mm) {
198 auto id = forward_match(x.first, deets, state).first;
205 if (my_reverse && deets.reverse_mismatches <= my_max_mm) {
206 auto id = reverse_match(x.first, deets, state).first;
216 bool process_best(State& state,
const std::pair<const char*, const char*>& x)
const {
217 auto deets = my_constant_matcher.
initialize(x.first, x.second - x.first);
219 int best_mismatches = my_max_mm + 1;
222 auto update = [&](std::pair<BarcodeIndex, int> match) ->
void {
226 if (match.second == best_mismatches) {
227 if (best_id != match.first) {
230 }
else if (match.second < best_mismatches) {
236 best_mismatches = match.second;
237 best_id = match.first;
241 while (!deets.finished) {
242 my_constant_matcher.
next(deets);
244 if (my_forward && deets.forward_mismatches <= my_max_mm) {
245 update(forward_match(x.first, deets, state));
248 if (my_reverse && deets.reverse_mismatches <= my_max_mm) {
249 update(reverse_match(x.first, deets, state));
254 ++state.counts[best_id];
263 State initialize()
const {
264 return State(my_counts.size());
267 void reduce(State& s) {
269 my_forward_lib.
reduce(s.forward_details);
272 my_reverse_lib.
reduce(s.reverse_details);
275 for (
decltype(my_counts.size()) i = 0, end = my_counts.size(); i < end; ++i) {
276 my_counts[i] += s.counts[i];
282 bool process(State& state,
const std::pair<const char*, const char*>& x)
const {
285 return process_first(state, x);
287 return process_best(state, x);
291 static constexpr bool use_names =
false;