Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor BLAST temp file and queries handling #102

Merged
merged 4 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 2 additions & 69 deletions blast/blastqueries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,15 @@
#include "program/settings.h"
#include <QTextStream>

BlastQueries::BlastQueries() :
m_tempNuclFile(0), m_tempProtFile(0)
{
m_presetColours = getPresetColours();
}

BlastQueries::BlastQueries()
: m_presetColours{getPresetColours()} {}

BlastQueries::~BlastQueries()
{
clearAllQueries();
}


void BlastQueries::createTempQueryFiles()
{
m_tempNuclFile.reset(new QFile(g_blastSearch->m_tempDirectory + "nucl_queries.fasta"));
m_tempProtFile.reset(new QFile(g_blastSearch->m_tempDirectory + "prot_queries.fasta"));
}

BlastQuery * BlastQueries::getQueryFromName(QString queryName)
{
for (size_t i = 0; i < m_queries.size(); ++i)
Expand All @@ -63,7 +53,6 @@ void BlastQueries::addQuery(BlastQuery * newQuery)
newQuery->setColour(m_presetColours[colourIndex]);

m_queries.push_back(newQuery);
updateTempFiles();
}


Expand All @@ -73,7 +62,6 @@ void BlastQueries::addQuery(BlastQuery * newQuery)
QString BlastQueries::renameQuery(BlastQuery * newQuery, QString newName)
{
newQuery->setName(getUniqueName(newName));
updateTempFiles();
return newQuery->getName();
}

Expand Down Expand Up @@ -105,7 +93,6 @@ void BlastQueries::clearAllQueries()
for (size_t i = 0; i < m_queries.size(); ++i)
delete m_queries[i];
m_queries.clear();
deleteTempFiles();
}

void BlastQueries::clearSomeQueries(std::vector<BlastQuery *> queriesToRemove)
Expand All @@ -115,47 +102,8 @@ void BlastQueries::clearSomeQueries(std::vector<BlastQuery *> queriesToRemove)
m_queries.erase(std::remove(m_queries.begin(), m_queries.end(), queriesToRemove[i]), m_queries.end());
delete queriesToRemove[i];
}

updateTempFiles();
}

void BlastQueries::deleteTempFiles()
{
if (tempNuclFileExists())
m_tempNuclFile->remove();
if (tempProtFileExists())
m_tempProtFile->remove();
}

void BlastQueries::updateTempFiles()
{
deleteTempFiles();

if (getQueryCount(NUCLEOTIDE) > 0)
writeTempFile(m_tempNuclFile, NUCLEOTIDE);

if (getQueryCount(PROTEIN) > 0)
writeTempFile(m_tempProtFile, PROTEIN);
}


void BlastQueries::writeTempFile(QSharedPointer<QFile> file, QuerySequenceType sequenceType)
{
file->open(QIODevice::Append | QIODevice::Text);
QTextStream out(file.data());
for (size_t i = 0; i < m_queries.size(); ++i)
{
if (m_queries[i]->getSequenceType() == sequenceType)
{
out << ">" << m_queries[i]->getName() << "\n";
out << m_queries[i]->getSequence();
out << "\n";
}
}
file->close();
}


void BlastQueries::searchOccurred()
{
for (size_t i = 0; i < m_queries.size(); ++i)
Expand Down Expand Up @@ -208,21 +156,6 @@ int BlastQueries::getQueryCount(QuerySequenceType sequenceType)
return count;
}


bool BlastQueries::tempNuclFileExists()
{
if (m_tempNuclFile.isNull())
return false;
return m_tempNuclFile->exists();
}
bool BlastQueries::tempProtFileExists()
{
if (m_tempProtFile.isNull())
return false;
return m_tempProtFile->exists();
}


//This function looks to see if a query pointer is in the list
//of queries. The query pointer given may or may not still
//actually exist, so it can't be dereferenced.
Expand Down
18 changes: 2 additions & 16 deletions blast/blastqueries.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,8 @@

#include <vector>

//This class manages all BLAST queries. It holds BlastQuery
//objects itself, and it creates/modifies/deletes the temp
//files which hold the queries for use in BLAST.
//There are two separate temp files, one for nucleotide
//queries (for blastn) and one for protein queries (for
//tblasn).
// This class manages all BLAST queries. It holds BlastQuery
// objects

