//Copyright 2017 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 "blastqueries.h" #include "../program/globals.h" #include "../program/settings.h" #include #include "blastsearch.h" #include "../program/memory.h" BlastQueries::BlastQueries() : m_tempNuclFile(0), m_tempProtFile(0) { 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) { if (m_queries[i]->getName() == queryName) return m_queries[i]; } return 0; } void BlastQueries::addQuery(BlastQuery * newQuery) { newQuery->setName(getUniqueName(newQuery->getName())); //Give the new query a colour int colourIndex = int(m_queries.size()); colourIndex %= m_presetColours.size(); newQuery->setColour(m_presetColours[colourIndex]); m_queries.push_back(newQuery); updateTempFiles(); } //This function renames the query. It returns the name given, because that //might not be exactly the same as the name passed to the function if it //wasn't unique. QString BlastQueries::renameQuery(BlastQuery * newQuery, QString newName) { newQuery->setName(getUniqueName(newName)); updateTempFiles(); return newQuery->getName(); } //This function looks at the name, and if it is not unique, it adds a suffix //to make it unique. Also make sure it's not "all" or "none", as those will //conflict with viewing all queries at once or no queries. QString BlastQueries::getUniqueName(QString name) { //If the query name ends in a semicolon, remove it. Ending semicolons //mess with BLAST. if (name.endsWith(';')) name.chop(1); //The name can't be empty. if (name == "") name = g_settings->unnamedQueryDefaultName; int queryNumber = 2; QString finalName = name; while (getQueryFromName(finalName) != 0 || finalName == "all" || finalName == "none") finalName = name + "_" + QString::number(queryNumber++); return finalName; } 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 queriesToRemove) { for (size_t i = 0; i < queriesToRemove.size(); ++i) { 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 file, SequenceType 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) m_queries[i]->setAsSearchedFor(); } void BlastQueries::clearSearchResults() { for (size_t i = 0; i < m_queries.size(); ++i) m_queries[i]->clearSearchResults(); } int BlastQueries::getQueryCount() { return int(m_queries.size()); } int BlastQueries::getQueryCountWithAtLeastOnePath() { int count = 0; for (size_t i = 0; i < m_queries.size(); ++i) { if (m_queries[i]->getPathCount() > 0) ++count; } return count; } int BlastQueries::getQueryPathCount() { int count = 0; for (size_t i = 0; i < m_queries.size(); ++i) count += m_queries[i]->getPathCount(); return count; } int BlastQueries::getQueryCount(SequenceType sequenceType) { int count = 0; for (size_t i = 0; i < m_queries.size(); ++i) { if (m_queries[i]->getSequenceType() == sequenceType) ++count; } 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. bool BlastQueries::isQueryPresent(BlastQuery * query) { for (size_t i = 0; i < m_queries.size(); ++i) { if (query == m_queries[i]) return true; } return false; } //This function looks at each BLAST query and tries to find a path through //the graph which covers the maximal amount of the query. void BlastQueries::findQueryPaths() { for (size_t i = 0; i < m_queries.size(); ++i) m_queries[i]->findQueryPaths(); }