48 SearchStrand
strand = SearchStrand::FORWARD;
60 forward(search_forward(options.strand)),
61 reverse(search_reverse(options.strand)),
62 constant(template_seq, template_length, options.strand),
63 max_mm(options.max_mismatches),
64 use_first(options.use_first)
68 std::unordered_map<std::string, int> counts;
71 bool forward, reverse;
76 bool has_match(
int obs_mismatches)
const {
77 return (obs_mismatches >= 0 && obs_mismatches <= max_mm);
86 State(
size_t varsize) : buffer(varsize,
' ') {}
88 std::unordered_map<std::string, int> counts;
93 void forward_match(
const char* seq,
size_t position, State& state)
const {
94 auto start = seq + position;
96 std::copy(start + range.first, start + range.second, state.buffer.data());
98 auto it = state.counts.find(state.buffer);
99 if (it != state.counts.end()) {
102 state.counts[state.buffer] = 1;
106 void reverse_match(
const char* seq,
size_t position, State& state)
const {
108 auto start = seq + position + range.first;
109 size_t len = state.buffer.size();
110 for (
size_t j = 0; j < len; ++j) {
111 state.buffer[j] = complement_base<true>(start[len - j - 1]);
114 auto it = state.counts.find(state.buffer);
115 if (it != state.counts.end()) {
118 state.counts[state.buffer] = 1;
122 void process(State& state,
const std::pair<const char*, const char*>& x)
const {
123 auto read_seq = x.first;
124 auto deets = constant.
initialize(read_seq, x.second - x.first);
127 while (!deets.finished) {
128 constant.
next(deets);
129 if (forward && has_match(deets.forward_mismatches)) {
130 forward_match(read_seq, deets.position, state);
133 if (reverse && has_match(deets.reverse_mismatches)) {
134 reverse_match(read_seq, deets.position, state);
140 int best = max_mm + 1;
141 bool best_forward =
true;
142 size_t best_position = 0;
143 bool best_tied =
false;
145 while (!deets.finished) {
146 constant.
next(deets);
148 if (forward && has_match(deets.forward_mismatches)) {
149 if (deets.forward_mismatches < best) {
150 best = deets.forward_mismatches;
151 best_position = deets.position;
154 }
else if (deets.forward_mismatches == best) {
159 if (reverse && has_match(deets.reverse_mismatches)) {
160 if (deets.reverse_mismatches < best) {
161 best = deets.reverse_mismatches;
162 best_position = deets.position;
163 best_forward =
false;
165 }
else if (deets.reverse_mismatches == best) {
171 if (!best_tied && best <= max_mm) {
173 forward_match(read_seq, best_position, state);
175 reverse_match(read_seq, best_position, state);
183 static constexpr bool use_names =
false;
192 State initialize()
const {
194 return State(range.second - range.first);
197 void reduce(State& s) {
198 for (
const auto& pair : s.counts) {
199 auto it = counts.find(pair.first);
200 if (it != counts.end()) {
201 it->second += pair.second;
203 counts[pair.first] = pair.second;
216 const std::unordered_map<std::string, int>&
get_counts()
const {