ExitCodes main_(int, const char **) override { //------------------------------------------------------------- // parameter handling //------------------------------------------------------------- //input/output files String in(getStringOption_("in")); String out(getStringOption_("out")); //------------------------------------------------------------- // loading input //------------------------------------------------------------- PeakMap exp; MzMLFile f; f.setLogType(log_type_); PeakFileOptions options; options.clearMSLevels(); options.addMSLevel(2); f.getOptions() = options; f.load(in, exp); writeDebug_("Data set contains " + String(exp.size()) + " spectra", 1); //------------------------------------------------------------- // calculations //------------------------------------------------------------- vector<PeptideIdentification> pep_ids; CompNovoIdentificationCID comp_novo_id; // set the options Param algorithm_param = getParam_().copy("algorithm:", true); comp_novo_id.setParameters(algorithm_param); comp_novo_id.getIdentifications(pep_ids, exp); algorithm_param = comp_novo_id.getParameters(); //------------------------------------------------------------- // writing output //------------------------------------------------------------- DateTime now = DateTime::now(); String date_string = now.get(); String identifier("CompNovoCID_" + date_string); for (vector<PeptideIdentification>::iterator it = pep_ids.begin(); it != pep_ids.end(); ++it) { it->assignRanks(); it->setIdentifier(identifier); } vector<ProteinIdentification> prot_ids; ProteinIdentification prot_id; prot_id.setIdentifier(identifier); prot_id.setDateTime(now); StringList ms_runs; exp.getPrimaryMSRunPath(ms_runs); prot_id.setPrimaryMSRunPath(ms_runs); ProteinIdentification::SearchParameters search_parameters; search_parameters.charges = "+2-+3"; if (algorithm_param.getValue("tryptic_only").toBool()) { search_parameters.digestion_enzyme = *(ProteaseDB::getInstance()->getEnzyme("Trypsin")); } else { search_parameters.digestion_enzyme = *(ProteaseDB::getInstance()->getEnzyme("no cleavage")); } search_parameters.mass_type = ProteinIdentification::MONOISOTOPIC; search_parameters.fixed_modifications = algorithm_param.getValue("fixed_modifications"); search_parameters.variable_modifications = algorithm_param.getValue("variable_modifications"); search_parameters.missed_cleavages = (UInt)algorithm_param.getValue("missed_cleavages"); search_parameters.fragment_mass_tolerance = (double)algorithm_param.getValue("fragment_mass_tolerance"); search_parameters.precursor_mass_tolerance = (double)algorithm_param.getValue("precursor_mass_tolerance"); search_parameters.fragment_mass_tolerance_ppm = false; search_parameters.precursor_mass_tolerance_ppm = false; prot_id.setSearchParameters(search_parameters); prot_id.setSearchEngineVersion("0.9beta"); prot_id.setSearchEngine("CompNovo"); prot_ids.push_back(prot_id); IdXMLFile().store(out, prot_ids, pep_ids); return EXECUTION_OK; }
ExitCodes main_(int, const char**) override { String tmp_dir = QDir::toNativeSeparators((File::getTempDirectory() + "/" + File::getUniqueName() + "/").toQString()); // body for the tmp files { QDir d; d.mkpath(tmp_dir.toQString()); } String logfile(getStringOption_("log")); String myrimatch_executable(getStringOption_("myrimatch_executable")); //------------------------------------------------------------- // get version of MyriMatch //------------------------------------------------------------- QProcess qp; String myrimatch_version; MyriMatchVersion myrimatch_version_i; // we invoke myrimatch w/o arguments. that yields a return code != 0. but // there is no other way for version 2.1 to get the version number qp.start(myrimatch_executable.toQString(), QStringList(), QIODevice::ReadOnly); // does automatic escaping etc... qp.waitForFinished(); String output(QString(qp.readAllStandardOutput())); vector<String> lines; vector<String> version_split; output.split('\n', lines); // the version number is expected to be in the second line if (lines.size() < 2) { writeLog_("Warning: MyriMatch version output (" + output + ") not formatted as expected!"); return EXTERNAL_PROGRAM_ERROR; } // the version is expected to be something like: // MyriMatch 2.1.111 (2011-12-27) lines[1].split(' ', version_split); if (version_split.size() == 3 && getVersion_(version_split[1], myrimatch_version_i)) { myrimatch_version = version_split[1].removeWhitespaces(); writeDebug_("Setting MyriMatch version to " + myrimatch_version, 1); } else { writeLog_("Warning: MyriMatch version output (" + output + ") not formatted as expected!"); return EXTERNAL_PROGRAM_ERROR; } if (! ( (myrimatch_version_i.myrimatch_major == 2) && // major must be 2 (myrimatch_version_i.myrimatch_minor == 1 || myrimatch_version_i.myrimatch_minor == 2) // minor .1 or .2 )) { writeLog_("Warning: unsupported MyriMatch version (" + myrimatch_version + "). Tested only for MyriMatch 2.1.x and 2.2.x." "\nIf you encounter parameter errors, you can try the flag 'ignoreConfigErrors', but be aware that MyriMatch might be misconfigured."); } //------------------------------------------------------------- // parsing parameters //------------------------------------------------------------- String inputfile_name = File::absolutePath(getStringOption_("in")); String outputfile_name = getStringOption_("out"); String db_name = File::absolutePath(String(getStringOption_("database"))); // building parameter String StringList parameters; if (getFlag_("ignoreConfigErrors")) parameters << "-ignoreConfigErrors"; // Common Identification engine options StringList static_mod_list; StringList dynamic_mod_list; translateModifications(static_mod_list, dynamic_mod_list); if (!static_mod_list.empty()) parameters << "-StaticMods" << ListUtils::concatenate(static_mod_list, " "); if (!dynamic_mod_list.empty()) parameters << "-DynamicMods" << ListUtils::concatenate(dynamic_mod_list, " "); parameters << "-ProteinDatabase" << File::absolutePath(db_name); if (getFlag_("precursor_mass_tolerance_avg")) { parameters << "-AvgPrecursorMzTolerance"; } else { parameters << "-MonoPrecursorMzTolerance"; } String precursor_mass_tolerance_unit = getStringOption_("precursor_mass_tolerance_unit") == "Da" ? " m/z" : " ppm"; parameters << String(getDoubleOption_("precursor_mass_tolerance")) + precursor_mass_tolerance_unit; String fragment_mass_tolerance_unit = getStringOption_("fragment_mass_tolerance_unit"); if (fragment_mass_tolerance_unit == "Da") { fragment_mass_tolerance_unit = "m/z"; } parameters << "-FragmentMzTolerance" << String(getDoubleOption_("fragment_mass_tolerance")) + " " + fragment_mass_tolerance_unit; StringList slf = getStringList_("SpectrumListFilters"); if (slf.size() > 0) { if (myrimatch_version_i.myrimatch_minor <= 1) { // use quotes around the slf arguments (will be added automatically by Qt during call), i.e. "-SpectrumListFilters" "peakPicking false 2-" parameters << "-SpectrumListFilters" << ListUtils::concatenate(slf, ";") << ""; } else { // no quotes -- pass a single argument, i.e. "-SpectrumListFilters peakPicking false 2-" parameters << "-SpectrumListFilters " + ListUtils::concatenate(slf, ";") << ""; } } //parameters << "-ThreadCountMultiplier" << String(getIntOption_("threads")); // MyriMatch does not recognise this, even though it's in the manual. // MyriMatch specific parameters parameters << "-NumChargeStates" << getIntOption_("NumChargeStates"); parameters << "-TicCutoffPercentage" << String(getDoubleOption_("TicCutoffPercentage")); parameters << "-MaxDynamicMods" << getIntOption_("MaxDynamicMods"); parameters << "-MaxResultRank" << getIntOption_("MaxResultRank"); parameters << "-MinTerminiCleavages" << getIntOption_("MinTerminiCleavages"); parameters << "-MaxMissedCleavages" << getIntOption_("MaxMissedCleavages"); String cleavage_rule = getStringOption_("CleavageRules"); if (cleavage_rule.empty()) { cleavage_rule = "Trypsin/P"; } parameters << "-CleavageRules" << cleavage_rule; // advanced parameters parameters << "-MinPeptideMass" << getDoubleOption_("MinPeptideMass"); parameters << "-MaxPeptideMass" << getDoubleOption_("MaxPeptideMass"); parameters << "-MinPeptideLength" << getIntOption_("MinPeptideLength"); parameters << "-MaxPeptideLength" << getIntOption_("MaxPeptideLength"); parameters << "-NumIntensityClasses" << getIntOption_("NumIntensityClasses"); parameters << "-ClassSizeMultiplier" << getDoubleOption_("ClassSizeMultiplier"); parameters << "-MonoisotopeAdjustmentSet" << getStringOption_("MonoisotopeAdjustmentSet"); parameters << "-cpus" << getIntOption_("threads"); // Constant parameters // DecoyPrefix worked only when set through the config file String cfg_file = tmp_dir + "myrimatch.cfg"; ofstream f(cfg_file.c_str()); f << "DecoyPrefix=\"\"\n"; f.close(); parameters << "-cfg" << cfg_file; // path to input file must be the last parameter parameters << inputfile_name; //------------------------------------------------------------- // calculations //------------------------------------------------------------- QStringList qparam; writeDebug_("MyriMatch arguments:", 1); writeDebug_(String("\"") + ListUtils::concatenate(parameters, "\" \"") + "\"", 1); for (Size i = 0; i < parameters.size(); ++i) { qparam << parameters[i].toQString(); } QProcess process; // Bad style, because it breaks relative paths? process.setWorkingDirectory(tmp_dir.toQString()); process.start(myrimatch_executable.toQString(), qparam, QIODevice::ReadOnly); bool success = process.waitForFinished(-1); String myri_msg(QString(process.readAllStandardOutput())); String myri_err(QString(process.readAllStandardError())); writeDebug_(myri_msg, 1); writeDebug_(myri_err, 0); if (!success || process.exitStatus() != 0 || process.exitCode() != 0) { writeLog_("Error: MyriMatch problem! (Details can be seen in the logfile: \"" + logfile + "\")"); writeLog_("Note: This message can also be triggered if you run out of space in your tmp directory"); return EXTERNAL_PROGRAM_ERROR; } //------------------------------------------------------------- // reading MyriMatch output //------------------------------------------------------------- writeDebug_("Reading output of MyriMatch", 5); String exp_name = File::basename(inputfile_name); String pep_file = tmp_dir + File::removeExtension(exp_name) + ".pepXML"; vector<ProteinIdentification> protein_identifications; vector<PeptideIdentification> peptide_identifications; PeakMap exp; if (File::exists(pep_file)) { MzMLFile fh; fh.load(inputfile_name, exp); SpectrumMetaDataLookup lookup; lookup.readSpectra(exp.getSpectra()); PepXMLFile().load(pep_file, protein_identifications, peptide_identifications, exp_name, lookup); } else { writeLog_("Error: MyriMatch problem! No pepXML output file (expected as '" + pep_file + "') was generated by MyriMatch."); writeLog_("Note: This message can be triggered if no MS2 spectra were found or no identifications were made."); writeLog_(" Myrimatch expects MS2 spectra in mzML files to contain the MSn tag. MSSpectrum with MS level 2 is not sufficient. You can use FileConverter to create such an mzML file by converting from mzML --> mzXML --> mzML."); return EXTERNAL_PROGRAM_ERROR; } if (debug_level_ == 0) { QFile(pep_file.toQString()).remove(); QFile(cfg_file.toQString()).remove(); } else { writeDebug_(String("Not removing '") + pep_file + "' for debugging purposes. Please delete manually!", 1); writeDebug_(String("Not removing '") + cfg_file + "' for debugging purposes. Please delete manually!", 1); } //------------------------------------------------------------- // writing results //------------------------------------------------------------- ProteinIdentification::SearchParameters search_parameters; search_parameters.db = getStringOption_("database"); ProteinIdentification::PeakMassType mass_type = getFlag_("precursor_mass_tolerance_avg") == true ? ProteinIdentification::AVERAGE : ProteinIdentification::MONOISOTOPIC; search_parameters.mass_type = mass_type; search_parameters.fixed_modifications = getStringList_("fixed_modifications"); search_parameters.variable_modifications = getStringList_("variable_modifications"); search_parameters.missed_cleavages = getIntOption_("MaxMissedCleavages"); search_parameters.fragment_mass_tolerance = getDoubleOption_("fragment_mass_tolerance"); search_parameters.precursor_mass_tolerance = getDoubleOption_("precursor_mass_tolerance"); search_parameters.precursor_mass_tolerance_ppm = getStringOption_("precursor_mass_tolerance_unit") == "ppm" ? true : false; search_parameters.fragment_mass_tolerance_ppm = getStringOption_("fragment_mass_tolerance_unit") == "ppm" ? true : false; protein_identifications[0].setSearchParameters(search_parameters); protein_identifications[0].setSearchEngineVersion(myrimatch_version); protein_identifications[0].setSearchEngine("MyriMatch"); if (!protein_identifications.empty()) { StringList ms_runs; exp.getPrimaryMSRunPath(ms_runs); protein_identifications[0].setPrimaryMSRunPath(ms_runs); } IdXMLFile().store(outputfile_name, protein_identifications, peptide_identifications); return EXECUTION_OK; }
ExitCodes main_(int, const char**) override { //------------------------------------------------------------- // parsing parameters //------------------------------------------------------------- String in(getStringOption_("in")); String out(getStringOption_("out")); String pair_in(getStringOption_("pair_in")); String feature_out(getStringOption_("feature_out")); double precursor_mass_tolerance(getDoubleOption_("precursor_mass_tolerance")); double RT_tolerance(getDoubleOption_("RT_tolerance")); double expansion_range(getDoubleOption_("expansion_range")); Size max_isotope(getIntOption_("max_isotope")); Int debug(getIntOption_("debug")); //------------------------------------------------------------- // reading input //------------------------------------------------------------- PeakMap exp; MzMLFile().load(in, exp); exp.sortSpectra(); exp.updateRanges(); // read pair file ifstream is(pair_in.c_str()); String line; vector<SILAC_pair> pairs; while (getline(is, line)) { line.trim(); if (line.empty() || line[0] == '#') { continue; } vector<String> split; line.split(' ', split); if (split.size() != 4) { cerr << "missformated line ('" << line << "') should be (space separated) 'm/z-light m/z-heavy charge rt'" << endl; } SILAC_pair p; p.mz_light = split[0].toDouble(); p.mz_heavy = split[1].toDouble(); p.charge = split[2].toInt(); p.rt = split[3].toDouble(); pairs.push_back(p); } is.close(); //------------------------------------------------------------- // calculations //------------------------------------------------------------- ConsensusMap results_map; results_map.getColumnHeaders()[0].label = "light"; results_map.getColumnHeaders()[0].filename = in; results_map.getColumnHeaders()[1].label = "heavy"; results_map.getColumnHeaders()[1].filename = in; FeatureFinderAlgorithmIsotopeWavelet iso_ff; Param ff_param(iso_ff.getParameters()); ff_param.setValue("max_charge", 3); ff_param.setValue("intensity_threshold", -1.0); iso_ff.setParameters(ff_param); FeatureFinder ff; ff.setLogType(ProgressLogger::NONE); vector<SILACQuantitation> quantlets; FeatureMap all_features; for (PeakMap::ConstIterator it = exp.begin(); it != exp.end(); ++it) { if (it->size() == 0 || it->getMSLevel() != 1 || !it->getInstrumentSettings().getZoomScan()) { continue; } PeakSpectrum new_spec = *it; // get spacing from data double min_spacing(numeric_limits<double>::max()); double last_mz(0); for (PeakSpectrum::ConstIterator pit = new_spec.begin(); pit != new_spec.end(); ++pit) { if (pit->getMZ() - last_mz < min_spacing) { min_spacing = pit->getMZ() - last_mz; } last_mz = pit->getMZ(); } writeDebug_("Min-spacing=" + String(min_spacing), 1); // split the spectrum into two subspectra, by using different hypothesis of // the SILAC pairs Size idx = 0; for (vector<SILAC_pair>::const_iterator pit = pairs.begin(); pit != pairs.end(); ++pit, ++idx) { // in RT window? if (fabs(it->getRT() - pit->rt) >= RT_tolerance) { continue; } // now excise the two ranges for the pair, complete isotope distributions of both, light and heavy PeakSpectrum light_spec, heavy_spec; light_spec.setRT(it->getRT()); heavy_spec.setRT(it->getRT()); for (PeakSpectrum::ConstIterator sit = it->begin(); sit != it->end(); ++sit) { double mz(sit->getMZ()); if (mz - (pit->mz_light - precursor_mass_tolerance) > 0 && (pit->mz_light + (double)max_isotope * Constants::NEUTRON_MASS_U / (double)pit->charge + precursor_mass_tolerance) - mz > 0) { light_spec.push_back(*sit); } if (mz - (pit->mz_heavy - precursor_mass_tolerance) > 0 && (pit->mz_heavy + (double)max_isotope * Constants::NEUTRON_MASS_U / (double)pit->charge + precursor_mass_tolerance) - mz > 0) { heavy_spec.push_back(*sit); } } // expand light spectrum Peak1D p; p.setIntensity(0); if (light_spec.size() > 0) { double lower_border = light_spec.begin()->getMZ() - expansion_range; for (double pos = light_spec.begin()->getMZ(); pos > lower_border; pos -= min_spacing) { p.setMZ(pos); light_spec.insert(light_spec.begin(), p); } double upper_border = light_spec.begin()->getMZ() - expansion_range; for (double pos = light_spec.rbegin()->getMZ(); pos < upper_border; pos += min_spacing) { p.setMZ(pos); light_spec.push_back(p); } } if (heavy_spec.size() > 0) { // expand heavy spectrum double lower_border = heavy_spec.begin()->getMZ() - expansion_range; for (double pos = heavy_spec.begin()->getMZ(); pos > lower_border; pos -= min_spacing) { p.setMZ(pos); heavy_spec.insert(heavy_spec.begin(), p); } double upper_border = heavy_spec.begin()->getMZ() - expansion_range; for (double pos = heavy_spec.rbegin()->getMZ(); pos < upper_border; pos += min_spacing) { p.setMZ(pos); heavy_spec.push_back(p); } } // create experiments for feature finding PeakMap new_exp_light, new_exp_heavy; new_exp_light.addSpectrum(light_spec); new_exp_heavy.addSpectrum(heavy_spec); if (debug > 9) { MzMLFile().store(String(it->getRT()) + "_debugging_light.mzML", new_exp_light); MzMLFile().store(String(it->getRT()) + "_debugging_heavy.mzML", new_exp_heavy); } writeDebug_("Spectrum-id: " + it->getNativeID() + " @ " + String(it->getRT()) + "s", 1); new_exp_light.updateRanges(); new_exp_heavy.updateRanges(); FeatureMap feature_map_light, feature_map_heavy, seeds; if (light_spec.size() > 0) { ff.run("isotope_wavelet", new_exp_light, feature_map_light, ff_param, seeds); } writeDebug_("#light_features=" + String(feature_map_light.size()), 1); if (heavy_spec.size() > 0) { ff.run("isotope_wavelet", new_exp_heavy, feature_map_heavy, ff_param, seeds); } writeDebug_("#heavy_features=" + String(feature_map_heavy.size()), 1); // search if feature maps to m/z value of pair vector<MatchedFeature> light, heavy; for (FeatureMap::const_iterator fit = feature_map_light.begin(); fit != feature_map_light.end(); ++fit) { all_features.push_back(*fit); light.push_back(MatchedFeature(*fit, idx)); } for (FeatureMap::const_iterator fit = feature_map_heavy.begin(); fit != feature_map_heavy.end(); ++fit) { all_features.push_back(*fit); heavy.push_back(MatchedFeature(*fit, idx)); } if (!heavy.empty() && !light.empty()) { writeDebug_("Finding best feature pair out of " + String(light.size()) + " light and " + String(heavy.size()) + " heavy matching features.", 1); // now find "good" matches, means the pair with the smallest m/z deviation Feature best_light, best_heavy; double best_deviation(numeric_limits<double>::max()); Size best_idx(pairs.size()); for (vector<MatchedFeature>::const_iterator fit1 = light.begin(); fit1 != light.end(); ++fit1) { for (vector<MatchedFeature>::const_iterator fit2 = heavy.begin(); fit2 != heavy.end(); ++fit2) { if (fit1->idx != fit2->idx || fit1->f.getCharge() != fit2->f.getCharge() || fabs(fit1->f.getMZ() - pairs[fit1->idx].mz_light) > precursor_mass_tolerance || fabs(fit2->f.getMZ() - pairs[fit2->idx].mz_heavy) > precursor_mass_tolerance) { continue; } double deviation(0); deviation = fabs((fit1->f.getMZ() - pairs[fit1->idx].mz_light) - (fit2->f.getMZ() - pairs[fit2->idx].mz_heavy)); if (deviation < best_deviation && deviation < precursor_mass_tolerance) { best_light = fit1->f; best_heavy = fit2->f; best_idx = fit1->idx; } } } if (best_idx == pairs.size()) { continue; } writeDebug_("Ratio: " + String(best_heavy.getIntensity() / best_light.getIntensity()), 1); ConsensusFeature SILAC_feature; SILAC_feature.setMZ((best_light.getMZ() + best_heavy.getMZ()) / 2.0); SILAC_feature.setRT((best_light.getRT() + best_heavy.getRT()) / 2.0); SILAC_feature.insert(0, best_light); SILAC_feature.insert(1, best_heavy); results_map.push_back(SILAC_feature); quantlets.push_back(SILACQuantitation(best_light.getIntensity(), best_heavy.getIntensity(), best_idx)); } } } // now calculate the final quantitation values from the quantlets Map<Size, vector<SILACQuantitation> > idx_to_quantlet; for (vector<SILACQuantitation>::const_iterator it = quantlets.begin(); it != quantlets.end(); ++it) { idx_to_quantlet[it->idx].push_back(*it); } for (Map<Size, vector<SILACQuantitation> >::ConstIterator it1 = idx_to_quantlet.begin(); it1 != idx_to_quantlet.end(); ++it1) { SILAC_pair silac_pair = pairs[it1->first]; // simply add up all intensities and calculate the final ratio double light_sum(0), heavy_sum(0); vector<double> light_ints, heavy_ints, ratios; for (vector<SILACQuantitation>::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) { light_sum += it2->light_intensity; light_ints.push_back(it2->light_intensity); heavy_sum += it2->heavy_intensity; heavy_ints.push_back(it2->heavy_intensity); ratios.push_back(it2->heavy_intensity / it2->light_intensity * (it2->heavy_intensity + it2->light_intensity)); } double absdev_ratios = Math::absdev(ratios.begin(), ratios.begin() + (ratios.size()) / (heavy_sum + light_sum)); cout << "Ratio: " << silac_pair.mz_light << " <-> " << silac_pair.mz_heavy << " @ " << silac_pair.rt << " s, ratio(h/l) " << heavy_sum / light_sum << " +/- " << absdev_ratios << " (#scans for quantation: " << String(it1->second.size()) << " )" << endl; } //------------------------------------------------------------- // writing output //------------------------------------------------------------- StringList ms_runs; exp.getPrimaryMSRunPath(ms_runs); if (feature_out != "") { all_features.setPrimaryMSRunPath(ms_runs); FeatureXMLFile().store(feature_out, all_features); } writeDebug_("Writing output", 1); results_map.setPrimaryMSRunPath(ms_runs); ConsensusXMLFile().store(out, results_map); return EXECUTION_OK; }
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; } }
ExitCodes main_(int, const char**) override { //input file names String in = getStringOption_("in"); String out = getStringOption_("out"); String out_mzq = getStringOption_("out_mzq"); //prevent loading of fragment spectra PeakFileOptions options; options.setMSLevels(vector<Int>(1, 1)); //reading input data MzMLFile f; f.getOptions() = options; f.setLogType(log_type_); PeakMap exp; f.load(in, exp); exp.updateRanges(); if (exp.getSpectra().empty()) { throw OpenMS::Exception::FileEmpty(__FILE__, __LINE__, __FUNCTION__, "Error: No MS1 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 spectra expected. To enforce processing of the data set the -force flag."); } } //load seeds FeatureMap seeds; if (getStringOption_("seeds") != "") { FeatureXMLFile().load(getStringOption_("seeds"), seeds); } //setup of FeatureFinder FeatureFinder ff; ff.setLogType(log_type_); // A map for the resulting features FeatureMap features; StringList ms_runs; exp.getPrimaryMSRunPath(ms_runs); features.setPrimaryMSRunPath(ms_runs); // get parameters specific for the feature finder Param feafi_param = getParam_().copy("algorithm:", true); writeDebug_("Parameters passed to FeatureFinder", feafi_param, 3); // Apply the feature finder ff.run(FeatureFinderAlgorithmPicked::getProductName(), exp, features, feafi_param, seeds); features.applyMemberFunction(&UniqueIdInterface::setUniqueId); // DEBUG if (debug_level_ > 10) { FeatureMap::Iterator it; for (it = features.begin(); it != features.end(); ++it) { if (!it->isMetaEmpty()) { vector<String> keys; it->getKeys(keys); LOG_INFO << "Feature " << it->getUniqueId() << endl; for (Size i = 0; i < keys.size(); i++) { LOG_INFO << " " << keys[i] << " = " << it->getMetaValue(keys[i]) << endl; } } } } //------------------------------------------------------------- // writing files //------------------------------------------------------------- //annotate output with data processing info addDataProcessing_(features, getProcessingInfo_(DataProcessing::QUANTITATION)); // write features to user specified output file FeatureXMLFile map_file; // Remove detailed convex hull information and subordinate features // (unless requested otherwise) to reduce file size of feature files // unless debugging is turned on. if (debug_level_ < 5) { FeatureMap::Iterator it; for (it = features.begin(); it != features.end(); ++it) { it->getConvexHull().expandToBoundingBox(); for (Size i = 0; i < it->getConvexHulls().size(); ++i) { it->getConvexHulls()[i].expandToBoundingBox(); } it->getSubordinates().clear(); } } map_file.store(out, features); if (!out_mzq.trim().empty()) { std::vector<DataProcessing> tmp; for (Size i = 0; i < exp[0].getDataProcessing().size(); i++) { tmp.push_back(*exp[0].getDataProcessing()[i].get()); } MSQuantifications msq(features, exp.getExperimentalSettings(), tmp ); msq.assignUIDs(); MzQuantMLFile file; file.store(out_mzq, msq); } return EXECUTION_OK; }