TransformationModelLinear::TransformationModelLinear( const TransformationModel::DataPoints & data, const Param & params) { params_ = params; data_given_ = !data.empty(); if (!data_given_ && params.exists("slope") && (params.exists("intercept"))) { // don't estimate parameters, use given values slope_ = params.getValue("slope"); intercept_ = params.getValue("intercept"); } else // estimate parameters from data { Param defaults; getDefaultParameters(defaults); params_.setDefaults(defaults); symmetric_ = params_.getValue("symmetric_regression") == "true"; size_t size = data.size(); if (size == 0) // no data { throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__, "no data points for 'linear' model"); } else if (size == 1) // degenerate case, but we can still do something { slope_ = 1.0; intercept_ = data[0].second - data[0].first; } else // compute least-squares fit { vector<double> x(size), y(size); for (size_t i = 0; i < size; ++i) { if (symmetric_) { x[i] = data[i].second + data[i].first; y[i] = data[i].second - data[i].first; } else { x[i] = data[i].first; y[i] = data[i].second; } } double cov00, cov01, cov11, sumsq; // covariance values, sum of squares double * x_start = &(x[0]), * y_start = &(y[0]); gsl_fit_linear(x_start, 1, y_start, 1, size, &intercept_, &slope_, &cov00, &cov01, &cov11, &sumsq); if (symmetric_) // undo coordinate transformation: { slope_ = (1.0 + slope_) / (1.0 - slope_); intercept_ = intercept_ * 1.41421356237309504880; // 1.41... = sqrt(2) } } } }
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; }
TransformationModelLinear::TransformationModelLinear(const TransformationModel::DataPoints& data, const Param& params) : TransformationModel(data, params) // initializes model { data_given_ = !data.empty(); if (!data_given_ && params.exists("slope") && params.exists("intercept")) { // don't estimate parameters, use given values slope_ = params.getValue("slope"); intercept_ = params.getValue("intercept"); } else // estimate parameters from data { Param defaults; getDefaultParameters(defaults); params_.setDefaults(defaults); symmetric_ = params_.getValue("symmetric_regression") == "true"; // weight the data (if weighting is specified) TransformationModel::DataPoints data_weighted = data; if ((params.exists("x_weight") && params.getValue("x_weight") != "") || (params.exists("y_weight") && params.getValue("y_weight") != "")) { weightData(data_weighted); } size_t size = data_weighted.size(); std::vector<Wm5::Vector2d> points; if (size == 0) // no data { throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "no data points for 'linear' model"); } else if (size == 1) // degenerate case, but we can still do something { slope_ = 1.0; intercept_ = data_weighted[0].second - data_weighted[0].first; } else // compute least-squares fit { for (size_t i = 0; i < size; ++i) { points.push_back(Wm5::Vector2d(data_weighted[i].first, data_weighted[i].second)); } if (!Wm5::HeightLineFit2<double>(static_cast<int>(size), &points.front(), slope_, intercept_)) { throw Exception::UnableToFit(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "TransformationModelLinear", "Unable to fit linear transformation to data points."); } } // update params params_.setValue("slope", slope_); params_.setValue("intercept", intercept_); } }
String File::getTempDirectory() { Param p = getSystemParameters(); if (p.exists("temp_dir") && String(p.getValue("temp_dir")).trim() != "") { return p.getValue("temp_dir"); } return String(QDir::tempPath()); }
//there is only one parameter at the moment Param getSubsectionDefaults_(const String& /*section*/) const { Param p = PosteriorErrorProbabilityModel().getParameters(); if (p.exists("out_plot")) { // hide from user -- we have a top-level param for that p.remove("out_plot"); } else { throw Exception::Precondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "INTERNAL ERROR: Param 'out_plot' was removed from fit-algorithm. Please update param handling internally!"); } return p; }
/// The current OpenMS user data path (for result files) String File::getUserDirectory() { Param p = getSystemParameters(); String dir; if (p.exists("home_dir") && String(p.getValue("home_dir")).trim() != "") { dir = p.getValue("home_dir"); } else { dir = String(QDir::homePath()); } dir.ensureLastChar('/'); return dir; }
int main(int argc, const char** argv) { //list of all the valid options Map<String, String> valid_options, valid_flags, option_lists; valid_flags["--help"] = "help"; valid_options["-ini"] = "ini"; Param param; param.parseCommandLine(argc, argv, valid_options, valid_flags, option_lists); // '--help' given if (param.exists("help")) { print_usage(); return 0; } // test if unknown options were given if (param.exists("unknown")) { // if TOPPView is packed as Mac OS X bundle it will get a -psn_.. parameter by default from the OS // if this is the only unknown option it will be ignored .. maybe this should be solved directly // in Param.h if (!(param.getValue("unknown").toString().hasSubstring("-psn") && !param.getValue("unknown").toString().hasSubstring(", "))) { cout << "Unknown option(s) '" << param.getValue("unknown").toString() << "' given. Aborting!" << endl; print_usage(); return 1; } } try { QApplicationTOPP a(argc, const_cast<char**>(argv)); a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); TOPPViewBase* mw = new TOPPViewBase(); a.connect(&a, SIGNAL(fileOpen(QString)), mw, SLOT(loadFile(QString))); mw->show(); // Create the splashscreen that is displayed while the application loads QSplashScreen* splash_screen = new QSplashScreen(QPixmap(":/TOPPView_Splashscreen.png")); splash_screen->show(); splash_screen->showMessage("Loading parameters"); QApplication::processEvents(); StopWatch stop_watch; stop_watch.start(); if (param.exists("ini")) { mw->loadPreferences((String)param.getValue("ini")); } //load command line files if (param.exists("misc")) { mw->loadFiles(param.getValue("misc"), splash_screen); } // We are about to show the application. // Proper time to remove the splashscreen, if at least 1.5 seconds have passed... while (stop_watch.getClockTime() < 1.5) /*wait*/ { } stop_watch.stop(); splash_screen->close(); delete splash_screen; #ifdef OPENMS_WINDOWSPLATFORM FreeConsole(); // get rid of console window at this point (we will not see any console output from this point on) AttachConsole(-1); // if the parent is a console, reattach to it - so we can see debug output - a normal user will usually not use cmd.exe to start a GUI) #endif int result = a.exec(); delete(mw); return result; } //######################## ERROR HANDLING ################################# catch (Exception::UnableToCreateFile& e) { cout << String("Error: Unable to write file (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileNotFound& e) { cout << String("Error: File not found (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileNotReadable& e) { cout << String("Error: File not readable (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileEmpty& e) { cout << String("Error: File empty (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::ParseError& e) { cout << String("Error: Unable to read file (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::InvalidValue& e) { cout << String("Error: Invalid value (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::BaseException& e) { cout << String("Error: Unexpected error (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } return 1; }
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); } }
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); } }
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); }
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); }
int main(int argc, const char** argv) { // list of all the valid options Map<String, String> valid_options, valid_flags, option_lists; valid_flags["--help"] = "help"; valid_flags["--debug"] = "debug"; valid_options["-ini"] = "ini"; // invalid, but keep for now in order to inform users where to find this functionality now valid_options["-execute"] = "execute"; valid_options["-out_dir"] = "out_dir"; Param param; param.parseCommandLine(argc, argv, valid_options, valid_flags, option_lists); // '--help' given if (param.exists("help")) { print_usage(); return 0; } // '-debug' given if (param.exists("debug")) { LOG_INFO << "Debug flag provided. Enabling 'LOG_DEBUG' ..." << std::endl; Log_debug.insert(cout); // allows to use LOG_DEBUG << "something" << std::endl; } // test if unknown options were given if (param.exists("unknown")) { // if TOPPAS is packed as Mac OS X bundle it will get a -psn_.. parameter by default from the OS // if this is the only unknown option it will be ignored .. maybe this should be solved directly // in Param.h if (!(param.getValue("unknown").toString().hasSubstring("-psn") && !param.getValue("unknown").toString().hasSubstring(", "))) { LOG_ERROR << "Unknown option(s) '" << param.getValue("unknown").toString() << "' given. Aborting!" << endl; print_usage(Log_error); return 1; } } try { if (param.exists("execute") || param.exists("out_dir")) { LOG_ERROR << "The parameters '-execute' and '-out_dir' are not valid anymore. This functionality has been moved to the ExecutePipeline tool." << endl; return 1; } QApplicationTOPP a(argc, const_cast<char**>(argv)); a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); TOPPASBase* mw = new TOPPASBase(); mw->show(); a.connect(&a, SIGNAL(fileOpen(QString)), mw, SLOT(openToppasFile(QString))); // Create the splashscreen that is displayed while the application loads (version is drawn dynamically) QPixmap qpm(":/TOPPAS_Splashscreen.png"); QPainter pt_ver(&qpm); pt_ver.setFont(QFont("Helvetica [Cronyx]", 15, 2, true)); pt_ver.setPen(QColor(44, 50, 152)); pt_ver.drawText(490, 84, VersionInfo::getVersion().toQString()); QSplashScreen* splash_screen = new QSplashScreen(qpm); splash_screen->show(); QApplication::processEvents(); StopWatch stop_watch; stop_watch.start(); if (param.exists("ini")) { mw->loadPreferences((String)param.getValue("ini")); } if (param.exists("misc")) { mw->loadFiles(param.getValue("misc"), splash_screen); } else // remember this new window as obsolete once a real workflow is loaded without this window being touched { // if this is not desired, simply call newPipeline() without arguments mw->newPipeline(mw->IDINITIALUNTITLED); } // We are about to show the application. // Proper time to remove the splash screen, if at least 1.5 seconds have passed... while (stop_watch.getClockTime() < 1.5) /*wait*/ { } stop_watch.stop(); splash_screen->close(); delete splash_screen; #ifdef OPENMS_WINDOWSPLATFORM FreeConsole(); // get rid of console window at this point (we will not see any console output from this point on) AttachConsole(-1); // if the parent is a console, reattach to it - so we can see debug output - a normal user will usually not use cmd.exe to start a GUI) #endif int result = a.exec(); delete(mw); return result; } //######################## ERROR HANDLING ################################# catch (Exception::UnableToCreateFile& e) { cout << String("Error: Unable to write file (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileNotFound& e) { cout << String("Error: File not found (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileNotReadable& e) { cout << String("Error: File not readable (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::FileEmpty& e) { cout << String("Error: File empty (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::ParseError& e) { cout << String("Error: Unable to read file (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::InvalidValue& e) { cout << String("Error: Invalid value (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } catch (Exception::BaseException& e) { cout << String("Error: Unexpected error (") << e.what() << ")" << endl << "Code location: " << e.getFile() << ":" << e.getLine() << endl; } return 1; }
int main(int argc, const char** argv) { #if defined(__APPLE__) // we do not want to load plugins as this leads to serious problems // when shipping on mac os x QApplication::setLibraryPaths(QStringList()); #endif // ensure correct encoding of paths QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); Map<String, String> option_lists; Map<String, String> options; options["-print"] = "print"; Map<String, String> flags; flags["--help"] = "help"; Param param; param.parseCommandLine(argc, argv, options, flags, option_lists); //catch command line errors if (param.exists("help") //help requested || argc > 3 //too many arguments || (argc == 3 && !param.exists("print")) //three argument but no -print || (param.exists("print") && param.getValue("print") == "") //-print but no file given ) { cerr << endl << "INIFileEditor -- An editor for OpenMS configuration files." << endl << endl << "Usage:" << endl << " INIFileEditor [options] [file]" << endl << endl << "Options are:" << endl << " --help Shows this help and exits" << endl << " -print <file> Prints the content of the file to the command line and exits" << endl << endl; return 0; } //print a ini file as text if (param.exists("print")) { Param data; ParamXMLFile paramFile; try { paramFile.load(param.getValue("print"), data); for (Param::ParamIterator it = data.begin(); it != data.end(); ++it) { cout << it.getName() << " = " << it->value << endl; } } catch (Exception::BaseException& e) { LOG_ERROR << "Error while parsing file '" << param.getValue("print") << "'\n"; LOG_ERROR << e << "\n"; } return 0; } //Create window QApplicationTOPP app(argc, const_cast<char**>(argv)); //set plastique style unless windows / mac style is available if (QStyleFactory::keys().contains("windowsxp", Qt::CaseInsensitive)) { app.setStyle("windowsxp"); } else if (QStyleFactory::keys().contains("macintosh", Qt::CaseInsensitive)) { app.setStyle("macintosh"); } else if (QStyleFactory::keys().contains("plastique", Qt::CaseInsensitive)) { app.setStyle("plastique"); } INIFileEditorWindow editor_window; //Open passed file if (argc == 2) { //cout << "OPEN: " << argv[1] << endl; editor_window.openFile(argv[1]); } #ifdef OPENMS_WINDOWSPLATFORM FreeConsole(); // get rid of console window at this point (we will not see any console output from this point on) AttachConsole(-1); // if the parent is a console, reattach to it - so we can see debug output - a normal user will usually not use cmd.exe to start a GUI) #endif editor_window.show(); return app.exec(); }