private PeptideGroupBuilder AddRow(PeptideGroupBuilder seqBuilder, MassListRowReader rowReader, IDictionary<string, FastaSequence> dictNameSeq, ICollection<PeptideGroupDocNode> peptideGroupsNew, long lineNum, List<MeasuredRetentionTime> irtPeptides, List<SpectrumMzInfo> librarySpectra, List<TransitionImportErrorInfo> errorList) { var info = rowReader.TransitionInfo; var irt = rowReader.Irt; var libraryIntensity = rowReader.LibraryIntensity; var productMz = rowReader.ProductMz; if (irt == null && rowReader.IrtColumn != -1) { var error = new TransitionImportErrorInfo(string.Format(Resources.MassListImporter_AddRow_Invalid_iRT_value_at_precusor_m_z__0__for_peptide__1_, rowReader.TransitionInfo.PrecursorMz, rowReader.TransitionInfo.ModifiedSequence), rowReader.IrtColumn, lineNum); errorList.Add(error); return seqBuilder; } if (libraryIntensity == null && rowReader.LibraryColumn != -1) { var error = new TransitionImportErrorInfo(string.Format(Resources.MassListImporter_AddRow_Invalid_library_intensity_at_precursor__0__for_peptide__1_, rowReader.TransitionInfo.PrecursorMz, rowReader.TransitionInfo.ModifiedSequence), rowReader.LibraryColumn, lineNum); errorList.Add(error); return seqBuilder; } string name = info.ProteinName; if (info.TransitionExps.Any(t => t.IsDecoy)) name = PeptideGroup.DECOYS; if (seqBuilder == null || (name != null && !Equals(name, seqBuilder.BaseName))) { if (seqBuilder != null) { AddPeptideGroup(peptideGroupsNew, seqBuilder, irtPeptides, librarySpectra, errorList); } FastaSequence fastaSeq; if (name != null && dictNameSeq.TryGetValue(name, out fastaSeq) && fastaSeq != null) seqBuilder = new PeptideGroupBuilder(fastaSeq, Document.Settings); else { string safeName = name != null ? Helpers.GetUniqueName(name, dictNameSeq.Keys) : Document.GetPeptideGroupId(true); seqBuilder = new PeptideGroupBuilder(">>" + safeName, true, Document.Settings) {BaseName = name}; // Not L10N } } try { seqBuilder.AppendTransition(info, irt, libraryIntensity, productMz, lineNum); } catch (InvalidDataException x) { throw new LineColNumberedIoException(x.Message, lineNum, -1, x); } return seqBuilder; }
private TransitionGroupLibraryIrtTriple[] FinalizeTransitionGroups(IList<TransitionGroupLibraryIrtTriple> groupTriples) { var finalTriples = new List<TransitionGroupLibraryIrtTriple>(); foreach (var groupTriple in groupTriples) { int iGroup = finalTriples.Count - 1; if (iGroup == -1 || !Equals(finalTriples[iGroup].NodeGroup.TransitionGroup, groupTriple.NodeGroup.TransitionGroup)) finalTriples.Add(groupTriple); else { // Check for consistent iRT values double? irt1 = finalTriples[iGroup].Irt; double? irt2 = groupTriple.Irt; bool bothIrtsNull = (irt1 == null && irt2 == null); if (!bothIrtsNull && (irt1 == null || irt2 == null)) { for (int i = 0; i < groupTriple.NodeGroup.TransitionCount; ++i) { var precursorMz = Math.Round(groupTriple.PrecursorMz, MassListImporter.MZ_ROUND_DIGITS); var errorInfo = new TransitionImportErrorInfo(string.Format(Resources.PeptideGroupBuilder_FinalizeTransitionGroups_Missing_iRT_value_for_peptide__0___precursor_m_z__1_, _activePeptide.Sequence, precursorMz), null, null); _peptideGroupErrorInfo.Add(errorInfo); } continue; } else if (!bothIrtsNull && Math.Abs(irt1.Value - irt2.Value) > DbIrtPeptide.IRT_MIN_DIFF) { // Make sure iRT values are reported in a deterministic order for testing if (irt1.Value > irt2.Value) Helpers.Swap(ref irt1, ref irt2); for (int i = 0; i < groupTriple.NodeGroup.TransitionCount; ++i) { var precursorMz = Math.Round(groupTriple.PrecursorMz, MassListImporter.MZ_ROUND_DIGITS); var errorInfo = new TransitionImportErrorInfo(string.Format(Resources.PeptideGroupBuilder_FinalizeTransitionGroups_Two_transitions_of_the_same_precursor___0___m_z__1_____have_different_iRT_values___2__and__3___iRT_values_must_be_assigned_consistently_in_an_imported_transition_list_, _activePeptide.Sequence, precursorMz, irt1.Value, irt2.Value), null, null); _peptideGroupErrorInfo.Add(errorInfo); } continue; } // Found repeated group, so merge transitions var spectrumErrors = new List<TransitionImportErrorInfo>(); finalTriples[iGroup].SpectrumInfo = finalTriples[iGroup].SpectrumInfo == null ? groupTriple.SpectrumInfo : finalTriples[iGroup].SpectrumInfo.CombineSpectrumInfo(groupTriple.SpectrumInfo, out spectrumErrors); if (spectrumErrors.Any()) { _peptideGroupErrorInfo.AddRange(spectrumErrors); continue; } finalTriples[iGroup].NodeGroup = (TransitionGroupDocNode)finalTriples[iGroup].NodeGroup.AddAll(groupTriple.NodeGroup.Children); } } var groups = groupTriples.Select(pair => pair.NodeGroup).ToList(); var finalGroups = finalTriples.Select(pair => pair.NodeGroup).ToList(); // If anything changed, make sure transitions are sorted if (!ArrayUtil.ReferencesEqual(groups, finalGroups)) { for (int i = 0; i < finalTriples.Count; i++) { var nodeGroup = finalTriples[i].NodeGroup; var arrayTran = CompleteTransitions(nodeGroup.Children.Cast<TransitionDocNode>()); finalTriples[i].NodeGroup = (TransitionGroupDocNode)nodeGroup.ChangeChildrenChecked(arrayTran); } } return finalTriples.ToArray(); }
private ExTransitionInfo CalcTransitionExplanations(ExTransitionInfo info, long lineNum, out TransitionImportErrorInfo errorInfo) { errorInfo = null; string sequence = info.PeptideSequence; double productMz = ProductMz; foreach (var transitionExp in info.TransitionExps.ToArray()) { var mods = transitionExp.Precursor.VariableMods; var calc = Settings.GetFragmentCalc(transitionExp.Precursor.LabelType, mods); double productPrecursorMass = calc.GetPrecursorFragmentMass(sequence); double[,] productMasses = calc.GetFragmentIonMasses(sequence); var potentialLosses = TransitionGroup.CalcPotentialLosses(sequence, Settings.PeptideSettings.Modifications, mods, calc.MassType); IonType? ionType; int? ordinal; TransitionLosses losses; int massShift; int productCharge = TransitionCalc.CalcProductCharge(productPrecursorMass, transitionExp.Precursor.PrecursorCharge, productMasses, potentialLosses, productMz, MzMatchTolerance, calc.MassType, transitionExp.ProductShiftType, out ionType, out ordinal, out losses, out massShift); if (productCharge > 0 && ionType.HasValue && ordinal.HasValue) { transitionExp.Product = new ProductExp(productCharge, ionType.Value, ordinal.Value, losses, massShift); } else { info.TransitionExps.Remove(transitionExp); } } if (info.TransitionExps.Count == 0) { productMz = Math.Round(productMz, MZ_ROUND_DIGITS); // TODO: Consistent central formatting for m/z values // Use Math.Round() to avoid forcing extra decimal places errorInfo = new TransitionImportErrorInfo(string.Format(Resources.MassListRowReader_CalcTransitionExplanations_Product_m_z_value__0__in_peptide__1__has_no_matching_product_ion, productMz, info.PeptideSequence), ProductColumn, lineNum); } else if (!Settings.TransitionSettings.Instrument.IsMeasurable(productMz)) { productMz = Math.Round(productMz, MZ_ROUND_DIGITS); errorInfo = new TransitionImportErrorInfo(TextUtil.SpaceSeparate(string.Format(Resources.MassListRowReader_CalcTransitionExplanations_The_product_m_z__0__is_out_of_range_for_the_instrument_settings__in_the_peptide_sequence__1_, productMz, info.PeptideSequence), Resources.MassListRowReader_CalcPrecursorExplanations_Check_the_Instrument_tab_in_the_Transition_Settings), ProductColumn, lineNum); } return info; }
public void AppendTransition(ExTransitionInfo info, double? irt, double? libraryIntensity, double productMz, long lineNum) { _autoManageChildren = false; // Treat this like a peptide list from now on. PeptideList = true; if (_activeFastaSeq == null && AA.Length > 0) _activeFastaSeq = new FastaSequence(Name, Description, Alternatives, AA); string sequence = info.PeptideSequence; if (_activePeptide != null) { if (IsPeptideChanged(info)) { CompletePeptide(true); } else { var intersectVariableMods = new List<ExplicitMods>(_activeVariableMods.Intersect( info.PotentialVarMods)); // If unable to explain the next transition with the existing peptide, but the // transition has the same precursor m/z as the last, try completing the existing // peptide, and see if the current precursor can be completed as a new peptide if (intersectVariableMods.Count == 0 && _activePrecursorMz == info.PrecursorMz) { CompletePeptide(false); intersectVariableMods = new List<ExplicitMods>(info.PotentialVarMods); foreach (var infoActive in _activeTransitionInfos) { intersectVariableMods = new List<ExplicitMods>(intersectVariableMods.Intersect( infoActive.PotentialVarMods)); } } if (intersectVariableMods.Count > 0) { _activeVariableMods = intersectVariableMods; } else if (_activePrecursorMz == info.PrecursorMz) { var precursorMz = Math.Round(info.PrecursorMz, MassListImporter.MZ_ROUND_DIGITS); var errorInfo = new TransitionImportErrorInfo(string.Format(Resources.PeptideGroupBuilder_AppendTransition_Failed_to_explain_all_transitions_for_0__m_z__1__with_a_single_set_of_modifications, info.PeptideSequence, precursorMz), null, lineNum); _peptideGroupErrorInfo.Add(errorInfo); return; } else { CompletePeptide(true); } } } if (_activePeptide == null) { int? begin = null; int? end = null; if (_activeFastaSeq != null) { begin = _activeFastaSeq.Sequence.IndexOf(sequence, StringComparison.Ordinal); if (begin == -1) { // CONSIDER: Use fasta sequence format code currently in SrmDocument to show formatted sequence. throw new InvalidDataException(string.Format(Resources.PeptideGroupBuilder_AppendTransition_The_peptide__0__was_not_found_in_the_sequence__1__, sequence, _activeFastaSeq.Name)); } end = begin + sequence.Length; } _activePeptide = new Peptide(_activeFastaSeq, sequence, begin, end, _enzyme.CountCleavagePoints(sequence), info.TransitionExps[0].IsDecoy); _activeModifiedSequence = info.ModifiedSequence; _activePrecursorMz = info.PrecursorMz; _activeVariableMods = new List<ExplicitMods>(info.PotentialVarMods.Distinct()); _activePrecursorExps = new List<PrecursorExp>(info.TransitionExps.Select(exp => exp.Precursor)); } var intersectPrecursors = new List<PrecursorExp>(_activePrecursorExps.Intersect( info.TransitionExps.Select(exp => exp.Precursor))); if (intersectPrecursors.Count > 0) { _activePrecursorExps = intersectPrecursors; } else if (_activePrecursorMz == info.PrecursorMz) { var precursorMz = Math.Round(_activePrecursorMz, MassListImporter.MZ_ROUND_DIGITS); var errorInfo = new TransitionImportErrorInfo(string.Format(Resources.PeptideGroupBuilder_AppendTransition_Failed_to_explain_all_transitions_for_m_z__0___peptide__1___with_a_single_precursor, precursorMz, info.PeptideSequence), null, lineNum); _peptideGroupErrorInfo.Add(errorInfo); return; } else { CompleteTransitionGroup(); } if (_irtValue.HasValue && (irt == null || Math.Abs(_irtValue.Value - irt.Value) > DbIrtPeptide.IRT_MIN_DIFF)) { var precursorMz = Math.Round(info.PrecursorMz, MassListImporter.MZ_ROUND_DIGITS); var errorInfo = new TransitionImportErrorInfo(string.Format(Resources.PeptideGroupBuilder_FinalizeTransitionGroups_Two_transitions_of_the_same_precursor___0___m_z__1_____have_different_iRT_values___2__and__3___iRT_values_must_be_assigned_consistently_in_an_imported_transition_list_, info.PeptideSequence, precursorMz, _irtValue, irt), null, lineNum); _peptideGroupErrorInfo.Add(errorInfo); return; } if (_activePrecursorMz == 0) { _activePrecursorMz = info.PrecursorMz; _activePrecursorExps = new List<PrecursorExp>(info.TransitionExps.Select(exp => exp.Precursor)); } _activeTransitionInfos.Add(info); if (libraryIntensity != null) { _activeLibraryIntensities.Add(new SpectrumPeaksInfo.MI { Intensity = (float)libraryIntensity.Value, Mz = productMz }); } _irtValue = irt; }
private ExTransitionInfo CalcPrecursorExplanations(ExTransitionInfo info, long lineNum, out TransitionImportErrorInfo errorInfo) { // Enumerate all possible variable modifications looking for an explanation // for the precursor information errorInfo = null; double precursorMz = info.PrecursorMz; double nearestMz = double.MaxValue; var peptideMods = Settings.PeptideSettings.Modifications; PeptideDocNode nodeForModPep = null; string modifiedSequence = info.ModifiedSequence; if (!Equals(modifiedSequence, info.PeptideSequence)) { if (!NodeDictionary.TryGetValue(modifiedSequence, out nodeForModPep)) { nodeForModPep = ModMatcher.GetModifiedNode(modifiedSequence, null); NodeDictionary.Add(modifiedSequence, nodeForModPep); } info.ModifiedSequence = nodeForModPep == null ? null : nodeForModPep.RawTextId; } var nodesToConsider = nodeForModPep != null ? new List<PeptideDocNode> {nodeForModPep} : Peptide.CreateAllDocNodes(Settings, info.PeptideSequence); foreach (var nodePep in nodesToConsider) { var variableMods = nodePep.ExplicitMods; var defaultLabelType = info.DefaultLabelType; double precursorMassH = Settings.GetPrecursorMass(defaultLabelType, info.PeptideSequence, variableMods); int precursorMassShift; int nearestCharge; int? precursorCharge = CalcPrecursorCharge(precursorMassH, precursorMz, MzMatchTolerance, !nodePep.IsProteomic, info.IsDecoy, out precursorMassShift, out nearestCharge); if (precursorCharge.HasValue) { info.TransitionExps.Add(new TransitionExp(variableMods, precursorCharge.Value, defaultLabelType, precursorMassShift)); } else { nearestMz = NearestMz(info.PrecursorMz, nearestMz, precursorMassH, nearestCharge); } if (!IsHeavyAllowed || info.IsExplicitLabelType) continue; foreach (var labelType in peptideMods.GetHeavyModifications().Select(typeMods => typeMods.LabelType)) { if (!Settings.HasPrecursorCalc(labelType, variableMods)) { continue; } precursorMassH = Settings.GetPrecursorMass(labelType, info.PeptideSequence, variableMods); precursorCharge = CalcPrecursorCharge(precursorMassH, precursorMz, MzMatchTolerance, !nodePep.IsProteomic, info.IsDecoy, out precursorMassShift, out nearestCharge); if (precursorCharge.HasValue) { info.TransitionExps.Add(new TransitionExp(variableMods, precursorCharge.Value, labelType, precursorMassShift)); } else { nearestMz = NearestMz(info.PrecursorMz, nearestMz, precursorMassH, nearestCharge); } } } if (info.TransitionExps.Count == 0) { // TODO: Consistent central formatting for m/z values // Use Math.Round() to avoid forcing extra decimal places nearestMz = Math.Round(nearestMz, MZ_ROUND_DIGITS); precursorMz = Math.Round(SequenceMassCalc.PersistentMZ(precursorMz), MZ_ROUND_DIGITS); double deltaMz = Math.Round(Math.Abs(precursorMz - nearestMz), MZ_ROUND_DIGITS); errorInfo = new TransitionImportErrorInfo(TextUtil.SpaceSeparate(string.Format(Resources.MassListRowReader_CalcPrecursorExplanations_, precursorMz, nearestMz, deltaMz, info.PeptideSequence), Resources.MzMatchException_suggestion), PrecursorColumn, lineNum); } else if (!Settings.TransitionSettings.Instrument.IsMeasurable(precursorMz)) { precursorMz = Math.Round(SequenceMassCalc.PersistentMZ(precursorMz), MZ_ROUND_DIGITS); errorInfo = new TransitionImportErrorInfo(TextUtil.SpaceSeparate(string.Format(Resources.MassListRowReader_CalcPrecursorExplanations_The_precursor_m_z__0__of_the_peptide__1__is_out_of_range_for_the_instrument_settings_, precursorMz, info.PeptideSequence), Resources.MassListRowReader_CalcPrecursorExplanations_Check_the_Instrument_tab_in_the_Transition_Settings), PrecursorColumn, lineNum); } // If it's within the instrument settings but not measurable, problem must be in the isolation scheme else if (!Settings.TransitionSettings.IsMeasurablePrecursor(precursorMz)) { precursorMz = Math.Round(SequenceMassCalc.PersistentMZ(precursorMz), MZ_ROUND_DIGITS); errorInfo = new TransitionImportErrorInfo(TextUtil.SpaceSeparate(string.Format(Resources.MassListRowReader_CalcPrecursorExplanations_The_precursor_m_z__0__of_the_peptide__1__is_outside_the_range_covered_by_the_DIA_isolation_scheme_, precursorMz, info.PeptideSequence), Resources.MassListRowReader_CalcPrecursorExplanations_Check_the_isolation_scheme_in_the_full_scan_settings_), PrecursorColumn, lineNum); } return info; }