//Copyright 2015 Ryan Wick
//This file is part of Bandage.
//Bandage is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//Bandage is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//You should have received a copy of the GNU General Public License
//along with Bandage. If not, see .
#include
#include
#include "ogdf/basic/Graph.h"
#include "ogdf/basic/GraphAttributes.h"
#include "../graph/assemblygraph.h"
#include "../program/settings.h"
#include "../blast/blastsearch.h"
#include "../ui/mygraphicsview.h"
#include "../program/memory.h"
#include "../graph/debruijnnode.h"
#include "../graph/debruijnedge.h"
#include "../program/globals.h"
#include "../command_line/commoncommandlinefunctions.h"
class BandageTests : public QObject
{
Q_OBJECT
private slots:
void loadFastg();
void loadLastGraph();
void loadTrinity();
void pathFunctionsOnLastGraph();
void pathFunctionsOnFastg();
void pathFunctionsOnGfaSequencesInGraph();
void pathFunctionsOnGfaSequencesInFasta();
void graphLocationFunctions();
void loadCsvData();
void loadCsvDataTrinity();
void blastSearch();
void blastSearchFilters();
void graphScope();
void commandLineSettings();
void sciNotComparisons();
void graphEdits();
void velvetToGfa();
void spadesToGfa();
void mergeNodesOnGfa();
void changeNodeNames();
void changeNodeDepths();
void blastQueryPaths();
void bandageInfo();
private:
void createGlobals();
bool createBlastTempDirectory();
void deleteBlastTempDirectory();
QString getTestDirectory();
DeBruijnEdge * getEdgeFromNodeNames(QString startingNodeName,
QString endingNodeName);
bool doCircularSequencesMatch(QByteArray s1, QByteArray s2);
};
void BandageTests::loadFastg()
{
createGlobals();
bool fastgGraphLoaded = g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
//Check that the graph loaded properly.
QCOMPARE(fastgGraphLoaded, true);
//Check that the appropriate number of nodes/edges are present.
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 88);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphEdges.size(), 118);
//Check the length of a couple nodes.
DeBruijnNode * node1 = g_assemblyGraph->m_deBruijnGraphNodes["1+"];
DeBruijnNode * node28 = g_assemblyGraph->m_deBruijnGraphNodes["28-"];
QCOMPARE(node1->getLength(), 6070);
QCOMPARE(node28->getLength(), 79);
}
void BandageTests::loadLastGraph()
{
createGlobals();
bool lastGraphLoaded = g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.LastGraph");
//Check that the graph loaded properly.
QCOMPARE(lastGraphLoaded, true);
//Check that the appropriate number of nodes/edges are present.
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 34);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphEdges.size(), 32);
//Check the length of a couple nodes.
DeBruijnNode * node1 = g_assemblyGraph->m_deBruijnGraphNodes["1+"];
DeBruijnNode * node14 = g_assemblyGraph->m_deBruijnGraphNodes["14-"];
QCOMPARE(node1->getLength(), 2000);
QCOMPARE(node14->getLength(), 60);
}
void BandageTests::loadTrinity()
{
createGlobals();
bool trinityLoaded = g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.Trinity.fasta");
//Check that the graph loaded properly.
QCOMPARE(trinityLoaded, true);
//Check that the appropriate number of nodes/edges are present.
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 1170);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphEdges.size(), 1056);
//Check the length of a couple nodes.
DeBruijnNode * node10241 = g_assemblyGraph->m_deBruijnGraphNodes["4|c4_10241+"];
DeBruijnNode * node3901 = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3901-"];
QCOMPARE(node10241->getLength(), 1186);
QCOMPARE(node3901->getLength(), 1);
}
//LastGraph files have no overlap in the edges, so these tests look at paths
//where the connections are simple.
void BandageTests::pathFunctionsOnLastGraph()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.LastGraph");
QString pathStringFailure;
Path testPath1 = Path::makeFromString("(1996) 9+, 13+ (5)", false, &pathStringFailure);
Path testPath2 = Path::makeFromString("(1996) 9+, 13+ (5)", false, &pathStringFailure);
Path testPath3 = Path::makeFromString("(1996) 9+, 13+ (6)", false, &pathStringFailure);
Path testPath4 = Path::makeFromString("9+, 13+, 14-", false, &pathStringFailure);
DeBruijnNode * node4Minus = g_assemblyGraph->m_deBruijnGraphNodes["4-"];
DeBruijnNode * node9Plus = g_assemblyGraph->m_deBruijnGraphNodes["9+"];
DeBruijnNode * node13Plus = g_assemblyGraph->m_deBruijnGraphNodes["13+"];
DeBruijnNode * node14Minus = g_assemblyGraph->m_deBruijnGraphNodes["14+"];
DeBruijnNode * node7Plus = g_assemblyGraph->m_deBruijnGraphNodes["7+"];
QCOMPARE(testPath1.getLength(), 10);
QCOMPARE(testPath1.getPathSequence(), QByteArray("GACCTATAGA"));
QCOMPARE(testPath1.isEmpty(), false);
QCOMPARE(testPath1.isCircular(), false);
QCOMPARE(testPath1 == testPath2, true);
QCOMPARE(testPath1 == testPath3, false);
QCOMPARE(testPath1.haveSameNodes(testPath3), true);
QCOMPARE(testPath1.hasNodeSubset(testPath4), true);
QCOMPARE(testPath4.hasNodeSubset(testPath1), false);
QCOMPARE(testPath1.getString(true), QString("(1996) 9+, 13+ (5)"));
QCOMPARE(testPath1.getString(false), QString("(1996)9+,13+(5)"));
QCOMPARE(testPath4.getString(true), QString("9+, 13+, 14-"));
QCOMPARE(testPath4.getString(false), QString("9+,13+,14-"));
QCOMPARE(testPath1.containsEntireNode(node13Plus), false);
QCOMPARE(testPath4.containsEntireNode(node13Plus), true);
QCOMPARE(testPath4.isInMiddleOfPath(node13Plus), true);
QCOMPARE(testPath4.isInMiddleOfPath(node14Minus), false);
QCOMPARE(testPath4.isInMiddleOfPath(node9Plus), false);
Path testPath4Extended;
QCOMPARE(testPath4.canNodeFitOnEnd(node7Plus, &testPath4Extended), true);
QCOMPARE(testPath4Extended.getString(true), QString("9+, 13+, 14-, 7+"));
QCOMPARE(testPath4.canNodeFitAtStart(node4Minus, &testPath4Extended), true);
QCOMPARE(testPath4Extended.getString(true), QString("4-, 9+, 13+, 14-"));
}
//FASTG files have overlaps in the edges, so these tests look at paths where
//the overlap has to be removed from the path sequence.
void BandageTests::pathFunctionsOnFastg()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
QString pathStringFailure;
Path testPath1 = Path::makeFromString("(50234) 6+, 26+, 23+, 26+, 24+ (200)", false, &pathStringFailure);
Path testPath2 = Path::makeFromString("26+, 23+", true, &pathStringFailure);
QCOMPARE(testPath1.getLength(), 1764);
QCOMPARE(testPath2.getLength(), 1387);
QCOMPARE(testPath1.isCircular(), false);
QCOMPARE(testPath2.isCircular(), true);
}
//This function tests paths on a GFA file which keeps its sequences in the GFA
//file.
void BandageTests::pathFunctionsOnGfaSequencesInGraph()
{
createGlobals();
bool gfaLoaded = g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test_plasmids.gfa");
QCOMPARE(gfaLoaded, true);
//Check that the number of nodes/edges.
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 18);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphEdges.size(), 24);
//Check a couple short paths.
QString pathStringFailure;
Path testPath1 = Path::makeFromString("232+, 277+", false, &pathStringFailure);
QByteArray testPath1Sequence = "CCTTATACGAAGCCCAGGTTAATCCTGGGCTTTTTGTTGAATCTGATCATTGGTAGCAAACAGATCAGGATTGGTAATTTTGATGTTTTCCTGACAACTCCTGCAAAGCATCAGCCCAGCAAAAAGTTGTACATGTTCCGTTGATTCACAGAAGGCACATGGCTTAGGAAAAGAGATGATATTGGCTGAATTGACTAATTCTGTTGACATAAGAAGTAACCTTGGATTGTACATATTTATTTTTAATAAATTTCAATACTTTATACCTAATTTAGCCACTAAAATTTGTACATTATTGTATAATCCATGTGTACATATTATTTTTTATAATTTTCATTCACTTAGACCCAAAATAGTATTTATTTTTGTACAACACCATGTACAGAACAATAATCATATAAATCAAATTTTTAGCATAAAAAAGTCCATTAATTTTGTACACAATTCTGAAACTTAAAAATCTAAACTTTCATCAATTTTTTTCATAATTTCAATAAATTAACCTTAATTTTAAGATATATTCTGAAATTTGGTTTGAAAGCTGTTTTTACATTATATTTCAATACTTTAAATCAAAAAATTGGATATTTTTTGAAAAACTCAATGAAAGTTTATTTTTTATTTAAAAACAACTAGTTATATTAGTTTTTATCCATTTTTTTGAAACAGTTTCTATATGATAAAAAAACCTATAAAAACCATATCTAGCAAAGGTTTGAGGGTTATCATCTTTAGATGCGTGGTGTGTGACAAAAAAATCCCGGCATGTGCCGGATTCTGGATTAGAAAATTGGCTAAAGTGACGTAGGACTGGTGCTTGGTTTTACATGGAAAAAAGTATTTATTTTCTGGTTTATAAAAACGTAAAAAGATCAGTTTTTGTTCATTCATCCAGGTTAAAAATTTCAACCTAAAACTTTAATTATGAAAAGCTTCACAGAAAGCATTCAAATGCGATTTAAGAGCCTTTATCTAAAAAACATAGATCTTATAGCGAAAAACAGAAAACAGCTCAAAAAACGCAAAAGAGAGTGAAGTAAAGAGATGTTTTGACTTTAGATAGCTGCATAGAGCGAGTGTCTACGAGCGAACTATCAAAATTTGCGTCTAGACTCTCTGAAAAACATTTTTTTGCCCTCTTTAGCCTAAGAAAGCTTAATTTTCATGCAGAAATTTGCTCCTGGACCGAGCGTAGCGAGAAAAAAAGCTCATGAGCGAAGCGAATTCCGAGTTGCTTTTGCTTTTTCTTAAAGTCACGCAAGTATTAACCAAAAAATTGCCCCGACGAACTGAGCGAAAGCGAAGTTCAATAGAGTTTGAGCGAAGCGAAAACCAAGGGC";
Path testPath2 = Path::makeFromString("277-, 232-", false, &pathStringFailure);
QByteArray testPath2Sequence = "GCCCTTGGTTTTCGCTTCGCTCAAACTCTATTGAACTTCGCTTTCGCTCAGTTCGTCGGGGCAATTTTTTGGTTAATACTTGCGTGACTTTAAGAAAAAGCAAAAGCAACTCGGAATTCGCTTCGCTCATGAGCTTTTTTTCTCGCTACGCTCGGTCCAGGAGCAAATTTCTGCATGAAAATTAAGCTTTCTTAGGCTAAAGAGGGCAAAAAAATGTTTTTCAGAGAGTCTAGACGCAAATTTTGATAGTTCGCTCGTAGACACTCGCTCTATGCAGCTATCTAAAGTCAAAACATCTCTTTACTTCACTCTCTTTTGCGTTTTTTGAGCTGTTTTCTGTTTTTCGCTATAAGATCTATGTTTTTTAGATAAAGGCTCTTAAATCGCATTTGAATGCTTTCTGTGAAGCTTTTCATAATTAAAGTTTTAGGTTGAAATTTTTAACCTGGATGAATGAACAAAAACTGATCTTTTTACGTTTTTATAAACCAGAAAATAAATACTTTTTTCCATGTAAAACCAAGCACCAGTCCTACGTCACTTTAGCCAATTTTCTAATCCAGAATCCGGCACATGCCGGGATTTTTTTGTCACACACCACGCATCTAAAGATGATAACCCTCAAACCTTTGCTAGATATGGTTTTTATAGGTTTTTTTATCATATAGAAACTGTTTCAAAAAAATGGATAAAAACTAATATAACTAGTTGTTTTTAAATAAAAAATAAACTTTCATTGAGTTTTTCAAAAAATATCCAATTTTTTGATTTAAAGTATTGAAATATAATGTAAAAACAGCTTTCAAACCAAATTTCAGAATATATCTTAAAATTAAGGTTAATTTATTGAAATTATGAAAAAAATTGATGAAAGTTTAGATTTTTAAGTTTCAGAATTGTGTACAAAATTAATGGACTTTTTTATGCTAAAAATTTGATTTATATGATTATTGTTCTGTACATGGTGTTGTACAAAAATAAATACTATTTTGGGTCTAAGTGAATGAAAATTATAAAAAATAATATGTACACATGGATTATACAATAATGTACAAATTTTAGTGGCTAAATTAGGTATAAAGTATTGAAATTTATTAAAAATAAATATGTACAATCCAAGGTTACTTCTTATGTCAACAGAATTAGTCAATTCAGCCAATATCATCTCTTTTCCTAAGCCATGTGCCTTCTGTGAATCAACGGAACATGTACAACTTTTTGCTGGGCTGATGCTTTGCAGGAGTTGTCAGGAAAACATCAAAATTACCAATCCTGATCTGTTTGCTACCAATGATCAGATTCAACAAAAAGCCCAGGATTAACCTGGGCTTCGTATAAGG";
QCOMPARE(testPath1.getPathSequence(), testPath1Sequence);
QCOMPARE(testPath2.getPathSequence(), testPath2Sequence);
}
//This function tests paths on a GFA file which keeps its sequences in a
//separate FASTA file.
void BandageTests::pathFunctionsOnGfaSequencesInFasta()
{
createGlobals();
bool gfaLoaded = g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test_plasmids_separate_sequences.gfa");
QCOMPARE(gfaLoaded, true);
//Check that the number of nodes/edges.
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 18);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphEdges.size(), 24);
//Since a node sequence hasn't be required yet, the nodes should still have
//just '*' for their sequence. But they should still report the correct
//length.
DeBruijnNode * node282Plus = g_assemblyGraph->m_deBruijnGraphNodes["282+"];
DeBruijnNode * node282Minus = g_assemblyGraph->m_deBruijnGraphNodes["282-"];
QCOMPARE(node282Plus->sequenceIsMissing(), true);
QCOMPARE(node282Minus->sequenceIsMissing(), true);
QCOMPARE(node282Plus->getLength(), 1819);
QCOMPARE(node282Minus->getLength(), 1819);
//Check a couple short paths.
QString pathStringFailure;
Path testPath1 = Path::makeFromString("232+, 277+", false, &pathStringFailure);
QByteArray testPath1Sequence = "CCTTATACGAAGCCCAGGTTAATCCTGGGCTTTTTGTTGAATCTGATCATTGGTAGCAAACAGATCAGGATTGGTAATTTTGATGTTTTCCTGACAACTCCTGCAAAGCATCAGCCCAGCAAAAAGTTGTACATGTTCCGTTGATTCACAGAAGGCACATGGCTTAGGAAAAGAGATGATATTGGCTGAATTGACTAATTCTGTTGACATAAGAAGTAACCTTGGATTGTACATATTTATTTTTAATAAATTTCAATACTTTATACCTAATTTAGCCACTAAAATTTGTACATTATTGTATAATCCATGTGTACATATTATTTTTTATAATTTTCATTCACTTAGACCCAAAATAGTATTTATTTTTGTACAACACCATGTACAGAACAATAATCATATAAATCAAATTTTTAGCATAAAAAAGTCCATTAATTTTGTACACAATTCTGAAACTTAAAAATCTAAACTTTCATCAATTTTTTTCATAATTTCAATAAATTAACCTTAATTTTAAGATATATTCTGAAATTTGGTTTGAAAGCTGTTTTTACATTATATTTCAATACTTTAAATCAAAAAATTGGATATTTTTTGAAAAACTCAATGAAAGTTTATTTTTTATTTAAAAACAACTAGTTATATTAGTTTTTATCCATTTTTTTGAAACAGTTTCTATATGATAAAAAAACCTATAAAAACCATATCTAGCAAAGGTTTGAGGGTTATCATCTTTAGATGCGTGGTGTGTGACAAAAAAATCCCGGCATGTGCCGGATTCTGGATTAGAAAATTGGCTAAAGTGACGTAGGACTGGTGCTTGGTTTTACATGGAAAAAAGTATTTATTTTCTGGTTTATAAAAACGTAAAAAGATCAGTTTTTGTTCATTCATCCAGGTTAAAAATTTCAACCTAAAACTTTAATTATGAAAAGCTTCACAGAAAGCATTCAAATGCGATTTAAGAGCCTTTATCTAAAAAACATAGATCTTATAGCGAAAAACAGAAAACAGCTCAAAAAACGCAAAAGAGAGTGAAGTAAAGAGATGTTTTGACTTTAGATAGCTGCATAGAGCGAGTGTCTACGAGCGAACTATCAAAATTTGCGTCTAGACTCTCTGAAAAACATTTTTTTGCCCTCTTTAGCCTAAGAAAGCTTAATTTTCATGCAGAAATTTGCTCCTGGACCGAGCGTAGCGAGAAAAAAAGCTCATGAGCGAAGCGAATTCCGAGTTGCTTTTGCTTTTTCTTAAAGTCACGCAAGTATTAACCAAAAAATTGCCCCGACGAACTGAGCGAAAGCGAAGTTCAATAGAGTTTGAGCGAAGCGAAAACCAAGGGC";
Path testPath2 = Path::makeFromString("277-, 232-", false, &pathStringFailure);
QByteArray testPath2Sequence = "GCCCTTGGTTTTCGCTTCGCTCAAACTCTATTGAACTTCGCTTTCGCTCAGTTCGTCGGGGCAATTTTTTGGTTAATACTTGCGTGACTTTAAGAAAAAGCAAAAGCAACTCGGAATTCGCTTCGCTCATGAGCTTTTTTTCTCGCTACGCTCGGTCCAGGAGCAAATTTCTGCATGAAAATTAAGCTTTCTTAGGCTAAAGAGGGCAAAAAAATGTTTTTCAGAGAGTCTAGACGCAAATTTTGATAGTTCGCTCGTAGACACTCGCTCTATGCAGCTATCTAAAGTCAAAACATCTCTTTACTTCACTCTCTTTTGCGTTTTTTGAGCTGTTTTCTGTTTTTCGCTATAAGATCTATGTTTTTTAGATAAAGGCTCTTAAATCGCATTTGAATGCTTTCTGTGAAGCTTTTCATAATTAAAGTTTTAGGTTGAAATTTTTAACCTGGATGAATGAACAAAAACTGATCTTTTTACGTTTTTATAAACCAGAAAATAAATACTTTTTTCCATGTAAAACCAAGCACCAGTCCTACGTCACTTTAGCCAATTTTCTAATCCAGAATCCGGCACATGCCGGGATTTTTTTGTCACACACCACGCATCTAAAGATGATAACCCTCAAACCTTTGCTAGATATGGTTTTTATAGGTTTTTTTATCATATAGAAACTGTTTCAAAAAAATGGATAAAAACTAATATAACTAGTTGTTTTTAAATAAAAAATAAACTTTCATTGAGTTTTTCAAAAAATATCCAATTTTTTGATTTAAAGTATTGAAATATAATGTAAAAACAGCTTTCAAACCAAATTTCAGAATATATCTTAAAATTAAGGTTAATTTATTGAAATTATGAAAAAAATTGATGAAAGTTTAGATTTTTAAGTTTCAGAATTGTGTACAAAATTAATGGACTTTTTTATGCTAAAAATTTGATTTATATGATTATTGTTCTGTACATGGTGTTGTACAAAAATAAATACTATTTTGGGTCTAAGTGAATGAAAATTATAAAAAATAATATGTACACATGGATTATACAATAATGTACAAATTTTAGTGGCTAAATTAGGTATAAAGTATTGAAATTTATTAAAAATAAATATGTACAATCCAAGGTTACTTCTTATGTCAACAGAATTAGTCAATTCAGCCAATATCATCTCTTTTCCTAAGCCATGTGCCTTCTGTGAATCAACGGAACATGTACAACTTTTTGCTGGGCTGATGCTTTGCAGGAGTTGTCAGGAAAACATCAAAATTACCAATCCTGATCTGTTTGCTACCAATGATCAGATTCAACAAAAAGCCCAGGATTAACCTGGGCTTCGTATAAGG";
//Check the paths sequences. Doing so will trigger the loading of node
//sequences from the FASTA file.
QCOMPARE(testPath1.getPathSequence(), testPath1Sequence);
QCOMPARE(testPath2.getPathSequence(), testPath2Sequence);
//Now that the paths have been accessed, the node sequences should be
//loaded (even the ones not in the path).
QCOMPARE(node282Plus->sequenceIsMissing(), false);
QCOMPARE(node282Minus->sequenceIsMissing(), false);
QCOMPARE(node282Plus->getLength(), 1819);
QCOMPARE(node282Minus->getLength(), 1819);
}
void BandageTests::graphLocationFunctions()
{
//First do some tests with a FASTG, where the overlap results in a simpler
//sitations: all positions have a reverse complement position in the
//reverse complement node.
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
DeBruijnNode * node12Plus = g_assemblyGraph->m_deBruijnGraphNodes["12+"];
DeBruijnNode * node3Plus = g_assemblyGraph->m_deBruijnGraphNodes["3+"];
GraphLocation location1(node12Plus, 1);
GraphLocation revCompLocation1 = location1.reverseComplementLocation();
QCOMPARE(location1.getBase(), 'C');
QCOMPARE(revCompLocation1.getBase(), 'G');
QCOMPARE(revCompLocation1.getPosition(), 394);
GraphLocation location2 = GraphLocation::endOfNode(node3Plus);
QCOMPARE(location2.getPosition(), 5869);
location2.moveLocation(-1);
QCOMPARE(location2.getPosition(), 5868);
location2.moveLocation(2);
QCOMPARE(location2.getNode()->getName(), QString("38-"));
QCOMPARE(location2.getPosition(), 1);
GraphLocation location3;
QCOMPARE(location2.isNull(), false);
QCOMPARE(location3.isNull(), true);
//Now look at a LastGraph file which is more complex. Because of the
//offset, reverse complement positions can be in different nodes and may
//not even exist.
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.LastGraph");
int kmer = g_assemblyGraph->m_kmer;
DeBruijnNode * node13Plus = g_assemblyGraph->m_deBruijnGraphNodes["13+"];
DeBruijnNode * node8Minus = g_assemblyGraph->m_deBruijnGraphNodes["8-"];
GraphLocation location4 = GraphLocation::startOfNode(node13Plus);
QCOMPARE(location4.getBase(), 'A');
QCOMPARE(location4.getPosition(), 1);
GraphLocation revCompLocation4 = location4.reverseComplementLocation();
QCOMPARE(revCompLocation4.getBase(), 'T');
QCOMPARE(revCompLocation4.getNode()->getName(), QString("13-"));
QCOMPARE(revCompLocation4.getPosition(), node13Plus->getLength() - kmer + 1);
GraphLocation location5 = GraphLocation::endOfNode(node8Minus);
GraphLocation location6 = location5;
location6.moveLocation(-60);
GraphLocation revCompLocation5 = location5.reverseComplementLocation();
GraphLocation revCompLocation6 = location6.reverseComplementLocation();
QCOMPARE(revCompLocation5.isNull(), true);
QCOMPARE(revCompLocation6.isNull(), false);
QCOMPARE(revCompLocation6.getNode()->getName(), QString("8+"));
QCOMPARE(revCompLocation6.getPosition(), 1);
}
void BandageTests::loadCsvData()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
QString errormsg;
QStringList columns;
bool coloursLoaded = false;
g_assemblyGraph->loadCSV(getTestDirectory() + "test.csv", &columns, &errormsg, &coloursLoaded);
DeBruijnNode * node6Plus = g_assemblyGraph->m_deBruijnGraphNodes["6+"];
DeBruijnNode * node6Minus = g_assemblyGraph->m_deBruijnGraphNodes["6-"];
DeBruijnNode * node7Plus = g_assemblyGraph->m_deBruijnGraphNodes["7+"];
DeBruijnNode * node4Plus = g_assemblyGraph->m_deBruijnGraphNodes["4+"];
DeBruijnNode * node4Minus = g_assemblyGraph->m_deBruijnGraphNodes["4-"];
DeBruijnNode * node3Plus = g_assemblyGraph->m_deBruijnGraphNodes["3+"];
DeBruijnNode * node5Minus = g_assemblyGraph->m_deBruijnGraphNodes["5-"];
DeBruijnNode * node8Plus = g_assemblyGraph->m_deBruijnGraphNodes["8+"];
DeBruijnNode * node9Plus = g_assemblyGraph->m_deBruijnGraphNodes["9+"];
QCOMPARE(columns.size(), 3);
QCOMPARE(errormsg, QString("There were 2 unmatched entries in the CSV."));
QCOMPARE(node6Plus->getCsvLine(0), QString("SIX_PLUS"));
QCOMPARE(node6Plus->getCsvLine(1), QString("6plus"));
QCOMPARE(node6Plus->getCsvLine(2), QString("plus6"));
QCOMPARE(node9Plus->getCsvLine(3), QString(""));
QCOMPARE(node9Plus->getCsvLine(25), QString(""));
QCOMPARE(node6Minus->getCsvLine(0), QString("SIX_MINUS"));
QCOMPARE(node6Minus->getCsvLine(1), QString("6minus"));
QCOMPARE(node6Minus->getCsvLine(2), QString("minus6"));
QCOMPARE(node7Plus->getCsvLine(0), QString("SEVEN_PLUS"));
QCOMPARE(node7Plus->getCsvLine(1), QString("7plus"));
QCOMPARE(node7Plus->getCsvLine(2), QString("plus7"));
QCOMPARE(node4Plus->getCsvLine(0), QString("FOUR_PLUS"));
QCOMPARE(node4Plus->getCsvLine(1), QString("4plus"));
QCOMPARE(node4Plus->getCsvLine(2), QString("plus4"));
QCOMPARE(node4Minus->getCsvLine(0), QString("FOUR_MINUS"));
QCOMPARE(node4Minus->getCsvLine(1), QString("4minus"));
QCOMPARE(node4Minus->getCsvLine(2), QString("minus4"));
QCOMPARE(node3Plus->getCsvLine(0), QString("THREE_PLUS"));
QCOMPARE(node3Plus->getCsvLine(1), QString("3plus"));
QCOMPARE(node3Plus->getCsvLine(2), QString("plus3"));
QCOMPARE(node5Minus->getCsvLine(0), QString("FIVE_MINUS"));
QCOMPARE(node5Minus->getCsvLine(1), QString(""));
QCOMPARE(node5Minus->getCsvLine(2), QString(""));
QCOMPARE(node8Plus->getCsvLine(0), QString("EIGHT_PLUS"));
QCOMPARE(node8Plus->getCsvLine(1), QString("8plus"));
QCOMPARE(node8Plus->getCsvLine(2), QString("plus8"));
QCOMPARE(node9Plus->getCsvLine(0), QString("NINE_PLUS"));
QCOMPARE(node9Plus->getCsvLine(1), QString("9plus"));
QCOMPARE(node9Plus->getCsvLine(2), QString("plus9"));
QCOMPARE(node9Plus->getCsvLine(3), QString(""));
QCOMPARE(node9Plus->getCsvLine(4), QString(""));
QCOMPARE(node9Plus->getCsvLine(5), QString(""));
}
void BandageTests::loadCsvDataTrinity()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.Trinity.fasta");
QString errormsg;
QStringList columns;
bool coloursLoaded = false;
g_assemblyGraph->loadCSV(getTestDirectory() + "test.Trinity.csv", &columns, &errormsg, &coloursLoaded);
DeBruijnNode * node3912Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3912+"];
DeBruijnNode * node3912Minus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3912-"];
DeBruijnNode * node3914Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3914+"];
DeBruijnNode * node3915Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3915+"];
DeBruijnNode * node3923Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3923+"];
DeBruijnNode * node3924Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3924+"];
DeBruijnNode * node3940Plus = g_assemblyGraph->m_deBruijnGraphNodes["19|c0_3940+"];
QCOMPARE(columns.size(), 1);
QCOMPARE(node3912Plus->getCsvLine(0), QString("3912PLUS"));
QCOMPARE(node3912Minus->getCsvLine(0), QString("3912MINUS"));
QCOMPARE(node3914Plus->getCsvLine(0), QString("3914PLUS"));
QCOMPARE(node3915Plus->getCsvLine(0), QString("3915PLUS"));
QCOMPARE(node3923Plus->getCsvLine(0), QString("3923PLUS"));
QCOMPARE(node3924Plus->getCsvLine(0), QString("3924PLUS"));
QCOMPARE(node3940Plus->getCsvLine(0), QString("3940PLUS"));
}
void BandageTests::blastSearch()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
g_settings->blastQueryFilename = getTestDirectory() + "test_queries1.fasta";
createBlastTempDirectory();
g_blastSearch->doAutoBlastSearch();
BlastQuery * exact = g_blastSearch->m_blastQueries.getQueryFromName("test_query_exact");
BlastQuery * one_mismatch = g_blastSearch->m_blastQueries.getQueryFromName("test_query_one_mismatch");
BlastQuery * one_insertion = g_blastSearch->m_blastQueries.getQueryFromName("test_query_one_insertion");
BlastQuery * one_deletion = g_blastSearch->m_blastQueries.getQueryFromName("test_query_one_deletion");
QCOMPARE(exact->getLength(), 100);
QCOMPARE(one_mismatch->getLength(), 100);
QCOMPARE(one_insertion->getLength(), 101);
QCOMPARE(one_deletion->getLength(), 99);
QSharedPointer exactHit = exact->getHits().at(0);
QSharedPointer one_mismatchHit = one_mismatch->getHits().at(0);
QSharedPointer one_insertionHit = one_insertion->getHits().at(0);
QSharedPointer one_deletionHit = one_deletion->getHits().at(0);
QCOMPARE(exactHit->m_numberMismatches, 0);
QCOMPARE(exactHit->m_numberGapOpens, 0);
QCOMPARE(one_mismatchHit->m_numberMismatches, 1);
QCOMPARE(one_mismatchHit->m_numberGapOpens, 0);
QCOMPARE(one_insertionHit->m_numberMismatches, 0);
QCOMPARE(one_insertionHit->m_numberGapOpens, 1);
QCOMPARE(one_deletionHit->m_numberMismatches, 0);
QCOMPARE(one_deletionHit->m_numberGapOpens, 1);
QCOMPARE(exactHit->m_percentIdentity < 100.0, false);
QCOMPARE(one_mismatchHit->m_percentIdentity < 100.0, true);
QCOMPARE(one_insertionHit->m_percentIdentity < 100.0, true);
QCOMPARE(one_deletionHit->m_percentIdentity < 100.0, true);
deleteBlastTempDirectory();
}
void BandageTests::blastSearchFilters()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
g_settings->blastQueryFilename = getTestDirectory() + "test_queries2.fasta";
createBlastTempDirectory();
//First do the search with no filters
g_blastSearch->doAutoBlastSearch();
int unfilteredHitCount = g_blastSearch->m_allHits.size();
//Now filter by e-value.
g_settings->blastEValueFilter.on = true;
g_settings->blastEValueFilter = SciNot(1.0, -5);
g_blastSearch->doAutoBlastSearch();
QCOMPARE(g_blastSearch->m_allHits.size(), 14);
QCOMPARE(g_blastSearch->m_allHits.size() < unfilteredHitCount, true);
//Now add a bit score filter.
g_settings->blastBitScoreFilter.on = true;
g_settings->blastBitScoreFilter = 100.0;
g_blastSearch->doAutoBlastSearch();
QCOMPARE(g_blastSearch->m_allHits.size(), 9);
//Now add an alignment length filter.
g_settings->blastAlignmentLengthFilter.on = true;
g_settings->blastAlignmentLengthFilter = 100;
g_blastSearch->doAutoBlastSearch();
QCOMPARE(g_blastSearch->m_allHits.size(), 8);
//Now add an identity filter.
g_settings->blastIdentityFilter.on = true;
g_settings->blastIdentityFilter = 50.0;
g_blastSearch->doAutoBlastSearch();
QCOMPARE(g_blastSearch->m_allHits.size(), 7);
//Now add a query coverage filter.
g_settings->blastQueryCoverageFilter.on = true;
g_settings->blastQueryCoverageFilter = 90.0;
g_blastSearch->doAutoBlastSearch();
QCOMPARE(g_blastSearch->m_allHits.size(), 5);
deleteBlastTempDirectory();
}
void BandageTests::graphScope()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
QString errorTitle;
QString errorMessage;
int drawnNodes;
std::vector startingNodes;
g_settings->graphScope = WHOLE_GRAPH;
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 44);
g_settings->graphScope = WHOLE_GRAPH;
g_settings->nodeDistance = 0;
g_settings->doubleMode = true;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 88);
g_settings->graphScope = AROUND_NODE;
g_settings->startingNodes = "1";
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 1);
g_settings->graphScope = AROUND_NODE;
g_settings->startingNodes = "1";
g_settings->nodeDistance = 0;
g_settings->doubleMode = true;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 2);
g_settings->graphScope = AROUND_NODE;
g_settings->startingNodes = "1+";
g_settings->nodeDistance = 0;
g_settings->doubleMode = true;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 1);
g_settings->graphScope = AROUND_NODE;
g_settings->startingNodes = "1";
g_settings->nodeDistance = 1;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 3);
g_settings->graphScope = AROUND_NODE;
g_settings->startingNodes = "1";
g_settings->nodeDistance = 2;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 10);
g_settings->graphScope = DEPTH_RANGE;
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
g_settings->minDepthRange = 0.0;
g_settings->maxDepthRange = 211.0;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 43);
g_settings->graphScope = DEPTH_RANGE;
g_settings->nodeDistance = 10;
g_settings->doubleMode = false;
g_settings->minDepthRange = 0.0;
g_settings->maxDepthRange = 211.0;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 43);
g_settings->graphScope = DEPTH_RANGE;
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
g_settings->minDepthRange = 211.0;
g_settings->maxDepthRange = 1000.0;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 1);
g_settings->graphScope = DEPTH_RANGE;
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
g_settings->minDepthRange = 40.0;
g_settings->maxDepthRange = 211.0;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 42);
createBlastTempDirectory();
g_settings->blastQueryFilename = getTestDirectory() + "test_queries1.fasta";
g_blastSearch->doAutoBlastSearch();
g_settings->graphScope = AROUND_BLAST_HITS;
g_settings->nodeDistance = 0;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "all");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 1);
g_settings->graphScope = AROUND_BLAST_HITS;
g_settings->nodeDistance = 1;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "all");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 3);
g_settings->graphScope = AROUND_BLAST_HITS;
g_settings->nodeDistance = 2;
g_settings->doubleMode = false;
startingNodes = g_assemblyGraph->getStartingNodes(&errorTitle, &errorMessage, g_settings->doubleMode, g_settings->startingNodes, "all");
g_assemblyGraph->buildOgdfGraphFromNodesAndEdges(startingNodes, g_settings->nodeDistance);
g_assemblyGraph->layoutGraph();
drawnNodes = g_assemblyGraph->getDrawnNodeCount();
QCOMPARE(drawnNodes, 9);
deleteBlastTempDirectory();
}
void BandageTests::commandLineSettings()
{
createGlobals();
QStringList commandLineSettings;
commandLineSettings = QString("--scope entire").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->graphScope, WHOLE_GRAPH);
commandLineSettings = QString("--scope aroundnodes").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->graphScope, AROUND_NODE);
commandLineSettings = QString("--scope aroundblast").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->graphScope, AROUND_BLAST_HITS);
commandLineSettings = QString("--scope depthrange").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->graphScope, DEPTH_RANGE);
commandLineSettings = QString("--nodes 5+").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->startingNodes, QString("5+"));
commandLineSettings = QString("--nodes 1,2,3").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->startingNodes, QString("1,2,3"));
QCOMPARE(g_settings->startingNodesExactMatch, true);
commandLineSettings = QString("--partial").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->startingNodesExactMatch, false);
commandLineSettings = QString("--distance 12").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeDistance.val, 12);
commandLineSettings = QString("--mindepth 1.2").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minDepthRange.val, 1.2);
commandLineSettings = QString("--maxdepth 2.1").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxDepthRange.val, 2.1);
QCOMPARE(g_settings->doubleMode, false);
commandLineSettings = QString("--double").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->doubleMode, true);
QCOMPARE(g_settings->nodeLengthMode, AUTO_NODE_LENGTH);
commandLineSettings = QString("--nodelen 10000").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeLengthMode, MANUAL_NODE_LENGTH);
QCOMPARE(g_settings->manualNodeLengthPerMegabase.val, 10000.0);
commandLineSettings = QString("--iter 1").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->graphLayoutQuality.val, 1);
commandLineSettings = QString("--nodewidth 4.2").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->averageNodeWidth.val, 4.2);
commandLineSettings = QString("--depwidth 0.222").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->depthEffectOnWidth.val, 0.222);
commandLineSettings = QString("--deppower 0.72").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->depthPower.val, 0.72);
QCOMPARE(g_settings->displayNodeNames, false);
commandLineSettings = QString("--names").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->displayNodeNames, true);
QCOMPARE(g_settings->displayNodeLengths, false);
commandLineSettings = QString("--lengths").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->displayNodeLengths, true);
QCOMPARE(g_settings->displayNodeDepth, false);
commandLineSettings = QString("--depth").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->displayNodeDepth, true);
QCOMPARE(g_settings->displayBlastHits, false);
commandLineSettings = QString("--blasthits").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->displayBlastHits, true);
commandLineSettings = QString("--fontsize 5").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->labelFont.pointSize(), 5);
commandLineSettings = QString("--edgecol #00ff00").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->edgeColour.name(), QString("#00ff00"));
commandLineSettings = QString("--edgewidth 5.5").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->edgeWidth.val, 5.5);
commandLineSettings = QString("--outcol #ff0000").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->outlineColour.name(), QString("#ff0000"));
commandLineSettings = QString("--outline 0.123").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->outlineThickness.val, 0.123);
commandLineSettings = QString("--selcol tomato").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->selectionColour.name(), QString("#ff6347"));
QCOMPARE(g_settings->antialiasing, true);
commandLineSettings = QString("--noaa").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->antialiasing, false);
commandLineSettings = QString("--textcol #550000ff").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->textColour.name(), QString("#0000ff"));
QCOMPARE(g_settings->textColour.alpha(), 85);
commandLineSettings = QString("--toutcol steelblue").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->textOutlineColour), QString("steelblue"));
commandLineSettings = QString("--toutline 0.321").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->textOutlineThickness.val, 0.321);
QCOMPARE(g_settings->positionTextNodeCentre, false);
commandLineSettings = QString("--centre").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->positionTextNodeCentre, true);
commandLineSettings = QString("--colour random").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeColourScheme, RANDOM_COLOURS);
commandLineSettings = QString("--colour uniform").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeColourScheme, UNIFORM_COLOURS);
commandLineSettings = QString("--colour depth").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeColourScheme, DEPTH_COLOUR);
commandLineSettings = QString("--colour blastsolid").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeColourScheme, BLAST_HITS_SOLID_COLOUR);
commandLineSettings = QString("--colour blastrainbow").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->nodeColourScheme, BLAST_HITS_RAINBOW_COLOUR);
commandLineSettings = QString("--ransatpos 12").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourPositiveSaturation.val, 12);
commandLineSettings = QString("--ransatneg 23").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourNegativeSaturation.val, 23);
commandLineSettings = QString("--ranligpos 34").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourPositiveLightness.val, 34);
commandLineSettings = QString("--ranligneg 45").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourNegativeLightness.val, 45);
commandLineSettings = QString("--ranopapos 56").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourPositiveOpacity.val, 56);
commandLineSettings = QString("--ranopaneg 67").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->randomColourNegativeOpacity.val, 67);
commandLineSettings = QString("--unicolpos springgreen").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->uniformPositiveNodeColour), QString("springgreen"));
commandLineSettings = QString("--unicolneg teal").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->uniformNegativeNodeColour), QString("teal"));
commandLineSettings = QString("--unicolspe papayawhip").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->uniformNodeSpecialColour), QString("papayawhip"));
commandLineSettings = QString("--depcollow mediumorchid").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->lowDepthColour), QString("mediumorchid"));
commandLineSettings = QString("--depcolhi linen").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(getColourName(g_settings->highDepthColour), QString("linen"));
QCOMPARE(g_settings->autoDepthValue, true);
commandLineSettings = QString("--depvallow 56.7").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->lowDepthValue.val, 56.7);
QCOMPARE(g_settings->autoDepthValue, false);
commandLineSettings = QString("--depvalhi 67.8").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->highDepthValue.val, 67.8);
commandLineSettings = QString("--depvalhi 67.8").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->highDepthValue.val, 67.8);
commandLineSettings = QString("--query queries.fasta").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastQueryFilename, QString("queries.fasta"));
commandLineSettings = QString("--blastp --abc").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastSearchParameters, QString("--abc"));
QCOMPARE(g_settings->blastAlignmentLengthFilter.on, false);
commandLineSettings = QString("--alfilter 543").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastAlignmentLengthFilter.on, true);
QCOMPARE(g_settings->blastAlignmentLengthFilter.val, 543);
QCOMPARE(g_settings->blastQueryCoverageFilter.on, false);
commandLineSettings = QString("--qcfilter 67.8").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastQueryCoverageFilter.on, true);
QCOMPARE(g_settings->blastQueryCoverageFilter.val, 67.8);
QCOMPARE(g_settings->blastIdentityFilter.on, false);
commandLineSettings = QString("--ifilter 12.3").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastIdentityFilter.on, true);
QCOMPARE(g_settings->blastIdentityFilter.val, 12.3);
QCOMPARE(g_settings->blastEValueFilter.on, false);
commandLineSettings = QString("--evfilter 8.5e-14").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastEValueFilter.on, true);
QCOMPARE(g_settings->blastEValueFilter.val, SciNot(8.5, -14));
QCOMPARE(g_settings->blastEValueFilter.val.getCoefficient(), 8.5);
QCOMPARE(g_settings->blastEValueFilter.val.getExponent(), -14);
QCOMPARE(g_settings->blastBitScoreFilter.on, false);
commandLineSettings = QString("--bsfilter 1234.5").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->blastBitScoreFilter.on, true);
QCOMPARE(g_settings->blastBitScoreFilter.val, 1234.5);
commandLineSettings = QString("--pathnodes 3").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxQueryPathNodes.val, 3);
commandLineSettings = QString("--minpatcov 0.543").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minQueryCoveredByPath.val, 0.543);
commandLineSettings = QString("--minhitcov 0.654").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minQueryCoveredByHits.val, 0.654);
QCOMPARE(g_settings->minQueryCoveredByHits.on, true);
commandLineSettings = QString("--minhitcov off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minQueryCoveredByHits.on, false);
commandLineSettings = QString("--minmeanid 0.765").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minMeanHitIdentity.val, 0.765);
QCOMPARE(g_settings->minMeanHitIdentity.on, true);
commandLineSettings = QString("--minmeanid off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minMeanHitIdentity.on, false);
commandLineSettings = QString("--minpatlen 0.97").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minLengthPercentage.val, 0.97);
QCOMPARE(g_settings->minLengthPercentage.on, true);
commandLineSettings = QString("--minpatlen off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minLengthPercentage.on, false);
commandLineSettings = QString("--maxpatlen 1.03").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxLengthPercentage.val, 1.03);
QCOMPARE(g_settings->maxLengthPercentage.on, true);
commandLineSettings = QString("--maxpatlen off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxLengthPercentage.on, false);
commandLineSettings = QString("--minlendis -1234").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minLengthBaseDiscrepancy.val, -1234);
QCOMPARE(g_settings->minLengthBaseDiscrepancy.on, true);
commandLineSettings = QString("--minlendis off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->minLengthBaseDiscrepancy.on, false);
commandLineSettings = QString("--maxlendis 4321").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxLengthBaseDiscrepancy.val, 4321);
QCOMPARE(g_settings->maxLengthBaseDiscrepancy.on, true);
commandLineSettings = QString("--maxlendis off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxLengthBaseDiscrepancy.on, false);
commandLineSettings = QString("--maxevprod 4e-500").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxEValueProduct.val.getCoefficient(), 4.0);
QCOMPARE(g_settings->maxEValueProduct.val.getExponent(), -500);
QCOMPARE(g_settings->maxEValueProduct.on, true);
commandLineSettings = QString("--maxevprod off").split(" ");
parseSettings(commandLineSettings);
QCOMPARE(g_settings->maxEValueProduct.on, false);
}
void BandageTests::sciNotComparisons()
{
SciNot sn01(1.0, 10);
SciNot sn02(10.0, 9);
SciNot sn03(0.1, 11);
SciNot sn04(5.0, 10);
SciNot sn05(-5.0, 15);
SciNot sn06(-6.0, 15);
SciNot sn07(-3.0, 3);
SciNot sn08(-0.3, 4);
SciNot sn09(-3.0, -3);
SciNot sn10(-0.3, -2);
SciNot sn11(1.4, 2);
SciNot sn12("1.4e2");
SciNot sn13("140");
QCOMPARE(sn01 == sn02, true);
QCOMPARE(sn01 == sn03, true);
QCOMPARE(sn01 == sn03, true);
QCOMPARE(sn01 >= sn03, true);
QCOMPARE(sn01 <= sn03, true);
QCOMPARE(sn01 != sn03, false);
QCOMPARE(sn01 < sn04, true);
QCOMPARE(sn01 <= sn04, true);
QCOMPARE(sn01 > sn04, false);
QCOMPARE(sn01 >= sn04, false);
QCOMPARE(sn04 > sn05, true);
QCOMPARE(sn04 < sn05, false);
QCOMPARE(sn06 < sn05, true);
QCOMPARE(sn06 <= sn05, true);
QCOMPARE(sn06 > sn05, false);
QCOMPARE(sn06 >= sn05, false);
QCOMPARE(sn07 == sn08, true);
QCOMPARE(sn07 != sn08, false);
QCOMPARE(sn09 == sn10, true);
QCOMPARE(sn09 != sn10, false);
QCOMPARE(sn11 == sn12, true);
QCOMPARE(sn11 == sn13, true);
QCOMPARE(sn01.asString(true), QString("1e10"));
QCOMPARE(sn01.asString(false), QString("1e10"));
QCOMPARE(sn11.asString(true), QString("1.4e2"));
QCOMPARE(sn11.asString(false), QString("140"));
}
void BandageTests::graphEdits()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 88);
QCOMPARE(int(g_assemblyGraph->m_deBruijnGraphEdges.size()), 118);
//Get the path sequence now to compare to the merged node sequence at the
//end.
QString pathStringFailure;
Path path = Path::makeFromString("6+, 26+, 23+, 26+, 24+", false, &pathStringFailure);
QByteArray pathSequence = path.getPathSequence();
g_assemblyGraph->duplicateNodePair(g_assemblyGraph->m_deBruijnGraphNodes["26+"], 0);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 90);
QCOMPARE(int(g_assemblyGraph->m_deBruijnGraphEdges.size()), 126);
std::vector edgesToRemove;
edgesToRemove.push_back(getEdgeFromNodeNames("26_copy+", "24+"));
edgesToRemove.push_back(getEdgeFromNodeNames("6+", "26+"));
edgesToRemove.push_back(getEdgeFromNodeNames("26+", "23+"));
edgesToRemove.push_back(getEdgeFromNodeNames("23+", "26_copy+"));
g_assemblyGraph->deleteEdges(&edgesToRemove);
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 90);
QCOMPARE(int(g_assemblyGraph->m_deBruijnGraphEdges.size()), 118);
g_assemblyGraph->mergeAllPossible();
QCOMPARE(g_assemblyGraph->m_deBruijnGraphNodes.size(), 82);
QCOMPARE(int(g_assemblyGraph->m_deBruijnGraphEdges.size()), 110);
DeBruijnNode * mergedNode = g_assemblyGraph->m_deBruijnGraphNodes["6_26_copy_23_26_24+"];
QCOMPARE(pathSequence, mergedNode->getSequence());
}
//Saving a Velvet graph to GFA is a bit complex because the node sequence offset
//must be filled in. This function tests aspects of that process.
void BandageTests::velvetToGfa()
{
//First load the graph as a LastGraph and pull out some information and a
//circular path sequence.
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "big_test.LastGraph");
int lastGraphNodeCount = g_assemblyGraph->m_nodeCount;
int lastGraphEdgeCount= g_assemblyGraph->m_edgeCount;
long long lastGraphTotalLength = g_assemblyGraph->m_totalLength;
long long lastGraphShortestContig = g_assemblyGraph->m_shortestContig;
long long lastGraphLongestContig = g_assemblyGraph->m_longestContig;
QString pathStringFailure;
Path lastGraphTestPath1 = Path::makeFromString("3176-, 3176+, 4125+, 3178-, 3283+, 3180+, 3177-", true, &pathStringFailure);
Path lastGraphTestPath2 = Path::makeFromString("3368+, 3369+, 3230+, 3231+, 3370-, 3143+, 3144+, 3145+, 3240+, 3241+, 3788-, 3787-, 3231+, 3252+, 3241-, 3240-, 3145-, 4164-, 4220+, 3368-, 3367+", true, &pathStringFailure);
QByteArray lastGraphTestPath1Sequence = lastGraphTestPath1.getPathSequence();
QByteArray lastGraphTestPath2Sequence = lastGraphTestPath2.getPathSequence();
//Now save the graph as a GFA and reload it and grab the same information.
g_assemblyGraph->saveEntireGraphToGfa(getTestDirectory() + "big_test_temp.gfa");
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "big_test_temp.gfa");
int gfaNodeCount = g_assemblyGraph->m_nodeCount;
int gfaEdgeCount= g_assemblyGraph->m_edgeCount;
long long gfaTotalLength = g_assemblyGraph->m_totalLength;
long long gfaShortestContig = g_assemblyGraph->m_shortestContig;
long long gfaLongestContig = g_assemblyGraph->m_longestContig;
Path gfaTestPath1 = Path::makeFromString("3176-, 3176+, 4125+, 3178-, 3283+, 3180+, 3177-", true, &pathStringFailure);
Path gfaTestPath2 = Path::makeFromString("3368+, 3369+, 3230+, 3231+, 3370-, 3143+, 3144+, 3145+, 3240+, 3241+, 3788-, 3787-, 3231+, 3252+, 3241-, 3240-, 3145-, 4164-, 4220+, 3368-, 3367+", true, &pathStringFailure);
QByteArray gfaTestPath1Sequence = gfaTestPath1.getPathSequence();
QByteArray gfaTestPath2Sequence = gfaTestPath2.getPathSequence();
//Now we compare the LastGraph info to the GFA info to make sure they are
//the same (or appropriately different). The k-mer size for this graph is
//51, so we expect each node to get 50 base pairs longer.
QCOMPARE(lastGraphNodeCount, gfaNodeCount);
QCOMPARE(lastGraphEdgeCount, gfaEdgeCount);
QCOMPARE(lastGraphTotalLength + 50 * lastGraphNodeCount, gfaTotalLength);
QCOMPARE(lastGraphShortestContig + 50, gfaShortestContig);
QCOMPARE(lastGraphLongestContig + 50, gfaLongestContig);
QCOMPARE(lastGraphTestPath1Sequence, gfaTestPath1Sequence);
QCOMPARE(lastGraphTestPath2Sequence, gfaTestPath2Sequence);
//Finally, delete the gfa file.
QFile::remove(getTestDirectory() + "big_test_temp.gfa");
}
void BandageTests::spadesToGfa()
{
//First load the graph as a FASTG and pull out some information and a
//path sequence.
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
int fastgNodeCount = g_assemblyGraph->m_nodeCount;
int fastgEdgeCount= g_assemblyGraph->m_edgeCount;
long long fastgTotalLength = g_assemblyGraph->m_totalLength;
long long fastgShortestContig = g_assemblyGraph->m_shortestContig;
long long fastgLongestContig = g_assemblyGraph->m_longestContig;
QString pathStringFailure;
Path fastgTestPath1 = Path::makeFromString("24+, 14+, 39-, 43-, 42-, 2-, 4+, 33+, 35-, 31-, 44-, 27+, 9-, 28-, 44+, 31+, 36+", false, &pathStringFailure);
Path fastgTestPath2 = Path::makeFromString("16+, 7+, 13+, 37+, 41-, 40-, 42+, 43+, 39+, 14-, 22-, 20+, 7-, 25-, 32-, 38+, 3-", false, &pathStringFailure);
QByteArray fastgTestPath1Sequence = fastgTestPath1.getPathSequence();
QByteArray fastgTestPath2Sequence = fastgTestPath2.getPathSequence();
//Now save the graph as a GFA and reload it and grab the same information.
g_assemblyGraph->saveEntireGraphToGfa(getTestDirectory() + "test_temp.gfa");
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test_temp.gfa");
int gfaNodeCount = g_assemblyGraph->m_nodeCount;
int gfaEdgeCount= g_assemblyGraph->m_edgeCount;
long long gfaTotalLength = g_assemblyGraph->m_totalLength;
long long gfaShortestContig = g_assemblyGraph->m_shortestContig;
long long gfaLongestContig = g_assemblyGraph->m_longestContig;
Path gfaTestPath1 = Path::makeFromString("24+, 14+, 39-, 43-, 42-, 2-, 4+, 33+, 35-, 31-, 44-, 27+, 9-, 28-, 44+, 31+, 36+", false, &pathStringFailure);
Path gfaTestPath2 = Path::makeFromString("16+, 7+, 13+, 37+, 41-, 40-, 42+, 43+, 39+, 14-, 22-, 20+, 7-, 25-, 32-, 38+, 3-", false, &pathStringFailure);
QByteArray gfaTestPath1Sequence = gfaTestPath1.getPathSequence();
QByteArray gfaTestPath2Sequence = gfaTestPath2.getPathSequence();
//Now we compare the LastGraph info to the GFA info to make sure they are
//the same (or appropriately different). The k-mer size for this graph is
//51, so we expect each node to get 50 base pairs longer.
QCOMPARE(fastgNodeCount, gfaNodeCount);
QCOMPARE(fastgEdgeCount, gfaEdgeCount);
QCOMPARE(fastgTotalLength, gfaTotalLength);
QCOMPARE(fastgShortestContig, gfaShortestContig);
QCOMPARE(fastgLongestContig, gfaLongestContig);
QCOMPARE(fastgTestPath1Sequence, gfaTestPath1Sequence);
QCOMPARE(fastgTestPath2Sequence, gfaTestPath2Sequence);
//Finally, delete the gfa file.
QFile::remove(getTestDirectory() + "test_temp.gfa");
}
void BandageTests::mergeNodesOnGfa()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test_plasmids.gfa");
DeBruijnNode * node6Plus = g_assemblyGraph->m_deBruijnGraphNodes["6+"];
DeBruijnNode * node280Plus = g_assemblyGraph->m_deBruijnGraphNodes["280+"];
DeBruijnNode * node232Minus = g_assemblyGraph->m_deBruijnGraphNodes["232-"];
DeBruijnNode * node333Plus = g_assemblyGraph->m_deBruijnGraphNodes["333+"];
DeBruijnNode * node289Plus = g_assemblyGraph->m_deBruijnGraphNodes["289+"];
DeBruijnNode * node283Plus = g_assemblyGraph->m_deBruijnGraphNodes["283+"];
DeBruijnNode * node277Plus = g_assemblyGraph->m_deBruijnGraphNodes["277+"];
DeBruijnNode * node297Plus = g_assemblyGraph->m_deBruijnGraphNodes["297+"];
DeBruijnNode * node282Plus = g_assemblyGraph->m_deBruijnGraphNodes["282+"];
//Create a path before merging the nodes.
QString pathStringFailure;
Path testPath1 = Path::makeFromString("6+, 280+, 232-, 333+, 289+, 283+", true, &pathStringFailure);
QByteArray path1Sequence = testPath1.getPathSequence();
int path1Length = testPath1.getLength();
int nodeTotalLength = node6Plus->getLength() + node280Plus->getLength() + node232Minus->getLength() +
node333Plus->getLength() + node289Plus->getLength() + node283Plus->getLength();
//The k-mer size in this test is 81, so the path should remove all of those overlaps.
QCOMPARE(path1Length, nodeTotalLength - 6 * 81);
//Now remove excess nodes.
std::vector nodesToDelete;
nodesToDelete.push_back(node277Plus);
nodesToDelete.push_back(node297Plus);
nodesToDelete.push_back(node282Plus);
g_assemblyGraph->deleteNodes(&nodesToDelete);
//There should now be six nodes in the graph (plus complements).
QCOMPARE(12, g_assemblyGraph->m_deBruijnGraphNodes.size());
//After a merge, there should be only one node (and its complement).
g_assemblyGraph->mergeAllPossible();
QCOMPARE(2, g_assemblyGraph->m_deBruijnGraphNodes.size());
//That last node should have a length of its six constituent nodes, minus
//the overlaps.
DeBruijnNode * lastNode = g_assemblyGraph->m_deBruijnGraphNodes.first();
QCOMPARE(lastNode->getLength(), nodeTotalLength - 5 * 81);
//If we make a circular path with this node, its length should be equal to
//the length of the path made before.
Path testPath2 = Path::makeFromString(lastNode->getName(), true, &pathStringFailure);
QCOMPARE(path1Length, testPath2.getLength());
//The sequence of this second path should also match the sequence of the
//first path.
QByteArray path2Sequence = testPath2.getPathSequence();
QCOMPARE(doCircularSequencesMatch(path1Sequence, path2Sequence), true);
}
void BandageTests::changeNodeNames()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
DeBruijnNode * node6Plus = g_assemblyGraph->m_deBruijnGraphNodes["6+"];
DeBruijnNode * node6Minus = g_assemblyGraph->m_deBruijnGraphNodes["6-"];
int nodeCountBefore = g_assemblyGraph->m_deBruijnGraphNodes.size();
g_assemblyGraph->changeNodeName("6", "12345");
DeBruijnNode * node12345Plus = g_assemblyGraph->m_deBruijnGraphNodes["12345+"];
DeBruijnNode * node12345Minus = g_assemblyGraph->m_deBruijnGraphNodes["12345-"];
int nodeCountAfter = g_assemblyGraph->m_deBruijnGraphNodes.size();
QCOMPARE(node6Plus, node12345Plus);
QCOMPARE(node6Minus, node12345Minus);
QCOMPARE(nodeCountBefore, nodeCountAfter);
}
void BandageTests::changeNodeDepths()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
DeBruijnNode * node6Plus = g_assemblyGraph->m_deBruijnGraphNodes["6+"];
DeBruijnNode * node6Minus = g_assemblyGraph->m_deBruijnGraphNodes["6-"];
DeBruijnNode * node7Plus = g_assemblyGraph->m_deBruijnGraphNodes["7+"];
DeBruijnNode * node7Minus = g_assemblyGraph->m_deBruijnGraphNodes["7-"];
std::vector nodes;
nodes.push_back(node6Plus);
nodes.push_back(node7Plus);
//Complementary pairs should have the same depth.
QCOMPARE(node6Plus->getDepth(), node6Minus->getDepth());
QCOMPARE(node7Plus->getDepth(), node7Minus->getDepth());
g_assemblyGraph->changeNodeDepth(&nodes, 0.5);
//Check to make sure the change worked.
QCOMPARE(0.5, node6Plus->getDepth());
QCOMPARE(0.5, node6Minus->getDepth());
QCOMPARE(0.5, node7Plus->getDepth());
QCOMPARE(0.5, node7Minus->getDepth());
}
void BandageTests::blastQueryPaths()
{
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test_query_paths.gfa");
Settings defaultSettings;
g_settings->blastQueryFilename = getTestDirectory() + "test_query_paths.fasta";
defaultSettings.blastQueryFilename = getTestDirectory() + "test_query_paths.fasta";
createBlastTempDirectory();
//Now filter by e-value to get only strong hits and do the BLAST search.
g_settings->blastEValueFilter.on = true;
g_settings->blastEValueFilter = SciNot(1.0, -5);
QList query1Paths;
QList query2Paths;
QList query3Paths;
QList query4Paths;
QList query5Paths;
QList query6Paths;
QList query7Paths;
//With the default settings, queries 1 to 5 should each have one path and
//queries 6 and 7 should have 0 (because of their large inserts).
g_blastSearch->doAutoBlastSearch();
query1Paths = g_blastSearch->m_blastQueries.m_queries[0]->getPaths();
query2Paths = g_blastSearch->m_blastQueries.m_queries[1]->getPaths();
query3Paths = g_blastSearch->m_blastQueries.m_queries[2]->getPaths();
query4Paths = g_blastSearch->m_blastQueries.m_queries[3]->getPaths();
query5Paths = g_blastSearch->m_blastQueries.m_queries[4]->getPaths();
query6Paths = g_blastSearch->m_blastQueries.m_queries[5]->getPaths();
query7Paths = g_blastSearch->m_blastQueries.m_queries[6]->getPaths();
QCOMPARE(query1Paths.size(), 1);
QCOMPARE(query2Paths.size(), 1);
QCOMPARE(query3Paths.size(), 1);
QCOMPARE(query4Paths.size(), 1);
QCOMPARE(query5Paths.size(), 1);
QCOMPARE(query6Paths.size(), 0);
QCOMPARE(query7Paths.size(), 0);
//query2 has a mean hit identity of 0.98.
g_settings->minMeanHitIdentity.on = true;
g_settings->minMeanHitIdentity = 0.979;
g_blastSearch->doAutoBlastSearch();
query2Paths = g_blastSearch->m_blastQueries.m_queries[1]->getPaths();
QCOMPARE(query2Paths.size(), 1);
g_settings->minMeanHitIdentity = 0.981;
g_blastSearch->doAutoBlastSearch();
query2Paths = g_blastSearch->m_blastQueries.m_queries[1]->getPaths();
QCOMPARE(query2Paths.size(), 0);
//Turning the filter off should make the path return.
g_settings->minMeanHitIdentity.on = false;
g_blastSearch->doAutoBlastSearch();
query2Paths = g_blastSearch->m_blastQueries.m_queries[1]->getPaths();
QCOMPARE(query2Paths.size(), 1);
*g_settings = defaultSettings;
//query3 has a length discrepancy of -20.
g_settings->minLengthBaseDiscrepancy.on = true;
g_settings->minLengthBaseDiscrepancy = -20;
g_blastSearch->doAutoBlastSearch();
query3Paths = g_blastSearch->m_blastQueries.m_queries[2]->getPaths();
QCOMPARE(query3Paths.size(), 1);
g_settings->minLengthBaseDiscrepancy = -19;
g_blastSearch->doAutoBlastSearch();
query3Paths = g_blastSearch->m_blastQueries.m_queries[2]->getPaths();
QCOMPARE(query3Paths.size(), 0);
//Turning the filter off should make the path return.
g_settings->minLengthBaseDiscrepancy.on = false;
g_blastSearch->doAutoBlastSearch();
query3Paths = g_blastSearch->m_blastQueries.m_queries[2]->getPaths();
QCOMPARE(query3Paths.size(), 1);
*g_settings = defaultSettings;
//query4 has a length discrepancy of +20.
g_settings->maxLengthBaseDiscrepancy.on = true;
g_settings->maxLengthBaseDiscrepancy = 20;
g_blastSearch->doAutoBlastSearch();
query4Paths = g_blastSearch->m_blastQueries.m_queries[3]->getPaths();
QCOMPARE(query4Paths.size(), 1);
g_settings->maxLengthBaseDiscrepancy = 19;
g_blastSearch->doAutoBlastSearch();
query4Paths = g_blastSearch->m_blastQueries.m_queries[3]->getPaths();
QCOMPARE(query4Paths.size(), 0);
//Turning the filter off should make the path return.
g_settings->maxLengthBaseDiscrepancy.on = false;
g_blastSearch->doAutoBlastSearch();
query4Paths = g_blastSearch->m_blastQueries.m_queries[3]->getPaths();
QCOMPARE(query4Paths.size(), 1);
*g_settings = defaultSettings;
//query5 has a path through 4 nodes.
g_settings->maxQueryPathNodes = 4;
g_blastSearch->doAutoBlastSearch();
query5Paths = g_blastSearch->m_blastQueries.m_queries[4]->getPaths();
QCOMPARE(query5Paths.size(), 1);
g_settings->maxQueryPathNodes = 3;
g_blastSearch->doAutoBlastSearch();
query5Paths = g_blastSearch->m_blastQueries.m_queries[4]->getPaths();
QCOMPARE(query5Paths.size(), 0);
*g_settings = defaultSettings;
//By turning off length restrictions, queries 6 and 7 should get path with
//a large insert in the middle.
g_settings->minLengthPercentage.on = false;
g_settings->maxLengthPercentage.on = false;
g_settings->minLengthBaseDiscrepancy.on = false;
g_settings->maxLengthBaseDiscrepancy.on = false;
g_blastSearch->doAutoBlastSearch();
query6Paths = g_blastSearch->m_blastQueries.m_queries[5]->getPaths();
query7Paths = g_blastSearch->m_blastQueries.m_queries[6]->getPaths();
QCOMPARE(query6Paths.size(), 1);
QCOMPARE(query7Paths.size(), 1);
//Adjusting on the max length restriction can allow query 6 to get a path
//and then query 7.
g_settings->maxLengthBaseDiscrepancy.on = true;
g_settings->maxLengthBaseDiscrepancy = 1999;
g_blastSearch->doAutoBlastSearch();
query6Paths = g_blastSearch->m_blastQueries.m_queries[5]->getPaths();
query7Paths = g_blastSearch->m_blastQueries.m_queries[6]->getPaths();
QCOMPARE(query6Paths.size(), 1);
QCOMPARE(query7Paths.size(), 0);
g_settings->maxLengthBaseDiscrepancy = 2000;
g_blastSearch->doAutoBlastSearch();
query6Paths = g_blastSearch->m_blastQueries.m_queries[5]->getPaths();
query7Paths = g_blastSearch->m_blastQueries.m_queries[6]->getPaths();
QCOMPARE(query6Paths.size(), 1);
QCOMPARE(query7Paths.size(), 1);
}
void BandageTests::bandageInfo()
{
int n50 = 0;
int shortestNode = 0;
int firstQuartile = 0;
int median = 0;
int thirdQuartile = 0;
int longestNode = 0;
int componentCount = 0;
int largestComponentLength = 0;
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.LastGraph");
g_assemblyGraph->getNodeStats(&n50, &shortestNode, &firstQuartile, &median, &thirdQuartile, &longestNode);
g_assemblyGraph->getGraphComponentCountAndLargestComponentSize(&componentCount, &largestComponentLength);
QCOMPARE(17, g_assemblyGraph->m_nodeCount);
QCOMPARE(16, g_assemblyGraph->m_edgeCount);
QCOMPARE(29939, g_assemblyGraph->m_totalLength);
QCOMPARE(10, g_assemblyGraph->getDeadEndCount());
QCOMPARE(2000, n50);
QCOMPARE(59, shortestNode);
QCOMPARE(2000, longestNode);
QCOMPARE(1, componentCount);
QCOMPARE(29939, largestComponentLength);
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.fastg");
g_assemblyGraph->getNodeStats(&n50, &shortestNode, &firstQuartile, &median, &thirdQuartile, &longestNode);
g_assemblyGraph->getGraphComponentCountAndLargestComponentSize(&componentCount, &largestComponentLength);
QCOMPARE(44, g_assemblyGraph->m_nodeCount);
QCOMPARE(59, g_assemblyGraph->m_edgeCount);
QCOMPARE(214441, g_assemblyGraph->m_totalLength);
QCOMPARE(0, g_assemblyGraph->getDeadEndCount());
QCOMPARE(35628, n50);
QCOMPARE(78, shortestNode);
QCOMPARE(52213, longestNode);
QCOMPARE(1, componentCount);
QCOMPARE(214441, largestComponentLength);
createGlobals();
g_assemblyGraph->loadGraphFromFile(getTestDirectory() + "test.Trinity.fasta");
g_assemblyGraph->getNodeStats(&n50, &shortestNode, &firstQuartile, &median, &thirdQuartile, &longestNode);
g_assemblyGraph->getGraphComponentCountAndLargestComponentSize(&componentCount, &largestComponentLength);
QCOMPARE(149, g_assemblyGraph->getDeadEndCount());
QCOMPARE(66, componentCount);
QCOMPARE(9398, largestComponentLength);
}
void BandageTests::createGlobals()
{
g_settings.reset(new Settings());
g_memory.reset(new Memory());
g_blastSearch.reset(new BlastSearch());
g_assemblyGraph.reset(new AssemblyGraph());
g_graphicsView = new MyGraphicsView();
}
bool BandageTests::createBlastTempDirectory()
{
//Running from the command line, it makes more sense to put the temp
//directory in the current directory.
g_blastSearch->m_tempDirectory = "bandage_temp-" + QString::number(QCoreApplication::applicationPid()) + "/";
if (!QDir().mkdir(g_blastSearch->m_tempDirectory))
return false;
g_blastSearch->m_blastQueries.createTempQueryFiles();
return true;
}
void BandageTests::deleteBlastTempDirectory()
{
if (g_blastSearch->m_tempDirectory != "" &&
QDir(g_blastSearch->m_tempDirectory).exists() &&
QDir(g_blastSearch->m_tempDirectory).dirName().contains("bandage_temp"))
QDir(g_blastSearch->m_tempDirectory).removeRecursively();
}
QString BandageTests::getTestDirectory()
{
QDir directory = QDir::current();
//We want to find a directory "Bandage/tests/". Keep backing up in the
//directory structure until we find it.
QString path;
while (true)
{
path = directory.path() + "/Bandage/tests/";
if (QDir(path).exists())
return path;
if (!directory.cdUp())
return "";
}
return "";
}
DeBruijnEdge * BandageTests::getEdgeFromNodeNames(QString startingNodeName,
QString endingNodeName)
{
DeBruijnNode * startingNode = g_assemblyGraph->m_deBruijnGraphNodes[startingNodeName];
DeBruijnNode * endingNode = g_assemblyGraph->m_deBruijnGraphNodes[endingNodeName];
QPair nodePair(startingNode, endingNode);
if (g_assemblyGraph->m_deBruijnGraphEdges.contains(nodePair))
return g_assemblyGraph->m_deBruijnGraphEdges[nodePair];
else
return 0;
}
//This function checks to see if two circular sequences match. It needs to
//check each possible rotation, as well as reverse complements.
bool BandageTests::doCircularSequencesMatch(QByteArray s1, QByteArray s2)
{
for (int i = 0; i < s1.length() - 1; ++i)
{
QByteArray rotatedS1 = s1.right(s1.length() - i) + s1.left(i);
if (rotatedS1 == s2)
return true;
}
//If the code got here, then all possible rotations of s1 failed to match
//s2. Now we try the reverse complement.
QByteArray s1Rc = AssemblyGraph::getReverseComplement(s1);
for (int i = 0; i < s1Rc.length() - 1; ++i)
{
QByteArray rotatedS1Rc = s1Rc.right(s1Rc.length() - i) + s1Rc.left(i);
if (rotatedS1Rc == s2)
return true;
}
return false;
}
QTEST_MAIN(BandageTests)
#include "bandagetests.moc"