bool JavaInfo::canRun(const String& java_executable, bool verbose_on_error) { QProcess qp; qp.start(java_executable.toQString(), QStringList() << "-version", QIODevice::ReadOnly); bool success = qp.waitForFinished(); if (!success && verbose_on_error) { LOG_ERROR << "Java-Check:\n"; if (qp.error() == QProcess::Timedout) { LOG_ERROR << " Java was found at '" << java_executable << "' but the process timed out (can happen on very busy systems).\n" << " Please free some resources or if you want to run the TOPP tool nevertheless set the TOPP tools 'force' flag in order to avoid this check." << std::endl; } else if (qp.error() == QProcess::FailedToStart) { LOG_ERROR << " Java not found at '" << java_executable << "'!\n" << " Make sure Java is installed and this location is correct.\n"; if (QDir::isRelativePath(java_executable.toQString())) { static String path; if (path.empty()) { path = getenv("PATH"); } LOG_ERROR << " You might need to add the Java binary to your PATH variable\n" << " or use an absolute path+filename pointing to Java.\n" << " The current SYSTEM PATH is: '" << path << "'.\n\n" #ifdef __APPLE__ << " On MacOSX, application bundles change the system PATH; Open your executable (e.g. KNIME/TOPPAS/TOPPView) from within the bundle (e.g. ./TOPPAS.app/Contents/MacOS/TOPPAS) to preserve the system PATH or use an absolute path to Java!\n" #endif << std::endl; } else { LOG_ERROR << " You gave an absolute path to Java. Please check if it's correct.\n" << " You can also try 'java' if your system path is correctly configured.\n" << std::endl; } } else { LOG_ERROR << " Error executing '" << java_executable << "'!\n" << " Error description: '" << qp.errorString().toStdString() << "'.\n"; } } return success; }
void IDEvaluationBase::showLogMessage_(IDEvaluationBase::LogState state, const String& heading, const String& body) { //Compose current time string DateTime d = DateTime::now(); String state_string; switch (state) { case LS_NOTICE: state_string = "NOTICE"; break; case LS_WARNING: state_string = "WARNING"; break; case LS_ERROR: state_string = "ERROR"; break; } //update log log_->append("=============================================================================="); log_->append((d.getTime() + " " + state_string + ": " + heading).toQString()); log_->append(body.toQString()); //show log tool window qobject_cast<QWidget*>(log_->parent())->show(); log_->moveCursor(QTextCursor::End); }
bool File::removeDirRecursively(const String& dir_name) { bool fail = false; QString path = dir_name.toQString(); QDir dir(path); QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); foreach(const QString &file_name, files) { if (!dir.remove(file_name)) { LOG_WARN << "Could not remove file " << String(file_name) << "!" << std::endl; fail = true; } } QStringList contained_dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); foreach(const QString &contained_dir, contained_dirs) { if (!removeDirRecursively(path + QDir::separator() + contained_dir)) { fail = true; } } QDir parent_dir(path); if (parent_dir.cdUp()) { if (!parent_dir.rmdir(path)) { std::cerr << "Could not remove directory " << String(dir.dirName()) << "!" << std::endl; fail = true; } } return !fail; }
QApplicationTOPP::QApplicationTOPP(int& argc, char** argv) : QApplication(argc, argv) { // register GUI ProgressLogger that can be used in GUI tools Factory<ProgressLogger::ProgressLoggerImpl>::registerProduct(GUIProgressLoggerImpl::getProductName(), &GUIProgressLoggerImpl::create); // set plastique style unless windows / mac style is available if (QStyleFactory::keys().contains("windowsxp", Qt::CaseInsensitive)) { this->setStyle("windowsxp"); } else if (QStyleFactory::keys().contains("macintosh", Qt::CaseInsensitive)) { this->setStyle("macintosh"); } else if (QStyleFactory::keys().contains("plastique", Qt::CaseInsensitive)) { this->setStyle("plastique"); } // customize look and feel via Qt style sheets String filename = File::find("GUISTYLE/qtStyleSheet.qss"); QFile fh(filename.toQString()); fh.open(QFile::ReadOnly); QString style_string = QLatin1String(fh.readAll()); //std::cerr << "Stylesheet content: " << style_string.toStdString() << "\n\n\n"; this->setStyleSheet(style_string); }
Param File::getSystemParameters() { String filename = String(QDir::homePath()) + "/.OpenMS/OpenMS.ini"; Param p; if (!File::readable(filename)) // create file { p = getSystemParameterDefaults_(); String dirname = String(QDir::homePath()) + "/.OpenMS"; QDir dir(dirname.toQString()); if (!dir.exists()) { if (!File::writable(dirname)) { LOG_WARN << "Warning: Cannot create folder '.OpenMS' in user home directory. Please check your environment!" << std::endl; LOG_WARN << " Home directory determined is: " << QDir::homePath().toStdString() << "." << std::endl; return p; } dir.mkpath("."); } if (!File::writable(filename)) { LOG_WARN << "Warning: Cannot create '.OpenMS/OpenMS.ini' in user home directory. Please check your environment!" << std::endl; LOG_WARN << " Home directory determined is: " << QDir::homePath().toStdString() << "." << std::endl; return p; } ParamXMLFile paramFile; paramFile.store(filename, p); } else { ParamXMLFile paramFile; paramFile.load(filename, p); // check version if (!p.exists("version") || (p.getValue("version") != VersionInfo::getVersion())) { if (!p.exists("version")) { LOG_WARN << "Broken file '" << filename << "' discovered. The 'version' tag is missing." << std::endl; } else // old version { LOG_WARN << "File '" << filename << "' is deprecated." << std::endl; } LOG_WARN << "Updating missing/wrong entries in '" << filename << "' with defaults!" << std::endl; Param p_new = getSystemParameterDefaults_(); p.setValue("version", VersionInfo::getVersion()); // update old version, such that p_new:version does not get overwritten during update() p_new.update(p); paramFile.store(filename, p_new); } } return p; }
String FileHandler::computeFileHash_(const String& filename) const { QCryptographicHash crypto(QCryptographicHash::Sha1); QFile file(filename.toQString()); file.open(QFile::ReadOnly); while (!file.atEnd()) { crypto.addData(file.read(8192)); } return String((QString)crypto.result().toHex()); }
QString ExpressionParser::convertFieldName(Object obj, QString fieldName) const { String className = obj.getClass().getName(); try { RSClass* rsc = rscm->getRSClass(className.toQString()); return QString::fromStdString(rsc->getFieldName(fieldName)); } catch (jace::MappingUnavailableException& ex) { // No mapping exists, so we assume the class is not obfuscated. // In that case we can just return the argument field name. return fieldName; } }
bool File::writable(const String& file) { QFileInfo fi(file.toQString()); bool tmp = false; if (fi.exists()) { tmp = fi.isWritable(); } else { QFile f; f.setFileName(file.toQString()); f.open(QIODevice::WriteOnly); tmp = f.isWritable(); f.remove(); } return tmp; }
TOPPASWidget::TOPPASWidget(const Param & /*preferences*/, QWidget * parent, const String & tmp_path) : QGraphicsView(parent), scene_(new TOPPASScene(this, tmp_path.toQString())) { setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_AlwaysShowToolTips); setRenderHint(QPainter::Antialiasing); setScene(scene_); setAcceptDrops(true); setDragMode(QGraphicsView::ScrollHandDrag); setFocusPolicy(Qt::StrongFocus); }
void DocumentIdentifier::setLoadedFilePath(const String & file_name) { // only change the path if we need to, otherwise low and upper case might be altered by Qt, making comparison in tests more tricky // i.e., a call to this will report unmatched strings // FeatureXMLFile().load(OPENMS_GET_TEST_DATA_PATH("FeatureXMLFile_1.featureXML"), e); // TEST_STRING_EQUAL(e.getLoadedFilePath(), OPENMS_GET_TEST_DATA_PATH("FeatureXMLFile_1.featureXML")); if (QDir::isRelativePath(file_name.toQString())) { file_path_ = File::absolutePath(file_name); } else { file_path_ = file_name; } }
bool File::fileList(const String& dir, const String& file_pattern, StringList& output, bool full_path) { QDir d(dir.toQString(), file_pattern.toQString(), QDir::Name, QDir::Files); QFileInfoList list = d.entryInfoList(); //clear and check if empty output.clear(); if (list.empty()) { return false; } //resize output output.resize(list.size()); //fill output UInt i = 0; for (QFileInfoList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) { output[i++] = full_path ? it->filePath() : it->fileName(); } return true; }
/* @brief: Catch exceptions in Qt GUI applications, preventing ungraceful exit Re-implementing QApplication::notify() to catch exception thrown in event handlers (which is most likely OpenMS code). */ bool QApplicationTOPP::notify(QObject* rec, QEvent* ev) { // this is called quite often (whenever a signal is fired), so mind performance! try { return QApplication::notify(rec, ev); } catch (Exception::BaseException& e) { String msg = String("Caught exception: '") + e.getName() + "' with message '" + e.getMessage() + "'"; LOG_ERROR << msg << "\n"; QMessageBox::warning(0, QString("Unexpected error occurred"), msg.toQString()); return false; // we could also exit() here... but no for now } return false; // never reached, so return value does not matter }
String File::find(const String& filename, StringList directories) { String filename_new = filename; // empty string cannot be found, so throw Exception. // The code below would return success on empty string, since a path is prepended and thus the location exists if (filename_new.trim().empty()) throw Exception::FileNotFound(__FILE__, __LINE__, __PRETTY_FUNCTION__, filename); //add data dir in OpenMS data path directories.push_back(getOpenMSDataPath()); //add path suffix to all specified directories String path = File::path(filename); if (path != "") { for (StringList::iterator it = directories.begin(); it != directories.end(); ++it) { it->ensureLastChar('/'); *it += path; } filename_new = File::basename(filename); } //look up file for (StringList::const_iterator it = directories.begin(); it != directories.end(); ++it) { String loc = *it; loc.ensureLastChar('/'); loc = loc + filename_new; if (exists(loc)) { return String(QDir::cleanPath(loc.toQString())); } } //if the file was not found, throw an exception throw Exception::FileNotFound(__FILE__, __LINE__, __PRETTY_FUNCTION__, filename); //this is never reached, but needs to be there to avoid compiler warnings return ""; }
void updateTOPPAS(const String& infile, const String& outfile) { Int this_instance = getIntOption_("instance"); INIUpdater updater; String tmp_ini_file = File::getTempDirectory() + "/" + File::getUniqueName() + "_INIUpdater.ini"; tmp_files_.push_back(tmp_ini_file); String path = File::getExecutablePath(); ParamXMLFile paramFile; Param p; paramFile.load(infile, p); // get version of TOPPAS file String version = "Unknown"; if (!p.exists("info:version")) { writeLog_("No OpenMS version information found in file " + infile + "! Assuming OpenMS 1.8 and below."); version = "1.8.0"; } else { version = p.getValue("info:version"); // TODO: return on newer version?! } Int vertices = p.getValue("info:num_vertices"); // update sections writeDebug_("#Vertices: " + String(vertices), 1); bool update_success = true; for (Int v = 0; v < vertices; ++v) { String sec_inst = "vertices:" + String(v) + ":"; // check for default instance if (!p.exists(sec_inst + "toppas_type")) { writeLog_("Update for file " + infile + " failed because the vertex #" + String(v) + " does not have a 'toppas_type' node. Check INI file for corruption!"); update_success = false; break; } if (p.getValue(sec_inst + "toppas_type") != "tool") // not a tool (but input/output/merge node) { continue; } if (!p.exists(sec_inst + "tool_name")) { writeLog_("Update for file " + infile + " failed because the vertex #" + String(v) + " does not have a 'tool_name' node. Check INI file for corruption!"); update_success = false; break; } String old_name = p.getValue(sec_inst + "tool_name"); String new_tool; String ttype; // find mapping to new tool (might be the same name) if (p.exists(sec_inst + "tool_type")) ttype = p.getValue(sec_inst + "tool_type"); if (!updater.getNewToolName(old_name, ttype, new_tool)) { String type_text = ((ttype == "") ? "" : " with type '" + ttype + "' "); writeLog_("Update for file " + infile + " failed because the tool '" + old_name + "'" + type_text + "is unknown. TOPPAS file seems to be corrupted!"); update_success = false; break; } // set new tool name p.setValue(sec_inst + "tool_name", new_tool); // delete TOPPAS type if (new_tool != "GenericWrapper") { p.setValue(sec_inst + "tool_type", ""); } // get defaults of new tool by calling it QProcess pr; QStringList arguments; arguments << "-write_ini"; arguments << tmp_ini_file.toQString(); arguments << "-instance"; arguments << String(this_instance).toQString(); pr.start((path + "/" + new_tool).toQString(), arguments); if (!pr.waitForFinished(-1)) { writeLog_("Update for file " + infile + " failed because the tool '" + new_tool + "' returned with an error! Check if the tool works properly."); update_success = false; break; } // update defaults with old values Param new_param; paramFile.load(tmp_ini_file, new_param); new_param = new_param.copy(new_tool + ":1", true); Param old_param = p.copy(sec_inst + "parameters", true); new_param.update(old_param); // push back changes p.remove(sec_inst + "parameters:"); p.insert(sec_inst + "parameters", new_param); } if (!update_success) { failed_.push_back(infile); return; } paramFile.store(tmp_ini_file, p); // update internal structure (e.g. edges format changed from 1.8 to 1.9) int argc = 1; const char* c = "IniUpdater"; const char** argv = &c; QApplication app(argc, const_cast<char**>(argv), false); String tmp_dir = File::getTempDirectory() + "/" + File::getUniqueName(); QDir d; d.mkpath(tmp_dir.toQString()); TOPPASScene ts(nullptr, tmp_dir.toQString(), false); paramFile.store(tmp_ini_file, p); ts.load(tmp_ini_file); ts.store(tmp_ini_file); paramFile.load(tmp_ini_file, p); // STORE if (outfile.empty()) // create a backup { QFileInfo fi(infile.toQString()); String new_name = String(fi.path()) + "/" + fi.completeBaseName() + "_v" + version + ".toppas"; QFile::rename(infile.toQString(), new_name.toQString()); // write new file paramFile.store(infile, p); } else { paramFile.store(outfile, p); } }
void updateINI(const String& infile, const String& outfile) { Int this_instance = getIntOption_("instance"); INIUpdater updater; String tmp_ini_file = File::getTempDirectory() + "/" + File::getUniqueName() + "_INIUpdater.ini"; tmp_files_.push_back(tmp_ini_file); String path = File::getExecutablePath(); Param p; ParamXMLFile paramFile; paramFile.load(infile, p); // get sections (usually there is only one - or the user has merged INI files manually) StringList sections = updater.getToolNamesFromINI(p); if (sections.empty()) { writeLog_("Update for file " + infile + " failed because tool section does not exist. Check INI file for corruption!"); failed_.push_back(infile); return; } // get version of first section String version_old = "Unknown"; if (!p.exists(sections[0] + ":version")) { writeLog_("No OpenMS version information found in file " + infile + "! Cannot update!"); failed_.push_back(infile); return; } else { version_old = p.getValue(sections[0] + ":version"); // TODO: return on newer version?! } // update sections writeDebug_("Section names: " + ListUtils::concatenate(sections, ", "), 1); bool update_success = true; for (Size s = 0; s < sections.size(); ++s) { String sec_inst = sections[s] + ":" + String(this_instance) + ":"; // check for default instance if (!p.exists(sec_inst + "debug")) { writeLog_("Update for file '" + infile + "' failed because the instance section '" + sec_inst + "' does not exist. Use -instance or check INI file for corruption!"); update_success = false; break; } String new_tool; String ttype; // find mapping to new tool (might be the same name) if (p.exists(sec_inst + "type")) ttype = p.getValue(sec_inst + "type"); if (!updater.getNewToolName(sections[s], ttype, new_tool)) { String type_text = ((ttype == "") ? "" : " with type '" + ttype + "' "); writeLog_("Update for file '" + infile + "' failed because the tool '" + sections[s] + "'" + type_text + "is unknown. TOPPAS file seems to be corrupted!"); update_success = false; break; } // get defaults of new tool by calling it QProcess pr; QStringList arguments; arguments << "-write_ini"; arguments << tmp_ini_file.toQString(); arguments << "-instance"; arguments << String(this_instance).toQString(); pr.start((path + "/" + new_tool).toQString(), arguments); if (!pr.waitForFinished(-1)) { writeLog_("Update for file '" + infile + "' failed because the tool '" + new_tool + "' returned with an error! Check if the tool works properly."); update_success = false; break; } // update defaults with old values Param new_param; paramFile.load(tmp_ini_file, new_param); new_param = new_param.copy(new_tool, true); Param old_param = p.copy(sections[s], true); new_param.update(old_param); // push back changes p.remove(sections[s] + ":"); p.insert(new_tool, new_param); } if (!update_success) { failed_.push_back(infile); return; } // STORE if (outfile.empty()) // create a backup { QFileInfo fi(infile.toQString()); String backup_filename = String(fi.path()) + "/" + fi.completeBaseName() + "_v" + version_old + ".ini"; QFile::rename(infile.toQString(), backup_filename.toQString()); std::cout << "Backup of input file created: " << backup_filename << std::endl; // write updated/new file paramFile.store(infile, p); } else { paramFile.store(outfile, p); } }
bool File::exists(const String& file) { QFileInfo fi(file.toQString()); return fi.exists(); }
END_SECTION START_SECTION(([EXTRA] ~String())) delete s_ptr; END_SECTION START_SECTION((String(const QString &s))) QString qs("bla"); String s(qs); TEST_EQUAL(s=="bla",true) END_SECTION START_SECTION((QString toQString() const)) QString qs("bla"); String s("bla"); TEST_EQUAL(s.toQString()==qs,true) END_SECTION START_SECTION((String(const char* s, SizeType length))) String s("abcdedfg",5); TEST_EQUAL(s,"abcde") String s2("abcdedfg",0); TEST_EQUAL(s2,"") String s3("abcdedfg",8); TEST_EQUAL(s3,"abcdedfg") String s4("abcdedfg",15); TEST_EQUAL(s4,"abcdedfg") END_SECTION
ExitCodes main_(int, const char **) override { // find the config for the tool: String type = getStringOption_("type"); Param tool_param = this->getParam_(); // check required parameters (TOPPBase does not do this as we did not use registerInputFile_(...) etc) Param p = tool_param.copy("ETool:", true); for (Param::ParamIterator it = p.begin(); it != p.end(); ++it) { if ((it->tags).count("required") > 0) { String in = it->value.toString().trim(); // will give '[]' for empty lists (hack, but DataValue class does not offer a convenient query) if (in.empty() || in == "[]") // any required parameter should have a value { LOG_ERROR << "The INI-parameter 'ETool:" << it->name << "' is required, but was not given! Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } else if ((it->tags).count("input file") > 0) // any required input file should exist { StringList ifs; switch (it->value.valueType()) { case DataValue::STRING_VALUE: ifs.push_back(it->value); break; case DataValue::STRING_LIST: ifs = it->value; break; default: LOG_ERROR << "The INI-parameter 'ETool:" << it->name << "' is tagged as input file and thus must be a string! Aborting ..."; return wrapExit(ILLEGAL_PARAMETERS); } for (StringList::const_iterator itf = ifs.begin(); itf != ifs.end(); ++itf) { if (!File::exists(*itf)) { LOG_ERROR << "Input file '" << *itf << "' does not exist! Aborting ..."; return wrapExit(INPUT_FILE_NOT_FOUND); } } } } } Internal::ToolDescription gw = ToolHandler::getTOPPToolList(true)[toolName_()]; for (Size i = 0; i < gw.types.size(); ++i) { if (type == gw.types[i]) { tde_ = gw.external_details[i]; if (tde_.working_directory.trim() == "") tde_.working_directory = "."; break; } } LOG_INFO << tde_.text_startup << "\n"; String command_args = tde_.commandline; // check for double spaces and warn if (command_args.hasSubstring(" ")) { LOG_WARN << "Command line contains double spaces, which is not allowed. Condensing...\n"; while (command_args.hasSubstring(" ")) { command_args.substitute(" ", " "); } LOG_WARN << "result: " << command_args << std::endl; } writeDebug_("CommandLine from ttd (unprocessed): " + command_args, 1); // do "pre" moves (e.g. if the wrapped tool works on its data in-place (overwrites) it - we need to make a copy first // - we copy the file // - we set the value of the affected parameter to the copied tmp file, such that subsequent calls target the tmp file for (Size i = 0; i < tde_.tr_table.pre_moves.size(); ++i) { const Internal::FileMapping & fm = tde_.tr_table.pre_moves[i]; // find target param: Param p = tool_param.copy("ETool:", true); String target = fm.target; if (!p.exists(target)) throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Cannot find target parameter '" + target + "' being mapped from external tools output!", target); String tmp_location = fm.location; // fragment's placeholder evaluation: createFragment_(tmp_location, p); // check if target already exists: String target_file = (String)p.getValue(target); if (File::exists(tmp_location)) { if (!File::remove(tmp_location)) { LOG_ERROR << "While writing a tmp file: Cannot remove conflicting file '" + tmp_location + "'. Check permissions! Aborting ..."; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } // create the temp file tmp_location target_file writeDebug_(String("Copying '") + target_file + "' to '" + tmp_location + "'", 1); bool move_ok = QFile::copy(target_file.toQString(), tmp_location.toQString()); if (!move_ok) { LOG_ERROR << "Copying the target file '" + tmp_location + "' from '" + target_file + "' failed! Aborting ..."; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } // set the input file's value to the temp file tool_param.setValue(String("ETool:") + target, tmp_location); } ///// construct the command line: std::map<int, std::string> mappings; // remember the values for each mapping (for file_post substitution later on) // go through mappings (reverse because replacing %10 must come before %1): for (std::map<Int, String>::reverse_iterator it = tde_.tr_table.mapping.rbegin(); it != tde_.tr_table.mapping.rend(); ++it) { //std::cout << "mapping #" << it->first << "\n"; String fragment = it->second; // fragment's placeholder evaluation: createFragment_(fragment, tool_param.copy("ETool:", true)); // replace fragment in cl //std::cout << "replace : " << "%"+String(it->first) << " with '" << fragment << "\n"; command_args.substitute("%" + String(it->first), fragment); // cache mapping mappings[it->first] = fragment; } QProcess builder; builder.setProcessChannelMode(QProcess::MergedChannels); String call = tde_.path + " " + command_args; writeDebug_("call command: " + call, 1); builder.setWorkingDirectory(tde_.working_directory.toQString()); builder.start(call.toQString()); if (!builder.waitForFinished(-1) || builder.exitStatus() != 0 || builder.exitCode() != 0) { LOG_ERROR << ("External tool returned with exit code (" + String(builder.exitCode()) + "), exit status (" + String(builder.exitStatus()) + ") or timed out. Aborting ...\n"); LOG_ERROR << ("External tool output:\n" + String(QString(builder.readAll()))); return wrapExit(EXTERNAL_PROGRAM_ERROR); } LOG_INFO << ("External tool output:\n" + String(QString(builder.readAll()))); // post processing (file moving via 'file_post' command) for (Size i = 0; i < tde_.tr_table.post_moves.size(); ++i) { const Internal::FileMapping & fm = tde_.tr_table.post_moves[i]; // find target param: Param p = tool_param.copy("ETool:", true); String source_file = fm.location; // fragment's placeholder evaluation: createFragment_(source_file, p, mappings); // check if target already exists: String target = fm.target; if (!p.exists(target)) throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Cannot find target parameter '" + target + "' being mapped from external tools output!", target); String target_file = (String)p.getValue(target); if (target_file.trim().empty()) // if target was not given, we skip the copying step (usually for optional parameters) { LOG_INFO << "Parameter '" + target + "' not given. Skipping forwarding of files.\n"; continue; } // check if the target exists already (should not; if yes, delete it before overwriting it) if (File::exists(target_file)) { if (!File::remove(target_file)) { LOG_ERROR << "Cannot remove conflicting file '" + target_file + "'. Check permissions! Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } // move to target writeDebug_(String("<file_post>: moving '") + source_file + "' to '" + target_file + "'", 1); if (!File::exists(source_file)) { LOG_ERROR << "Moving the source file '" + source_file + "' during <file_post> failed, since it does not exist!\n" << "Make sure the external program created the file and its filename is either\n" << "unique or you only run one GenericWrapper at a time to avoid overwriting of files!\n" << "Ideally, (if the external program allows to specify output filenames directly) avoid <file_post>\n" << "in the TTD and request the output file directly. Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } bool move_ok = QFile::rename(source_file.toQString(), target_file.toQString()); if (!move_ok) { LOG_ERROR << "Moving the target file '" + target_file + "' from '" + source_file + "' failed!\n" << "This file exists, but is either currently open for writing or otherwise blocked (concurrent process?). Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } LOG_INFO << tde_.text_finish << "\n"; return wrapExit(EXECUTION_OK); }
TEST_STRING_EQUAL(File::removeExtension("/home/doe/file.txt"),"/home/doe/file") TEST_STRING_EQUAL(File::removeExtension("/home/doe/file.txt.tgz"),"/home/doe/file.txt") END_SECTION START_SECTION((static bool isDirectory(const String& path))) TEST_EQUAL(File::isDirectory(""),false) TEST_EQUAL(File::isDirectory("."),true) TEST_EQUAL(File::isDirectory(OPENMS_GET_TEST_DATA_PATH("")),true) TEST_EQUAL(File::isDirectory(OPENMS_GET_TEST_DATA_PATH("does_not_exists.txt")),false) TEST_EQUAL(File::isDirectory(OPENMS_GET_TEST_DATA_PATH("File_test_text.txt")),false) END_SECTION START_SECTION(static bool removeDirRecursively(const String &dir_name)) QDir d; String dirname = File::getTempDirectory() + "/" + File::getUniqueName() + "/" + File::getUniqueName() + "/"; TEST_EQUAL(d.mkpath(dirname.toQString()), TRUE); TextFile tf; tf.store(dirname + "test.txt"); TEST_EQUAL(File::removeDirRecursively(dirname), true) END_SECTION START_SECTION(static String getTempDirectory()) TEST_NOT_EQUAL(File::getTempDirectory(), String()) TEST_EQUAL(File::exists(File::getTempDirectory()), true) END_SECTION START_SECTION(static String getUserDirectory()) TEST_NOT_EQUAL(File::getUserDirectory(), String()) TEST_EQUAL(File::exists(File::getUserDirectory()), true) // set user directory to a path set by environmental variable and test that
bool File::isDirectory(const String& path) { QFileInfo fi(path.toQString()); return fi.isDir(); }
void createFragment_(String & fragment, const Param & param) { //std::cerr << "FRAGMENT: " << fragment << "\n\n"; // e.g.: -input %BASENAME[%%in].mzML // we have to make this little detour param -> vector<String> // to sort the param names by length, otherwise we have a // problem with parameter substitution // i.e., if A is a prefix of B and gets replaced first, the // suffix of B remains and will cause trouble! vector<String> param_names; param_names.reserve(param.size()); for (Param::ParamIterator it = param.begin(); it != param.end(); ++it) { param_names.push_back(it->name); } // sort by length std::sort(param_names.begin(), param_names.end(), reverseComparator(StringSizeLess())); // iterate through all input params and replace with values: SignedSize allowed_percent(0); // filenames might contain '%', which are allowed to remain there (and even must remain) for (vector<String>::iterator it = param_names.begin(); it != param_names.end(); ++it) { if (!fragment.hasSubstring("%%" + *it)) continue; String s_new = paramToString_(param.getEntry(*it)); allowed_percent += s_new.length() - String(s_new).substitute("%", "").length(); //std::cerr << "IN: " << s_new << "(" << allowed_percent << "\n"; fragment.substitute("%%" + *it, s_new); } if (fragment.hasSubstring("%%")) throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Invalid '%%' found in '" + fragment + "' after replacing all parameters!", fragment); // %TMP replace: fragment.substitute("%TMP", File::getTempDirectory()); // %RND replace: fragment.substitute("%RND", String(UniqueIdGenerator::getUniqueId())); // %WORKINGDIR replace: fragment.substitute("%WORKINGDIR", tde_.working_directory); // %DIR% replace { QRegExp rx("%DIR\\[(.*)\\]"); rx.setMinimal(true); int pos = 0; QString t_tmp = fragment.toQString(); //std::cout << "fragment is:" << fragment << std::endl; while ((pos = rx.indexIn(t_tmp, pos)) != -1) { String value = rx.cap(1); // param name (hopefully) // replace in fragment: QFileInfo qfi(value.toQString()); //std::cout << "match @ " << pos << " " << value << " --> " << qfi.canonicalPath() << "\n"; t_tmp = t_tmp.replace(String("%DIR[" + value + "]").toQString(), qfi.canonicalPath()); } fragment = String(t_tmp); //std::cout << "NEW fragment is:" << fragment << std::endl; } // %BASENAME% replace { QRegExp rx("%BASENAME\\[(.*)\\]"); rx.setMinimal(true); int pos = 0, count = 0; QString t_tmp = fragment.toQString(); while ((pos = rx.indexIn(t_tmp, pos)) != -1) { //std::cout << "match @ " << pos << "\n"; String value = rx.cap(1); // param name (hopefully) // replace in fragment: QFileInfo qfi(value.toQString()); //std::cout << "match @ " << pos << " " << value << " --> " << qfi.completeBaseName() << "\n"; t_tmp = t_tmp.replace(String("%BASENAME[" + value + "]").toQString(), qfi.completeBaseName()); ++count; } // update expected count of valid '%' allowed_percent -= (fragment.length() - String(fragment).substitute("%", "").length()) // original # of % - (t_tmp.length() - String(t_tmp).substitute("%", "").length()) // new # of % - count; // expected # of % due to %BASENAME fragment = String(t_tmp); } SignedSize diff = (fragment.length() - String(fragment).substitute("%", "").length()) - allowed_percent; //std::cerr << "allowed: " << allowed_percent << "\n" << "diff: " << diff << " in: " << fragment << "\n"; if (diff > 0) throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Mapping still contains '%' after substitution! Did you use % instead of %%?", fragment); else if (diff < 0) throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Error: '%' from a filename where accidentally considered command tags! " "This is a bug! Remove '%' from input filesnames to fix, but please report this as well!", fragment); //std::cout << fragment << "'\n"; }
ExitCodes main_(Int, const char**) override { //------------------------------------------------------------- // (1) variables //------------------------------------------------------------- InspectInfile inspect_infile; InspectOutfile inspect_outfile; vector<String> trie_database_filenames, sequence_database_filenames, index_filenames; String string_buffer, trie_database_filename, index_filename, snd_trie_database_filename, snd_index_filename, inspect_logfile, logfile, inspect_directory, temp_data_directory, snd_trie_database, snd_trie_database_directory, output_filename, inspect_input_filename, inspect_output_filename, modifications_filename, isotope_filename; bool inspect_in(false), inspect_out(false), blind_only(false), blind(false), monoisotopic(false); double p_value_threshold(1.0); char separator = '/'; ContactPerson contact_person; ExitCodes exit_code = EXECUTION_OK; // filename and tag: file has to: 1 - exist 2 - be readable 4 - writable 8 - be deleted afterwards map<String, Size> files; Size const exist(1), readable(2), writable(4), delete_afterwards(8); //------------------------------------------------------------- // (2) parsing and checking parameters //------------------------------------------------------------- modifications_filename = getStringOption_("modifications_xml_file"); if (getFlag_("list_modifications")) { if (modifications_filename.empty()) { writeLog_("No modifications XML file given. Aborting!"); return INPUT_FILE_NOT_FOUND; } if (!File::readable(modifications_filename)) { writeLog_("Modifications XML file is not readable. Aborting!"); return INPUT_FILE_NOT_READABLE; } map<String, pair<String, String> > PTM_informations; try { PTMXMLFile().load(modifications_filename, PTM_informations); } catch (Exception::ParseError& pe) { writeLog_(pe.getMessage()); return PARSE_ERROR; } // output the information stringstream PTM_info; String::size_type max_name_length(4), max_composition_length(11), max_amino_acids_length(11); for (map<String, pair<String, String> >::const_iterator mod_it = PTM_informations.begin(); mod_it != PTM_informations.end(); ++mod_it) { max_name_length = max(max_name_length, mod_it->first.length()); max_composition_length = max(max_composition_length, mod_it->second.first.length()); max_amino_acids_length = max(max_amino_acids_length, mod_it->second.second.length()); } PTM_info << "name" << String(max_name_length - 4, ' ') << "\t" << "composition" << String(max_composition_length - 11, ' ') << "\t" << "amino_acids" << String(max_amino_acids_length - 11, ' ') << endl; for (map<String, pair<String, String> >::const_iterator mod_it = PTM_informations.begin(); mod_it != PTM_informations.end(); ++mod_it) { PTM_info << mod_it->first << String(max_name_length - mod_it->first.length(), ' ') << "\t" << mod_it->second.first << String(max_composition_length - mod_it->second.first.length(), ' ') << "\t" << mod_it->second.second << String(max_amino_acids_length - mod_it->second.second.length(), ' ') << endl; } std::cout << PTM_info.str() << std::endl; return EXECUTION_OK; } logfile = getStringOption_("log"); if (logfile.empty()) { logfile = "temp.inspect.log"; files[logfile] = (writable | delete_afterwards); } else files[logfile] = writable; inspect_in = getFlag_("inspect_in"); inspect_out = getFlag_("inspect_out"); if (inspect_in && inspect_out) { writeLog_("Both Inspect flags set. Only one of the two flags [-inspect_in|-inspect_out] can be set. Aborting!"); return ILLEGAL_PARAMETERS; } if (inspect_in) writeDebug_("Inspect flag: mascot_in (reads in MzXML/MzData, writes Inspect generic format)", 1); else if (inspect_out) writeDebug_("Inspect flag: mascot_in (reads in Inspect result file, writes idXML file)", 1); else writeDebug_("No Inspect flag set: reads in MzXML/MzData, writes idXML file", 1); // a 'normal' inspect run corresponds to both inspect_in and inspect_out set if (!inspect_in && !inspect_out) inspect_in = inspect_out = true; if (inspect_out && inspect_in) { temp_data_directory = getStringOption_("temp_data_directory"); if (temp_data_directory.empty()) { writeLog_("No directory for temporary files specified. Aborting!"); printUsage_(); return ILLEGAL_PARAMETERS; } temp_data_directory = File::absolutePath(temp_data_directory); temp_data_directory.ensureLastChar(separator); } string_buffer = getStringOption_("in"); if (string_buffer.empty()) { writeLog_("No input file specified. Aborting!"); printUsage_(); return ILLEGAL_PARAMETERS; } else { string_buffer = File::absolutePath(string_buffer); if (inspect_in) { PeakMap experiment; String type; try { inspect_outfile.getExperiment(experiment, type, string_buffer); // may throw an exception if the filetype could not be determined } catch (Exception::ParseError& pe) { writeLog_(pe.getMessage()); return PARSE_ERROR; } if (type != "mzXML") { string_buffer.append(".mzXML"); MzXMLFile().store(string_buffer, experiment); files[string_buffer] = (writable | delete_afterwards); } inspect_infile.setSpectra(string_buffer); if (inspect_out) { inspect_output_filename = getStringOption_("inspect_output"); if (inspect_output_filename.empty()) { inspect_output_filename = temp_data_directory + "tmp.direct.inspect.output"; files[inspect_output_filename] = (writable | delete_afterwards); } else { inspect_output_filename = File::absolutePath(inspect_output_filename); files[inspect_output_filename] = writable; } } } else { inspect_output_filename = string_buffer; inspect_output_filename = File::absolutePath(inspect_output_filename); files[inspect_output_filename] = readable; } } string_buffer = getStringOption_("out"); if (string_buffer.empty()) { writeLog_("No output file specified. Aborting!"); return ILLEGAL_PARAMETERS; } else { string_buffer = File::absolutePath(string_buffer); if (inspect_out) output_filename = string_buffer; else inspect_input_filename = string_buffer; files[string_buffer] = writable; } if (inspect_in && inspect_out) { inspect_input_filename = getStringOption_("inspect_input"); if (inspect_input_filename.empty()) { inspect_input_filename = temp_data_directory + "tmp.inspect.input"; files[inspect_input_filename] = (writable | delete_afterwards); } else { inspect_input_filename = File::absolutePath(inspect_input_filename); files[inspect_input_filename] = writable; } } inspect_directory = getStringOption_("inspect_directory"); if (inspect_in && inspect_directory.empty() && inspect_out) { writeLog_("No inspect directory file specified. Aborting!"); return ILLEGAL_PARAMETERS; } inspect_directory = File::absolutePath(inspect_directory); inspect_directory.ensureLastChar(separator); blind_only = getFlag_("blind:blind_only"); contact_person.setName(getStringOption_("contact_name")); contact_person.setInstitution(getStringOption_("contact_institution")); contact_person.setContactInfo(getStringOption_("contact_info")); if (inspect_in) { string_buffer = getStringOption_("trie_dbs"); if (!string_buffer.empty()) { // get the single databases string_buffer.split(',', trie_database_filenames); if (trie_database_filenames.empty()) trie_database_filenames.push_back(string_buffer); // the database files have to be readable, (by the way changing the names using the absolute path) for (vector<String>::iterator trie_database_filenames_it = trie_database_filenames.begin(); trie_database_filenames_it != trie_database_filenames.end(); ++trie_database_filenames_it) { *trie_database_filenames_it = File::absolutePath(*trie_database_filenames_it); files[*trie_database_filenames_it] = readable; // get the according index file if (trie_database_filenames_it->hasSuffix(".trie")) string_buffer = trie_database_filenames_it->substr(0, trie_database_filenames_it->length() - 4) + "index"; else string_buffer = *trie_database_filenames_it + "index"; index_filenames.push_back(string_buffer); files[string_buffer] = readable; } } string_buffer = getStringOption_("dbs"); if (!string_buffer.empty()) { // get the single sequence files string_buffer.split(',', sequence_database_filenames); if (sequence_database_filenames.empty()) sequence_database_filenames.push_back(string_buffer); // the sequence files have to be readable, (by the way changing the names using the absolute path) for (vector<String>::iterator sequence_database_filenames_it = sequence_database_filenames.begin(); sequence_database_filenames_it != sequence_database_filenames.end(); ++sequence_database_filenames_it) { *sequence_database_filenames_it = File::absolutePath(*sequence_database_filenames_it); files[*sequence_database_filenames_it] = readable; } } // at least one of the parameters db or sequence_file has to be set if (trie_database_filenames.empty() && sequence_database_filenames.empty()) { writeLog_("No database specified. Aborting!"); return ILLEGAL_PARAMETERS; } bool no_tmp_dbs = getFlag_("no_tmp_dbs"); // blind - running inspect in blind mode after running a normal mode to minimize the database blind = getFlag_("blind:blind"); if (blind && inspect_in && !inspect_out) { blind = false; blind_only = true; } trie_database_filename = getStringOption_("new_db"); if (trie_database_filename.empty() && (!sequence_database_filenames.empty() || trie_database_filenames.size() != 1)) { if (!inspect_out) { writeLog_("No name for new trie database given. Aborting!"); return ILLEGAL_PARAMETERS; } else { if (no_tmp_dbs) { writeLog_("no_tmp_dbs flag set but no name for database given. Aborting!"); return ILLEGAL_PARAMETERS; } else { trie_database_filename = temp_data_directory + "tmp.inspect.db.trie"; files[trie_database_filename] = (writable | delete_afterwards); inspect_infile.setDb(trie_database_filename); index_filename = temp_data_directory + "tmp.inspect.db.index"; files[index_filename] = (writable | delete_afterwards); } } } else { // if only one trie database is given, this one is used if (trie_database_filename.empty()) trie_database_filename = trie_database_filenames.front(); trie_database_filename = File::absolutePath(trie_database_filename); if (trie_database_filename.hasSuffix(".trie")) { inspect_infile.setDb(trie_database_filename); index_filename = trie_database_filename.substr(0, trie_database_filename.length() - 4) + "index"; } else { index_filename = trie_database_filename + ".index"; trie_database_filename = trie_database_filename + ".trie"; inspect_infile.setDb(trie_database_filename); } files[trie_database_filename] = writable; files[index_filename] = writable; } if (blind && blind_only) { writeLog_("Both blind flags set. Only one of the two flags [-blind|-blind_only] can be set. Aborting!"); return ILLEGAL_PARAMETERS; } snd_trie_database = getStringOption_("blind:snd_db"); if (no_tmp_dbs && blind && snd_trie_database.empty()) { writeLog_("No_tmp_dbs and blind flag set but no name for minimized database given. Aborting!"); return ILLEGAL_PARAMETERS; } else if (blind && snd_trie_database.empty()) { snd_trie_database_filename = temp_data_directory + "tmp.inspect.db.snd.trie"; snd_index_filename = temp_data_directory + "tmp.inspect.db.snd.index"; files[snd_trie_database_filename] = (writable | delete_afterwards); files[snd_index_filename] = (writable | delete_afterwards); } else if (blind) { snd_trie_database = File::absolutePath(snd_trie_database); if (snd_trie_database.hasSuffix(".trie")) { snd_trie_database_filename = snd_trie_database; snd_index_filename = snd_trie_database.substr(0, snd_trie_database.size() - 4) + "index"; files[snd_trie_database_filename] = writable; files[snd_index_filename] = writable; } else { snd_trie_database_filename = snd_trie_database + ".trie"; snd_index_filename = snd_trie_database + ".index"; files[snd_trie_database_filename] = writable; files[snd_index_filename] = writable; } } // get the known modifications monoisotopic = getFlag_("use_monoisotopic_mod_mass"); if (!blind_only) { // modifications string_buffer = getStringOption_("modifications"); try { inspect_infile.handlePTMs(string_buffer, modifications_filename, monoisotopic); } catch (Exception::FileNotFound& /*fnf_e*/) { writeLog_("No modifications XML file given. Aborting!"); return INPUT_FILE_NOT_FOUND; } catch (Exception::FileNotReadable& /*fnr_e*/) { writeLog_("Modifications XML file is not readable. Aborting!"); return INPUT_FILE_NOT_READABLE; } catch (Exception::ParseError& p_e) { writeLog_(String(p_e.getMessage()) + ". Aborting!"); return PARSE_ERROR; } } inspect_infile.setEnzyme(getStringOption_("cleavage")); inspect_infile.setInstrument(getStringOption_("instrument")); inspect_infile.setModificationsPerPeptide(getIntOption_("max_modifications_pp")); if (inspect_infile.getModificationsPerPeptide() < 1 && !inspect_infile.getModifications().empty()) { writeLog_("Modifications specified, but max_modifications_pp not set. Setting it to 1."); inspect_infile.setModificationsPerPeptide(1); } inspect_infile.setPrecursorMassTolerance(getDoubleOption_("precursor_mass_tolerance")); if ((inspect_infile.getPrecursorMassTolerance() < 0 && inspect_infile.getPrecursorMassTolerance() != -1)) { writeLog_("Illegal precursor mass tolerance (<0) given. Aborting!"); return ILLEGAL_PARAMETERS; } inspect_infile.setPeakMassTolerance(getDoubleOption_("peak_mass_tolerance")); if ((inspect_infile.getPeakMassTolerance() < 0 && inspect_infile.getPeakMassTolerance() != -1)) { writeLog_("Illegal peak mass tolerance (<0) given. Aborting!"); return ILLEGAL_PARAMETERS; } if (getFlag_("multicharge")) inspect_infile.setMulticharge(1); inspect_infile.setTagCount(getIntOption_("tag_count")); if ((inspect_infile.getTagCount() < 0 && inspect_infile.getTagCount() != -1)) { writeLog_("Illegal number of tags (tag_count <0) given. Aborting!"); return ILLEGAL_PARAMETERS; } inspect_infile.setMaxPTMsize(getDoubleOption_("blind:max_ptm_size")); if ((inspect_infile.getMaxPTMsize() < 10 || inspect_infile.getMaxPTMsize() > 2000) && inspect_infile.getMaxPTMsize() != -1) { writeLog_("Illegal maximum modification size (not in [10,2000]). Aborting!"); return ILLEGAL_PARAMETERS; } } if (inspect_out) { p_value_threshold = getDoubleOption_("p_value"); if ((p_value_threshold < 0) || (p_value_threshold > 1)) { writeLog_("Illegal p-value. Aborting!"); return ILLEGAL_PARAMETERS; } inspect_logfile = temp_data_directory + "tmp.inspect.log"; files[inspect_logfile] = (writable | delete_afterwards); } if (blind && inspect_in) { double cutoff_p_value = getDoubleOption_("blind:p_value_blind"); if ((cutoff_p_value < 0) || (cutoff_p_value > 1)) { writeLog_("Illegal p-value for blind search. Aborting!"); return ILLEGAL_PARAMETERS; } } //------------------------------------------------------------- // (3) running program according to parameters //------------------------------------------------------------- // checking accessability of files Size file_tag(0); for (map<String, Size>::const_iterator files_it = files.begin(); files_it != files.end(); ++files_it) { string_buffer = files_it->first; file_tag = files_it->second; if ((file_tag & exist || file_tag & readable) && !File::exists(string_buffer)) { exit_code = INPUT_FILE_NOT_FOUND; writeLog_(String("File ") + string_buffer + " does not exist. Aborting!"); break; } if ((file_tag & readable) && !File::readable(string_buffer)) { exit_code = INPUT_FILE_NOT_READABLE; writeLog_(String("File ") + string_buffer + " is not readable. Aborting!"); break; } bool existed = File::exists(string_buffer); if ((file_tag & writable) && !File::writable(string_buffer)) { exit_code = CANNOT_WRITE_OUTPUT_FILE; writeLog_(String("Cannot write file ") + string_buffer + ". Aborting!"); break; } else if (!existed) remove(string_buffer.c_str()); existed = false; } vector<Size> wanted_records; // creating the input file and converting and merging the databases if (exit_code == EXECUTION_OK && inspect_in) { if (!sequence_database_filenames.empty() || trie_database_filenames.size() != 1) // don't do it, if only one trie database is given { // merging the trie databases (all but the first databases are appended) vector<String>::const_iterator index_filenames_itt = index_filenames.begin(); for (vector<String>::const_iterator trie_database_filenames_it = trie_database_filenames.begin(); trie_database_filenames_it != trie_database_filenames.end(); ++trie_database_filenames_it, ++index_filenames_itt) { inspect_outfile.compressTrieDB(*trie_database_filenames_it, *index_filenames_itt, wanted_records, trie_database_filename, index_filename, (trie_database_filenames_it != trie_database_filenames.begin())); } // converting and merging the other databases (all but the first database are appended) for (vector<String>::const_iterator sequence_database_filenames_it = sequence_database_filenames.begin(); sequence_database_filenames_it != sequence_database_filenames.end(); ++sequence_database_filenames_it) { inspect_outfile.generateTrieDB(*sequence_database_filenames_it, trie_database_filename, index_filename, ((sequence_database_filenames_it != sequence_database_filenames.begin()) || (!sequence_database_filenames.empty()))); } } if (blind_only) inspect_infile.setBlind(true); inspect_infile.store(inspect_input_filename); } // running inspect and generating a second database from the results and running inspect in blind mode on this new database if (exit_code == EXECUTION_OK && blind && inspect_in && inspect_out) { writeLog_("Searching and generating minimised database for blind mode ..."); writeDebug_("The Inspect process created the following output:", 1); String call; call.append(" -r "); call.append(inspect_directory); call.append(" -i "); call.append(inspect_input_filename); call.append(" -o "); call.append(inspect_output_filename); // writing the inspect output to a temporary file call.append(" -e "); call.append(inspect_logfile); Int status = QProcess::execute((inspect_directory + "inspect").toQString(), QStringList(call.toQString().split(" ", QString::SkipEmptyParts))); // does automatic escaping etc... if (status != 0) { TextFile tf(inspect_logfile); string_buffer.clear(); string_buffer.concatenate(tf.begin(), tf.end()); writeLog_("Inspect problem: " + string_buffer + " Aborting!"); exit_code = EXTERNAL_PROGRAM_ERROR; } wanted_records = inspect_outfile.getWantedRecords(inspect_output_filename, p_value_threshold); if (wanted_records.empty()) { IdXMLFile idXML_file; idXML_file.store(output_filename, vector<ProteinIdentification>(), vector<PeptideIdentification>()); inspect_out = false; writeLog_("No proteins matching criteria for generating minimized database for blind search. Aborting!"); exit_code = UNKNOWN_ERROR; } else { inspect_outfile.compressTrieDB(trie_database_filename, index_filename, wanted_records, snd_trie_database_filename, snd_index_filename, false); // setting the database name to the new database inspect_infile.setDb(snd_trie_database_filename); inspect_infile.setBlind(true); inspect_infile.store(inspect_input_filename); } } // writing the output of inspect Into an idXML file if (exit_code == EXECUTION_OK && inspect_in && inspect_out) { String call; call.append(" -r "); call.append(inspect_directory); call.append(" -i "); call.append(inspect_input_filename); call.append(" -o "); call.append(inspect_output_filename); // writing the inspect output to a temporary file call.append(" -e "); call.append(inspect_logfile); writeLog_("Searching ..."); writeDebug_("The Inspect process created the following output:", 1); Int status = QProcess::execute((inspect_directory + "inspect").toQString(), QStringList(call.toQString().split(" ", QString::SkipEmptyParts))); // does automatic escaping etc... if (status != 0) { TextFile tf(inspect_logfile); string_buffer.clear(); string_buffer.concatenate(tf.begin(), tf.end()); writeLog_("Inspect problem: " + string_buffer + ". Aborting!"); exit_code = EXTERNAL_PROGRAM_ERROR; } } if (exit_code == EXECUTION_OK && inspect_out) { vector<PeptideIdentification> peptide_identifications; ProteinIdentification protein_identification; IdXMLFile idXML_file; if (inspect_in) // the version can only be retrieved by running inspect without parameters { // first get the InsPecT version QProcess builder; builder.start((inspect_directory + "inspect").toQString(), QStringList()); // does automatic escaping etc... if (!builder.waitForFinished(-1)) { writeLog_("Inspect problem: " + String(QString(builder.readAll())) + ". Aborting!"); exit_code = EXTERNAL_PROGRAM_ERROR; } else { QString output = builder.readAll(); // set the search engine and its version and the score type if (!inspect_outfile.getSearchEngineAndVersion(output, protein_identification)) LOG_WARN << "Could not read version of InsPecT from:\n" << String(output) << "\n\n"; } } else protein_identification.setSearchEngine("InsPecT"); if (exit_code == EXECUTION_OK) { if (!File::empty(inspect_output_filename)) { // set the parameters ProteinIdentification::SearchParameters sp; if (monoisotopic) { sp.mass_type = ProteinIdentification::MONOISOTOPIC; } else { sp.mass_type = ProteinIdentification::AVERAGE; } if (ProteaseDB::getInstance()->hasEnzyme(inspect_infile.getEnzyme())) { sp.digestion_enzyme = *(ProteaseDB::getInstance()->getEnzyme(inspect_infile.getEnzyme())); } sp.fragment_mass_tolerance = inspect_infile.getPeakMassTolerance(); sp.precursor_mass_tolerance = inspect_infile.getPrecursorMassTolerance(); protein_identification.setSearchParameters(sp); try { inspect_outfile.load(inspect_output_filename, peptide_identifications, protein_identification, p_value_threshold, inspect_infile.getDb()); } catch (Exception::ParseError& pe) { writeLog_(pe.getMessage()); exit_code = INPUT_FILE_CORRUPT; } if (exit_code == EXECUTION_OK) { vector<ProteinIdentification> protein_identifications(1, protein_identification); idXML_file.store(output_filename, protein_identifications, peptide_identifications); } } else { idXML_file.store(output_filename, vector<ProteinIdentification>(), vector<PeptideIdentification>()); writeLog_("No proteins identified!"); } } } // if an external program error occured, the logfile must not be deleted if (exit_code == EXTERNAL_PROGRAM_ERROR) { writeLog_("PepNovo problem. Aborting! (Details can be seen in the logfile: \"" + logfile + "\")"); files[logfile] = readable; } // deleting all temporary files for (map<String, Size>::const_iterator files_it = files.begin(); files_it != files.end(); ++files_it) { if (files_it->second & delete_afterwards) remove(files_it->first.c_str()); } return exit_code; }
bool File::empty(const String& file) { QFileInfo fi(file.toQString()); return !fi.exists() || fi.size() == 0; }
ExitCodes main_(int, const char**) override { //------------------------------------------------------------- // parsing parameters //------------------------------------------------------------- // do this early, to see if comet is installed String comet_executable = getStringOption_("comet_executable"); String tmp_param = File::getTemporaryFile(); writeLog_("Comet is writing the default parameter file..."); runExternalProcess_(comet_executable.toQString(), QStringList() << "-p" << tmp_param.c_str()); String inputfile_name = getStringOption_("in"); String out = getStringOption_("out"); //------------------------------------------------------------- // reading input //------------------------------------------------------------- String db_name(getStringOption_("database")); if (!File::readable(db_name)) { String full_db_name; try { full_db_name = File::findDatabase(db_name); } catch (...) { printUsage_(); return ILLEGAL_PARAMETERS; } db_name = full_db_name; } //tmp_dir String tmp_dir = makeAutoRemoveTempDirectory_(); String tmp_pepxml = tmp_dir + "result.pep.xml"; String tmp_pin = tmp_dir + "result.pin"; String default_params = getStringOption_("default_params_file"); String tmp_file; //default params given or to be written if (default_params.empty()) { tmp_file = tmp_dir + "param.txt"; ofstream os(tmp_file.c_str()); createParamFile_(os); os.close(); } else { tmp_file = default_params; } PeakMap exp; MzMLFile mzml_file; mzml_file.getOptions().setMSLevels({2}); // only load msLevel 2 mzml_file.setLogType(log_type_); mzml_file.load(inputfile_name, exp); if (exp.getSpectra().empty()) { throw OpenMS::Exception::FileEmpty(__FILE__, __LINE__, __FUNCTION__, "Error: No MS2 spectra in input file."); } // determine type of spectral data (profile or centroided) SpectrumSettings::SpectrumType spectrum_type = exp[0].getType(); if (spectrum_type == SpectrumSettings::PROFILE) { if (!getFlag_("force")) { throw OpenMS::Exception::IllegalArgument(__FILE__, __LINE__, __FUNCTION__, "Error: Profile data provided but centroided MS2 spectra expected. To enforce processing of the data set the -force flag."); } } //------------------------------------------------------------- // calculations //------------------------------------------------------------- String paramP = "-P" + tmp_file; String paramN = "-N" + File::removeExtension(File::removeExtension(tmp_pepxml)); QStringList arguments; arguments << paramP.toQString() << paramN.toQString() << inputfile_name.toQString(); //------------------------------------------------------------- // run comet //------------------------------------------------------------- // Comet execution with the executable and the arguments StringList TOPPBase::ExitCodes exit_code = runExternalProcess_(comet_executable.toQString(), arguments); if (exit_code != EXECUTION_OK) { return exit_code; } //------------------------------------------------------------- // writing IdXML output //------------------------------------------------------------- // read the pep.xml put of Comet and write it to idXML vector<PeptideIdentification> peptide_identifications; vector<ProteinIdentification> protein_identifications; writeDebug_("load PepXMLFile", 1); PepXMLFile().load(tmp_pepxml, protein_identifications, peptide_identifications); writeDebug_("write idXMLFile", 1); writeDebug_(out, 1); IdXMLFile().store(out, protein_identifications, peptide_identifications); //------------------------------------------------------------- // create (move) optional pin output //------------------------------------------------------------- String pin_out = getStringOption_("pin_out"); if (!pin_out.empty()) { // move the temporary file to the actual destination: if (!File::rename(tmp_pin, pin_out)) { return CANNOT_WRITE_OUTPUT_FILE; } } return EXECUTION_OK; }
ExitCodes main_(int, const char **) { // find the config for the tool: String type = getStringOption_("type"); Param tool_param = this->getParam_(); // check required parameters (TOPPBase does not do this as we did not use registerInputFile_(...) etc) Param p = tool_param.copy("ETool:", true); for (Param::ParamIterator it = p.begin(); it != p.end(); ++it) { if ((it->tags).count("required") > 0) { if (it->value.toString().trim().empty()) // any required parameter should have a value { LOG_ERROR << "The INI-parameter '" + it->name + "' is required, but was not given! Aborting ..."; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } else if ((it->tags).count("input file") > 0) // any required input file should exist { if (!File::exists(it->value)) { LOG_ERROR << "Input file '" + String(it->value) + "' does not exist! Aborting ..."; return wrapExit(INPUT_FILE_NOT_FOUND); } } } } Internal::ToolDescription gw = ToolHandler::getTOPPToolList(true)[toolName_()]; for (Size i = 0; i < gw.types.size(); ++i) { if (type == gw.types[i]) { tde_ = gw.external_details[i]; if (tde_.working_directory.trim() == "") tde_.working_directory = "."; break; } } LOG_INFO << tde_.text_startup << "\n"; String command_args = tde_.commandline; // check for double spaces and warn if (command_args.hasSubstring(" ")) { LOG_WARN << "Commandline contains double spaces, which is not allowed. Condensing...\n"; while (command_args.hasSubstring(" ")) { command_args.substitute(" ", " "); } LOG_WARN << "result: " << command_args << std::endl; } writeDebug_("CommandLine from ttd (unprocessed): " + command_args, 1); // do "pre" moves (e.g. if the wrapped tool works on its data in-place (overwrites) it - we need to make a copy first // - we copy the file // - we set the value of the affected parameter to the copied tmp file, such that subsequent calls target the tmp file for (Size i = 0; i < tde_.tr_table.pre_moves.size(); ++i) { const Internal::FileMapping & fm = tde_.tr_table.pre_moves[i]; // find target param: Param p = tool_param.copy("ETool:", true); String target = fm.target; if (!p.exists(target)) throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Cannot find target parameter '" + target + "' being mapped from external tools output!", target); String tmp_location = fm.location; // fragment's placeholder evaluation: createFragment_(tmp_location, p); // check if target already exists: String target_file = (String)p.getValue(target); if (File::exists(tmp_location)) { if (!File::remove(tmp_location)) { LOG_ERROR << "While writing a tmp file: Cannot remove conflicting file '" + tmp_location + "'. Check permissions! Aborting ..."; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } // create the temp file tmp_location target_file writeDebug_(String("Copying '") + target_file + "' to '" + tmp_location + "'", 1); bool move_ok = QFile::copy(target_file.toQString(), tmp_location.toQString()); if (!move_ok) { LOG_ERROR << "Copying the target file '" + tmp_location + "' from '" + target_file + "' failed! Aborting ..."; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } // set the input file's value to the temp file tool_param.setValue(String("ETool:") + target, tmp_location); } ///// construct the command line: // go through mappings (reverse because replacing %10 must come before %1): for (std::map<Int, String>::reverse_iterator it = tde_.tr_table.mapping.rbegin(); it != tde_.tr_table.mapping.rend(); ++it) { //std::cout << "mapping #" << it->first << "\n"; String fragment = it->second; // fragment's placeholder evaluation: createFragment_(fragment, tool_param.copy("ETool:", true)); // replace fragment in cl //std::cout << "replace : " << "%"+String(it->first) << " with '" << fragment << "\n"; command_args.substitute("%" + String(it->first), fragment); } QProcess builder; builder.setProcessChannelMode(QProcess::MergedChannels); String call = tde_.path + " " + command_args; writeDebug_("call command: " + call, 1); builder.setWorkingDirectory(tde_.working_directory.toQString()); builder.start(call.toQString()); if (!builder.waitForFinished(-1) || builder.exitStatus() != 0 || builder.exitCode() != 0) { LOG_ERROR << ("External tool returned with non-zero exit code (" + String(builder.exitCode()) + "), exit status (" + String(builder.exitStatus()) + ") or timed out. Aborting ...\n"); LOG_ERROR << ("External tool output:\n" + String(QString(builder.readAll()))); return wrapExit(EXTERNAL_PROGRAM_ERROR); } LOG_INFO << ("External tool output:\n" + String(QString(builder.readAll()))); // post processing (file moving via 'file' command) for (Size i = 0; i < tde_.tr_table.post_moves.size(); ++i) { const Internal::FileMapping & fm = tde_.tr_table.post_moves[i]; // find target param: Param p = tool_param.copy("ETool:", true); String target = fm.target; if (!p.exists(target)) throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Cannot find target parameter '" + target + "' being mapped from external tools output!", target); String source = fm.location; // fragment's placeholder evaluation: createFragment_(source, p); // check if target already exists: String target_file = (String)p.getValue(target); if (target_file.trim().empty()) // if target was not given, we skip the copying step (usually for optional parameters) { LOG_INFO << "Parameter '" + target + "' not given. Skipping forwarding of files.\n"; continue; } if (File::exists(target_file)) { if (!File::remove(target_file)) { LOG_ERROR << "Cannot remove conflicting file '" + target_file + "'. Check permissions! Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } // move to target writeDebug_(String("moving '") + source + "' to '" + target_file + "'", 1); bool move_ok = QFile::rename(source.toQString(), target_file.toQString()); if (!move_ok) { LOG_ERROR << "Moving the target file '" + target_file + "' from '" + source + "' failed! Aborting ..." << std::endl; return wrapExit(CANNOT_WRITE_OUTPUT_FILE); } } LOG_INFO << tde_.text_finish << "\n"; return wrapExit(EXECUTION_OK); }
String File::path(const String& file) { QFileInfo fi(file.toQString()); return fi.path(); }
String File::basename(const String& file) { QFileInfo fi(file.toQString()); return fi.fileName(); }
String File::absolutePath(const String& file) { QFileInfo fi(file.toQString()); return fi.absoluteFilePath(); }
bool File::readable(const String& file) { QFileInfo fi(file.toQString()); return fi.exists() && fi.isReadable(); }
ExitCodes main_(int , const char**) override { // path to the log file String logfile(getStringOption_("log")); String pepnovo_executable(getStringOption_("pepnovo_executable")); PeakMap exp; String inputfile_name = getStringOption_("in"); writeDebug_(String("Input file: ") + inputfile_name, 1); String outputfile_name = getStringOption_("out"); writeDebug_(String("Output file: ") + outputfile_name, 1); String model_directory = getStringOption_("model_directory"); writeDebug_(String("model directory: ") + model_directory, 1); String model_name = getStringOption_("model"); writeDebug_(String("model directory: ") + model_name, 1); double fragment_tolerance = getDoubleOption_("fragment_tolerance"); if (fragment_tolerance!=-1.0 && (fragment_tolerance<0 || fragment_tolerance>0.75)) { writeLog_("Invalid fragment tolerance"); printUsage_(); return ILLEGAL_PARAMETERS; } double pm_tolerance = getDoubleOption_("pm_tolerance"); if (pm_tolerance!=-1.0 && (pm_tolerance<0.0 || pm_tolerance>5.0)) { writeLog_("Invalid fragment tolerance"); printUsage_(); return ILLEGAL_PARAMETERS; } Int tag_length = getIntOption_("tag_length"); if ( tag_length!=-1 && (tag_length<3 || tag_length>6)) { writeLog_("Invalid fragment tolerance"); printUsage_(); return ILLEGAL_PARAMETERS; } String digest = getStringOption_("digest"); Size num_solutions=getIntOption_("num_solutions"); //------------------------------------------------------------- // reading input //------------------------------------------------------------- // only load msLevel 2 MzMLFile mzml_infile; mzml_infile.getOptions().addMSLevel(2); mzml_infile.setLogType(log_type_); mzml_infile.load(inputfile_name, exp); // we map the native id to the MZ and RT to be able to // map the IDs back to the spectra (RT, and MZ Meta Information) PepNovoOutfile::IndexPosMappingType index_to_precursor; for (Size i = 0; i < exp.size(); ++i) { index_to_precursor[i]= make_pair(exp[i].getRT(), exp[i].getPrecursors()[0].getPosition()[0]); //set entry <RT, MZ> } logfile = getStringOption_("log"); QDir qdir_models_source(model_directory.c_str()); if (!qdir_models_source.exists()) { writeLog_("The model directory does not exist"); return INPUT_FILE_NOT_FOUND; } // create temp directory QDir qdir_temp(File::getTempDirectory().toQString()); String temp_data_directory = File::getUniqueName(); qdir_temp.mkdir(temp_data_directory.toQString()); qdir_temp.cd(temp_data_directory.toQString()); temp_data_directory = File::getTempDirectory() + "/" + temp_data_directory; // delete later String mgf_file = temp_data_directory + "/" + File::getUniqueName() + ".mgf"; // the mzXML parser of PepNovo is somewhat broken.. don't use mzXML MascotGenericFile().store(mgf_file, exp); bool error(false); try { //temporary File to store PepNovo output String temp_pepnovo_outfile = qdir_temp.absoluteFilePath("tmp_pepnovo_out.txt"); String tmp_models_dir = qdir_temp.absoluteFilePath("Models"); std::map<String, String>mods_and_keys; //, key_to_id; if (qdir_temp.cd("Models")) { writeLog_("The temporary directory already contains \"Model\" Folder. Please delete it and re-run. Aborting!"); return CANNOT_WRITE_OUTPUT_FILE; } else { qdir_temp.mkdir("Models"); qdir_temp.cd("Models"); } //copy the Models folder of OpenMS into the temp_data_directory QStringList pepnovo_files = qdir_models_source.entryList(QDir::Dirs | QDir::Files|QDir::NoDotAndDotDot); if (pepnovo_files.empty()) { writeLog_("The \"Model\" directory does not contain model files. Aborting!"); return INPUT_FILE_NOT_FOUND; } for (QStringList::ConstIterator file_it=pepnovo_files.begin(); file_it!=pepnovo_files.end(); ++file_it) { if (qdir_models_source.cd(*file_it)) { qdir_temp.mkdir(*file_it); qdir_temp.cd(*file_it); QStringList subdir_files = qdir_models_source.entryList(QDir::Dirs | QDir::Files|QDir::NoDotAndDotDot); for (QStringList::ConstIterator subdir_file_it=subdir_files.begin(); subdir_file_it!=subdir_files.end(); ++subdir_file_it) { QFile::copy(qdir_models_source.filePath(*subdir_file_it), qdir_temp.filePath(*subdir_file_it)); } qdir_temp.cdUp(); qdir_models_source.cdUp(); } else { QFile::copy(qdir_models_source.filePath(*file_it), qdir_temp.filePath(*file_it)); } } //generate PTM File and store in temp directory PepNovoInfile p_novo_infile; String ptm_command; if (!getStringList_("fixed_modifications").empty() || !getStringList_("variable_modifications").empty()) { p_novo_infile.setModifications(getStringList_("fixed_modifications"), getStringList_("variable_modifications")); p_novo_infile.store(qdir_temp.filePath("PepNovo_PTMs.txt")); pepnovo_files.append("PepNovo_PTMs.txt"); p_novo_infile.getModifications(mods_and_keys); for (std::map<String, String>::const_iterator key_it=mods_and_keys.begin(); key_it!=mods_and_keys.end();++key_it) { if (ptm_command!="") { ptm_command+=":"; } ptm_command+= key_it->first; //key_to_id[key_it->second]=key_it->first; } } //------------------------------------------------------------- // (3) running program according to parameters //------------------------------------------------------------- QStringList arguments; arguments << "-file" << mgf_file.toQString(); arguments << "-model" << model_name.toQString(); if (pm_tolerance != -1 ) arguments << "-pm_tolerance"<<String(pm_tolerance).toQString(); if (fragment_tolerance != -1 ) arguments << "-fragment_tolerance" <<String(fragment_tolerance).toQString(); if (!ptm_command.empty()) arguments <<"-PTMs" <<ptm_command.toQString(); if (getFlag_("correct_pm")) arguments << "-correct_pm"; if (getFlag_("use_spectrum_charge")) arguments << "-use_spectrum_charge"; if (getFlag_("use_spectrum_mz")) arguments << "-use_spectrum_mz"; if (getFlag_("no_quality_filter")) arguments << "-no_quality_filter"; arguments << "-digest" << digest.toQString(); arguments << "-num_solutions" << String(num_solutions).toQString(); if (tag_length!=-1) arguments<<"-tag_length" << String(tag_length).toQString(); arguments<<"-model_dir" << tmp_models_dir.toQString(); //arguments<<">" << temp_pepnovo_outfile.toQString(); writeDebug_("Use this line to call PepNovo: ", 1); writeDebug_(pepnovo_executable + " " + String(arguments.join(" ")), 1); QProcess process; process.setStandardOutputFile(temp_pepnovo_outfile.toQString()); process.setStandardErrorFile(temp_pepnovo_outfile.toQString()); process.start(pepnovo_executable.toQString(), arguments); // does automatic escaping etc... if (process.waitForFinished(-1)) { //if PepNovo finished successfully use PepNovoOutfile to parse the results and generate idXML std::vector< PeptideIdentification > peptide_identifications; ProteinIdentification protein_identification; StringList ms_runs; exp.getPrimaryMSRunPath(ms_runs); protein_identification.setPrimaryMSRunPath(ms_runs); PepNovoOutfile p_novo_outfile; //resolve PTMs (match them back to the OpenMs Identifier String) std::vector<ProteinIdentification>prot_ids; p_novo_outfile.load(temp_pepnovo_outfile, peptide_identifications, protein_identification, -1e5, index_to_precursor, mods_and_keys); prot_ids.push_back(protein_identification); IdXMLFile().store(outputfile_name, prot_ids, peptide_identifications); } if (process.exitStatus() != 0) error = true; } catch(Exception::BaseException &exc) { writeLog_(exc.what()); LOG_ERROR << "Error occurred: " << exc.what() << std::endl; error = true; } if (!error) { File::removeDirRecursively(temp_data_directory); return EXECUTION_OK; } else { writeLog_("PepNovo problem. Aborting! (Details can be seen in outfiles: '" + temp_data_directory + "')"); return EXTERNAL_PROGRAM_ERROR; } }