void SimplePairFinder::run(const std::vector<ConsensusMap> & input_maps, ConsensusMap & result_map) { if (input_maps.size() != 2) throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "exactly two input maps required"); checkIds_(input_maps); // progress dots Int progress_dots = 0; if (this->param_.exists("debug::progress_dots")) { progress_dots = (Int) this->param_.getValue("debug:progress_dots"); } Int number_of_considered_element_pairs = 0; // For each element in map 0, find its best friend in map 1 std::vector<UInt> best_companion_index_0(input_maps[0].size(), UInt(-1)); std::vector<double> best_companion_quality_0(input_maps[0].size(), 0); for (UInt fi0 = 0; fi0 < input_maps[0].size(); ++fi0) { double best_quality = -std::numeric_limits<double>::max(); for (UInt fi1 = 0; fi1 < input_maps[1].size(); ++fi1) { double quality = similarity_(input_maps[0][fi0], input_maps[1][fi1]); if (quality > best_quality) { best_quality = quality; best_companion_index_0[fi0] = fi1; } ++number_of_considered_element_pairs; if (progress_dots && !(number_of_considered_element_pairs % progress_dots)) { std::cout << '-' << std::flush; } } best_companion_quality_0[fi0] = best_quality; } // For each element in map 1, find its best friend in map 0 std::vector<UInt> best_companion_index_1(input_maps[1].size(), UInt(-1)); std::vector<double> best_companion_quality_1(input_maps[1].size(), 0); for (UInt fi1 = 0; fi1 < input_maps[1].size(); ++fi1) { double best_quality = -std::numeric_limits<double>::max(); for (UInt fi0 = 0; fi0 < input_maps[0].size(); ++fi0) { double quality = similarity_(input_maps[0][fi0], input_maps[1][fi1]); if (quality > best_quality) { best_quality = quality; best_companion_index_1[fi1] = fi0; } ++number_of_considered_element_pairs; if (progress_dots && !(number_of_considered_element_pairs % progress_dots)) { std::cout << '+' << std::flush; } } best_companion_quality_1[fi1] = best_quality; } // And if both like each other, they become a pair. // element_pairs_->clear(); for (UInt fi0 = 0; fi0 < input_maps[0].size(); ++fi0) { // fi0 likes someone ... if (best_companion_quality_0[fi0] > pair_min_quality_) { // ... who likes him too ... UInt best_companion_of_fi0 = best_companion_index_0[fi0]; if (best_companion_index_1[best_companion_of_fi0] == fi0 && best_companion_quality_1[best_companion_of_fi0] > pair_min_quality_ ) { ConsensusFeature f; f.insert(input_maps[0][fi0]); f.insert(input_maps[1][best_companion_of_fi0]); f.computeConsensus(); f.setQuality(best_companion_quality_0[fi0] + best_companion_quality_1[best_companion_of_fi0]); result_map.push_back(f); } } } return; }
ExitCodes main_(int, const char**) override { //------------------------------------------------------------- // parameter handling //------------------------------------------------------------- String in = getStringOption_("in"); String out = getStringOption_("out"); FileTypes::Type out_type = FileTypes::nameToType(getStringOption_("out_type")); if (out_type == FileTypes::UNKNOWN) { out_type = FileHandler().getTypeByFileName(out); } //------------------------------------------------------------- // loading input //------------------------------------------------------------- MzMLFile mz_data_file; mz_data_file.setLogType(log_type_); PeakMap ms_peakmap; std::vector<Int> ms_level(1, 1); (mz_data_file.getOptions()).setMSLevels(ms_level); mz_data_file.load(in, ms_peakmap); if (ms_peakmap.size() == 0) { LOG_WARN << "The given file does not contain any conventional peak data, but might" " contain chromatograms. This tool currently cannot handle them, sorry."; return INCOMPATIBLE_INPUT_DATA; } // make sure that the spectra are sorted by m/z ms_peakmap.sortSpectra(true); //------------------------------------------------------------- // get params for MTD and EPD algorithms //------------------------------------------------------------- Param com_param = getParam_().copy("algorithm:common:", true); writeDebug_("Common parameters passed to both sub-algorithms (mtd and epd)", com_param, 3); Param mtd_param = getParam_().copy("algorithm:mtd:", true); writeDebug_("Parameters passed to MassTraceDetection", mtd_param, 3); Param epd_param = getParam_().copy("algorithm:epd:", true); writeDebug_("Parameters passed to ElutionPeakDetection", epd_param, 3); //------------------------------------------------------------- // configure and run MTD //------------------------------------------------------------- MassTraceDetection mt_ext; mtd_param.insert("", com_param); mtd_param.remove("chrom_fwhm"); mt_ext.setParameters(mtd_param); vector<MassTrace> m_traces; mt_ext.run(ms_peakmap, m_traces); vector<MassTrace> m_traces_final; bool use_epd = epd_param.getValue("enabled").toBool(); if (!use_epd) { swap(m_traces_final, m_traces); } else { ElutionPeakDetection ep_det; epd_param.remove("enabled"); // artificially added above epd_param.insert("", com_param); ep_det.setParameters(epd_param); std::vector<MassTrace> split_mtraces; // note: this step will destroy any meta data annotation (e.g. FWHM_mz_avg) ep_det.detectPeaks(m_traces, split_mtraces); if (ep_det.getParameters().getValue("width_filtering") == "auto") { m_traces_final.clear(); ep_det.filterByPeakWidth(split_mtraces, m_traces_final); LOG_INFO << "Notice: " << split_mtraces.size() - m_traces_final.size() << " of total " << split_mtraces.size() << " were dropped because of too low peak width." << std::endl; } else { swap(m_traces_final, split_mtraces); } } //------------------------------------------------------------- // writing consensus map output //------------------------------------------------------------- if (out_type == FileTypes::CONSENSUSXML) { ConsensusMap consensus_map; StringList ms_runs; ms_peakmap.getPrimaryMSRunPath(ms_runs); consensus_map.setPrimaryMSRunPath(ms_runs); for (Size i = 0; i < m_traces_final.size(); ++i) { if (m_traces_final[i].getSize() == 0) continue; ConsensusFeature fcons; int k = 0; for (MassTrace::const_iterator it = m_traces_final[i].begin(); it != m_traces_final[i].end(); ++it) { FeatureHandle fhandle; fhandle.setRT(it->getRT()); fhandle.setMZ(it->getMZ()); fhandle.setIntensity(it->getIntensity()); fhandle.setUniqueId(++k); fcons.insert(fhandle); } fcons.setMetaValue(3, m_traces_final[i].getLabel()); fcons.setCharge(0); fcons.setWidth(m_traces_final[i].estimateFWHM(use_epd)); fcons.setQuality(1 - (1.0 / m_traces_final[i].getSize())); fcons.setRT(m_traces_final[i].getCentroidRT()); fcons.setMZ(m_traces_final[i].getCentroidMZ()); fcons.setIntensity(m_traces_final[i].getIntensity(false)); consensus_map.push_back(fcons); } consensus_map.applyMemberFunction(&UniqueIdInterface::setUniqueId); addDataProcessing_(consensus_map, getProcessingInfo_(DataProcessing::QUANTITATION)); consensus_map.setUniqueId(); ConsensusXMLFile().store(out, consensus_map); } else //(out_type == FileTypes::FEATUREXML) { //----------------------------------------------------------- // convert mass traces to features //----------------------------------------------------------- std::vector<double> stats_sd; FeatureMap ms_feat_map; StringList ms_runs; ms_peakmap.getPrimaryMSRunPath(ms_runs); ms_feat_map.setPrimaryMSRunPath(ms_runs); for (Size i = 0; i < m_traces_final.size(); ++i) { if (m_traces_final[i].getSize() == 0) continue; m_traces_final[i].updateMeanMZ(); m_traces_final[i].updateWeightedMZsd(); Feature f; f.setMetaValue(3, m_traces_final[i].getLabel()); f.setCharge(0); f.setMZ(m_traces_final[i].getCentroidMZ()); f.setIntensity(m_traces_final[i].getIntensity(false)); f.setRT(m_traces_final[i].getCentroidRT()); f.setWidth(m_traces_final[i].estimateFWHM(use_epd)); f.setOverallQuality(1 - (1.0 / m_traces_final[i].getSize())); f.getConvexHulls().push_back(m_traces_final[i].getConvexhull()); double sd = m_traces_final[i].getCentroidSD(); f.setMetaValue("SD", sd); f.setMetaValue("SD_ppm", sd / f.getMZ() * 1e6); if (m_traces_final[i].fwhm_mz_avg > 0) f.setMetaValue("FWHM_mz_avg", m_traces_final[i].fwhm_mz_avg); stats_sd.push_back(m_traces_final[i].getCentroidSD()); ms_feat_map.push_back(f); } // print some stats about standard deviation of mass traces if (stats_sd.size() > 0) { std::sort(stats_sd.begin(), stats_sd.end()); LOG_INFO << "Mass trace m/z s.d.\n" << " low quartile: " << stats_sd[stats_sd.size() * 1 / 4] << "\n" << " median: " << stats_sd[stats_sd.size() * 1 / 2] << "\n" << " upp quartile: " << stats_sd[stats_sd.size() * 3 / 4] << std::endl; } ms_feat_map.applyMemberFunction(&UniqueIdInterface::setUniqueId); //------------------------------------------------------------- // writing output //------------------------------------------------------------- // annotate output with data processing info TODO addDataProcessing_(ms_feat_map, getProcessingInfo_(DataProcessing::QUANTITATION)); //ms_feat_map.setUniqueId(); FeatureXMLFile().store(out, ms_feat_map); } return EXECUTION_OK; }
void QTClusterFinder::makeConsensusFeature_(list<QTCluster> & clustering, ConsensusFeature & feature, OpenMSBoost::unordered_map<GridFeature *, std::vector< QTCluster * > > & element_mapping) { // find the best cluster (a valid cluster with the highest score) list<QTCluster>::iterator best = clustering.begin(); while (best != clustering.end() && best->isInvalid()) {++best;} for (list<QTCluster>::iterator it = best; it != clustering.end(); ++it) { if (!it->isInvalid()) { if (it->getQuality() > best->getQuality()) { best = it; } } } // no more clusters to process -> clear clustering and return if (best == clustering.end()) { clustering.clear(); return; } OpenMSBoost::unordered_map<Size, GridFeature *> elements; best->getElements(elements); // cout << "Elements: " << elements.size() << " with best " << best->getQuality() << " invalid " << best->isInvalid() << endl; // create consensus feature from best cluster: feature.setQuality(best->getQuality()); for (OpenMSBoost::unordered_map<Size, GridFeature *>::const_iterator it = elements.begin(); it != elements.end(); ++it) { feature.insert(it->first, it->second->getFeature()); } feature.computeConsensus(); // update the clustering: // 1. remove current "best" cluster // 2. update all clusters accordingly and invalidate elements whose central // element is removed best->setInvalid(); for (OpenMSBoost::unordered_map<Size, GridFeature *>::const_iterator it = elements.begin(); it != elements.end(); ++it) { for (std::vector< QTCluster* >::iterator cluster = element_mapping[&(*it->second)].begin(); cluster != element_mapping[&(*it->second)].end(); ++cluster) { // we do not want to update invalid features (saves time and does not // recompute the quality) if (!(*cluster)->isInvalid()) { if (!(*cluster)->update(elements)) // cluster is invalid (center point removed): { (*cluster)->setInvalid(); } } } } }