From 3dd4cb3397240fc1a2e375ae0831bc74f51523d9 Mon Sep 17 00:00:00 2001 From: LTLA Date: Fri, 6 Oct 2023 00:39:24 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20crisprVe?= =?UTF-8?q?rse/kaori@8bd388ba9026fd13318e5bdea79c90b51b87f3ad=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...natorialBarcodesSingleEnd_8hpp_source.html | 355 +++++++-------- docs/DualBarcodesPairedEnd_8hpp_source.html | 417 +++++++++--------- 2 files changed, 393 insertions(+), 379 deletions(-) diff --git a/docs/CombinatorialBarcodesSingleEnd_8hpp_source.html b/docs/CombinatorialBarcodesSingleEnd_8hpp_source.html index add500f..8b1e1a8 100644 --- a/docs/CombinatorialBarcodesSingleEnd_8hpp_source.html +++ b/docs/CombinatorialBarcodesSingleEnd_8hpp_source.html @@ -164,187 +164,190 @@
136 int total = 0;
137
138 std::array<int, num_variable> temp;
-
139
-
140 // Default constructors should be called in this case, so it should be fine.
-
141 std::array<typename SimpleBarcodeSearch::State, num_variable> forward_details, reverse_details;
-
142 };
-
147private:
-
148 template<bool reverse>
-
149 std::pair<bool, int> find_match(
-
150 const char* seq,
-
151 size_t position,
-
152 int obs_mismatches,
-
153 const std::array<SimpleBarcodeSearch, num_variable>& libs,
-
154 std::array<typename SimpleBarcodeSearch::State, num_variable>& states,
-
155 std::array<int, num_variable>& temp)
-
156 const {
-
157 const auto& regions = constant_matcher.template variable_regions<reverse>();
-
158
-
159 for (size_t r = 0; r < num_variable; ++r) {
-
160 auto range = regions[r];
-
161 auto start = seq + position;
-
162 std::string current(start + range.first, start + range.second);
-
163
-
164 auto& curstate = states[r];
-
165 libs[r].search(current, curstate, max_mm - obs_mismatches);
-
166 if (curstate.index < 0) {
-
167 return std::make_pair(false, 0);
-
168 }
-
169
-
170 obs_mismatches += curstate.mismatches;
-
171 if (obs_mismatches > max_mm) {
-
172 return std::make_pair(false, 0);
-
173 }
-
174
-
175 if constexpr(reverse) {
-
176 temp[num_variable - r - 1] = curstate.index;
-
177 } else {
-
178 temp[r] = curstate.index;
-
179 }
-
180 }
-
181
-
182 return std::make_pair(true, obs_mismatches);
-
183 }
+
139 std::string buffer;
+
140
+
141 // Default constructors should be called in this case, so it should be fine.
+
142 std::array<typename SimpleBarcodeSearch::State, num_variable> forward_details, reverse_details;
+
143 };
+
148private:
+
149 template<bool reverse>
+
150 std::pair<bool, int> find_match(
+
151 const char* seq,
+
152 size_t position,
+
153 int obs_mismatches,
+
154 const std::array<SimpleBarcodeSearch, num_variable>& libs,
+
155 std::array<typename SimpleBarcodeSearch::State, num_variable>& states,
+
156 std::array<int, num_variable>& temp,
+
157 std::string& buffer
+
158 ) const {
+
159 const auto& regions = constant_matcher.template variable_regions<reverse>();
+
160
+
161 for (size_t r = 0; r < num_variable; ++r) {
+
162 auto range = regions[r];
+
163 auto start = seq + position;
+
164 buffer.clear(); // clear and insert preserves buffer's existing heap allocation.
+
165 buffer.insert(buffer.end(), start + range.first, start + range.second);
+
166
+
167 auto& curstate = states[r];
+
168 libs[r].search(buffer, curstate, max_mm - obs_mismatches);
+
169 if (curstate.index < 0) {
+
170 return std::make_pair(false, 0);
+
171 }
+
172
+
173 obs_mismatches += curstate.mismatches;
+
174 if (obs_mismatches > max_mm) {
+
175 return std::make_pair(false, 0);
+
176 }
+
177
+
178 if constexpr(reverse) {
+
179 temp[num_variable - r - 1] = curstate.index;
+
180 } else {
+
181 temp[r] = curstate.index;
+
182 }
+
183 }
184
-
185 std::pair<bool, int> forward_match(const char* seq, const typename ScanTemplate<max_size>::State& deets, State& state) const {
-
186 return find_match<false>(seq, deets.position, deets.forward_mismatches, forward_lib, state.forward_details, state.temp);
-
187 }
-
188
-
189 std::pair<bool, int> reverse_match(const char* seq, const typename ScanTemplate<max_size>::State& deets, State& state) const {
-
190 return find_match<true>(seq, deets.position, deets.reverse_mismatches, reverse_lib, state.reverse_details, state.temp);
-
191 }
-
192
-
193private:
-
194 void process_first(State& state, const std::pair<const char*, const char*>& x) const {
-
195 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
-
196
-
197 while (!deets.finished) {
-
198 constant_matcher.next(deets);
+
185 return std::make_pair(true, obs_mismatches);
+
186 }
+
187
+
188 std::pair<bool, int> forward_match(const char* seq, const typename ScanTemplate<max_size>::State& deets, State& state) const {
+
189 return find_match<false>(seq, deets.position, deets.forward_mismatches, forward_lib, state.forward_details, state.temp, state.buffer);
+
190 }
+
191
+
192 std::pair<bool, int> reverse_match(const char* seq, const typename ScanTemplate<max_size>::State& deets, State& state) const {
+
193 return find_match<true>(seq, deets.position, deets.reverse_mismatches, reverse_lib, state.reverse_details, state.temp, state.buffer);
+
194 }
+
195
+
196private:
+
197 void process_first(State& state, const std::pair<const char*, const char*>& x) const {
+
198 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
199
-
200 if (forward && deets.forward_mismatches <= max_mm) {
-
201 if (forward_match(x.first, deets, state).first) {
-
202 state.collected.push_back(state.temp);
-
203 return;
-
204 }
-
205 }
-
206
-
207 if (reverse && deets.reverse_mismatches <= max_mm) {
-
208 if (reverse_match(x.first, deets, state).first) {
-
209 state.collected.push_back(state.temp);
-
210 return;
-
211 }
-
212 }
-
213 }
-
214 }
-
215
-
216 void process_best(State& state, const std::pair<const char*, const char*>& x) const {
-
217 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
-
218 bool found = false;
-
219 int best_mismatches = max_mm + 1;
-
220 std::array<int, num_variable> best_id;
-
221
-
222 auto update = [&](std::pair<int, int> match) -> void {
-
223 if (match.first && match.second <= best_mismatches) {
-
224 if (match.second == best_mismatches) {
-
225 if (best_id != state.temp) { // ambiguous.
-
226 found = false;
-
227 }
-
228 } else {
-
229 // A further optimization at this point would be to narrow
-
230 // max_mm to the current 'best_mismatches'. But
-
231 // this probably isn't worth it.
-
232
-
233 found = true;
-
234 best_mismatches = match.second;
-
235 best_id = state.temp;
-
236 }
-
237 }
-
238 };
-
239
-
240 while (!deets.finished) {
-
241 constant_matcher.next(deets);
+
200 while (!deets.finished) {
+
201 constant_matcher.next(deets);
+
202
+
203 if (forward && deets.forward_mismatches <= max_mm) {
+
204 if (forward_match(x.first, deets, state).first) {
+
205 state.collected.push_back(state.temp);
+
206 return;
+
207 }
+
208 }
+
209
+
210 if (reverse && deets.reverse_mismatches <= max_mm) {
+
211 if (reverse_match(x.first, deets, state).first) {
+
212 state.collected.push_back(state.temp);
+
213 return;
+
214 }
+
215 }
+
216 }
+
217 }
+
218
+
219 void process_best(State& state, const std::pair<const char*, const char*>& x) const {
+
220 auto deets = constant_matcher.initialize(x.first, x.second - x.first);
+
221 bool found = false;
+
222 int best_mismatches = max_mm + 1;
+
223 std::array<int, num_variable> best_id;
+
224
+
225 auto update = [&](std::pair<bool, int> match) -> void {
+
226 if (match.first && match.second <= best_mismatches) {
+
227 if (match.second == best_mismatches) {
+
228 if (best_id != state.temp) { // ambiguous.
+
229 found = false;
+
230 }
+
231 } else {
+
232 // A further optimization at this point would be to narrow
+
233 // max_mm to the current 'best_mismatches'. But
+
234 // this probably isn't worth it.
+
235
+
236 found = true;
+
237 best_mismatches = match.second;
+
238 best_id = state.temp;
+
239 }
+
240 }
+
241 };
242
-
243 if (forward && deets.forward_mismatches <= max_mm) {
-
244 update(forward_match(x.first, deets, state));
-
245 }
-
246
-
247 if (reverse && deets.reverse_mismatches <= max_mm) {
-
248 update(reverse_match(x.first, deets, state));
-
249 }
-
250 }
-
251
-
252 if (found) {
-
253 state.collected.push_back(best_id);
-
254 }
-
255 }
-
256
-
257public:
-
261 State initialize() const {
-
262 return State();
-
263 }
-
264
-
265 void reduce(State& s) {
-
266 if (forward) {
-
267 for (size_t r = 0; r < num_variable; ++r) {
-
268 forward_lib[r].reduce(s.forward_details[r]);
-
269 }
-
270 }
-
271 if (reverse) {
-
272 for (size_t r = 0; r < num_variable; ++r) {
-
273 reverse_lib[r].reduce(s.reverse_details[r]);
-
274 }
-
275 }
-
276
-
277 combinations.insert(combinations.end(), s.collected.begin(), s.collected.end());
-
278 total += s.total;
-
279 return;
-
280 }
-
281
-
282 void process(State& state, const std::pair<const char*, const char*>& x) const {
-
283 if (use_first) {
-
284 process_first(state, x);
-
285 } else {
-
286 process_best(state, x);
-
287 }
-
288 ++state.total;
-
289 }
-
290
-
291 static constexpr bool use_names = false;
-
296public:
-
300 void sort() {
-
301 sort_combinations(combinations, num_options);
-
302 }
-
303
-
307 const std::vector<std::array<int, num_variable> >& get_combinations() const {
-
308 return combinations;
-
309 }
-
310
-
314 int get_total() const {
-
315 return total;
-
316 }
-
317private:
-
318 bool forward;
-
319 bool reverse;
-
320 int max_mm;
-
321 bool use_first;
-
322 size_t nregions;
-
323
-
324 ScanTemplate<max_size> constant_matcher;
-
325 std::array<SimpleBarcodeSearch, num_variable> forward_lib, reverse_lib;
-
326 std::array<size_t, num_variable> num_options;
-
327
-
328 std::vector<std::array<int, num_variable> > combinations;
-
329 int total = 0;
-
330};
-
331
-
332}
-
333
-
334#endif
+
243 while (!deets.finished) {
+
244 constant_matcher.next(deets);
+
245
+
246 if (forward && deets.forward_mismatches <= max_mm) {
+
247 update(forward_match(x.first, deets, state));
+
248 }
+
249
+
250 if (reverse && deets.reverse_mismatches <= max_mm) {
+
251 update(reverse_match(x.first, deets, state));
+
252 }
+
253 }
+
254
+
255 if (found) {
+
256 state.collected.push_back(best_id);
+
257 }
+
258 }
+
259
+
260public:
+
264 State initialize() const {
+
265 return State();
+
266 }
+
267
+
268 void reduce(State& s) {
+
269 if (forward) {
+
270 for (size_t r = 0; r < num_variable; ++r) {
+
271 forward_lib[r].reduce(s.forward_details[r]);
+
272 }
+
273 }
+
274 if (reverse) {
+
275 for (size_t r = 0; r < num_variable; ++r) {
+
276 reverse_lib[r].reduce(s.reverse_details[r]);
+
277 }
+
278 }
+
279
+
280 combinations.insert(combinations.end(), s.collected.begin(), s.collected.end());
+
281 total += s.total;
+
282 return;
+
283 }
+
284
+
285 void process(State& state, const std::pair<const char*, const char*>& x) const {
+
286 if (use_first) {
+
287 process_first(state, x);
+
288 } else {
+
289 process_best(state, x);
+
290 }
+
291 ++state.total;
+
292 }
+
293
+
294 static constexpr bool use_names = false;
+
299public:
+
303 void sort() {
+
304 sort_combinations(combinations, num_options);
+
305 }
+
306
+
310 const std::vector<std::array<int, num_variable> >& get_combinations() const {
+
311 return combinations;
+
312 }
+
313
+
317 int get_total() const {
+
318 return total;
+
319 }
+
320private:
+
321 bool forward;
+
322 bool reverse;
+
323 int max_mm;
+
324 bool use_first;
+
325 size_t nregions;
+
326
+
327 ScanTemplate<max_size> constant_matcher;
+
328 std::array<SimpleBarcodeSearch, num_variable> forward_lib, reverse_lib;
+
329 std::array<size_t, num_variable> num_options;
+
330
+
331 std::vector<std::array<int, num_variable> > combinations;
+
332 int total = 0;
+
333};
+
334
+
335}
+
336
+
337#endif
Handler for single-end combinatorial barcodes.
Definition: CombinatorialBarcodesSingleEnd.hpp:31
CombinatorialBarcodesSingleEnd & set_first(bool t=true)
Definition: CombinatorialBarcodesSingleEnd.hpp:125
-
const std::vector< std::array< int, num_variable > > & get_combinations() const
Definition: CombinatorialBarcodesSingleEnd.hpp:307
-
void sort()
Definition: CombinatorialBarcodesSingleEnd.hpp:300
-
int get_total() const
Definition: CombinatorialBarcodesSingleEnd.hpp:314
+
const std::vector< std::array< int, num_variable > > & get_combinations() const
Definition: CombinatorialBarcodesSingleEnd.hpp:310
+
void sort()
Definition: CombinatorialBarcodesSingleEnd.hpp:303
+
int get_total() const
Definition: CombinatorialBarcodesSingleEnd.hpp:317
CombinatorialBarcodesSingleEnd(const char *template_seq, size_t template_length, const BarcodePoolContainer &barcode_pools, const Options &options)
Definition: CombinatorialBarcodesSingleEnd.hpp:71
Scan a read sequence for the template sequence.
Definition: ScanTemplate.hpp:34
Search for known barcode sequences.
Definition: BarcodeSearch.hpp:105
diff --git a/docs/DualBarcodesPairedEnd_8hpp_source.html b/docs/DualBarcodesPairedEnd_8hpp_source.html index b0dabac..a6d02d3 100644 --- a/docs/DualBarcodesPairedEnd_8hpp_source.html +++ b/docs/DualBarcodesPairedEnd_8hpp_source.html @@ -202,215 +202,226 @@
187 std::vector<int> counts;
188 int total = 0;
189
-
190 std::vector<std::pair<std::string, int> > buffer2;
-
191
-
192 // Default constructors should be called in this case, so it should be fine.
-
193 typename SegmentedBarcodeSearch<2>::State details;
-
194 };
-
195
-
196 State initialize() const {
-
197 return State(counts.size());
-
198 }
-
199
-
200 void reduce(State& s) {
-
201 varlib.reduce(s.details);
-
202 for (size_t i = 0; i < counts.size(); ++i) {
-
203 counts[i] += s.counts[i];
-
204 }
-
205 total += s.total;
-
206 }
-
207
-
208 constexpr static bool use_names = false;
-
213private:
-
214 static void emit_output(std::pair<std::string, int>& output, const char* start, const char* end, int mm) {
-
215 output.first = std::string(start, end);
-
216 output.second = mm;
-
217 return;
-
218 }
-
219
-
220 static void emit_output(std::vector<std::pair<std::string, int> >& output, const char* start, const char* end, int mm) {
-
221 output.emplace_back(std::string(start, end), mm);
-
222 return;
-
223 }
-
224
-
225 template<class Store>
-
226 static bool inner_process(
-
227 bool reverse,
-
228 const ScanTemplate<max_size>& constant,
-
229 int max_mm,
-
230 const char* against,
-
231 typename ScanTemplate<max_size>::State& deets,
-
232 Store& output)
-
233 {
-
234 while (!deets.finished) {
-
235 constant.next(deets);
-
236 if (reverse) {
-
237 if (deets.reverse_mismatches <= max_mm) {
-
238 const auto& reg = constant.template variable_regions<true>()[0];
-
239 auto start = against + deets.position;
-
240 emit_output(output, start + reg.first, start + reg.second, deets.reverse_mismatches);
-
241 return true;
-
242 }
-
243 } else {
-
244 if (deets.forward_mismatches <= max_mm) {
-
245 const auto& reg = constant.variable_regions()[0];
-
246 auto start = against + deets.position;
-
247 emit_output(output, start + reg.first, start + reg.second, deets.forward_mismatches);
-
248 return true;
-
249 }
-
250 }
-
251 }
-
252 return false;
-
253 }
-
254
-
255 bool process_first(State& state, const std::pair<const char*, const char*>& against1, const std::pair<const char*, const char*>& against2) const {
-
256 auto deets1 = constant1.initialize(against1.first, against1.second - against1.first);
-
257 std::pair<std::string, int> match1;
-
258
-
259 auto deets2 = constant2.initialize(against2.first, against2.second - against2.first);
-
260 state.buffer2.clear();
+
190 std::pair<std::string, int> first_match;
+
191 std::vector<std::pair<std::string, int> > second_matches;
+
192 std::string combined;
+
193
+
194 // Default constructors should be called in this case, so it should be fine.
+
195 typename SegmentedBarcodeSearch<2>::State details;
+
196 };
+
197
+
198 State initialize() const {
+
199 return State(counts.size());
+
200 }
+
201
+
202 void reduce(State& s) {
+
203 varlib.reduce(s.details);
+
204 for (size_t i = 0; i < counts.size(); ++i) {
+
205 counts[i] += s.counts[i];
+
206 }
+
207 total += s.total;
+
208 }
+
209
+
210 constexpr static bool use_names = false;
+
215private:
+
216 static void fill_store(std::pair<std::string, int>& first_match, const char* start, const char* end, int mm) {
+
217 first_match.first.clear();
+
218 first_match.first.insert(first_match.first.end(), start, end);
+
219 first_match.second = mm;
+
220 return;
+
221 }
+
222
+
223 static void fill_store(std::vector<std::pair<std::string, int> >& second_matches, const char* start, const char* end, int mm) {
+
224 second_matches.emplace_back(std::string(start, end), mm);
+
225 return;
+
226 }
+
227
+
228 template<class Store>
+
229 static bool inner_process(
+
230 bool reverse,
+
231 const ScanTemplate<max_size>& constant,
+
232 int max_mm,
+
233 const char* against,
+
234 typename ScanTemplate<max_size>::State& deets,
+
235 Store& store)
+
236 {
+
237 while (!deets.finished) {
+
238 constant.next(deets);
+
239 if (reverse) {
+
240 if (deets.reverse_mismatches <= max_mm) {
+
241 const auto& reg = constant.template variable_regions<true>()[0];
+
242 auto start = against + deets.position;
+
243 fill_store(store, start + reg.first, start + reg.second, deets.reverse_mismatches);
+
244 return true;
+
245 }
+
246 } else {
+
247 if (deets.forward_mismatches <= max_mm) {
+
248 const auto& reg = constant.variable_regions()[0];
+
249 auto start = against + deets.position;
+
250 fill_store(store, start + reg.first, start + reg.second, deets.forward_mismatches);
+
251 return true;
+
252 }
+
253 }
+
254 }
+
255 return false;
+
256 }
+
257
+
258 bool process_first(State& state, const std::pair<const char*, const char*>& against1, const std::pair<const char*, const char*>& against2) const {
+
259 auto deets1 = constant1.initialize(against1.first, against1.second - against1.first);
+
260 auto deets2 = constant2.initialize(against2.first, against2.second - against2.first);
261
-
262 auto checker = [&](size_t idx2) -> bool {
-
263 const auto& current2 = state.buffer2[idx2];
-
264 auto combined = match1.first + current2.first;
-
265 varlib.search(combined, state.details, std::array<int, 2>{ max_mm1 - match1.second, max_mm2 - current2.second });
-
266
-
267 if (state.details.index >= 0) {
-
268 ++state.counts[state.details.index];
-
269 return true;
-
270 } else {
-
271 return false;
-
272 }
-
273 };
-
274
-
275 // Looping over all hits of the second for each hit of the first.
-
276 while (inner_process(search_reverse1, constant1, max_mm1, against1.first, deets1, match1)) {
-
277 if (deets2.finished) {
-
278 for (size_t i = 0; i < state.buffer2.size(); ++i) {
-
279 if (checker(i)) {
-
280 return true;
-
281 }
-
282 }
-
283 } else {
-
284 while (inner_process(search_reverse2, constant2, max_mm2, against2.first, deets2, state.buffer2)) {
-
285 if (checker(state.buffer2.size() - 1)) {
-
286 return true;
-
287 }
-
288 }
-
289 if (state.buffer2.empty()) {
-
290 break;
-
291 }
-
292 }
-
293 }
-
294
-
295 return false;
-
296 }
-
297
-
298 std::pair<int, int> process_best(State& state, const std::pair<const char*, const char*>& against1, const std::pair<const char*, const char*>& against2) const {
-
299 auto deets1 = constant1.initialize(against1.first, against1.second - against1.first);
-
300 std::pair<std::string, int> match1;
-
301
-
302 auto deets2 = constant2.initialize(against2.first, against2.second - against2.first);
-
303 state.buffer2.clear();
-
304
-
305 int chosen = -1;
-
306 int best_mismatches = max_mm1 + max_mm2 + 1;
-
307
-
308 auto checker = [&](size_t idx2) -> void {
-
309 const auto& current2 = state.buffer2[idx2];
-
310 auto combined = match1.first + current2.first;
-
311 varlib.search(combined, state.details, std::array<int, 2>{ max_mm1 - match1.second, max_mm2 - current2.second });
-
312
-
313 int cur_mismatches = state.details.mismatches;
-
314 if (cur_mismatches < best_mismatches) {
-
315 chosen = state.details.index;
-
316 best_mismatches = cur_mismatches;
-
317 } else if (cur_mismatches == best_mismatches && chosen != state.details.index) { // ambiguous.
-
318 chosen = -1;
-
319 }
-
320 };
-
321
-
322 while (inner_process(search_reverse1, constant1, max_mm1, against1.first, deets1, match1)) {
-
323 if (deets2.finished) {
-
324 for (size_t i = 0; i < state.buffer2.size(); ++i) {
-
325 checker(i);
-
326 }
-
327 } else {
-
328 while (inner_process(search_reverse2, constant2, max_mm2, against2.first, deets2, state.buffer2)) {
-
329 checker(state.buffer2.size() - 1);
-
330 }
-
331 if (state.buffer2.empty()) {
-
332 break;
-
333 }
-
334 }
-
335 }
-
336
-
337 return std::make_pair(chosen, best_mismatches);
-
338 }
+
262 state.second_matches.clear();
+
263
+
264 auto checker = [&](size_t idx2) -> bool {
+
265 const auto& current2 = state.second_matches[idx2];
+
266 state.combined = state.first_match.first;
+
267 state.combined += current2.first; // on a separate line to avoid creating a std::string intermediate.
+
268 varlib.search(state.combined, state.details, std::array<int, 2>{ max_mm1 - state.first_match.second, max_mm2 - current2.second });
+
269
+
270 if (state.details.index >= 0) {
+
271 ++state.counts[state.details.index];
+
272 return true;
+
273 } else {
+
274 return false;
+
275 }
+
276 };
+
277
+
278 // Looping over all hits of the second for each hit of the first read.
+
279 // This is done in a slightly convoluted way; we only search for
+
280 // all hits of the second read _after_ we find the first hit of the
+
281 // first read, so as to avoid a wasted search on the second read
+
282 // if we never found a hit on the first read.
+
283 while (inner_process(search_reverse1, constant1, max_mm1, against1.first, deets1, state.first_match)) {
+
284 if (!deets2.finished) {
+
285 // Alright, populating the second match buffer. We also
+
286 // return immediately if any of them form a valid
+
287 // combination with the first hit of the first read.
+
288 while (inner_process(search_reverse2, constant2, max_mm2, against2.first, deets2, state.second_matches)) {
+
289 if (checker(state.second_matches.size() - 1)) {
+
290 return true;
+
291 }
+
292 }
+
293 if (state.second_matches.empty()) {
+
294 break;
+
295 }
+
296 } else {
+
297 // And then this part does all the pairwise comparisons with
+
298 // every hit in the first read.
+
299 for (size_t i = 0; i < state.second_matches.size(); ++i) {
+
300 if (checker(i)) {
+
301 return true;
+
302 }
+
303 }
+
304 }
+
305 }
+
306
+
307 return false;
+
308 }
+
309
+
310 std::pair<int, int> process_best(State& state, const std::pair<const char*, const char*>& against1, const std::pair<const char*, const char*>& against2) const {
+
311 auto deets1 = constant1.initialize(against1.first, against1.second - against1.first);
+
312 auto deets2 = constant2.initialize(against2.first, against2.second - against2.first);
+
313
+
314 state.second_matches.clear();
+
315 int chosen = -1;
+
316 int best_mismatches = max_mm1 + max_mm2 + 1;
+
317
+
318 auto checker = [&](size_t idx2) -> void {
+
319 const auto& current2 = state.second_matches[idx2];
+
320 state.combined = state.first_match.first;
+
321 state.combined += current2.first; // separate line is deliberate.
+
322 varlib.search(state.combined, state.details, std::array<int, 2>{ max_mm1 - state.first_match.second, max_mm2 - current2.second });
+
323
+
324 int cur_mismatches = state.details.mismatches;
+
325 if (cur_mismatches < best_mismatches) {
+
326 chosen = state.details.index;
+
327 best_mismatches = cur_mismatches;
+
328 } else if (cur_mismatches == best_mismatches && chosen != state.details.index) { // ambiguous.
+
329 chosen = -1;
+
330 }
+
331 };
+
332
+
333 // Getting all hits on the second read, and then looping over that
+
334 // vector for each hit of the first read. We have to do all pairwise
+
335 // comparisons anyway to find the best hit.
+
336 while (inner_process(search_reverse2, constant2, max_mm2, against2.first, deets2, state.second_matches)) {
+
337 checker(state.second_matches.size() - 1);
+
338 }
339
-
340public:
-
344 bool process(State& state, const std::pair<const char*, const char*>& r1, const std::pair<const char*, const char*>& r2) const {
-
345 bool found;
-
346
-
347 if (use_first) {
-
348 found = process_first(state, r1, r2);
-
349 if (!found && randomized) {
-
350 found = process_first(state, r2, r1);
-
351 }
-
352
-
353 } else {
-
354 auto best = process_best(state, r1, r2);
-
355 if (randomized) {
-
356 auto best2 = process_best(state, r2, r1);
-
357 if (best.first < 0 || best.second > best2.second) {
-
358 best = best2;
-
359 } else if (best.second == best2.second && best.first != best2.first) {
-
360 best.first = -1; // ambiguous.
-
361 }
+
340 if (!state.second_matches.empty()) {
+
341 while (inner_process(search_reverse1, constant1, max_mm1, against1.first, deets1, state.first_match)) {
+
342 for (size_t i = 0; i < state.second_matches.size(); ++i) {
+
343 checker(i);
+
344 }
+
345 }
+
346 }
+
347
+
348 return std::make_pair(chosen, best_mismatches);
+
349 }
+
350
+
351public:
+
355 bool process(State& state, const std::pair<const char*, const char*>& r1, const std::pair<const char*, const char*>& r2) const {
+
356 bool found;
+
357
+
358 if (use_first) {
+
359 found = process_first(state, r1, r2);
+
360 if (!found && randomized) {
+
361 found = process_first(state, r2, r1);
362 }
363
-
364 found = best.first >= 0;
-
365 if (found) {
-
366 ++state.counts[best.first];
-
367 }
-
368 }
-
369
-
370 ++state.total;
-
371 return found;
-
372 }
-
377private:
-
378 bool search_reverse1, search_reverse2;
-
379
-
380 ScanTemplate<max_size> constant1, constant2;
-
381 SegmentedBarcodeSearch<2> varlib;
-
382 int max_mm1, max_mm2;
-
383
-
384 bool randomized;
-
385 bool use_first = true;
-
386
-
387 std::vector<int> counts;
-
388 int total = 0;
-
389
-
390public:
-
396 const std::vector<int>& get_counts() const {
-
397 return counts;
-
398 }
-
399
-
403 int get_total() const {
-
404 return total;
-
405 }
-
406};
-
407
-
411// Soft-deprecated back-compatible aliases.
-
412template<size_t max_size>
-
413using DualBarcodes = DualBarcodesPairedEnd<max_size>;
-
418}
-
419
-
420#endif
+
364 } else {
+
365 auto best = process_best(state, r1, r2);
+
366 if (randomized) {
+
367 auto best2 = process_best(state, r2, r1);
+
368 if (best.first < 0 || best.second > best2.second) {
+
369 best = best2;
+
370 } else if (best.second == best2.second && best.first != best2.first) {
+
371 best.first = -1; // ambiguous.
+
372 }
+
373 }
+
374
+
375 found = best.first >= 0;
+
376 if (found) {
+
377 ++state.counts[best.first];
+
378 }
+
379 }
+
380
+
381 ++state.total;
+
382 return found;
+
383 }
+
388private:
+
389 bool search_reverse1, search_reverse2;
+
390
+
391 ScanTemplate<max_size> constant1, constant2;
+
392 SegmentedBarcodeSearch<2> varlib;
+
393 int max_mm1, max_mm2;
+
394
+
395 bool randomized;
+
396 bool use_first = true;
+
397
+
398 std::vector<int> counts;
+
399 int total = 0;
+
400
+
401public:
+
407 const std::vector<int>& get_counts() const {
+
408 return counts;
+
409 }
+
410
+
414 int get_total() const {
+
415 return total;
+
416 }
+
417};
+
418
+
422// Soft-deprecated back-compatible aliases.
+
423template<size_t max_size>
+
424using DualBarcodes = DualBarcodesPairedEnd<max_size>;
+
429}
+
430
+
431#endif
Handler for dual barcodes.
Definition: DualBarcodesPairedEnd.hpp:27
-
const std::vector< int > & get_counts() const
Definition: DualBarcodesPairedEnd.hpp:396
+
const std::vector< int > & get_counts() const
Definition: DualBarcodesPairedEnd.hpp:407
DualBarcodesPairedEnd(const char *template_seq1, size_t template_length1, const BarcodePool &barcode_pool1, const char *template_seq2, size_t template_length2, const BarcodePool &barcode_pool2, const Options &options)
Definition: DualBarcodesPairedEnd.hpp:92
-
int get_total() const
Definition: DualBarcodesPairedEnd.hpp:403
+
int get_total() const
Definition: DualBarcodesPairedEnd.hpp:414
Search for known barcode sequences with segmented mismatches.
Definition: BarcodeSearch.hpp:290
void reduce(State &state)
Definition: BarcodeSearch.hpp:423
void search(const std::string &search_seq, State &state) const
Definition: BarcodeSearch.hpp:461