예제 #1
0
TEST(RangeTest, SetRanges) {
    Ranges rs;
    rs.setRanges("199");

    EXPECT_TRUE(rs.contains(199));
    EXPECT_EQ(rs.size(), 1);
}
예제 #2
0
int
main(int /*argc*/, char** /*argv*/)
{
	typedef gnash::geometry::SnappingRanges2d<int> Ranges;
	typedef gnash::geometry::Range2d<int> Bounds;

	string filename = string(TGTDIR) + string("/") + string(INPUT_FILENAME);
	MovieTester tester(filename);

	gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
	dbglogfile.setVerbosity(1);

	// Colors we'll use during the test
	rgba red(255,0,0,255);
	rgba white(255,255,255,255);
	rgba black(0,0,0,255);

	// Ranges we'll use during the test
	Range2d<int> redRange(300,300,360,360);
	Range2d<int> blackRange(330,270,450,390);

	// Coordinates we'll use during testing
	int x_left = 270; // on the left of any DisplayObject
	int x_red = 310; // on the red square
	int x_int = 340; // on the intersection between the red and black squares
	int x_black = 370; // on black square
	int x_right = 460; // on the right of any DisplayObject
	int y = 330;

	Ranges invalidated;
	MovieClip* root = tester.getRootMovie();
	assert(root);

	// FRAME 1 (start)

	check_equals(root->get_frame_count(), 4);
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 0);
	check_equals(root->getDisplayList().size(), 1);  // dejagnu clip
	invalidated = tester.getInvalidatedRanges();
	check( invalidated.contains(76, 4) ); // the "-xtrace enabled-" label...

	tester.advance(); // FRAME 2, place DisplayObjects (black on top)
	invalidated = tester.getInvalidatedRanges();
	
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 1);
	check_equals(root->getDisplayList().size(), 3); // dejagnu + red square + black square

	// check invalidated bounds contain both the red and black square
	check( invalidated.contains(redRange) );
	check( invalidated.contains(blackRange) );
	
	// Check that the black square is over the red square
	check_pixel(x_left, y, 2, white, 2); 
	check_pixel(x_red, y, 2, red, 2); 
	check_pixel(x_int, y, 2, black, 2);  // black is *over* red square
	check_pixel(x_black, y, 2, black, 2);  
	check_pixel(x_right, y, 2, white, 2);  

	tester.advance(); // FRAME 3, depth-swap the two DisplayObjects
	invalidated = tester.getInvalidatedRanges();
	
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 2);
	check_equals(root->getDisplayList().size(), 3); // dejagnu + red square + black square

	// check invalidated bounds to contain the intersection
	// between the two DisplayObjects.
	//
	check( invalidated.contains(Intersection(redRange,blackRange)) );
	
	// Check that the black square is now behind the red square
	check_pixel(x_left, y, 2, white, 2); 
	check_pixel(x_red, y, 2, red, 2); 
	check_pixel(x_int, y, 2, red, 2);  // black is *behind* red square
	check_pixel(x_black, y, 2, black, 2);  
	check_pixel(x_right, y, 2, white, 2);  

	tester.advance(); // FRAME 4, jump to frame 2 and stop
	invalidated = tester.getInvalidatedRanges();

	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_STOP);
	check_equals(root->get_current_frame(), 1);
	check_equals(root->getDisplayList().size(), 3); // dejagnu + red square + black square

	// Invalidated bounds can't be Null because something is printed 
	// in the XTRACE window... Anyway, the squares should be far enoguh
	// to assume the invalidated bounds won't contain their intersection
	//
	// Gnash has an huge invalidated bounds for the whole movie lifetime, btw....
	// 
	xcheck( ! invalidated.intersects(Intersection(redRange,blackRange)) );

	// Check that the black square is still behind the red square
	check_pixel(x_left, y, 2, white, 2); 
	check_pixel(x_red, y, 2, red, 2); 
	check_pixel(x_int, y, 2, red, 2);  // black is *behind* red square
	check_pixel(x_black, y, 2, black, 2);  
	check_pixel(x_right, y, 2, white, 2);  
}
int
main(int /*argc*/, char** /*argv*/)
{
	typedef gnash::geometry::SnappingRanges2d<int> Ranges;
	typedef gnash::geometry::Range2d<int> Bounds;

	string filename = string(TGTDIR) + string("/") + string(INPUT_FILENAME);
	MovieTester tester(filename);

	gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
	dbglogfile.setVerbosity(1);

	// Colors we'll use during the test
	rgba red(255,0,0,255);
	rgba green(0,255,0,255);
	rgba white(255,255,255,255);

	// Ranges we'll use during the test
	Range2d<int> redRange(100,300,160,360);
	Range2d<int> greenRange(130,330,190,390);

	Ranges invalidated;
	MovieClip* root = tester.getRootMovie();
	assert(root);

	// FRAME 1 (start)

	check_equals(root->get_frame_count(), 4);
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 0);
	check_equals(root->getDisplayList().size(), 1);  // dejagnu clip
	invalidated = tester.getInvalidatedRanges();
	check( invalidated.contains(76, 4) ); // the "-xtrace enabled-" label...

	tester.advance(); // FRAME 2, place DisplayObject
	invalidated = tester.getInvalidatedRanges();
	
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 1);
	check_equals(root->getDisplayList().size(), 2); // dejagnu + red char

	// check invalidated bounds contain the red instance (100,300 - 160,360)
	check( invalidated.contains(redRange) );
	
	// check that we have a red square at (100,300 - 160,360)
	check_pixel(104, 304, 2, red, 2); // UL
	check_pixel(156, 304, 2, red, 2); // UR
	check_pixel(156, 356, 2, red, 2); // LL
	check_pixel(104, 356, 2, red, 2); // LR

	// and nothing around it...
	check_pixel( 96, 330, 2, white, 2); // Left
	check_pixel(164, 330, 2, white, 2); // Right
	check_pixel(130, 296, 2, white, 2); // Top
	check_pixel(130, 364, 2, white, 2); // Bottom

	tester.advance(); // FRAME 3, replace DisplayObject
	invalidated = tester.getInvalidatedRanges();
	
	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
	check_equals(root->get_current_frame(), 2);
	check_equals(root->getDisplayList().size(), 2); // dejagnu + green char 

	// check invalidated bounds to contain:
	// 	- the green square (added)
	// 	- the red square (removed)
	//
	check( invalidated.contains(redRange) );
	check( invalidated.contains(greenRange) );
	
	// check that we have a green square at (130,330 - 190,390)
	check_pixel(134, 334, 2, green, 2); // UL
	check_pixel(186, 334, 2, green, 2); // UR
	check_pixel(186, 386, 2, green, 2); // LL
	check_pixel(134, 386, 2, green, 2); // LR

	// and nothing around it...
	check_pixel(126, 360, 2, white, 2); // Left
	check_pixel(194, 360, 2, white, 2); // Right
	check_pixel(160, 326, 2, white, 2); // Top
	check_pixel(160, 394, 2, white, 2); // Bottom

	tester.advance(); // FRAME 4, jump to frame 2 and stop
	invalidated = tester.getInvalidatedRanges();

	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_STOP);
	check_equals(root->get_current_frame(), 1);
	check_equals(root->getDisplayList().size(), 2); // dejagnu + red char 

	// check invalidated bounds to contain:
	// 	- the green square (removed)
	// 	- the red square (added)
	//
	check( invalidated.contains(redRange) );
	check( invalidated.contains(greenRange) );

	// check that we have a red square at (100,300 - 160,360)
	check_pixel(104, 304, 2, red, 2); // UL
	check_pixel(156, 304, 2, red, 2); // UR
	check_pixel(156, 356, 2, red, 2); // LL
	check_pixel(104, 356, 2, red, 2); // LR

	// and nothing around it...
	check_pixel( 96, 330, 2, white, 2); // Left
	check_pixel(164, 330, 2, white, 2); // Right
	check_pixel(130, 296, 2, white, 2); // Top
	check_pixel(130, 364, 2, white, 2); // Bottom

}
예제 #4
0
int main(int argc, char* argv[]) {
#ifdef USE_GOOGLE_PROFILER
    char *profileFileName = getenv("CPUPROFILE");
    if (profileFileName != NULL) {
      ProfilerStart(profileFileName);
    }
    else {
      ProfilerStart("google_profile.txt");
    }
#endif

    // Register inputs and outputs.
    string samFileName, refFileName, outFileName;

    CommandLineParser clp;
    clp.RegisterStringOption("file.sam", &samFileName,
                             "Input SAM file.");
    clp.RegisterStringOption("reference.fasta", &refFileName,
                             "Reference used to generate reads.");
    clp.RegisterStringOption("out.sam", &outFileName,
                             "Output SAM file.");
    clp.RegisterPreviousFlagsAsHidden();

    // Register filter criteria options.
    int minAlnLength = 50;
    float minPctSimilarity = 70, minPctAccuracy = 70;
    string hitPolicyStr = "randombest";
    bool useScoreCutoff = false;
    int  scoreCutoff = INF_INT;
    int  scoreSignInt = -1;
    RegisterFilterOptions(clp, minAlnLength, minPctSimilarity, 
                          minPctAccuracy, hitPolicyStr, useScoreCutoff,
                          scoreSignInt, scoreCutoff);

    int seed = 1; 
    clp.RegisterIntOption("seed", &seed,
            "(1)  Seed for random number generator.\n"
            "If seed is 0, then use current time as seed.",
            CommandLineParser::Integer);

    string holeNumberStr;
    Ranges holeNumberRanges;
    clp.RegisterStringOption("holeNumbers", &holeNumberStr,
            "A string of comma-delimited hole number ranges to output hits, "
            "such as '1,2,10-12'. "
            "This requires hit titles to be in SMRT read title format.");

    bool parseSmrtTitle = false;
    clp.RegisterFlagOption("smrtTitle", &parseSmrtTitle,
            "Use this option when filtering alignments generated by "
            "programs other than blasr, e.g. bwa-sw or gmap. "
            "  Parse read coordinates from the SMRT read title. " 
            "The title is in the format /name/hole/coordinates, where"
            " coordinates are in the format \\d+_\\d+, and represent "
            "the interval of the read that was aligned.");
    /* This experimental option can be useful for metagenomics, in which case
     * there are hundreds of sequences in the target, of which many titles are
     * long and may contain white spaces (e.g., ' ', '\t'). 
     * In order to save disc space and avoid the (possibly) none unique mapping
     * between full and short reference names, one may call blasr with 
     * -titleTable option to represent all target sequences in the output
     * by their indices in the title table.*/

    string titleTableName = "";
    clp.RegisterStringOption("titleTable", &titleTableName,
            "Use this experimental option when filtering alignments generated by "
            "blasr with -titleTable titleTableName, in which case "
            "reference titles in SAM are represented by their "
            "indices (e.g., 0, 1, 2, ...) in the title table.");

    string adapterGffFileName = "";
    clp.RegisterStringOption("filterAdapterOnly", &adapterGffFileName,
            "Use this option to remove reads which can only map to adapters " 
            "specified in the GFF file.");

    bool verbose = false;
    clp.RegisterFlagOption("v", &verbose, "Be verbose.");

    clp.SetExamples(
            "Because SAM has optional tags that have different meanings"
            " in different programs, careful usage is required in order "
            "to have proper output.  The \"xs\" tag in bwa-sw is used to "
            "show the suboptimal score, but in PacBio SAM (blasr) it is "
            "defined as the start in the query sequence of the alignment.\n"
            "When \"-smrtTitle\" is specified, the xs tag is ignored, but "
            "when it is not specified, the coordinates given by the xs and "
            "xe tags are used to define the interval of a read that is "
            "aligned.  The CIGAR string is relative to this interval.");

    clp.ParseCommandLine(argc, argv);

    // Set random number seed. 
    if (seed == 0) {
        srand(time(NULL));
    } else {
        srand(seed);
    }
    
    scoreSign = (scoreSignInt == -1)?ScoreSign::NEGATIVE:ScoreSign::POSITIVE;
    Score s(static_cast<float>(scoreCutoff), scoreSign);
    FilterCriteria filterCriteria(minAlnLength, minPctSimilarity, 
                                  minPctAccuracy, true, s);
    filterCriteria.Verbose(verbose);
    HitPolicy hitPolicy(hitPolicyStr, scoreSign);
                                  
    string errMsg;
    if (not filterCriteria.MakeSane(errMsg)) {
        cout << errMsg << endl;
        exit(1);
    }

    // Parse hole number ranges. 
    if (holeNumberStr.size() != 0) {
        if (not holeNumberRanges.setRanges(holeNumberStr)) {
            cout << "Could not parse hole number ranges: "
                 << holeNumberStr << "." << endl;
            exit(1);
        } 
    }

    // Open output file.
    ostream * outFilePtr = &cout;
	ofstream outFileStrm;
	if (outFileName != "") {
		CrucialOpen(outFileName, outFileStrm, std::ios::out);
		outFilePtr = &outFileStrm;
	}
    
    GFFFile adapterGffFile;
    if (adapterGffFileName != "")
        adapterGffFile.ReadAll(adapterGffFileName);
    
    SAMReader<SAMFullReferenceSequence, SAMReadGroup, SAMAlignment> samReader;
    FASTAReader fastaReader;

    //
    // Initialize samReader and fastaReader.
    //
    samReader.Initialize(samFileName);
    fastaReader.Initialize(refFileName);

    //
    // Configure the file log.
    //
    string command;
    CommandLineParser::CommandLineToString(argc, argv, command);
    string log = "Filter sam hits.";
    string program = "samFilter";
    string versionString = VERSION;
    AppendPerforceChangelist(PERFORCE_VERSION_STRING, versionString);

    //
    // Read necessary input.
    //
    vector<FASTASequence> references;
    fastaReader.ReadAllSequences(references);

    // If the SAM file is generated by blasr with -titleTable,
    // then references in the SAM are represented by 
    // their corresponding indices in the title table.
    // In that case, we need to convert reference titles in fasta file
    // to their corresponding indices in the title table, such that
    // references in both SAM and fasta files are represented
    // by title table indices and therefore can match.
    if (titleTableName != "") {
        ConvertTitlesToTitleTableIndices(references, titleTableName);
    }
 
    AlignmentSet<SAMFullReferenceSequence, SAMReadGroup, SAMAlignment> alignmentSet;
    vector<string> allHeaders = samReader.ReadHeader(alignmentSet); 

    // Process SAM Header.
    string commandLineString;
    clp.CommandLineToString(argc, argv, commandLineString);
    allHeaders.push_back("@PG\tID:SAMFILTER\tVN:" + versionString + \
                         "\tCL:" + program + " " + commandLineString);
    for (int i = 0; i < allHeaders.size(); i++) {
        outFileStrm << allHeaders[i] << endl;
    }

    //
    // The order of references in vector<FASTASequence> references and
    // AlignmentSet<, , >alignmentSet.references can be different.
    // Rearrange alignmentSet.references such that they are ordered in
    // exactly the same way as vector<FASTASequence> references.
    //
    alignmentSet.RearrangeReferences(references);

    // Map reference name obtained from SAM file to indices
    map<string, int> refNameToIndex;
    for (int i = 0; i < references.size(); i++) {
        string refName = alignmentSet.references[i].GetSequenceName();
        refNameToIndex[refName] = i;
    }

    //
    // Store the alignments.
    //
    SAMAlignment samAlignment;
    int alignIndex = 0; 

    //
    // For 150K, each chip produces about 300M sequences 
    // (not including quality values and etc.).
    // Let's assume that the sam file and reference data can 
    // fit in the memory. 
    // Need to scale for larger sequal data in the future.
    //
    vector<SAMAlignment> allSAMAlignments;
    while (samReader.GetNextAlignment(samAlignment)) {
        if (samAlignment.rName == "*") {
            continue;
        }

        if (parseSmrtTitle and holeNumberStr.size() != 0) {
            string movieName;
            int thisHoleNumber;
            if (not ParsePBIReadName(samAlignment.qName, 
                                     movieName, 
                                     thisHoleNumber)) {
                cout << "ERROR, could not parse SMRT title: "
                     << samAlignment.qName << "." << endl;
                exit(1);
            }
            if (not holeNumberRanges.contains(UInt(thisHoleNumber))) {
                if (verbose) 
                    cout << thisHoleNumber << " is not in range." << endl; 
                continue;
            }
        }

        if (samAlignment.cigar.find('P') != string::npos) {
            cout << "WARNING. Could not process SAM record with 'P' in "
                 << "its cigar string." << endl;
            continue;
        }

        vector<AlignmentCandidate<> > convertedAlignments;
        SAMAlignmentsToCandidates(samAlignment, 
                references, refNameToIndex,
                convertedAlignments, parseSmrtTitle, false);
        
        if (convertedAlignments.size() > 1) {
            cout << "WARNING. Ignore multiple segments." << endl;
            continue;
        }

        for (int i = 0; i < 1; i++) {
            AlignmentCandidate<> & alignment = convertedAlignments[i];

            //score func does not matter
            DistanceMatrixScoreFunction<DNASequence, DNASequence> distFunc; 
            ComputeAlignmentStats(alignment, alignment.qAlignedSeq.seq, 
                                  alignment.tAlignedSeq.seq, distFunc);
                                  
            // Check whether this alignment can only map to adapters in 
            // the adapter GFF file.
            if (adapterGffFileName != "" and 
                CheckAdapterOnly(adapterGffFile, alignment, refNameToIndex)) {
                if (verbose)
                    cout << alignment.qName << " filter adapter only."
                         << endl;
                continue;
            }

            // Assign score to samAlignment.
            samAlignment.score = samAlignment.as;

            if (not filterCriteria.Satisfy(static_cast<AlignmentCandidate<> *>(&alignment))) {
                continue;
            }
            allSAMAlignments.push_back( samAlignment ); 

            alignment.FreeSubsequences();
        }
        ++alignIndex;
    }

    // Sort all SAM alignments by qName, score and target position.
    sort(allSAMAlignments.begin(), allSAMAlignments.end(), 
         byQNameScoreTStart);

    unsigned int groupBegin = 0;
    unsigned int groupEnd = -1;
    vector<SAMAlignment> filteredSAMAlignments;
    while(groupBegin < allSAMAlignments.size()) {
        // Get the next group of SAM alignments which have the same qName
        // from allSAMAlignments[groupBegin ... groupEnd)
        GetNextSAMAlignmentGroup(allSAMAlignments, groupBegin, groupEnd);
        vector<unsigned int> hitIndices = ApplyHitPolicy(
                hitPolicy, allSAMAlignments, groupBegin, groupEnd);
        for(unsigned int i = 0; i < hitIndices.size(); i++) {
            filteredSAMAlignments.push_back(allSAMAlignments[hitIndices[i]]);
        }
        groupBegin = groupEnd;
    }

    // Sort all SAM alignments by reference name and query name
    sort(filteredSAMAlignments.begin(), filteredSAMAlignments.end(), 
         byRNameQName);

    for(unsigned int i = 0; i < filteredSAMAlignments.size(); i++) {
        filteredSAMAlignments[i].PrintSAMAlignment(outFileStrm);
    }

	if (outFileName != "") {
		outFileStrm.close();
	}
#ifdef USE_GOOGLE_PROFILER
  ProfilerStop();
#endif
    return 0;
}