///////////////////////////////////////////////////////////////////////////// // merge the target to the search feature void MS1FeatureMerger::mergeFeatures(SHFeature * target, SHFeature * toMerge) { double TOT_AREA = target->get_peak_area() + toMerge->get_peak_area(); // merge the m/z: target->set_MZ( (target->get_peak_area() * target->get_MZ() + toMerge->get_peak_area() * toMerge->get_MZ()) / TOT_AREA); // merge S/N: target->setSignalToNoise( (target->getSignalToNoise() * target->get_peak_area() + toMerge->getSignalToNoise() * toMerge->get_peak_area()) / TOT_AREA); // merge score: target->set_peak_score( (target->get_peak_score() * target->get_peak_area() + toMerge->get_peak_score() * toMerge->get_peak_area()) / TOT_AREA); // merge first the elution profiles: FeatureLCProfile * targetLC = target->getLCelutionProfile(); FeatureLCProfile * mergeLC = toMerge->getLCelutionProfile(); // add points of the toMerge to the target: map<int, MS1Signal>::iterator LC = mergeLC->getLCelutionSignalsStart(); while (LC != mergeLC->getLCelutionSignalsEnd()) { targetLC->addMS1elutionSignal(&(LC->second)); ++LC; } // possible extra info: if (target->getFeatureExtraInformation().empty()) { target->setFeatureExtraInformation(toMerge->getFeatureExtraInformation()); } // compute new parameters computeNewMS1FeatureParameters(target); // copy MS/MS information: if (toMerge->get_MS2_info(-3.0)) { target->add_MS2_info(toMerge->get_MS2_SCAN_MAP()); } }
////////////////////////////////////////////////////////////////// // Compute a varietiy of parameters for the LC elution peak void MS1FeatureMerger::computeNewMS1FeatureParameters(SHFeature * in) { FeatureLCProfile * lcProfile = in->getLCelutionProfile(); // define the apex treshold: double maxIntens = -1; map<int, MS1Signal>::iterator LC = lcProfile->getLCelutionSignalsStart(); while (LC != lcProfile->getLCelutionSignalsEnd()) { if (maxIntens < (*LC).second.intensity) { maxIntens = (*LC).second.intensity; } ++LC; } // get the MS peak above noise to copmute: double THRESHOLD = maxIntens / in->getSignalToNoise(); vector<MS1Signal *> computeMap; LC = lcProfile->getLCelutionSignalsStart(); in->set_scan_start((*LC).second.scan); in->set_retention_time_START((*LC).second.TR); while (LC != lcProfile->getLCelutionSignalsEnd()) { if ((*LC).second.intensity >= THRESHOLD) { computeMap.push_back(&(LC->second)); } ++LC; } --LC; in->set_scan_end((*LC).second.scan); in->set_retention_time_END((*LC).second.TR); if (!computeMap.empty()) { vector<MS1Signal *>::iterator P = computeMap.begin(); double TOT_AREA = 0; double start_TR = 0; double start_int = 0; double apexScan = 0; double apexTr = 0; double end_TR = 0; double end_int = 0; start_TR = (*P)->TR; start_int = (*P)->intensity; ++P; // go through all peaks in the LC elution profile: while (P != computeMap.end()) { if ((*P)->intensity >= THRESHOLD) { end_TR = (*P)->TR; end_int = (*P)->intensity; // compute an area between local start / end ms peak: double area = computeDeltaArea(start_TR, start_int - THRESHOLD, end_TR, end_int - THRESHOLD); TOT_AREA += area; apexScan += (double) ((*P)->scan) * area; apexTr += start_TR * area; // next scan: start_TR = end_TR; start_int = end_int; } ++P; } // if contained only one peak! if (computeMap.size() == 1) { in->set_peak_area((float) start_int); in->set_retention_time(in->get_retention_time_START()); in->set_scan_number(in->get_scan_start()); } else { in->set_peak_area((float) TOT_AREA); apexScan /= TOT_AREA; in->set_scan_number((int) apexScan); apexTr /= TOT_AREA; in->set_retention_time(apexTr); } // set the apex ms peak: LC = lcProfile->getLCelutionSignalMap()->lower_bound(in->get_scan_number()); in->set_apex_peak_intensity((*LC).second.intensity); } else { // no good peak above threshold, so reset all the features parameters to remove the feature in->set_peak_area(0); in->set_scan_number(0); in->set_retention_time(0); } }
////////////////////////////////////////////////// // find to this feature the features which should be merged vector<SHFeature *>::iterator MS1FeatureMerger::findFeaturesToMerge(SHFeature * search, vector<SHFeature *>::iterator mapCurrent, vector<SHFeature *> * Fmap) { bool log10Intens = true; // get the elution profile: FeatureLCProfile * searchLC = search->getLCelutionProfile(); while (mapCurrent != Fmap->end()) { // check absolute retention time difference: bool toMerge = false; SHFeature * mergedTarget = (*mapCurrent); double deltaTr = fabs(search->get_retention_time() - mergedTarget->get_retention_time()); if (deltaTr <= SuperHirnParameters::instance()->getInitialTrTolerance()) { // compare the end / start of the elution peak: MS1Signal * start; MS1Signal * end; if (search->get_retention_time() < mergedTarget->get_retention_time()) { start = &(searchLC->getLastLCelutionSignal()->second); end = &(mergedTarget->getLCelutionProfile()->getLCelutionSignalsStart()->second); } else { end = &(mergedTarget->getLCelutionProfile()->getLastLCelutionSignal()->second); start = &(searchLC->getLCelutionSignalsStart()->second); } double startIntens = start->intensity; if (log10Intens) { startIntens = log10(startIntens); } double endIntens = end->intensity; if (log10Intens) { endIntens = log10(endIntens); } double deltaIntens = fabs(startIntens - endIntens); deltaIntens /= startIntens; deltaTr = fabs(start->TR - end->TR); if ((deltaTr <= SuperHirnParameters::instance()->getMs1FeatureMergingTrTolerance()) && (deltaIntens <= SuperHirnParameters::instance()->getPercentageIntensityElutionBorderVariation())) { toMerge = true; } } if (toMerge) { // search->show_info();(*mapCurrent)->show_info(); mergeFeatures(search, mergedTarget); idsToRemove.push_back(mergedTarget->get_feature_ID()); mapCurrent = Fmap->erase(mapCurrent); if (search->get_peak_area() == 0) { idsToRemove.push_back(search->get_feature_ID()); mapCurrent++; break; } } else { mapCurrent++; } } return mapCurrent; }