| 83 | |
| 84 | template <typename MapType> |
| 85 | void QTClusterFinder::run_(const vector<MapType>& input_maps, |
| 86 | ConsensusMap& result_map) |
| 87 | { |
| 88 | // update parameters (dummy) |
| 89 | setParameters_(1, 1); |
| 90 | |
| 91 | if (use_IDs_) |
| 92 | { |
| 93 | // map string "modified sequence/charge" to all RTs the feature has been observed in the different maps |
| 94 | std::unordered_map<String, std::vector<double>> ided_feat_rts; |
| 95 | //std::unordered_map<String, std::vector<const typename MapType::FeatureType*>> ided_feats; |
| 96 | double minRT = std::numeric_limits<double>::max(); |
| 97 | for (auto& map : input_maps) |
| 98 | { |
| 99 | for (auto feat : map) //OMS_CODING_TEST_EXCLUDE Note: needs copy to sort |
| 100 | { |
| 101 | if (feat.getRT() < minRT) minRT = feat.getRT(); |
| 102 | auto& pepIDs = feat.getPeptideIdentifications(); |
| 103 | if (!pepIDs.empty()) |
| 104 | { |
| 105 | //TODO I think we sort in run_internal again. Could be avoided. |
| 106 | feat.sortPeptideIdentifications(); |
| 107 | auto& hits = pepIDs[0].getHits(); |
| 108 | if (!hits.empty()) |
| 109 | { |
| 110 | if ((hits[0].getScore() > min_score_ && pepIDs[0].isHigherScoreBetter()) || |
| 111 | (hits[0].getScore() < min_score_ && !pepIDs[0].isHigherScoreBetter())) |
| 112 | { |
| 113 | //TODO we could loosen the score filtering by requiring only ONE IDed feature of a peptide to pass the threshold. |
| 114 | // Would require a second pass though |
| 115 | const String key = pepIDs[0].getHits()[0].getSequence().toString() + "/" + feat.getCharge(); |
| 116 | const auto [it, inserted] = ided_feat_rts.emplace(key, std::vector<double>{feat.getRT()}); |
| 117 | if (!inserted) // already present |
| 118 | { |
| 119 | it->second.push_back(feat.getRT()); |
| 120 | } |
| 121 | //TODO we could score the whole feature instead of just the RT to calculate tolerances based on |
| 122 | // a combined score (RT/mz; using the scoring function of this class) instead of just RT |
| 123 | /*const auto it_inserted_feat = ided_feats.emplace(key, std::vector<const typename MapType::FeatureType*>{&feat}); |
| 124 | if (!it_inserted_feat.second) |
| 125 | { |
| 126 | it_inserted_feat.first->second.push_back(&feat); |
| 127 | }*/ |
| 128 | } |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | //Note: this does not differentiate between the variety of differences between distinct map pairs. E.g. |
| 135 | // differences between map 1 and map 2 might be usually very small (e.g. they are replicates), while |
| 136 | // differences between map 1 and map 3 are large, since they are different conditions. But we might lose |
| 137 | // robust estimates and use more memory if we split them. |
| 138 | std::vector<std::pair<double,std::vector<double>>> medians_diffs; |
| 139 | medians_diffs.resize(ided_feat_rts.size()); |
| 140 | Size c = 0; |
| 141 | // for every ID, calculate median RT and differences |
| 142 | for (auto& id_rts : ided_feat_rts) |
nothing calls this directly
no test coverage detected