Commit patch to not break on spaces.
[bowtie.git] / aligner_seed_mm.h
1 /*
2  * aligner_seed_mm.h
3  */
4
5 #ifndef ALIGNER_SEED_MM_H_
6 #define ALIGNER_SEED_MM_H_
7
8 #include <utility>
9 #include <vector>
10 #include "aligner.h"
11 #include "hit.h"
12 #include "row_chaser.h"
13 #include "range_chaser.h"
14 #include "aligner_metrics.h"
15
16 /**
17  * Concrete factory class for constructing unpaired exact aligners.
18  */
19 class UnpairedSeedAlignerFactory : public AlignerFactory {
20
21         typedef RangeSourceDriver<EbwtRangeSource> TRangeSrcDr;
22         typedef std::vector<TRangeSrcDr*> TRangeSrcDrPtrVec;
23         typedef CostAwareRangeSourceDriver<EbwtRangeSource> TCostAwareRangeSrcDr;
24
25 public:
26         UnpairedSeedAlignerFactory(
27                         Ebwt<String<Dna> >& ebwtFw,
28                         Ebwt<String<Dna> >* ebwtBw,
29                         bool doFw,
30                         bool doRc,
31                         uint32_t seedMms,
32                         uint32_t seedLen,
33                         int qualCutoff,
34                         int maxBts,
35                         HitSink& sink,
36                         const HitSinkPerThreadFactory& sinkPtFactory,
37                         RangeCache* cacheFw,
38                         RangeCache* cacheBw,
39                         uint32_t cacheLimit,
40                         ChunkPool *pool,
41                         BitPairReference* refs,
42                         vector<String<Dna5> >& os,
43                         bool maqPenalty,
44                         bool qualOrder,
45                         bool strandFix,
46                         bool rangeMode,
47                         bool verbose,
48                         bool quiet,
49                         uint32_t seed,
50                         AlignerMetrics *metrics) :
51                         ebwtFw_(ebwtFw),
52                         ebwtBw_(ebwtBw),
53                         doFw_(doFw), doRc_(doRc),
54                         seedMms_(seedMms),
55                         seedLen_(seedLen),
56                         qualCutoff_(qualCutoff),
57                         maxBts_(maxBts),
58                         sink_(sink),
59                         sinkPtFactory_(sinkPtFactory),
60                         cacheFw_(cacheFw),
61                         cacheBw_(cacheBw),
62                         cacheLimit_(cacheLimit),
63                         pool_(pool),
64                         refs_(refs),
65                         os_(os),
66                         strandFix_(strandFix),
67                         maqPenalty_(maqPenalty),
68                         qualOrder_(qualOrder),
69                         rangeMode_(rangeMode),
70                         verbose_(verbose),
71                         quiet_(quiet),
72                         metrics_(metrics)
73         {
74                 assert(ebwtFw.isInMemory());
75         }
76
77         /**
78          * Create a new UnpairedExactAlignerV1s.
79          */
80         virtual Aligner* create() const {
81                 HitSinkPerThread* sinkPt = sinkPtFactory_.create();
82                 EbwtSearchParams<String<Dna> >* params =
83                         new EbwtSearchParams<String<Dna> >(*sinkPt, os_);
84                 int *btCnt = new int[1];
85                 *btCnt = maxBts_;
86
87                 TRangeSrcDrPtrVec *drVec = new TRangeSrcDrPtrVec();
88                 if(seedMms_ == 0) {
89                         const int halfAndHalf = 0;
90                         bool mate1 = true;
91                         EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
92                                  ebwtBw_, true,  qualCutoff_, true, verbose_, quiet_,
93                                  halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
94                         EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
95                                 &ebwtFw_, false, qualCutoff_, true, verbose_, quiet_,
96                                 halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
97                         EbwtRangeSourceDriver * driverFw = new EbwtRangeSourceDriver(
98                                 *params, rFw_Bw, true, false, maqPenalty_, qualOrder_, sink_, sinkPt,
99                                 seedLen_,   // seedLen
100                                 true,       // nudgeLeft (not applicable)
101                                 PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
102                                 PIN_TO_SEED_EDGE, // "
103                                 PIN_TO_SEED_EDGE, // "
104                                 PIN_TO_SEED_EDGE, // "
105                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
106                         EbwtRangeSourceDriver * driverRc = new EbwtRangeSourceDriver(
107                                 *params, rRc_Fw, false, false, maqPenalty_, qualOrder_, sink_, sinkPt,
108                                 seedLen_,   // seedLen
109                                 true,       // nudgeLeft (not applicable)
110                                 PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
111                                 PIN_TO_SEED_EDGE, // "
112                                 PIN_TO_SEED_EDGE, // "
113                                 PIN_TO_SEED_EDGE, // "
114                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
115                         if(doFw_) drVec->push_back(driverFw);
116                         if(doRc_) drVec->push_back(driverRc);
117
118                 } else if(seedMms_ == 1) {
119                         const int halfAndHalf = 0;
120                         bool fw = true;
121                         bool mate1 = true;
122
123                         EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
124                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
125                                  halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
126                         EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
127                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
128                                  halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
129                         EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
130                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
131                                  halfAndHalf, true,  maqPenalty_, qualOrder_, metrics_);
132
133                         EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
134                                 *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_,
135                                 sink_, sinkPt, seedLen_,
136                                 true,       // nudgeLeft
137                                 PIN_TO_HI_HALF_EDGE,
138                                 PIN_TO_SEED_EDGE,
139                                 PIN_TO_SEED_EDGE,
140                                 PIN_TO_SEED_EDGE,
141                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
142                         EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
143                                 *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_,
144                                 sink_, sinkPt, seedLen_,
145                                 true,       // nudgeLeft
146                                 PIN_TO_SEED_EDGE,
147                                 PIN_TO_SEED_EDGE,
148                                 PIN_TO_SEED_EDGE,
149                                 PIN_TO_SEED_EDGE,
150                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
151                         EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
152                                 *params, rFw_FwSeedGen, fw, true, maqPenalty_,
153                                 qualOrder_, sink_, sinkPt, seedLen_,
154                                 false,      // nudgeLeft
155                                 PIN_TO_HI_HALF_EDGE,
156                                 PIN_TO_SEED_EDGE,
157                                 PIN_TO_SEED_EDGE,
158                                 PIN_TO_SEED_EDGE,
159                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
160                         EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
161                                 drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
162
163                         fw = false;
164
165                         EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
166                                 &ebwtFw_, fw, qualCutoff_, true,  verbose_, quiet_,
167                                 halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
168                         EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
169                                 &ebwtFw_, fw, qualCutoff_, true,  verbose_, quiet_,
170                                 halfAndHalf, false, maqPenalty_, qualOrder_, metrics_);
171                         EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
172                                  ebwtBw_, fw, qualCutoff_, false, verbose_, quiet_,
173                                 halfAndHalf, true,  maqPenalty_, qualOrder_, metrics_);
174
175                         EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
176                                 *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
177                                 seedLen_,   // seedLen
178                                 true,       // nudgeLeft
179                                 PIN_TO_HI_HALF_EDGE,
180                                 PIN_TO_SEED_EDGE,
181                                 PIN_TO_SEED_EDGE,
182                                 PIN_TO_SEED_EDGE,
183                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
184                         EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
185                                 *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
186                                 seedLen_,   // seedLen
187                                 true,       // nudgeLeft
188                                 PIN_TO_SEED_EDGE,
189                                 PIN_TO_SEED_EDGE,
190                                 PIN_TO_SEED_EDGE,
191                                 PIN_TO_SEED_EDGE,
192                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
193                         EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
194                                 *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
195                                 seedLen_,   // seedLen
196                                 false,      // nudgeLeft
197                                 PIN_TO_HI_HALF_EDGE,
198                                 PIN_TO_SEED_EDGE,
199                                 PIN_TO_SEED_EDGE,
200                                 PIN_TO_SEED_EDGE,
201                                 os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
202                         EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
203                                 drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, true);
204
205                         if(doFw_) {
206                                 drVec->push_back(drFw_Bw);
207                                 drVec->push_back(drFw_Seed);
208                         }
209                         if(doRc_) {
210                                 drVec->push_back(drRc_Fw);
211                                 drVec->push_back(drRc_Seed);
212                         }
213                 } else if(seedMms_ == 2) {
214
215                         bool fw = true;
216                         bool mate1 = true;
217
218                         EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
219                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_, metrics_);
220                         EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
221                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_, metrics_);
222                         EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
223                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_, metrics_);
224                         EbwtRangeSource *rFw_BwHalf = new EbwtRangeSource(
225                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_, metrics_);
226
227                         EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
228                                 *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
229                                 seedLen_,   // seedLen
230                                 true,       // nudgeLeft
231                                 PIN_TO_HI_HALF_EDGE,
232                                 PIN_TO_HI_HALF_EDGE,
233                                 PIN_TO_SEED_EDGE,
234                                 PIN_TO_SEED_EDGE,
235                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
236                         EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
237                                 *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
238                                 seedLen_,   // seedLen
239                                 true,       // nudgeLeft
240                                 PIN_TO_SEED_EDGE,
241                                 PIN_TO_SEED_EDGE,
242                                 PIN_TO_SEED_EDGE,
243                                 PIN_TO_SEED_EDGE,
244                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
245                         EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
246                                 *params, rFw_FwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
247                                 seedLen_,   // seedLen
248                                 false,      // nudgeLeft
249                                 PIN_TO_HI_HALF_EDGE,
250                                 PIN_TO_HI_HALF_EDGE,
251                                 PIN_TO_SEED_EDGE,
252                                 PIN_TO_SEED_EDGE,
253                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
254                         EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
255                                 drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
256                         EbwtRangeSourceDriver * drFw_BwHalf = new EbwtRangeSourceDriver(
257                                 *params, rFw_BwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
258                                 seedLen_,   // seedLen
259                                 true,       // nudgeLeft
260                                 PIN_TO_BEGINNING,    // nothing's unrevisitable
261                                 PIN_TO_HI_HALF_EDGE,
262                                 PIN_TO_SEED_EDGE,
263                                 PIN_TO_SEED_EDGE,
264                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
265
266                         fw = false;
267
268                         EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
269                                 &ebwtFw_, fw, qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_, metrics_);
270                         EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
271                                 &ebwtFw_, fw, qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_, metrics_);
272                         EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
273                                  ebwtBw_, fw, qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_, metrics_);
274                         EbwtRangeSource *rRc_FwHalf = new EbwtRangeSource(
275                                 &ebwtFw_, fw, qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_, metrics_);
276
277                         EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
278                                 *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
279                                 seedLen_,   // seedLen
280                                 true,       // nudgeLeft
281                                 PIN_TO_HI_HALF_EDGE, // no mismatches in hi half
282                                 PIN_TO_HI_HALF_EDGE,
283                                 PIN_TO_SEED_EDGE,    // up to 2 in lo half
284                                 PIN_TO_SEED_EDGE,
285                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
286                         EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
287                                 *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
288                                 seedLen_,   // seedLen
289                                 true,       // nudgeLeft
290                                 PIN_TO_SEED_EDGE,
291                                 PIN_TO_SEED_EDGE,
292                                 PIN_TO_SEED_EDGE,
293                                 PIN_TO_SEED_EDGE,
294                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
295                         EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
296                                 *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
297                                 seedLen_,   // seedLen
298                                 false,      // nudgeLeft
299                                 PIN_TO_HI_HALF_EDGE, // no mismatches in lo half
300                                 PIN_TO_HI_HALF_EDGE,
301                                 PIN_TO_SEED_EDGE,    // up to 2 in hi half
302                                 PIN_TO_SEED_EDGE,
303                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
304                         EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
305                                 drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, true);
306                         EbwtRangeSourceDriver * drRc_FwHalf = new EbwtRangeSourceDriver(
307                                 *params, rRc_FwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
308                                 seedLen_,   // seedLen
309                                 true,       // nudgeLeft
310                                 PIN_TO_BEGINNING,    // nothing's unrevisitable
311                                 PIN_TO_HI_HALF_EDGE,
312                                 PIN_TO_SEED_EDGE,
313                                 PIN_TO_SEED_EDGE,
314                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
315
316                         if(doFw_) {
317                                 drVec->push_back(drFw_Bw);
318                                 drVec->push_back(drFw_Seed);
319                                 drVec->push_back(drFw_BwHalf);
320                         }
321                         if(doRc_) {
322                                 drVec->push_back(drRc_Fw);
323                                 drVec->push_back(drRc_Seed);
324                                 drVec->push_back(drRc_FwHalf);
325                         }
326                 } else if(seedMms_ > 2) {
327
328                         bool fw = true;
329                         bool mate1 = true;
330
331                         EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
332                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
333                                  0, false, maqPenalty_, qualOrder_, metrics_);
334
335                         // Partial and full aligners for alignments with 0
336                         // mismatches in the lo-half and up to 3 mismatches in the
337                         // hi-half
338                         EbwtRangeSourceFactory *rFw_BwSeed03 = new EbwtRangeSourceFactory(
339                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
340                                  0, false, maqPenalty_, qualOrder_, metrics_);
341                         EbwtRangeSource *rFw_FwSeedGen03 = new EbwtRangeSource(
342                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
343                                  0, true,  maqPenalty_, qualOrder_, metrics_);
344
345                         // Partial and full aligners for alignments with 1
346                         // mismatch in the lo-half and up to 2 mismatches in the
347                         // hi-half
348                         EbwtRangeSourceFactory *rFw_BwSeed12 = new EbwtRangeSourceFactory(
349                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
350                                  0, false, maqPenalty_, qualOrder_, metrics_);
351                         // Note: the following is half-and-half (unlike the 03 version)
352                         EbwtRangeSource *rFw_FwSeedGen12 = new EbwtRangeSource(
353                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
354                                  3,  true,  maqPenalty_, qualOrder_, metrics_);
355
356                         EbwtRangeSource *rFw_BwHalf12 = new EbwtRangeSource(
357                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_,
358                                  2,  false, maqPenalty_, qualOrder_, metrics_);
359
360                         EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
361                                 *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_,
362                                 sink_, sinkPt, seedLen_,
363                                 true,       // nudgeLeft
364                                 PIN_TO_HI_HALF_EDGE, // 0 mismatches in hi-half
365                                 PIN_TO_HI_HALF_EDGE,
366                                 PIN_TO_HI_HALF_EDGE,
367                                 PIN_TO_SEED_EDGE,    // up to 3 mismatches in lo-half
368                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
369
370                         EbwtRangeSourceDriverFactory * drFw_BwSeed03 = new EbwtRangeSourceDriverFactory(
371                                 *params, rFw_BwSeed03, fw, false, maqPenalty_, qualOrder_,
372                                 sink_, sinkPt, seedLen_,
373                                 true,       // nudgeLeft
374                                 PIN_TO_SEED_EDGE,
375                                 PIN_TO_SEED_EDGE,
376                                 PIN_TO_SEED_EDGE,
377                                 PIN_TO_SEED_EDGE,
378                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
379                         EbwtRangeSourceDriver * drFw_FwSeedGen03 = new EbwtRangeSourceDriver(
380                                 *params, rFw_FwSeedGen03, fw, true, maqPenalty_, qualOrder_,
381                                 sink_, sinkPt, seedLen_,
382                                 false,      // nudgeLeft
383                                 PIN_TO_HI_HALF_EDGE,
384                                 PIN_TO_HI_HALF_EDGE,
385                                 PIN_TO_HI_HALF_EDGE,
386                                 PIN_TO_SEED_EDGE,
387                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
388                         EbwtSeededRangeSourceDriver * drFw_Seed03 = new EbwtSeededRangeSourceDriver(
389                                 drFw_BwSeed03, drFw_FwSeedGen03, fw, seedLen_, verbose_, quiet_, mate1);
390
391                         EbwtRangeSourceDriverFactory * drFw_BwSeed12 = new EbwtRangeSourceDriverFactory(
392                                 *params, rFw_BwSeed12, fw, false, maqPenalty_, qualOrder_,
393                                 sink_, sinkPt, seedLen_,
394                                 true,       // nudgeLeft
395                                 PIN_TO_SEED_EDGE,
396                                 PIN_TO_SEED_EDGE,
397                                 PIN_TO_SEED_EDGE,
398                                 PIN_TO_SEED_EDGE,
399                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
400                         EbwtRangeSourceDriver * drFw_FwSeedGen12 = new EbwtRangeSourceDriver(
401                                 *params, rFw_FwSeedGen12, fw, true, maqPenalty_, qualOrder_,
402                                 sink_, sinkPt, seedLen_,
403                                 false,      // nudgeLeft
404                                 PIN_TO_BEGINNING,
405                                 PIN_TO_HI_HALF_EDGE, // 1-mismatch in lo-half
406                                 PIN_TO_HI_HALF_EDGE,
407                                 PIN_TO_SEED_EDGE,    // 1 or 2 mismatches in hi-half
408                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
409                         EbwtSeededRangeSourceDriver * drFw_Seed12 = new EbwtSeededRangeSourceDriver(
410                                 drFw_BwSeed12, drFw_FwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
411
412                         EbwtRangeSourceDriver * drFw_BwHalf12 = new EbwtRangeSourceDriver(
413                                 *params, rFw_BwHalf12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
414                                 seedLen_,   // seedLen
415                                 true,       // nudgeLeft
416                                 PIN_TO_BEGINNING,    // nothing's unrevisitable
417                                 PIN_TO_HI_HALF_EDGE,
418                                 PIN_TO_HI_HALF_EDGE,
419                                 PIN_TO_SEED_EDGE,
420                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
421
422                         fw = false;
423
424                         EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
425                                 &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
426                                 0, false, maqPenalty_, qualOrder_, metrics_);
427
428                         // Partial and full aligners for alignments with 0
429                         // mismatches in the lo-half and up to 3 mismatches in the
430                         // hi-half
431                         EbwtRangeSourceFactory *rRc_FwSeed03 = new EbwtRangeSourceFactory(
432                                 &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
433                                 0, false, maqPenalty_, qualOrder_, metrics_);
434                         EbwtRangeSource *rRc_BwSeedGen03 = new EbwtRangeSource(
435                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_,
436                                 0, true,  maqPenalty_, qualOrder_, metrics_);
437
438                         // Partial and full aligners for alignments with 1
439                         // mismatch in the lo-half and up to 2 mismatches in the
440                         // hi-half
441                         EbwtRangeSourceFactory *rRc_FwSeed12 = new EbwtRangeSourceFactory(
442                                 &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
443                                 0, false, maqPenalty_, qualOrder_, metrics_);
444                         EbwtRangeSource *rRc_BwSeedGen12 = new EbwtRangeSource(
445                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_,
446                                 3,  true,  maqPenalty_, qualOrder_, metrics_);
447
448                         EbwtRangeSource *rRc_FwHalf12 = new EbwtRangeSource(
449                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
450                                 2,  false, maqPenalty_, qualOrder_, metrics_);
451
452                         EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
453                                 *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
454                                 seedLen_,   // seedLen
455                                 true,       // nudgeLeft
456                                 PIN_TO_HI_HALF_EDGE,
457                                 PIN_TO_HI_HALF_EDGE,
458                                 PIN_TO_HI_HALF_EDGE,
459                                 PIN_TO_SEED_EDGE,
460                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
461
462                         EbwtRangeSourceDriverFactory * drRc_FwSeed03 = new EbwtRangeSourceDriverFactory(
463                                 *params, rRc_FwSeed03, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
464                                 seedLen_,   // seedLen
465                                 true,       // nudgeLeft
466                                 PIN_TO_SEED_EDGE,
467                                 PIN_TO_SEED_EDGE,
468                                 PIN_TO_SEED_EDGE,
469                                 PIN_TO_SEED_EDGE,
470                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
471                         EbwtRangeSourceDriver * drRc_BwSeedGen03 = new EbwtRangeSourceDriver(
472                                 *params, rRc_BwSeedGen03, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
473                                 seedLen_,   // seedLen
474                                 false,      // nudgeLeft
475                                 PIN_TO_HI_HALF_EDGE,
476                                 PIN_TO_HI_HALF_EDGE,
477                                 PIN_TO_HI_HALF_EDGE,
478                                 PIN_TO_SEED_EDGE,
479                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
480                         EbwtSeededRangeSourceDriver * drRc_Seed03 = new EbwtSeededRangeSourceDriver(
481                                 drRc_FwSeed03, drRc_BwSeedGen03, fw, seedLen_, verbose_, quiet_, mate1);
482
483                         EbwtRangeSourceDriverFactory * drRc_FwSeed12 = new EbwtRangeSourceDriverFactory(
484                                 *params, rRc_FwSeed12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
485                                 seedLen_,   // seedLen
486                                 true,       // nudgeLeft
487                                 PIN_TO_SEED_EDGE,
488                                 PIN_TO_SEED_EDGE,
489                                 PIN_TO_SEED_EDGE,
490                                 PIN_TO_SEED_EDGE,
491                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
492                         EbwtRangeSourceDriver * drRc_BwSeedGen12 = new EbwtRangeSourceDriver(
493                                 *params, rRc_BwSeedGen12, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
494                                 seedLen_,   // seedLen
495                                 false,      // nudgeLeft
496                                 PIN_TO_BEGINNING,
497                                 PIN_TO_HI_HALF_EDGE,
498                                 PIN_TO_HI_HALF_EDGE,
499                                 PIN_TO_SEED_EDGE,
500                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
501                         EbwtSeededRangeSourceDriver * drRc_Seed12 = new EbwtSeededRangeSourceDriver(
502                                 drRc_FwSeed12, drRc_BwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
503
504                         EbwtRangeSourceDriver * drRc_FwHalf12 = new EbwtRangeSourceDriver(
505                                 *params, rRc_FwHalf12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
506                                 seedLen_,   // seedLen
507                                 true,       // nudgeLeft
508                                 PIN_TO_BEGINNING,    // nothing's unrevisitable
509                                 PIN_TO_HI_HALF_EDGE,
510                                 PIN_TO_HI_HALF_EDGE,
511                                 PIN_TO_SEED_EDGE,
512                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
513
514                         if(doFw_) {
515                                 drVec->push_back(drFw_Bw);
516                                 drVec->push_back(drFw_Seed03);
517                                 drVec->push_back(drFw_Seed12);
518                                 drVec->push_back(drFw_BwHalf12);
519                         }
520                         if(doRc_) {
521                                 drVec->push_back(drRc_Fw);
522                                 drVec->push_back(drRc_Seed03);
523                                 drVec->push_back(drRc_Seed12);
524                                 drVec->push_back(drRc_FwHalf12);
525                         }
526                 } else {
527                         cerr << "Unsupported --stateful mode: " << seedMms_ << endl;
528                 }
529                 TCostAwareRangeSrcDr* dr = new TCostAwareRangeSrcDr(strandFix_, drVec, verbose_, quiet_, false);
530                 delete drVec;
531
532                 // Set up a RangeChaser
533                 RangeChaser<String<Dna> > *rchase =
534                         new RangeChaser<String<Dna> >(cacheLimit_, cacheFw_, cacheBw_, metrics_);
535
536                 return new UnpairedAlignerV2<EbwtRangeSource>(
537                         params, dr, rchase,
538                         sink_, sinkPtFactory_, sinkPt, os_, refs_,
539                         rangeMode_, verbose_, quiet_, maxBts_, pool_, btCnt,
540                         metrics_);
541         }
542
543 private:
544         Ebwt<String<Dna> >& ebwtFw_;
545         Ebwt<String<Dna> >* ebwtBw_;
546         bool doFw_;
547         bool doRc_;
548         const uint32_t seedMms_;
549         const uint32_t seedLen_;
550         const int qualCutoff_;
551         const int maxBts_;
552         HitSink& sink_;
553         const HitSinkPerThreadFactory& sinkPtFactory_;
554         RangeCache *cacheFw_;
555         RangeCache *cacheBw_;
556         const uint32_t cacheLimit_;
557         ChunkPool *pool_;
558         BitPairReference* refs_;
559         vector<String<Dna5> >& os_;
560         bool strandFix_;
561         bool maqPenalty_;
562         bool qualOrder_;
563         bool rangeMode_;
564         bool verbose_;
565         bool quiet_;
566         AlignerMetrics *metrics_;
567 };
568
569 /**
570  * Concrete factory class for constructing unpaired exact aligners.
571  */
572 class PairedSeedAlignerFactory : public AlignerFactory {
573         typedef RangeSourceDriver<EbwtRangeSource> TRangeSrcDr;
574         typedef std::vector<TRangeSrcDr*> TRangeSrcDrPtrVec;
575         typedef CostAwareRangeSourceDriver<EbwtRangeSource> TCostAwareRangeSrcDr;
576 public:
577         PairedSeedAlignerFactory(
578                         Ebwt<String<Dna> >& ebwtFw,
579                         Ebwt<String<Dna> >* ebwtBw,
580                         bool color,
581                         bool v1,
582                         bool doFw,
583                         bool doRc,
584                         uint32_t seedMms,
585                         uint32_t seedLen,
586                         int qualCutoff,
587                         int maxBts,
588                         HitSink& sink,
589                         const HitSinkPerThreadFactory& sinkPtFactory,
590                         bool mate1fw,
591                         bool mate2fw,
592                         uint32_t peInner,
593                         uint32_t peOuter,
594                         bool dontReconcile,
595                         uint32_t symCeil,
596                         uint32_t mixedThresh,
597                         uint32_t mixedAttemptLim,
598                         RangeCache* cacheFw,
599                         RangeCache* cacheBw,
600                         uint32_t cacheLimit,
601                         ChunkPool *pool,
602                         BitPairReference* refs,
603                         vector<String<Dna5> >& os,
604                         bool reportSe,
605                         bool maqPenalty,
606                         bool qualOrder,
607                         bool strandFix,
608                         bool rangeMode,
609                         bool verbose,
610                         bool quiet,
611                         uint32_t seed) :
612                         ebwtFw_(ebwtFw),
613                         ebwtBw_(ebwtBw),
614                         color_(color),
615                         v1_(v1),
616                         doFw_(doFw),
617                         doRc_(doRc),
618                         seedMms_(seedMms),
619                         seedLen_(seedLen),
620                         qualCutoff_(qualCutoff),
621                         maxBts_(maxBts),
622                         sink_(sink),
623                         sinkPtFactory_(sinkPtFactory),
624                         mate1fw_(mate1fw),
625                         mate2fw_(mate2fw),
626                         peInner_(peInner),
627                         peOuter_(peOuter),
628                         dontReconcile_(dontReconcile),
629                         symCeil_(symCeil),
630                         mixedThresh_(mixedThresh),
631                         mixedAttemptLim_(mixedAttemptLim),
632                         cacheFw_(cacheFw),
633                         cacheBw_(cacheBw),
634                         cacheLimit_(cacheLimit),
635                         pool_(pool),
636                         refs_(refs), os_(os),
637                         reportSe_(reportSe),
638                         maqPenalty_(maqPenalty),
639                         qualOrder_(qualOrder),
640                         strandFix_(strandFix),
641                         rangeMode_(rangeMode),
642                         verbose_(verbose),
643                         quiet_(quiet)
644         {
645                 assert(ebwtFw.isInMemory());
646                 assert(ebwtBw->isInMemory());
647         }
648
649         /**
650          * Create a new UnpairedExactAlignerV1s.
651          */
652         virtual Aligner* create() const {
653                 HitSinkPerThread* sinkPt = sinkPtFactory_.createMult(2);
654                 HitSinkPerThread* sinkPtSe1 = NULL, * sinkPtSe2 = NULL;
655                 EbwtSearchParams<String<Dna> >* params =
656                         new EbwtSearchParams<String<Dna> >(*sinkPt, os_);
657                 EbwtSearchParams<String<Dna> >* paramsSe1 = NULL, * paramsSe2 = NULL;
658                 if(reportSe_) {
659                         sinkPtSe1 = sinkPtFactory_.create();
660                         sinkPtSe2 = sinkPtFactory_.create();
661                         paramsSe1 =
662                                 new EbwtSearchParams<String<Dna> >(*sinkPtSe1, os_);
663                         paramsSe2 =
664                                 new EbwtSearchParams<String<Dna> >(*sinkPtSe2, os_);
665                 }
666                 RefAligner<String<Dna5> >* refAligner = NULL;
667                 int *btCnt = new int[1];
668                 *btCnt = maxBts_;
669                 if(seedMms_ == 0) {
670                         refAligner = new Seed0RefAligner<String<Dna5> >(color_, verbose_, quiet_, seedLen_, qualCutoff_, maqPenalty_);
671                 } else if(seedMms_ == 1) {
672                         refAligner = new Seed1RefAligner<String<Dna5> >(color_, verbose_, quiet_, seedLen_, qualCutoff_, maqPenalty_);
673                 } else if(seedMms_ == 2) {
674                         refAligner = new Seed2RefAligner<String<Dna5> >(color_, verbose_, quiet_, seedLen_, qualCutoff_, maqPenalty_);
675                 } else {
676                         refAligner = new Seed3RefAligner<String<Dna5> >(color_, verbose_, quiet_, seedLen_, qualCutoff_, maqPenalty_);
677                 }
678                 bool do1Fw = true;
679                 bool do1Rc = true;
680                 bool do2Fw = true;
681                 bool do2Rc = true;
682                 if(!doFw_) {
683                         if(mate1fw_) do1Fw = false;
684                         else         do1Rc = false;
685                         if(mate2fw_) do2Fw = false;
686                         else         do2Rc = false;
687                 }
688                 if(!doRc_) {
689                         if(mate1fw_) do1Rc = false;
690                         else         do1Fw = false;
691                         if(mate2fw_) do2Rc = false;
692                         else         do2Fw = false;
693                 }
694                 TRangeSrcDrPtrVec *dr1FwVec = new TRangeSrcDrPtrVec();
695                 TRangeSrcDrPtrVec *dr1RcVec;
696                 TRangeSrcDrPtrVec *dr2FwVec;
697                 TRangeSrcDrPtrVec *dr2RcVec;
698                 if(v1_) {
699                         dr1RcVec = new TRangeSrcDrPtrVec();
700                         dr2FwVec = new TRangeSrcDrPtrVec();
701                         dr2RcVec = new TRangeSrcDrPtrVec();
702                 } else {
703                         dr1RcVec = dr1FwVec;
704                         dr2FwVec = dr1FwVec;
705                         dr2RcVec = dr1FwVec;
706                 }
707                 if(seedMms_ == 0) {
708                         const int halfAndHalf = 0;
709                         if(do1Fw) {
710                                 bool mate1 = true;
711                                 bool fw = true;
712                                 EbwtRangeSource *r1Fw_Bw = new EbwtRangeSource(
713                                          ebwtBw_, fw,  qualCutoff_, true, verbose_, quiet_,
714                                          halfAndHalf, false, maqPenalty_, qualOrder_);
715                                 EbwtRangeSourceDriver *dr1Fw_Bw = new EbwtRangeSourceDriver(
716                                         *params, r1Fw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
717                                         seedLen_,   // seedLen
718                                         true,       // nudgeLeft (not applicable)
719                                         PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
720                                         PIN_TO_SEED_EDGE, // "
721                                         PIN_TO_SEED_EDGE, // "
722                                         PIN_TO_SEED_EDGE, // "
723                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
724                                 dr1FwVec->push_back(dr1Fw_Bw);
725                         }
726                         if(do2Fw) {
727                                 bool mate1 = false;
728                                 bool fw = true;
729                                 EbwtRangeSource *r2Fw_Bw = new EbwtRangeSource(
730                                          ebwtBw_, fw,  qualCutoff_, true, verbose_, quiet_, halfAndHalf,
731                                          false, maqPenalty_, qualOrder_);
732                                 EbwtRangeSourceDriver *dr2Fw_Bw = new EbwtRangeSourceDriver(
733                                         *params, r2Fw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
734                                         seedLen_,   // seedLen
735                                         true,       // nudgeLeft (not applicable)
736                                         PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
737                                         PIN_TO_SEED_EDGE, // "
738                                         PIN_TO_SEED_EDGE, // "
739                                         PIN_TO_SEED_EDGE, // "
740                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
741                                 dr2FwVec->push_back(dr2Fw_Bw);
742                         }
743                         if(do1Rc) {
744                                 bool mate1 = true;
745                                 bool fw = false;
746                                 EbwtRangeSource *r1Rc_Fw = new EbwtRangeSource(
747                                         &ebwtFw_, fw,  qualCutoff_, true, verbose_, quiet_,
748                                         halfAndHalf, false, maqPenalty_, qualOrder_);
749                                 EbwtRangeSourceDriver *dr1Rc_Fw = new EbwtRangeSourceDriver(
750                                         *params, r1Rc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
751                                         seedLen_,   // seedLen
752                                         true,       // nudgeLeft (not applicable)
753                                         PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
754                                         PIN_TO_SEED_EDGE, // "
755                                         PIN_TO_SEED_EDGE, // "
756                                         PIN_TO_SEED_EDGE, // "
757                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
758                                 dr1RcVec->push_back(dr1Rc_Fw);
759                         }
760                         if(do2Rc) {
761                                 bool mate1 = false;
762                                 bool fw = false;
763                                 EbwtRangeSource *r2Rc_Fw = new EbwtRangeSource(
764                                         &ebwtFw_, fw,  qualCutoff_, true, verbose_, quiet_,
765                                         halfAndHalf, false, maqPenalty_, qualOrder_);
766                                 EbwtRangeSourceDriver *dr2Rc_Fw = new EbwtRangeSourceDriver(
767                                         *params, r2Rc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
768                                         seedLen_,   // seedLen
769                                         true,       // nudgeLeft (not applicable)
770                                         PIN_TO_SEED_EDGE, // whole alignment is unrevisitable
771                                         PIN_TO_SEED_EDGE, // "
772                                         PIN_TO_SEED_EDGE, // "
773                                         PIN_TO_SEED_EDGE, // "
774                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
775                                 dr2RcVec->push_back(dr2Rc_Fw);
776                         }
777                 } else if(seedMms_ == 1) {
778                         const int halfAndHalf = 0;
779                         if(do1Fw) {
780                                 bool mate1 = true;
781                                 bool fw = true;
782                                 EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
783                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
784                                         halfAndHalf, false, maqPenalty_, qualOrder_);
785                                 EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
786                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
787                                         halfAndHalf, false, maqPenalty_, qualOrder_);
788                                 EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
789                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
790                                         halfAndHalf, true,  maqPenalty_, qualOrder_);
791                                 EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
792                                         *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
793                                         seedLen_,   // seedLen
794                                         true,       // nudgeLeft
795                                         PIN_TO_HI_HALF_EDGE,
796                                         PIN_TO_SEED_EDGE,
797                                         PIN_TO_SEED_EDGE,
798                                         PIN_TO_SEED_EDGE,
799                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
800                                 EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
801                                         *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
802                                         seedLen_,   // seedLen
803                                         true,       // nudgeLeft
804                                         PIN_TO_SEED_EDGE,
805                                         PIN_TO_SEED_EDGE,
806                                         PIN_TO_SEED_EDGE,
807                                         PIN_TO_SEED_EDGE,
808                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
809                                 EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
810                                         *params, rFw_FwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
811                                         seedLen_,   // seedLen
812                                         false,      // nudgeLeft
813                                         PIN_TO_HI_HALF_EDGE,
814                                         PIN_TO_SEED_EDGE,
815                                         PIN_TO_SEED_EDGE,
816                                         PIN_TO_SEED_EDGE,
817                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
818                                 EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
819                                         drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
820                                 dr1FwVec->push_back(drFw_Bw);
821                                 dr1FwVec->push_back(drFw_Seed);
822                         }
823                         if(do2Fw) {
824                                 bool mate1 = false;
825                                 bool fw = true;
826                                 EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
827                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
828                                         halfAndHalf, false, maqPenalty_, qualOrder_);
829                                 EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
830                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_,
831                                         halfAndHalf, false, maqPenalty_, qualOrder_);
832                                 EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
833                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_,
834                                         halfAndHalf, true,  maqPenalty_, qualOrder_);
835                                 EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
836                                         *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
837                                         seedLen_,   // seedLen
838                                         true,       // nudgeLeft
839                                         PIN_TO_HI_HALF_EDGE,
840                                         PIN_TO_SEED_EDGE,
841                                         PIN_TO_SEED_EDGE,
842                                         PIN_TO_SEED_EDGE,
843                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
844                                 EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
845                                         *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
846                                         seedLen_,   // seedLen
847                                         true,       // nudgeLeft
848                                         PIN_TO_SEED_EDGE,
849                                         PIN_TO_SEED_EDGE,
850                                         PIN_TO_SEED_EDGE,
851                                         PIN_TO_SEED_EDGE,
852                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
853                                 EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
854                                         *params, rFw_FwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
855                                         seedLen_,   // seedLen
856                                         false,      // nudgeLeft
857                                         PIN_TO_HI_HALF_EDGE,
858                                         PIN_TO_SEED_EDGE,
859                                         PIN_TO_SEED_EDGE,
860                                         PIN_TO_SEED_EDGE,
861                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
862                                 EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
863                                         drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
864                                 dr2FwVec->push_back(drFw_Bw);
865                                 dr2FwVec->push_back(drFw_Seed);
866                         }
867                         if(do1Rc) {
868                                 bool mate1 = true;
869                                 bool fw = false;
870                                 EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
871                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
872                                         halfAndHalf, false, maqPenalty_, qualOrder_);
873                                 EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
874                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
875                                         halfAndHalf, false, maqPenalty_, qualOrder_);
876                                 EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
877                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_,
878                                         halfAndHalf, true,  maqPenalty_, qualOrder_);
879                                 EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
880                                         *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
881                                         seedLen_,   // seedLen
882                                         true,       // nudgeLeft
883                                         PIN_TO_HI_HALF_EDGE,
884                                         PIN_TO_SEED_EDGE,
885                                         PIN_TO_SEED_EDGE,
886                                         PIN_TO_SEED_EDGE,
887                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
888                                 EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
889                                         *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
890                                         seedLen_,   // seedLen
891                                         true,       // nudgeLeft
892                                         PIN_TO_SEED_EDGE,
893                                         PIN_TO_SEED_EDGE,
894                                         PIN_TO_SEED_EDGE,
895                                         PIN_TO_SEED_EDGE,
896                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
897                                 EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
898                                         *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
899                                         seedLen_,   // seedLen
900                                         false,      // nudgeLeft
901                                         PIN_TO_HI_HALF_EDGE,
902                                         PIN_TO_SEED_EDGE,
903                                         PIN_TO_SEED_EDGE,
904                                         PIN_TO_SEED_EDGE,
905                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
906                                 EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
907                                         drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
908                                 dr1RcVec->push_back(drRc_Fw);
909                                 dr1RcVec->push_back(drRc_Seed);
910                         }
911                         if(do2Rc) {
912                                 bool mate1 = false;
913                                 bool fw = false;
914                                 EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
915                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
916                                         halfAndHalf, false, maqPenalty_, qualOrder_);
917                                 EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
918                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_,
919                                         halfAndHalf, false, maqPenalty_, qualOrder_);
920                                 EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
921                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_,
922                                         halfAndHalf, true,  maqPenalty_, qualOrder_);
923                                 EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
924                                         *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
925                                         seedLen_,   // seedLen
926                                         true,       // nudgeLeft
927                                         PIN_TO_HI_HALF_EDGE,
928                                         PIN_TO_SEED_EDGE,
929                                         PIN_TO_SEED_EDGE,
930                                         PIN_TO_SEED_EDGE,
931                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
932                                 EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
933                                         *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
934                                         seedLen_,   // seedLen
935                                         true,       // nudgeLeft
936                                         PIN_TO_SEED_EDGE,
937                                         PIN_TO_SEED_EDGE,
938                                         PIN_TO_SEED_EDGE,
939                                         PIN_TO_SEED_EDGE,
940                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
941                                 EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
942                                         *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
943                                         seedLen_,   // seedLen
944                                         false,      // nudgeLeft
945                                         PIN_TO_HI_HALF_EDGE,
946                                         PIN_TO_SEED_EDGE,
947                                         PIN_TO_SEED_EDGE,
948                                         PIN_TO_SEED_EDGE,
949                                         os_, verbose_, quiet_, mate1, pool_, NULL); // no backtrack limit for -n 1/2
950                                 EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
951                                         drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
952                                 dr2RcVec->push_back(drRc_Fw);
953                                 dr2RcVec->push_back(drRc_Seed);
954                         }
955                 } else if(seedMms_ > 1) {
956                         bool two = seedMms_ == 2;
957                         if(do1Fw) {
958                                 bool mate1 = true;
959                                 bool fw = true;
960                                 EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
961                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
962                                 EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
963                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
964                                 EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
965                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_);
966                                 EbwtRangeSource *rFw_BwHalf = new EbwtRangeSource(
967                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_);
968                                 EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
969                                         *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
970                                         seedLen_,   // seedLen
971                                         true,       // nudgeLeft
972                                         PIN_TO_HI_HALF_EDGE,
973                                         PIN_TO_HI_HALF_EDGE,
974                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
975                                         PIN_TO_SEED_EDGE,
976                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
977                                 EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
978                                         *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
979                                         seedLen_,   // seedLen
980                                         true,       // nudgeLeft
981                                         PIN_TO_SEED_EDGE,
982                                         PIN_TO_SEED_EDGE,
983                                         PIN_TO_SEED_EDGE,
984                                         PIN_TO_SEED_EDGE,
985                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
986                                 EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
987                                         *params, rFw_FwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
988                                         seedLen_,   // seedLen
989                                         false,      // nudgeLeft
990                                         PIN_TO_HI_HALF_EDGE,
991                                         PIN_TO_HI_HALF_EDGE,
992                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
993                                         PIN_TO_SEED_EDGE,
994                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
995                                 EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
996                                         drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
997                                 EbwtRangeSourceDriverFactory * drFw_BwSeed12 = NULL;
998                                 if(!two) {
999                                         EbwtRangeSourceFactory *rFw_BwSeed12 = new EbwtRangeSourceFactory(
1000                                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1001                                         drFw_BwSeed12 = new EbwtRangeSourceDriverFactory(
1002                                                 *params, rFw_BwSeed12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1003                                                 seedLen_,   // seedLen
1004                                                 true,       // nudgeLeft
1005                                                 PIN_TO_SEED_EDGE,
1006                                                 PIN_TO_SEED_EDGE,
1007                                                 PIN_TO_SEED_EDGE,
1008                                                 PIN_TO_SEED_EDGE,
1009                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1010                                 }
1011                                 EbwtRangeSourceDriver * drFw_FwSeedGen12 = NULL;
1012                                 if(!two) {
1013                                         EbwtRangeSource *rFw_FwSeedGen12 = new EbwtRangeSource(
1014                                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 3,  true,  maqPenalty_, qualOrder_);
1015                                         drFw_FwSeedGen12 = new EbwtRangeSourceDriver(
1016                                                 *params, rFw_FwSeedGen12, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1017                                                 seedLen_,   // seedLen
1018                                                 false,      // nudgeLeft
1019                                                 PIN_TO_BEGINNING,
1020                                                 PIN_TO_HI_HALF_EDGE,
1021                                                 PIN_TO_HI_HALF_EDGE,
1022                                                 PIN_TO_SEED_EDGE,
1023                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1024                                 }
1025                                 EbwtSeededRangeSourceDriver * drFw_Seed12 = NULL;
1026                                 if(!two) {
1027                                         drFw_Seed12 = new EbwtSeededRangeSourceDriver(
1028                                                 drFw_BwSeed12, drFw_FwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
1029                                 }
1030                                 EbwtRangeSourceDriver * drFw_BwHalf = new EbwtRangeSourceDriver(
1031                                         *params, rFw_BwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1032                                         seedLen_,   // seedLen
1033                                         true,       // nudgeLeft
1034                                         PIN_TO_BEGINNING,    // nothing's unrevisitable
1035                                         PIN_TO_HI_HALF_EDGE,
1036                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1037                                         PIN_TO_SEED_EDGE,
1038                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1039                                 dr1FwVec->push_back(drFw_Bw);
1040                                 dr1FwVec->push_back(drFw_Seed);
1041                                 if(drFw_Seed12 != NULL) {
1042                                         dr1FwVec->push_back(drFw_Seed12);
1043                                 }
1044                                 dr1FwVec->push_back(drFw_BwHalf);
1045                         }
1046                         if(do2Fw) {
1047                                 bool mate1 = false;
1048                                 bool fw = true;
1049                                 EbwtRangeSource *rFw_Bw = new EbwtRangeSource(
1050                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1051                                 EbwtRangeSourceFactory *rFw_BwSeed = new EbwtRangeSourceFactory(
1052                                          ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1053                                 EbwtRangeSource *rFw_FwSeedGen = new EbwtRangeSource(
1054                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_);
1055                                 EbwtRangeSource *rFw_BwHalf = new EbwtRangeSource(
1056                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_);
1057
1058                                 EbwtRangeSourceDriver * drFw_Bw = new EbwtRangeSourceDriver(
1059                                         *params, rFw_Bw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1060                                         seedLen_,   // seedLen
1061                                         true,       // nudgeLeft
1062                                         PIN_TO_HI_HALF_EDGE,
1063                                         PIN_TO_HI_HALF_EDGE,
1064                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1065                                         PIN_TO_SEED_EDGE,
1066                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1067                                 EbwtRangeSourceDriverFactory * drFw_BwSeed = new EbwtRangeSourceDriverFactory(
1068                                         *params, rFw_BwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1069                                         seedLen_,   // seedLen
1070                                         true,       // nudgeLeft
1071                                         PIN_TO_SEED_EDGE,
1072                                         PIN_TO_SEED_EDGE,
1073                                         PIN_TO_SEED_EDGE,
1074                                         PIN_TO_SEED_EDGE,
1075                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1076                                 EbwtRangeSourceDriver * drFw_FwSeedGen = new EbwtRangeSourceDriver(
1077                                         *params, rFw_FwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1078                                         seedLen_,   // seedLen
1079                                         false,      // nudgeLeft
1080                                         PIN_TO_HI_HALF_EDGE,
1081                                         PIN_TO_HI_HALF_EDGE,
1082                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1083                                         PIN_TO_SEED_EDGE,
1084                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1085                                 EbwtSeededRangeSourceDriver * drFw_Seed = new EbwtSeededRangeSourceDriver(
1086                                         drFw_BwSeed, drFw_FwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
1087                                 EbwtRangeSourceDriverFactory * drFw_BwSeed12 = NULL;
1088                                 if(!two) {
1089                                         EbwtRangeSourceFactory *rFw_BwSeed12 = new EbwtRangeSourceFactory(
1090                                                  ebwtBw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1091                                         drFw_BwSeed12 = new EbwtRangeSourceDriverFactory(
1092                                                 *params, rFw_BwSeed12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1093                                                 seedLen_,   // seedLen
1094                                                 true,       // nudgeLeft
1095                                                 PIN_TO_SEED_EDGE,
1096                                                 PIN_TO_SEED_EDGE,
1097                                                 PIN_TO_SEED_EDGE,
1098                                                 PIN_TO_SEED_EDGE,
1099                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1100                                 }
1101                                 EbwtRangeSourceDriver * drFw_FwSeedGen12 = NULL;
1102                                 if(!two) {
1103                                         EbwtRangeSource *rFw_FwSeedGen12 = new EbwtRangeSource(
1104                                                 &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 3,  true,  maqPenalty_, qualOrder_);
1105                                         drFw_FwSeedGen12 = new EbwtRangeSourceDriver(
1106                                                 *params, rFw_FwSeedGen12, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1107                                                 seedLen_,   // seedLen
1108                                                 false,      // nudgeLeft
1109                                                 PIN_TO_BEGINNING,
1110                                                 PIN_TO_HI_HALF_EDGE,
1111                                                 PIN_TO_HI_HALF_EDGE,
1112                                                 PIN_TO_SEED_EDGE,
1113                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1114                                 }
1115                                 EbwtSeededRangeSourceDriver * drFw_Seed12 = NULL;
1116                                 if(!two) {
1117                                         drFw_Seed12 = new EbwtSeededRangeSourceDriver(
1118                                                 drFw_BwSeed12, drFw_FwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
1119                                 }
1120                                 EbwtRangeSourceDriver * drFw_BwHalf = new EbwtRangeSourceDriver(
1121                                         *params, rFw_BwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1122                                         seedLen_,   // seedLen
1123                                         true,       // nudgeLeft
1124                                         PIN_TO_BEGINNING,    // nothing's unrevisitable
1125                                         PIN_TO_HI_HALF_EDGE,
1126                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1127                                         PIN_TO_SEED_EDGE,
1128                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1129                                 dr2FwVec->push_back(drFw_Bw);
1130                                 dr2FwVec->push_back(drFw_Seed);
1131                                 if(drFw_Seed12 != NULL) {
1132                                         dr2FwVec->push_back(drFw_Seed12);
1133                                 }
1134                                 dr2FwVec->push_back(drFw_BwHalf);
1135                         }
1136                         if(do1Rc) {
1137                                 bool mate1 = true;
1138                                 bool fw = false;
1139                                 EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
1140                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1141                                 EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
1142                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1143                                 EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
1144                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_);
1145                                 EbwtRangeSource *rRc_FwHalf = new EbwtRangeSource(
1146                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_);
1147
1148                                 EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
1149                                         *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1150                                         seedLen_,   // seedLen
1151                                         true,       // nudgeLeft
1152                                         PIN_TO_HI_HALF_EDGE,
1153                                         PIN_TO_HI_HALF_EDGE,
1154                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1155                                         PIN_TO_SEED_EDGE,
1156                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1157                                 EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
1158                                         *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1159                                         seedLen_,   // seedLen
1160                                         true,       // nudgeLeft
1161                                         PIN_TO_SEED_EDGE,
1162                                         PIN_TO_SEED_EDGE,
1163                                         PIN_TO_SEED_EDGE,
1164                                         PIN_TO_SEED_EDGE,
1165                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1166                                 EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
1167                                         *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1168                                         seedLen_,   // seedLen
1169                                         false,      // nudgeLeft
1170                                         PIN_TO_HI_HALF_EDGE,
1171                                         PIN_TO_HI_HALF_EDGE,
1172                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1173                                         PIN_TO_SEED_EDGE,
1174                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1175                                 EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
1176                                         drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
1177                                 EbwtRangeSourceDriverFactory * drRc_FwSeed12 = NULL;
1178                                 if(!two) {
1179                                         EbwtRangeSourceFactory *rRc_FwSeed12 = new EbwtRangeSourceFactory(
1180                                                 &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1181                                         drRc_FwSeed12 = new EbwtRangeSourceDriverFactory(
1182                                                 *params, rRc_FwSeed12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1183                                                 seedLen_,   // seedLen
1184                                                 true,       // nudgeLeft
1185                                                 PIN_TO_SEED_EDGE,
1186                                                 PIN_TO_SEED_EDGE,
1187                                                 PIN_TO_SEED_EDGE,
1188                                                 PIN_TO_SEED_EDGE,
1189                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1190                                 }
1191                                 EbwtRangeSourceDriver * drRc_BwSeedGen12 = NULL;
1192                                 if(!two) {
1193                                         EbwtRangeSource *rRc_BwSeedGen12 = new EbwtRangeSource(
1194                                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 3,  true,  maqPenalty_, qualOrder_);
1195                                         drRc_BwSeedGen12 = new EbwtRangeSourceDriver(
1196                                                 *params, rRc_BwSeedGen12, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1197                                                 seedLen_,   // seedLen
1198                                                 false,      // nudgeLeft
1199                                                 PIN_TO_BEGINNING,
1200                                                 PIN_TO_HI_HALF_EDGE,
1201                                                 PIN_TO_HI_HALF_EDGE,
1202                                                 PIN_TO_SEED_EDGE,
1203                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1204                                 }
1205                                 EbwtSeededRangeSourceDriver * drRc_Seed12 = NULL;
1206                                 if(!two) {
1207                                         drRc_Seed12 = new EbwtSeededRangeSourceDriver(
1208                                                 drRc_FwSeed12, drRc_BwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
1209                                 }
1210                                 EbwtRangeSourceDriver * drRc_FwHalf = new EbwtRangeSourceDriver(
1211                                         *params, rRc_FwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1212                                         seedLen_,   // seedLen
1213                                         true,       // nudgeLeft
1214                                         PIN_TO_BEGINNING,    // nothing's unrevisitable
1215                                         PIN_TO_HI_HALF_EDGE,
1216                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1217                                         PIN_TO_SEED_EDGE,
1218                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1219                                 dr1RcVec->push_back(drRc_Fw);
1220                                 dr1RcVec->push_back(drRc_Seed);
1221                                 if(drRc_Seed12 != NULL) {
1222                                         dr1RcVec->push_back(drRc_Seed12);
1223                                 }
1224                                 dr1RcVec->push_back(drRc_FwHalf);
1225                         }
1226                         if(do2Rc) {
1227                                 bool mate1 = false;
1228                                 bool fw = false;
1229                                 EbwtRangeSource *rRc_Fw = new EbwtRangeSource(
1230                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1231                                 EbwtRangeSourceFactory *rRc_FwSeed = new EbwtRangeSourceFactory(
1232                                         &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1233                                 EbwtRangeSource *rRc_BwSeedGen = new EbwtRangeSource(
1234                                          ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 0, true,  maqPenalty_, qualOrder_);
1235                                 EbwtRangeSource *rRc_FwHalf = new EbwtRangeSource(
1236                                         &ebwtFw_, fw,  qualCutoff_, false, verbose_, quiet_, 2,  false, maqPenalty_, qualOrder_);
1237
1238                                 EbwtRangeSourceDriver * drRc_Fw = new EbwtRangeSourceDriver(
1239                                         *params, rRc_Fw, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1240                                         seedLen_,   // seedLen
1241                                         true,       // nudgeLeft
1242                                         PIN_TO_HI_HALF_EDGE,
1243                                         PIN_TO_HI_HALF_EDGE,
1244                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1245                                         PIN_TO_SEED_EDGE,
1246                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1247                                 EbwtRangeSourceDriverFactory * drRc_FwSeed = new EbwtRangeSourceDriverFactory(
1248                                         *params, rRc_FwSeed, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1249                                         seedLen_,   // seedLen
1250                                         true,       // nudgeLeft
1251                                         PIN_TO_SEED_EDGE,
1252                                         PIN_TO_SEED_EDGE,
1253                                         PIN_TO_SEED_EDGE,
1254                                         PIN_TO_SEED_EDGE,
1255                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1256                                 EbwtRangeSourceDriver * drRc_BwSeedGen = new EbwtRangeSourceDriver(
1257                                         *params, rRc_BwSeedGen, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1258                                         seedLen_,   // seedLen
1259                                         false,      // nudgeLeft
1260                                         PIN_TO_HI_HALF_EDGE,
1261                                         PIN_TO_HI_HALF_EDGE,
1262                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1263                                         PIN_TO_SEED_EDGE,
1264                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1265                                 EbwtSeededRangeSourceDriver * drRc_Seed = new EbwtSeededRangeSourceDriver(
1266                                         drRc_FwSeed, drRc_BwSeedGen, fw, seedLen_, verbose_, quiet_, mate1);
1267                                 EbwtRangeSourceDriverFactory * drRc_FwSeed12 = NULL;
1268                                 if(!two) {
1269                                         EbwtRangeSourceFactory *rRc_FwSeed12 = new EbwtRangeSourceFactory(
1270                                                 &ebwtFw_, fw,  qualCutoff_, true,  verbose_, quiet_, 0, false, maqPenalty_, qualOrder_);
1271                                         drRc_FwSeed12 = new EbwtRangeSourceDriverFactory(
1272                                                 *params, rRc_FwSeed12, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1273                                                 seedLen_,   // seedLen
1274                                                 true,       // nudgeLeft
1275                                                 PIN_TO_SEED_EDGE,
1276                                                 PIN_TO_SEED_EDGE,
1277                                                 PIN_TO_SEED_EDGE,
1278                                                 PIN_TO_SEED_EDGE,
1279                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1280                                 }
1281                                 EbwtRangeSourceDriver * drRc_BwSeedGen12 = NULL;
1282                                 if(!two) {
1283                                         EbwtRangeSource *rRc_BwSeedGen12 = new EbwtRangeSource(
1284                                                  ebwtBw_, fw,  qualCutoff_, false, verbose_, quiet_, 3,  true,  maqPenalty_, qualOrder_);
1285                                         drRc_BwSeedGen12 = new EbwtRangeSourceDriver(
1286                                                 *params, rRc_BwSeedGen12, fw, true, maqPenalty_, qualOrder_, sink_, sinkPt,
1287                                                 seedLen_,   // seedLen
1288                                                 false,      // nudgeLeft
1289                                                 PIN_TO_BEGINNING,
1290                                                 PIN_TO_HI_HALF_EDGE,
1291                                                 PIN_TO_HI_HALF_EDGE,
1292                                                 PIN_TO_SEED_EDGE,
1293                                                 os_, verbose_, quiet_, mate1, pool_, btCnt);
1294                                 }
1295                                 EbwtSeededRangeSourceDriver * drRc_Seed12 = NULL;
1296                                 if(!two) {
1297                                         drRc_Seed12 = new EbwtSeededRangeSourceDriver(
1298                                                 drRc_FwSeed12, drRc_BwSeedGen12, fw, seedLen_, verbose_, quiet_, mate1);
1299                                 }
1300                                 EbwtRangeSourceDriver * drRc_FwHalf = new EbwtRangeSourceDriver(
1301                                         *params, rRc_FwHalf, fw, false, maqPenalty_, qualOrder_, sink_, sinkPt,
1302                                         seedLen_,   // seedLen
1303                                         true,       // nudgeLeft
1304                                         PIN_TO_BEGINNING,    // nothing's unrevisitable
1305                                         PIN_TO_HI_HALF_EDGE,
1306                                         two ? PIN_TO_SEED_EDGE : PIN_TO_HI_HALF_EDGE,
1307                                         PIN_TO_SEED_EDGE,
1308                                         os_, verbose_, quiet_, mate1, pool_, btCnt);
1309                                 dr2RcVec->push_back(drRc_Fw);
1310                                 dr2RcVec->push_back(drRc_Seed);
1311                                 if(drRc_Seed12 != NULL) {
1312                                         dr2RcVec->push_back(drRc_Seed12);
1313                                 }
1314                                 dr2RcVec->push_back(drRc_FwHalf);
1315                         }
1316                 } else {
1317                         cerr << "Unsupported --stateful mode: " << seedMms_ << endl;
1318                 }
1319                 // Set up a RangeChaser
1320                 RangeChaser<String<Dna> > *rchase =
1321                         new RangeChaser<String<Dna> >(cacheLimit_, cacheFw_, cacheBw_);
1322
1323                 if(v1_) {
1324                         PairedBWAlignerV1<EbwtRangeSource>* al = new PairedBWAlignerV1<EbwtRangeSource>(
1325                                 params,
1326                                 new TCostAwareRangeSrcDr(strandFix_, dr1FwVec, verbose_, quiet_, false),
1327                                 new TCostAwareRangeSrcDr(strandFix_, dr1RcVec, verbose_, quiet_, false),
1328                                 new TCostAwareRangeSrcDr(strandFix_, dr2FwVec, verbose_, quiet_, false),
1329                                 new TCostAwareRangeSrcDr(strandFix_, dr2RcVec, verbose_, quiet_, false),
1330                                 refAligner, rchase, sink_, sinkPtFactory_, sinkPt,
1331                                 mate1fw_, mate2fw_, peInner_, peOuter_, dontReconcile_,
1332                                 symCeil_, mixedThresh_, mixedAttemptLim_, refs_,
1333                                 rangeMode_, verbose_, quiet_, maxBts_, pool_,
1334                                 btCnt);
1335                         delete dr1FwVec;
1336                         delete dr1RcVec;
1337                         delete dr2FwVec;
1338                         delete dr2RcVec;
1339                         return al;
1340                 } else {
1341                         // We dumped all the drivers into dr1FwVec
1342                         PairedBWAlignerV2<EbwtRangeSource>* al = new PairedBWAlignerV2<EbwtRangeSource>(
1343                                 params, paramsSe1, paramsSe2,
1344                                 new TCostAwareRangeSrcDr(strandFix_, dr1FwVec, verbose_, quiet_, true),
1345                                 refAligner, rchase, sink_, sinkPtFactory_, sinkPt,
1346                                 sinkPtSe1, sinkPtSe2, mate1fw_, mate2fw_, peInner_, peOuter_,
1347                                 mixedAttemptLim_, refs_, rangeMode_, verbose_,
1348                                 quiet_, maxBts_, pool_, btCnt);
1349                         delete dr1FwVec;
1350                         return al;
1351                 }
1352         }
1353
1354 private:
1355         Ebwt<String<Dna> >& ebwtFw_;
1356         Ebwt<String<Dna> >* ebwtBw_;
1357         bool color_;
1358         const bool v1_; // whether to use V1 PairedAligner
1359         const bool doFw_;
1360         const bool doRc_;
1361         const uint32_t seedMms_;
1362         const uint32_t seedLen_;
1363         const int qualCutoff_;
1364         const int maxBts_;
1365         HitSink& sink_;
1366         const HitSinkPerThreadFactory& sinkPtFactory_;
1367         const bool mate1fw_;
1368         const bool mate2fw_;
1369         const uint32_t peInner_;
1370         const uint32_t peOuter_;
1371         const bool dontReconcile_;
1372         const uint32_t symCeil_;
1373         const uint32_t mixedThresh_;
1374         const uint32_t mixedAttemptLim_;
1375         RangeCache *cacheFw_;
1376         RangeCache *cacheBw_;
1377         const uint32_t cacheLimit_;
1378         ChunkPool *pool_;
1379         BitPairReference* refs_;
1380         vector<String<Dna5> >& os_;
1381         const bool reportSe_;
1382         const bool maqPenalty_;
1383         const bool qualOrder_;
1384         const bool strandFix_;
1385         const bool rangeMode_;
1386         const bool verbose_;
1387         const bool quiet_;
1388 };
1389
1390 #endif /* ALIGNER_SEED_MM_H_ */