Ejemplo n.º 1
0
  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)
        }
      }
    }
  }
Ejemplo n.º 2
0
  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;
  }
Ejemplo n.º 3
0
  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_);
    }
  }
Ejemplo n.º 4
0
 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;
 }
Ejemplo n.º 6
0
 /// 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;
 }
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
  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);
    }
  }
Ejemplo n.º 9
0
  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);
    }
  }
Ejemplo n.º 10
0
  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);
  }
Ejemplo n.º 11
0
  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);
  }
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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();
}