class BlastQueries
{
Expand All @@ -43,7 +39,6 @@ class BlastQueries

BlastQuery * getQueryFromName(QString queryName);

void createTempQueryFiles();
void addQuery(BlastQuery * newQuery);
QString renameQuery(BlastQuery * newQuery, QString newName);
void clearAllQueries();
Expand All @@ -60,16 +55,7 @@ class BlastQueries
std::vector<QColor> m_presetColours;

private:
QSharedPointer<QFile> m_tempNuclFile;
QSharedPointer<QFile> m_tempProtFile;

void deleteTempFiles();
void updateTempFiles();
bool tempNuclFileExists();
bool tempProtFileExists();
void writeTempFile(QSharedPointer<QFile> file, QuerySequenceType sequenceType);
QString getUniqueName(QString name);

};

#endif // BLASTQUERIES_H
17 changes: 5 additions & 12 deletions blast/blastsearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@
#include <QApplication>
#include <cmath>

BlastSearch::BlastSearch() :
m_blastQueries(), m_tempDirectory("bandage_temp/")
{
}
BlastSearch::BlastSearch(const QDir &workDir) :
m_blastQueries(), m_tempDirectory(workDir.filePath("bandage_temp_XXXXXX")) {}

BlastSearch::~BlastSearch()
{
cleanUp();
clearBlastHits();
m_blastQueries.clearAllQueries();
}

void BlastSearch::clearBlastHits()
Expand Down Expand Up @@ -244,13 +243,7 @@ void BlastSearch::clearSomeQueries(std::vector<BlastQuery *> queriesToRemove)

