///////////////////////////////////////////////////////////////////////////// // 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); } }