Repeating a search from a Mascot results file.
#include "msparser.hpp"
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
using namespace matrix_science;
static bool repeatSearch(const char * filename);
static int usage(const char * progName);
static void compareResults(ms_mascotresfile & originalSearch,
const char * repeatedSearchFileName);
int main(int argc, char * argv[])
{
if (argc == 2)
return repeatSearch(argv[1]);
else
return usage(argv[0]);
}
static bool repeatSearch(const char * filename)
{
bool success = false;
ms_mascotresfile file(filename);
if (file.isValid())
{
std::ostringstream s;
s << "----12345\n"
<< "Content-Disposition: form-data; name=\"QUE\""
<< std::endl << std::endl;
int count = 1;
std::string key = file.enumerateSectionKeys(ms_mascotresfile::SEC_PARAMETERS,
count);
while (!key.empty())
{
std::string val = file.getSectionValueStr(ms_mascotresfile::SEC_PARAMETERS,
key.c_str());
if (!val.empty() && key != "INTERMEDIATE" && key != "RULES" && key != "SEARCH")
s << key << "=" << val << std::endl;
key = file.enumerateSectionKeys(ms_mascotresfile::SEC_PARAMETERS, ++count);
}
s << "SEARCH=SQ" << std::endl;
s << "INTERMEDIATE=" << filename << std::endl;
for (int q=1; q <= file.getNumQueries(); q++)
s << file.getRepeatSearchString(q) << std::endl;
s << "----12345--\n";
FILE * f = popen("./nph-mascot.exe 4 -commandline > tmp.txt", "w");
if (f)
{
fwrite(s.str().c_str(), s.str().length(), 1, f);
pclose(f);
if ((f = fopen("tmp.txt", "r")) != 0)
{
char buf[1000];
while (fgets(buf, sizeof(buf), f))
{
if (strstr(buf, "SUCCESS") && fgets(buf, sizeof(buf), f))
{
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
compareResults(file, buf);
success = true;
}
else if (strstr(buf, "ERROR"))
{
std::cout << "Search failed: " << buf;
while (fgets(buf, sizeof(buf), f))
{
std::cout << buf;
}
}
}
fclose(f);
}
else
{
std::cout << "Can't open tmp file. \n";
}
}
else
{
std::cout << "Cannot open pipe to nph-mascot.exe to repeat search for file "
<< filename << std::endl;
}
}
else
{
std::cout << "Cannot open results file " << filename
<< " " << file.getLastErrorString() << std::endl;
}
return success;
}
static void compareResults(ms_mascotresfile & originalSearch,
const char * repeatedSearchFileName)
{
ms_mascotresfile repeatedSearch(repeatedSearchFileName);
bool anyReport = false;
if (repeatedSearch.isValid())
{
if (originalSearch.anyPMF())
{
ms_proteinsummary originalResults(originalSearch);
ms_proteinsummary repeatedResults(repeatedSearch);
ms_protein * originalProt = originalResults.getHit(1);
ms_protein * repeatedProt = repeatedResults.getHit(1);
if (originalProt && repeatedProt)
{
double diff = repeatedProt->getScore()-originalProt->getScore();
if (diff > 10.0)
{
std::cout << "Protein score is "
<< diff
<< " higher for search "
<< originalSearch.getFileName()
<< " than "
<< repeatedSearchFileName
<< std::endl;
anyReport = true;
}
}
}
else
{
ms_peptidesummary originalResults(originalSearch);
ms_peptidesummary repeatedResults(repeatedSearch);
for (int q=1; q <= originalSearch.getNumQueries(); q++)
{
ms_peptide * pepOriginal, *pepRepeated;
if (originalResults.getPeptide(q, 1, pepOriginal)
&& repeatedResults.getPeptide(q, 1, pepRepeated))
{
double diff = pepRepeated->getIonsScore()
- pepOriginal->getIonsScore();
if (diff > 10.0)
{
std::cout << "Query " << q
<< "has score " << diff
<< " higher for search "
<< originalSearch.getFileName()
<< " than "
<< repeatedSearchFileName
<< std::endl;
anyReport = true;
}
}
}
}
if (!anyReport)
std::cout << "Similar results for "
<< originalSearch.getFileName()
<< " and "
<< repeatedSearchFileName
<< std::endl;
}
else
std::cout << "Invalid repeat search "
<< repeatedSearch.getLastErrorString();
}
static int usage(const char * progName)
{
std::cout << progName << " results_file " << std::endl
<< "Given an mascot results file name, repeat the search "
<< "against the same data" << std::endl
<< " results_file is a full path to a results file" << std::endl
<< "The program must be run from the mascot cgi directory"
<< std::endl;
return 1;
}