void BlastSearch::emptyTempDirectory() const
{
//Safety checks
if (g_blastSearch->m_tempDirectory == "")
return;
if (!g_blastSearch->m_tempDirectory.contains("bandage_temp"))
return;

QDir tempDirectory(m_tempDirectory);
QDir tempDirectory(m_tempDirectory.path());
tempDirectory.setNameFilters(QStringList() << "*.*");
tempDirectory.setFilter(QDir::Files);
foreach(QString dirFile, tempDirectory.entryList())
Expand Down
12 changes: 6 additions & 6 deletions blast/blastsearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@

#include "blasthit.h"
#include "blastqueries.h"
#include "program/scinot.h"

#include <QProcess>
#include <QString>
#include <QList>
#include <QSharedPointer>
#include <QDir>
#include <QTemporaryDir>

#include <vector>

//This is a class to hold all BLAST search related stuff.
//An instance of it is made available to the whole program
//as a global.

class QProcess;

class BlastSearch
{
public:
BlastSearch();
explicit BlastSearch(const QDir &workDir = QDir::temp());
~BlastSearch();

BlastQueries m_blastQueries;
Expand All @@ -46,7 +46,7 @@ class BlastSearch
bool m_cancelRunBlastSearch{};
QProcess *m_makeblastdb{};
QProcess *m_blast{};
QString m_tempDirectory;
QTemporaryDir m_tempDirectory;
std::vector<std::shared_ptr<BlastHit>> m_allHits;

static QString getNodeNameFromString(const QString& nodeString);
Expand Down
9 changes: 6 additions & 3 deletions blast/buildblastdatabaseworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ void BuildBlastDatabaseWorker::buildBlastDatabase()
{
g_blastSearch->m_cancelBuildBlastDatabase = false;

QFile file(g_blastSearch->m_tempDirectory + "all_nodes.fasta");
file.open(QIODevice::WriteOnly | QIODevice::Text);
QFile file(g_blastSearch->m_tempDirectory.filePath("all_nodes.fasta"));
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
emit finishedBuild("Failed to open: " + file.fileName());
return;
}
QTextStream out(&file);

for (auto &entry : g_assemblyGraph->m_deBruijnGraphNodes) {
Expand Down Expand Up @@ -72,7 +75,7 @@ void BuildBlastDatabaseWorker::buildBlastDatabase()
}

QStringList makeBlastdbOptions;
makeBlastdbOptions << "-in" << (g_blastSearch->m_tempDirectory + "all_nodes.fasta")
makeBlastdbOptions << "-in" << (g_blastSearch->m_tempDirectory.filePath("all_nodes.fasta"))
<< "-dbtype" << "nucl";

g_blastSearch->m_makeblastdb = new QProcess();
Expand Down
34 changes: 29 additions & 5 deletions blast/runblastsearchworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "program/globals.h"
#include "program/settings.h"

#include <QTemporaryFile>

RunBlastSearchWorker::RunBlastSearchWorker(QString blastnCommand, QString tblastnCommand, QString parameters) :
m_blastnCommand(blastnCommand), m_tblastnCommand(tblastnCommand), m_parameters(parameters)
{
Expand Down Expand Up @@ -64,14 +66,36 @@ void RunBlastSearchWorker::runBlastSearch()
emit finishedSearch(m_error);
}

static void writeQueryFile(QFile *file,
const BlastQueries &queries,
QuerySequenceType sequenceType) {

QString RunBlastSearchWorker::runOneBlastSearch(QuerySequenceType sequenceType, bool * success)
{
QTextStream out(file);
for (const auto *query: queries.m_queries) {
if (query->getSequenceType() != sequenceType)
continue;

out << '>' << query->getName() << '\n'
<< query->getSequence()
<< '\n';
}
}

QString RunBlastSearchWorker::runOneBlastSearch(QuerySequenceType sequenceType, bool * success) {
QStringList blastOptions;

blastOptions << "-query" << (g_blastSearch-> m_tempDirectory +
(sequenceType == NUCLEOTIDE ? "nucl_queries.fasta" : "prot_queries.fasta"))
<< "-db" << (g_blastSearch->m_tempDirectory + "all_nodes.fasta")
QTemporaryFile tmpFile(g_blastSearch->m_tempDirectory.filePath(sequenceType == NUCLEOTIDE ?
"nucl_queries.XXXXXX.fasta" : "prot_queries.XXXXXX.fasta"));
if (!tmpFile.open()) {
m_error = "Failed to create temporary query file";
*success = false;
return "";
}

writeQueryFile(&tmpFile, g_blastSearch->m_blastQueries, sequenceType);

blastOptions << "-query" << tmpFile.fileName()
<< "-db" << (g_blastSearch->m_tempDirectory.filePath("all_nodes.fasta"))
<< "-outfmt" << "6";
blastOptions << m_parameters.split(" ", Qt::SkipEmptyParts);

Expand Down
22 changes: 0 additions & 22 deletions command_line/commoncommandlinefunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,28 +1189,6 @@ void getCommonHelp(QStringList * text)



bool 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(QApplication::applicationPid()) + "/";

if (!QDir().mkdir(g_blastSearch->m_tempDirectory))
return false;

g_blastSearch->m_blastQueries.createTempQueryFiles();
return true;
}

void 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 getElapsedTime(const QDateTime& start, const QDateTime& end)
{
Expand Down
3 changes: 0 additions & 3 deletions command_line/commoncommandlinefunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ void parseSettings(QStringList arguments);
void getCommonHelp(QStringList * text);
void getSettingsUsage(QStringList *text);

bool createBlastTempDirectory();
void deleteBlastTempDirectory();

QString getElapsedTime(const QDateTime& start, const QDateTime& end);

void getGraphScopeOptions(QStringList * text);
Expand Down
6 changes: 2 additions & 4 deletions command_line/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ int bandageImage(QStringList arguments)

if (blastUsed)
{
if (!createBlastTempDirectory())
if (!g_blastSearch->m_tempDirectory.isValid())
{
err << "Error creating temporary directory for BLAST files" << Qt::endl;
err << "Error creating temporary directory for BLAST files: " << g_blastSearch->m_tempDirectory.errorString() << Qt::endl;
return 1;
}

Expand Down Expand Up @@ -227,8 +227,6 @@ int bandageImage(QStringList arguments)
else
returnCode = 0;

if (blastUsed)
deleteBlastTempDirectory();

return returnCode;
}
Expand Down
5 changes: 2 additions & 3 deletions command_line/querypaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ int bandageQueryPaths(QStringList arguments)
return 1;
out << "done" << Qt::endl;

if (!createBlastTempDirectory())
if (!g_blastSearch->m_tempDirectory.isValid())
{
err << "Error creating temporary directory for BLAST files" << Qt::endl;
err << "Error creating temporary directory for BLAST files: " << g_blastSearch->m_tempDirectory.errorString() << Qt::endl;
return 1;
}

Expand Down Expand Up @@ -261,7 +261,6 @@ int bandageQueryPaths(QStringList arguments)

out << Qt::endl << "Elapsed time: " << getElapsedTime(startTime, QDateTime::currentDateTime()) << Qt::endl;

deleteBlastTempDirectory();
return 0;
}

Expand Down
Loading