50 SearchStrand
strand = SearchStrand::FORWARD;
68 forward(search_forward(options.strand)),
69 reverse(search_reverse(options.strand)),
70 max_mm(options.max_mismatches),
71 use_first(options.use_first),
72 constant_matcher(template_seq, template_length, options.strand)
74 const auto& regions = constant_matcher.variable_regions();
75 num_variable = regions.size();
76 if (barcode_pools.size() != num_variable) {
77 throw std::runtime_error(
"length of 'barcode_pools' should equal the number of variable regions");
80 for (
size_t i = 0; i < num_variable; ++i) {
81 size_t rlen = regions[i].second - regions[i].first;
82 size_t vlen = barcode_pools[i].length;
84 throw std::runtime_error(
"length of variable region " + std::to_string(i + 1) +
" (" + std::to_string(rlen) +
85 ") should be the same as its sequences (" + std::to_string(vlen) +
")");
89 size_t num_choices = 0;
91 num_choices = barcode_pools[0].size();
92 for (
size_t i = 1; i < num_variable; ++i) {
93 if (num_choices != barcode_pools[i].size()) {
94 throw std::runtime_error(
"all entries of 'barcode_pools' should have the same length");
98 counts.resize(num_choices);
101 std::vector<std::string> combined(num_choices);
102 for (
size_t v = 0; v < num_variable; ++v) {
103 const auto& curpool = barcode_pools[v];
104 size_t n = curpool.length;
105 for (
size_t c = 0; c < num_choices; ++c) {
106 auto ptr = curpool[c];
107 combined[c].insert(combined[c].end(), ptr, ptr + n);
131 std::vector<int> counts;
144 template<
bool reverse>
145 std::pair<int, int> find_match(
149 const SimpleBarcodeSearch& lib,
150 typename SimpleBarcodeSearch::State state,
153 const auto& regions = constant_matcher.template variable_regions<reverse>();
156 for (
size_t r = 0; r < num_variable; ++r) {
157 auto start = seq + position;
158 buffer.insert(buffer.end(), start + regions[r].first, start + regions[r].second);
161 lib.search(buffer, state, max_mm - obs_mismatches);
162 return std::make_pair(state.index, obs_mismatches + state.mismatches);
165 std::pair<int, int> forward_match(
const char* seq,
const typename ScanTemplate<max_size>::State& deets, State& state)
const {
166 return find_match<false>(seq, deets.position, deets.forward_mismatches, forward_lib, state.forward_details, state.buffer);
169 std::pair<int, int> reverse_match(
const char* seq,
const typename ScanTemplate<max_size>::State& deets, State& state)
const {
170 return find_match<true>(seq, deets.position, deets.reverse_mismatches, reverse_lib, state.reverse_details, state.buffer);
174 bool process_first(State& state,
const std::pair<const char*, const char*>& x)
const {
175 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
177 while (!deets.finished) {
178 constant_matcher.next(deets);
180 if (forward && deets.forward_mismatches <= max_mm) {
181 auto id = forward_match(x.first, deets, state).first;
188 if (reverse && deets.reverse_mismatches <= max_mm) {
189 auto id = reverse_match(x.first, deets, state).first;
199 bool process_best(State& state,
const std::pair<const char*, const char*>& x)
const {
200 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
202 int best_mismatches = max_mm + 1;
205 auto update = [&](std::pair<int, int> match) ->
void {
206 if (match.first < 0){
209 if (match.second == best_mismatches) {
210 if (best_id != match.first) {
213 }
else if (match.second < best_mismatches) {
219 best_mismatches = match.second;
220 best_id = match.first;
224 while (!deets.finished) {
225 constant_matcher.next(deets);
227 if (forward && deets.forward_mismatches <= max_mm) {
228 update(forward_match(x.first, deets, state));
231 if (reverse && deets.reverse_mismatches <= max_mm) {
232 update(reverse_match(x.first, deets, state));
237 ++state.counts[best_id];
246 State initialize()
const {
248 output.counts.resize(counts.size());
252 void reduce(State& s) {
254 forward_lib.
reduce(s.forward_details);
257 reverse_lib.
reduce(s.reverse_details);
260 for (
size_t i = 0, end = counts.size(); i < end; ++i) {
261 counts[i] += s.counts[i];
267 bool process(State& state,
const std::pair<const char*, const char*>& x)
const {
270 return process_first(state, x);
272 return process_best(state, x);
276 static constexpr bool use_names =
false;
305 std::vector<int> counts;