Ejemplo n.º 1
0
static int testEval() {
    // verify eval results are symmetrical (White/Black, right/left)
    const int CASES = 25;
    static const string fens[CASES] = {
        "8/4K3/8/1NR5/8/4k1r1/8/8 w - -",
        "8/4K3/8/1N6/6p1/4k2p/8/8 w - -",
        "8/4K3/8/1r6/6B1/4k2N/8/8 w - -",
        "3b4/1n3n2/1pk3Np/p7/P4P1p/1P6/5BK1/3R4 b - -",
        "8/3r1ppk/8/P6P/3n4/2K5/R2B4/8 b - -",
        "1rb1r1k1/2q2pb1/pp1p4/2n1pPPQ/Pn1BP3/1NN4R/1PP4P/R5K1 b - -",
        "6k1/1b4p1/5p1p/pq3P2/1p1BP3/1P2QR1P/P1r3PK/8 w - -",
        "8/5pk1/7p/3p1R2/p1p3P1/2P2K1P/1P1r4/8 w - -",
        "6k1/p3pp2/6p1/7P/R7/b1q2P2/B1P1K2P/7R b - -",
        "r7/1b4k1/pp1np1p1/3pq1NN/7P/4P3/PP4P1/1Q3RK1 b - -",
        "4b3/2p4p/pp1bk3/2p3p1/2P5/PPB2PP1/7P/3K1N2 w - -",
        "r1bqr1k1/ppp2ppp/3p4/4n3/2PN4/P1Q1P3/1PB2PPP/R4RK1 b - -",
        "r4rk1/1ppqbppp/p2p1n2/8/1n1PP3/1Q3N2/PP1N1PPP/R1B1R1K1 b - -",
        "r6k/1p4bp/1p1n1pp1/1B6/8/P4NP1/1P3P1P/2R3K1 w - -",
        "r1b2r1k/pp3n1p/2p1p3/3Pnppq/3PP3/1P1N1PP1/P5BP/R1Q2RK1 w - -",
        "2kr3r/1bpnqp2/1p2p3/p2p3p/P1PPBPp1/2P1P1P1/2QN2P1/1R2K2R w K -",
        "8/1R6/3k4/2p5/2p1B3/5K2/8/8 w - -",
        "1BR2rk1/pP1nbpp1/B2P2p1/8/8/8/1P4P1/3n2K1 b - -",
        "r1b1k2r/1p1n1pp1/p6p/2p5/4Nb2/5NP1/PPP2P1P/1K1R1B1R b kq -",
        "r1b2rk1/1p1n1pp1/p6p/2p5/4Nb2/3R1NP1/PPP2P1P/1K1R1B2 b - -",
        "1kr5/1p1b2R1/p3p2Q/2bp3P/8/P1PB1P2/1P1K1P2/R6q b - -",
        "rb3rk1/1p1RRpp1/p6p/r1p5/4Nb2/5NP1/PPP2P1P/1K3B2 b - -",
        "5rk1/1pqn2pp/4pn2/p7/2P5/4PP2/1B2BP1P/3Q1RK1 w - -",
        "3k1q2/p3p1p1/1p1nQ3/3P4/P2P4/B2P4/6KP/8 b - -",
        "6k1/4R1P1/5P2/5K1p/7r/8/8/8 w - -"
    };
    
    int errs = 0;
    for (int i = 0; i < CASES; i++) {
        Board board;
        if (!BoardIO::readFEN(board, fens[i].c_str())) {
            cerr << "testEval case " << i << " error in FEN: " << fens[i] << endl;
            ++errs;
            continue;
        }
        Scoring *s = new Scoring();
        int eval1 = s->evalu8(board);
        board.flip();
        int eval2 = s->evalu8(board);
        if (eval1 != eval2) {
            ++errs;
            cerr << "testEval case " << i << " eval mismatch" << endl;
        }
        delete s;
    }
    return errs;
}
Ejemplo n.º 2
0
double Game::GameState::Score(int player)
{
	int other = OtherPlayer(player);

	if (playerState[player]->HasWon()) return 1;
	if (playerState[other]->HasWon()) return 0;

	Scoring *sc = &scoring[player];

	sc->Reset();
	sc->SetAligned(SCORE_ALIGN_PLAYER, playerState[player]->nbAlignementDone, boardDesc->align);
	sc->SetAligned(SCORE_ALIGN_OTHER, playerState[other]->nbAlignementDone, boardDesc->align);
	sc->SetRandom();

	return (*sc)();
}
Ejemplo n.º 3
0
static int testEval() {
    // verify eval results are symmetrical (White/Black, right/left)
    const int CASES = 9;
    static const string fens[CASES] = {
        "8/4K3/8/1NR5/8/4k1r1/8/8 w - -",
        "8/4K3/8/1N6/6p1/4k2p/8/8 w - -",
        "8/4K3/8/1r6/6B1/4k2N/8/8 w - -",
        "3b4/1n3n2/1pk3Np/p7/P4P1p/1P6/5BK1/3R4 b - -",
        "8/3r1ppk/8/P6P/3n4/2K5/R2B4/8 b - -",
        "1rb1r1k1/2q2pb1/pp1p4/2n1pPPQ/Pn1BP3/1NN4R/1PP4P/R5K1 b - -",
        "6k1/1b4p1/5p1p/pq3P2/1p1BP3/1P2QR1P/P1r3PK/8 w - -",
        "8/5pk1/7p/3p1R2/p1p3P1/2P2K1P/1P1r4/8 w - -",
        "6k1/p3pp2/6p1/7P/R7/b1q2P2/B1P1K2P/7R b - -"
    };
    int errs = 0;
    for (int i = 0; i < CASES; i++) {
        Board board;
        if (!BoardIO::readFEN(board, fens[i].c_str())) {
            cerr << "testEval case " << i << " error in FEN: " << fens[i] << endl;
            ++errs;
            continue;
        }
        Scoring *s = new Scoring();
        int eval1 = s->evalu8(board);
        board.flip();
        int eval2 = s->evalu8(board);
        if (eval1 != eval2) {
            ++errs;
            cerr << "testEval case " << i << " eval mismatch" << endl;
        }
        board.flip2();
        int eval3 = s->evalu8(board);
        if (eval1 != eval3) {
            ++errs;
            cerr << "testEval case " << i << " eval mismatch" << endl;
        }
        delete s;
    }
    return errs;
}
Ejemplo n.º 4
0
/**
 * A way of feeding simply tests to the seed alignment infrastructure.
 */
int main(int argc, char **argv) {

    EList<string> strs;
    //                            GCTATATAGCGCGCTCGCATCATTTTGTGT
    strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA"
                          "NNNNNNNNNN"
                          "CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA"));
    //                            GCTATATAGCGCGCTTGCATCATTTTGTGT
    //                                           ^
    bool packed = false;
    int color = 0;
	pair<GFM*, GFM*> gfms = GFM::fromStrings<SString<char> >(
		strs,
		packed,
		REF_READ_REVERSE,
		Ebwt::default_bigEndian,
		Ebwt::default_lineRate,
		Ebwt::default_offRate,
		Ebwt::default_ftabChars,
		".aligner_seed2.cpp.tmp",
		Ebwt::default_useBlockwise,
		Ebwt::default_bmax,
		Ebwt::default_bmaxMultSqrt,
		Ebwt::default_bmaxDivN,
		Ebwt::default_dcv,
		Ebwt::default_seed,
		false,  // verbose
		false,  // autoMem
		false); // sanity
    
    gfms.first->loadIntoMemory (-1, true, true, true, true, false);
    gfms.second->loadIntoMemory(1, true, true, true, true, false);
	
	int testnum = 0;

	// Query is longer than ftab and matches exactly twice
    for(int rc = 0; rc < 2; rc++) {
		for(int i = 0; i < 2; i++) {
			cerr << "Test " << (++testnum) << endl;
			cerr << "  Query with length greater than ftab" << endl;
			DescentMetrics mets;
			PerReadMetrics prm;
			DescentDriver dr;
			
			// Set up the read
			BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			if(rc) {
				seq.reverseComp();
				qual.reverse();
			}
			dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);

			// Set up the DescentConfig
			DescentConfig conf;
			conf.cons.init(GFM::default_ftabChars, 1.0);
			conf.expol = DESC_EX_NONE;
			
			// Set up the search roots
			dr.addRoot(
				conf,   // DescentConfig
				(i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root
				(i == 0) ? true : false,           // left-to-right?
				rc == 0,   // forward?
				0.0f);   // root priority
			
			// Do the search
			Scoring sc = Scoring::base1();
			dr.go(sc, *gfms.first, *gfms.second, mets, prm);
			
			// Confirm that an exact-matching alignment was found
			assert_eq(1, dr.sink().nrange());
			assert_eq(2, dr.sink().nelt());
		}
	}
	
	// Query has length euqal to ftab and matches exactly twice
    for(int i = 0; i < 2; i++) {
		cerr << "Test " << (++testnum) << endl;
		cerr << "  Query with length equal to ftab" << endl;
        DescentMetrics mets;
		PerReadMetrics prm;
        DescentDriver dr;
        
        // Set up the read
        BTDnaString seq ("GCTATATAGC", true);
        BTString    qual("ABCDEFGHIa");
		dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
        
        // Set up the DescentConfig
        DescentConfig conf;
        conf.cons.init(GFM::default_ftabChars, 1.0);
        conf.expol = DESC_EX_NONE;
        
        // Set up the search roots
        dr.addRoot(
            conf,   // DescentConfig
            (i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root
            (i == 0) ? true : false,           // left-to-right?
            true,   // forward?
            0.0f);   // root priority
        
        // Do the search
        Scoring sc = Scoring::base1();
        dr.go(sc, *gfms.first, *gfms.second, mets, prm);
		
		// Confirm that an exact-matching alignment was found
		assert_eq(1, dr.sink().nrange());
		assert_eq(2, dr.sink().nelt());
    }

	// Query has length less than ftab length and matches exactly twice
    for(int i = 0; i < 2; i++) {
		cerr << "Test " << (++testnum) << endl;
		cerr << "  Query with length less than ftab" << endl;
        DescentMetrics mets;
		PerReadMetrics prm;
        DescentDriver dr;
        
        // Set up the read
        BTDnaString seq ("GCTATATAG", true);
        BTString    qual("ABCDEFGHI");
		dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
        
        // Set up the DescentConfig
        DescentConfig conf;
        conf.cons.init(GFM::default_ftabChars, 1.0);
        conf.expol = DESC_EX_NONE;
        
        // Set up the search roots
        dr.addRoot(
            conf,   // DescentConfig
            (i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root
            (i == 0) ? true : false,           // left-to-right?
            true,   // forward?
            0.0f);   // root priority
        
        // Do the search
        Scoring sc = Scoring::base1();
        dr.go(sc, *gfms.first, *gfms.second, mets, prm);
		
		// Confirm that an exact-matching alignment was found
		assert_eq(1, dr.sink().nrange());
		assert_eq(2, dr.sink().nelt());
    }
	
	// Search root is in the middle of the read, requiring a bounce
    for(int i = 0; i < 2; i++) {
		cerr << "Test " << (++testnum) << endl;
		cerr << "  Search root in middle of read" << endl;
        DescentMetrics mets;
		PerReadMetrics prm;
        DescentDriver dr;
        
        // Set up the read
		//                012345678901234567890123456789
        BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
        BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
		TIndexOffU top, bot;
		top = bot = 0;
		bool ret = gfms.first->contains("GCGCTCGCATCATTTTGTGT", &top, &bot);
		cerr << ret << ", " << top << ", " << bot << endl;
		dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
        
        // Set up the DescentConfig
        DescentConfig conf;
        conf.cons.init(GFM::default_ftabChars, 1.0);
        conf.expol = DESC_EX_NONE;
        
        // Set up the search roots
        dr.addRoot(
            conf,   // DescentConfig
            (i == 0) ? 10 : (seq.length() - 1 - 10), // 5' offset into read of root
            (i == 0) ? true : false,                 // left-to-right?
            true,   // forward?
            0.0f);   // root priority
        
        // Do the search
        Scoring sc = Scoring::base1();
        dr.go(sc, *gfms.first, *gfms.second, mets, prm);
		
		// Confirm that an exact-matching alignment was found
		assert_eq(1, dr.sink().nrange());
		assert_eq(2, dr.sink().nelt());
    }

	delete gfms.first;
	delete gfms.second;
	
	strs.clear();
    strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA"
                          "NNNNNNNNNN"
                          "CATGTCAGCTATATAGCG"));
	gfms = GFM::fromStrings<SString<char> >(
		strs,
		packed,
		REF_READ_REVERSE,
		GFM::default_bigEndian,
		GFM::default_lineRate,
		GFM::default_offRate,
		GFM::default_ftabChars,
		".aligner_seed2.cpp.tmp",
		GFM::default_useBlockwise,
		GFM::default_bmax,
		GfM::default_bmaxMultSqrt,
		GFM::default_bmaxDivN,
		GFM::default_dcv,
		GFM::default_seed,
		false,  // verbose
		false,  // autoMem
		false); // sanity
    
    gfms.first->loadIntoMemory (-1, true, true, true, true, false);
    gfms.second->loadIntoMemory(1, true, true, true, true, false);
	
	// Query is longer than ftab and matches exactly once.  One search root for
	// forward read.
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			for(size_t j = 0; j < seq.length(); j++) {
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query with length greater than ftab and matches exactly once" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				// Set up the read
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				conf.cons.init(GFM::default_ftabChars, 1.0);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);   // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				assert_eq(1, dr.sink().nelt());
			}
		}
	}

	// Query is longer than ftab and its reverse complement matches exactly
	// once.  Search roots on forward and reverse-comp reads.
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			for(size_t j = 0; j < seq.length(); j++) {
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query with length greater than ftab and reverse complement matches exactly once" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				// Set up the read
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				conf.cons.init(GFM::default_ftabChars, 1.0);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);   // root priority
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					false,  // forward?
					1.0f);   // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				assert_eq(1, dr.sink().nelt());
			}
		}
	}

	// Query is longer than ftab and matches exactly once with one mismatch
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||||||||||||||||||
			BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			//                012345678901234567890123456789
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			for(size_t k = 0; k < orig.length(); k++) {
				BTDnaString seq = orig;
				seq.set(seq[k] ^ 3, k);
				for(size_t j = 0; j < seq.length(); j++) {
					// Assume left-to-right
					size_t beg = j;
					size_t end = j + GFM::default_ftabChars;
					// Mismatch penalty is 3, so we have to skip starting
					// points that are within 2 from the mismatch
					if((i > 0 && j > 0) || j == seq.length()-1) {
						// Right-to-left
						if(beg < GFM::default_ftabChars) {
							beg = 0;
						} else {
							beg -= GFM::default_ftabChars;
						}
						end -= GFM::default_ftabChars;
					}
					size_t kk = k;
					//if(rc) {
					//	kk = seq.length() - k - 1;
					//}
					if(beg <= kk && end > kk) {
						continue;
					}
					if((j > kk) ? (j - kk <= 2) : (kk - j <= 2)) {
						continue;
					}
					cerr << "Test " << (++testnum) << endl;
					cerr << "  Query with length greater than ftab and matches exactly once with 1mm" << endl;
					DescentMetrics mets;
					PerReadMetrics prm;
					DescentDriver dr;
					
					dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
					
					// Set up the DescentConfig
					DescentConfig conf;
					// Changed 
					conf.cons.init(0, 1.0);
					conf.expol = DESC_EX_NONE;
					
					// Set up the search roots
					dr.addRoot(
						conf,    // DescentConfig
						j,       // 5' offset into read of root
						i == 0,  // left-to-right?
						true,    // forward?
						0.0f);    // root priority
					
					// Do the search
					Scoring sc = Scoring::base1();
					dr.go(sc, *gfms.first, *gfms.second, mets, prm);
					
					// Confirm that an exact-matching alignment was found
					assert_eq(1, dr.sink().nrange());
					assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
					assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
					cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
					assert_eq(1, dr.sink().nelt());
					last_topf = dr.sink()[0].topf;
					last_botf = dr.sink()[0].botf;
				}
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one N mismatch
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||||||||||||||||||
			BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			//                012345678901234567890123456789
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			for(size_t k = 0; k < orig.length(); k++) {
				BTDnaString seq = orig;
				seq.set(4, k);
				for(size_t j = 0; j < seq.length(); j++) {
					// Assume left-to-right
					size_t beg = j;
					size_t end = j + GFM::default_ftabChars;
					// Mismatch penalty is 3, so we have to skip starting
					// points that are within 2 from the mismatch
					if((i > 0 && j > 0) || j == seq.length()-1) {
						// Right-to-left
						if(beg < GFM::default_ftabChars) {
							beg = 0;
						} else {
							beg -= GFM::default_ftabChars;
						}
						end -= GFM::default_ftabChars;
					}
					if(beg <= k && end > k) {
						continue;
					}
					if((j > k) ? (j - k <= 2) : (k - j <= 2)) {
						continue;
					}
					cerr << "Test " << (++testnum) << endl;
					cerr << "  Query with length greater than ftab and matches exactly once with 1mm" << endl;
					DescentMetrics mets;
					PerReadMetrics prm;
					DescentDriver dr;
					
					dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
					
					// Set up the DescentConfig
					DescentConfig conf;
					// Changed 
					conf.cons.init(0, 1.0);
					conf.expol = DESC_EX_NONE;
					
					// Set up the search roots
					dr.addRoot(
						conf,   // DescentConfig
						j,      // 5' offset into read of root
						i == 0, // left-to-right?
						true,   // forward?
						0.0f);   // root priority
					
					// Do the search
					Scoring sc = Scoring::base1();
					dr.go(sc, *gfms.first, *gfms.second, mets, prm);
					
					// Confirm that an exact-matching alignment was found
					assert_eq(1, dr.sink().nrange());
					assert_eq(sc.n(40), dr.sink()[0].pen);
					assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
					assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
					cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
					assert_eq(1, dr.sink().nelt());
					last_topf = dr.sink()[0].topf;
					last_botf = dr.sink()[0].botf;
				}
			}
		}
    }

	// Throw a bunch of queries with a bunch of Ns in and try to force an assert
	{
		RandomSource rnd(79);
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||||||||||||||||||
			BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			//                012345678901234567890123456789
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			if(i == 1) {
				orig.reverseComp();
				qual.reverse();
			}
			for(size_t trials = 0; trials < 100; trials++) {
				BTDnaString seq = orig;
				size_t ns = 10;
				for(size_t k = 0; k < ns; k++) {
					size_t pos = rnd.nextU32() % seq.length();
					seq.set(4, pos);
				}
				
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query with a bunch of Ns" << endl;
				
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(GFM::default_ftabChars, 1.0);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				for(size_t k = 0; k < ns; k++) {
					size_t j = rnd.nextU32() % seq.length();
					bool ltr = (rnd.nextU2() == 0) ? true : false;
					bool fw = (rnd.nextU2() == 0) ? true : false;
					dr.addRoot(
						conf,   // DescentConfig
						j,      // 5' offset into read of root
						ltr,    // left-to-right?
						fw,     // forward?
						0.0f);   // root priority
				}
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one mismatch
	{
		RandomSource rnd(77);
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||||||||||||||||||
			BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true);
			//                012345678901234567890123456789
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIabc");
			//       revcomp: ACACAAAATGATGCGAGCGCGCTATATAGC
			//       revqual: cbaIHGFEDCBAihgfedcbaIHGFEDCBA
			bool fwi = (i == 0);
			if(!fwi) {
				orig.reverseComp();
			}
			for(size_t k = 0; k < orig.length(); k++) {
				BTDnaString seq = orig;
				seq.set(seq[k] ^ 3, k);
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query with length greater than ftab and matches exactly once with 1mm.  Many search roots." << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(0, 1.0);
				conf.expol = DESC_EX_NONE;
				
				// Set up several random search roots
				bool onegood = false;
				for(size_t y = 0; y < 10; y++) {
					size_t j = rnd.nextU32() % seq.length();
					bool ltr = (rnd.nextU2() == 0) ? true : false;
					bool fw = (rnd.nextU2() == 0) ? true : false;
					dr.addRoot(
						conf,     // DescentConfig
						(TReadOff)j,        // 5' offset into read of root
						ltr,      // left-to-right?
						fw,       // forward?
						(float)((float)y * 1.0f)); // root priority
					// Assume left-to-right
					size_t beg = j;
					size_t end = j + GFM::default_ftabChars;
					// Mismatch penalty is 3, so we have to skip starting
					// points that are within 2 from the mismatch
					if(!ltr) {
						// Right-to-left
						if(beg < GFM::default_ftabChars) {
							beg = 0;
						} else {
							beg -= GFM::default_ftabChars;
						}
						end -= GFM::default_ftabChars;
					}
					bool good = true;
					if(fw != fwi) {
						good = false;
					}
					if(beg <= k && end > k) {
						good = false;
					}
					if((j > k) ? (j - k <= 2) : (k - j <= 2)) {
						good = false;
					}
					if(good) {
						onegood = true;
					}
				}
				if(!onegood) {
					continue;
				}
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one read gap
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
		for(int k = 0; k < 2; k++) {
			// Set up the read
			//                GCTATATAGCGCGCCTGCATCATTTTGTGT
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                |||||||||||||||///////////////
			BTDnaString seq ("GCTATATAGCGCGCTGCATCATTTTGTGT", true);
			//                01234567890123456789012345678
			//                87654321098765432109876543210
			BTString    qual("ABCDEFGHIabcdefghiABCDEFGHIab");
			if(k == 1) {
				seq.reverseComp();
				qual.reverse();
			}
			assert_eq(seq.length(), qual.length());
			// js iterate over offsets from 5' end for the search root
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				if(k == 1) {
					beg = seq.length() - beg - 1;
				}
				size_t end = beg + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				assert_geq(end, beg);
				if(beg <= 15 && end >= 15) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a read gap of length 1" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				Read q("test", seq.toZBuf(), qual.toZBuf());
				assert(q.repOk());
				dr.initRead(q, -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(0, 0.5);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					k == 0, // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert_eq(sc.readGapOpen() + 0 * sc.readGapExtend(), dr.sink()[0].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}}
    }

	// Query is longer than ftab and matches exactly once with one read gap of
	// length 3
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
		for(int k = 0; k < 2; k++) {
			// Set up the read
			//                GCTATATAGCGCGCGCTCATCATTTTGTGT
			//    Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||   |||||||||||||
			BTDnaString seq ("GCTATATAGCGCGC" "CATCATTTTGTGT", true);
			//                01234567890123   4567890123456
			//                65432109876543   2109876543210
			BTString    qual("ABCDEFGHIabcde" "fghiABCDEFGHI");
			if(k == 1) {
				seq.reverseComp();
				qual.reverse();
			}
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				if(k == 1) {
					beg = seq.length() - beg - 1;
				}
				size_t end = beg + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 14 && end >= 14) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a read gap of length 3" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed
				conf.cons.init(0, 0.2);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					k == 0, // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				// Need to adjust the mismatch penalty up to avoid alignments
				// with lots of mismatches.
				sc.setMmPen(COST_MODEL_CONSTANT, 6, 6);
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert_eq(sc.readGapOpen() + 2 * sc.readGapExtend(), dr.sink()[0].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}}
    }

	// Query is longer than ftab and matches exactly once with one reference gap
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGC" "TCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||   ||||||||||||||||
			BTDnaString seq ("GCTATATAGCGCGCA""TCGCATCATTTTGTGT", true);
			//                012345678901234  5678901234567890
			BTString    qual("ABCDEFGHIabcdef""ghiABCDEFGHIabcd");
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				size_t end = j + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 14 && end >= 14) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a reference gap of length 1" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(1, 0.5);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				// Need to adjust the mismatch penalty up to avoid alignments
				// with lots of mismatches.
				sc.setMmPen(COST_MODEL_CONSTANT, 6, 6);
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert_eq(sc.refGapOpen() + 0 * sc.refGapExtend(), dr.sink()[0].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one reference gap
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//    Ref: CATGTCAGCTATATAGCGCGC"   "TCGCATCATTTTGTGTGTAAACCA
			//                ||||||||||||||     ||||||||||||||||
			BTDnaString seq ("GCTATATAGCGCGCATG""TCGCATCATTTTGTGT", true);
			//                01234567890123456  7890123456789012
			BTString    qual("ABCDEFGHIabcdefgh""iABCDEFGHIabcdef");
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				size_t end = j + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 14 && end >= 14) {
					continue;
				}
				if(beg <= 15 && end >= 15) {
					continue;
				}
				if(beg <= 16 && end >= 16) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a reference gap of length 1" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(1, 0.25);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				// Need to adjust the mismatch penalty up to avoid alignments
				// with lots of mismatches.
				sc.setMmPen(COST_MODEL_CONSTANT, 6, 6);
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert_eq(sc.refGapOpen() + 2 * sc.refGapExtend(), dr.sink()[0].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one read gap,
	// one ref gap, and one mismatch
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//           Ref: CATGTCAGCT   ATATAGCGCGCT  CGCATCATTTTGTGTGTAAACCA
			//                ||||||||||   ||||||||||||   |||||| |||||||||||||
			BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGTGTAAAC", true);
			//                0123456789  0123456789012   34567890123456789012
			BTString    qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF");
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				size_t end = j + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 10 && end >= 10) {
					continue;
				}
				if(beg <= 22 && end >= 22) {
					continue;
				}
				if(beg <= 30 && end >= 30) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a read gap of length 1" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(1, 0.5);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(1, dr.sink().nrange());
				assert_eq(sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[0].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(1, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

	delete gfms.first;
	delete gfms.second;
	
	//  Ref CATGTCAGCT-ATATAGCGCGCTCGCATCATTTTGTGTGTAAAC
	//      |||||||||| |||||||||||| |||||| |||||||||||||
	//  Rd  CATGTCAGCTGATATAGCGCGCT-GCATCAATTTGTGTGTAAAC
	strs.clear();
    strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAAC"
                          "NNNNNNNNNN"
                          "CATGTCAGCTGATATAGCGCGCTCGCATCATTTTGTGTGTAAAC" // same but without first ref gap
                          "N"
                          "CATGTCAGCTATATAGCGCGCTGCATCATTTTGTGTGTAAAC" // same but without first read gap
                          "N"
                          "CATGTCAGCTATATAGCGCGCTCGCATCAATTTGTGTGTAAAC" // same but without first mismatch
                          "N"
                          "CATGTCAGCTGATATAGCGCGCTGCATCAATTTGTGTGTAAAC" // Exact match for read
						  ));
	gfms = GFM::fromStrings<SString<char> >(
		strs,
		packed,
		REF_READ_REVERSE,
		GFM::default_bigEndian,
		GFM::default_lineRate,
		GFM::default_offRate,
		GFM::default_ftabChars,
		".aligner_seed2.cpp.tmp",
		GFM::default_useBlockwise,
		GFM::default_bmax,
		GFM::default_bmaxMultSqrt,
		GFM::default_bmaxDivN,
		GFM::default_dcv,
		GFM::default_seed,
		false,  // verbose
		false,  // autoMem
		false); // sanity
    
    gfms.first->loadIntoMemory (color, -1, true, true, true, true, false);
    gfms.second->loadIntoMemory(color,  1, true, true, true, true, false);

	// Query is longer than ftab and matches exactly once with one read gap,
	// one ref gap, and one mismatch
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//           Ref: CATGTCAGCT   ATATAGCGCGCT  CGCATCATTTTGTGTGTAAACCA
			//                ||||||||||   ||||||||||||   |||||| |||||||||||||
			BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGTGTAAAC", true);
			//                0123456789  0123456789012   34567890123456789012
			BTString    qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF");
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				size_t end = j + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 10 && end >= 10) {
					continue;
				}
				if(beg <= 22 && end >= 22) {
					continue;
				}
				if(beg <= 30 && end >= 30) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches once with a read gap of length 1" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(1, 0.5);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(5, dr.sink().nrange());
				assert_eq(0, dr.sink()[0].pen);
				assert_eq(min(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[1].pen);
				assert_eq(max(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[2].pen);
				assert_eq(sc.readGapOpen() + sc.refGapOpen(), dr.sink()[3].pen);
				assert_eq(sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[4].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(5, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

	// Query is longer than ftab and matches exactly once with one read gap,
	// one ref gap, one mismatch, and one N
	{
		size_t last_topf = std::numeric_limits<size_t>::max();
		size_t last_botf = std::numeric_limits<size_t>::max();
		for(int i = 0; i < 2; i++) {
			// Set up the read
			//           Ref: CATGTCAGCT   ATATAGCGCGCT  CGCATCATTTTGTGTGTAAACCA
			//                ||||||||||   ||||||||||||   |||||| |||||| ||||||
			BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGNGTAAAC", true);
			//                0123456789  0123456789012   34567890123456789012
			BTString    qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF");
			for(size_t j = 0; j < seq.length(); j++) {
				// Assume left-to-right
				size_t beg = j;
				size_t end = j + GFM::default_ftabChars;
				// Mismatch penalty is 3, so we have to skip starting
				// points that are within 2 from the mismatch
				if((i > 0 && j > 0) || j == seq.length()-1) {
					// Right-to-left
					if(beg < GFM::default_ftabChars) {
						beg = 0;
					} else {
						beg -= GFM::default_ftabChars;
					}
					end -= GFM::default_ftabChars;
				}
				if(beg <= 10 && end >= 10) {
					continue;
				}
				if(beg <= 22 && end >= 22) {
					continue;
				}
				if(beg <= 30 && end >= 30) {
					continue;
				}
				if(beg <= 36 && end >= 36) {
					continue;
				}
				cerr << "Test " << (++testnum) << endl;
				cerr << "  Query matches with various patterns of gaps, mismatches and Ns" << endl;
				DescentMetrics mets;
				PerReadMetrics prm;
				DescentDriver dr;
				
				dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50);
				
				// Set up the DescentConfig
				DescentConfig conf;
				// Changed 
				conf.cons.init(1, 0.5);
				conf.expol = DESC_EX_NONE;
				
				// Set up the search roots
				dr.addRoot(
					conf,   // DescentConfig
					j,      // 5' offset into read of root
					i == 0, // left-to-right?
					true,   // forward?
					0.0f);  // root priority
				
				// Do the search
				Scoring sc = Scoring::base1();
				sc.setNPen(COST_MODEL_CONSTANT, 1);
				dr.go(sc, *gfms.first, *gfms.second, mets, prm);
				
				// Confirm that an exact-matching alignment was found
				assert_eq(5, dr.sink().nrange());
				assert_eq(sc.n(40), dr.sink()[0].pen);
				assert_eq(sc.n(40) + min(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[1].pen);
				assert_eq(sc.n(40) + max(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[2].pen);
				assert_eq(sc.n(40) + sc.readGapOpen() + sc.refGapOpen(), dr.sink()[3].pen);
				assert_eq(sc.n(40) + sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[4].pen);
				assert(last_topf == std::numeric_limits<size_t>::max() || last_topf == dr.sink()[0].topf);
				assert(last_botf == std::numeric_limits<size_t>::max() || last_botf == dr.sink()[0].botf);
				cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl;
				assert_eq(5, dr.sink().nelt());
				last_topf = dr.sink()[0].topf;
				last_botf = dr.sink()[0].botf;
			}
		}
    }

    delete gfms.first;
    delete gfms.second;
	
	cerr << "DONE" << endl;
}
Ejemplo n.º 5
0
static int testDrawEval() {
    // verify detection of KBP and other draw situations
    const int DRAW_CASES = 11;
    static const string draw_fens[DRAW_CASES] = {
        "k7/8/P7/B7/1K6/8/8/8 w - - 0 1", // KBP draw
        "8/8/8/1k6/b7/p7/8/K7 b - - 0 1", // KBP draw
        "8/8/8/8/7b/4k2p/8/6K1 b - - 0 1", // KBP draw
        "8/7k/4B3/8/6KP/8/8/8 b - - 0 3", // KBP draw
        "8/8/2KN3k/8/3N4/8/8/8 w - - 0 1", // KNN draw
        "8/8/2KN3k/8/3N4/8/8/8 w - - 0 1", // KNN draw
        "8/8/8/3n4/8/2kn3K/8/8 b - - 0 1", // KNN draw
        "8/8/2K4k/8/3N4/8/8/8 w - - 0 1", // KN draw
        "8/8/8/3n4/8/2k4K/8/8 b - - 0 1", // KN draw
        "8/8/8/8/8/2k4K/8/8 b - - 0 1", // KK draw
        "8/8/8/2B1b3/8/2k4K/8/8 b - - 0 1" // KB vs KB draw (same color)
        // technically these are draws but not recognized yet:
        //"8/8/8/1k6/b7/p7/8/2K5 b - - 0 1", // KBP draw
        // 8/5k2/8/5B2/8/6KP/8/8 w - - 0 1 // KBP draw
    };

    const int NON_DRAW_CASES = 3;
    static const string nondraw_fens[NON_DRAW_CASES] = {
        "8/7k/8/6B1/6KP/8/8/8 w - - 0 3", // KBP right-color pawn
        "8/3k3B/8/8/5K2/7P/8/8 b - - 0 1", // KBP opp king too far
        "6K1/8/6b1/6k1/8/6B1/8/8 w - - 0 1" // opp color bishops
    };
    int errs = 0;
#if defined(NALIMOV_TBS) || defined(GAVIOTA_TBS)
    int tmp = options.search.use_tablebases;
    options.search.use_tablebases = 0;
#endif
    for (int i = 0; i < DRAW_CASES; i++) {
        Board board;
        if (!BoardIO::readFEN(board, draw_fens[i].c_str())) {
            cerr << "testDrawEval draw case " << i << " error in FEN: " << draw_fens[i] << endl;
            ++errs;
            continue;
        }
        Scoring *s = new Scoring();
        if (!s->isDraw(board)) {
            cerr << "testDrawEval: error in draw case " << i << " fen=" << draw_fens[i] << endl;
            ++errs;
        }
	delete s;
    }
    for (int i = 0; i < NON_DRAW_CASES; i++) {
        Board board;
        if (!BoardIO::readFEN(board, nondraw_fens[i].c_str())) {
            cerr << "testDrawEval non-draw case " << i << " error in FEN: " << nondraw_fens[i] << endl;
            ++errs;
            continue;
        }
        Scoring *s = new Scoring();
        if (s->isDraw(board)) {
            cerr << "testDrawEval: error in non-draw case " << i << " fen=" << nondraw_fens[i] << endl;
            ++errs;
        }
	delete s;
    }
#if defined(NALIMOV_TBS) || defined(GAVIOTA_TBS)
    options.search.use_tablebases = tmp;
#endif
    return errs;
}
Ejemplo n.º 6
0
        static float computeScore(
                bool const inverted,
                AutoTextArray<sse4> const & ATA,
                pattern_type const & pattern,
                Scoring const & scoring,
                unsigned int const pos,
                unsigned int const patl
                )
        {
                if ( inverted )
                {
                        double rawscore = 1.0f;
                        char const * mapped = inverted ? pattern.transposed : pattern.mapped;
                        unsigned int j = patl;

                        unsigned int wordpos = pos/32;
                        u_int64_t const firstword = ATA.getTextWord( wordpos );
                        u_int64_t const mask = 0x3ull;
                        unsigned int const firstrest = 32-(pos % 32);
                        unsigned int firstloopstop = std::min(firstrest,patl);

                        unsigned int shift = 2*(firstrest-1);
                        unsigned int i = 0;
                        unsigned int rest = patl;
                        
                        for ( ; i < firstloopstop; ++i, shift-=2 )
                        {
                                unsigned int const refbase = ((firstword>>shift)&mask);
                                unsigned int const patbase = mapped[i];
                                unsigned int const quality = pattern.getQuality(--j);
                                double const localrawscore = scoring.getRawLogScoreTable(refbase,patbase,quality);
                                rawscore += localrawscore;
                                // assert ( ((firstword>>shift)&mask) == ATA[pos+i] );
                        }

                        rest -= firstloopstop;
                        
                        while ( rest >= 32 )
                        {
                                shift = 62;
                                unsigned int const loopstop = i+32;
                                u_int64_t const word = ATA.getTextWord(++wordpos);
                                
                                for ( ; i < loopstop; ++i, shift -= 2 )
                                {
                                        unsigned int const refbase = ((word>>shift)&mask);
                                        unsigned int const patbase = mapped[i];
                                        unsigned int const quality = pattern.getQuality(--j);
                                        double const localrawscore = scoring.getRawLogScoreTable(refbase,patbase,quality);
                                        rawscore += localrawscore;
                                        // assert ( ((word>>shift)&mask) == ATA[pos+i] );
                                }
                                
                                rest -= 32;
                        }
                        
                        if ( rest )
                        {
				shift = 62;
				unsigned int const loopstop = i+rest;
				u_int64_t const word = ATA.getTextWord(++wordpos);
					
				for ( ; i < loopstop; ++i, shift -= 2 )
				{
					unsigned int const refbase = ((word>>shift)&mask);
					unsigned int const patbase = mapped[i];
					unsigned int const quality = pattern.getQuality(--j);
					double const localrawscore = scoring.getRawLogScoreTable(refbase,patbase,quality);
					rawscore += localrawscore;
					// assert ( ((word>>shift)&mask) == ATA[pos+i] );
				}
                        }                        

                        return rawscore;
                }
                else
                {