private bool IsVisibleIon(MatchedFragmentIon mfi) { // Show precursor ions when they are supposed to be shown, regardless of charge // N.B. for fragments, we look at abs value of charge. CONSIDER(bspratt): for small mol libs we may want finer per-adduct control return(mfi.Ordinal > 0 && ShowTypes.Contains(mfi.IonType) && (mfi.IonType == IonType.precursor || ShowCharges.Contains(Math.Abs(mfi.Charge.AdductCharge)))); }
private string GetLabel(MatchedFragmentIon mfi, int rank, bool showMz) { var label = new StringBuilder(string.IsNullOrEmpty(mfi.FragmentName) ? mfi.IonType.GetLocalizedString() : mfi.FragmentName); if (string.IsNullOrEmpty(mfi.FragmentName) && !Transition.IsPrecursor(mfi.IonType)) { label.Append(mfi.Ordinal.ToString(LocalizationHelper.CurrentCulture)); } if (mfi.Losses != null) { label.Append(@" -"); label.Append(Math.Round(mfi.Losses.Mass, 1)); } var chargeIndicator = mfi.Charge.Equals(Adduct.SINGLY_PROTONATED) ? string.Empty : Transition.GetChargeIndicator(mfi.Charge); label.Append(chargeIndicator); if (showMz) { label.Append(string.Format(@" = {0:F01}", mfi.PredictedMz)); } if (rank > 0 && ShowRanks) { label.Append(TextUtil.SEPARATOR_SPACE).Append(string.Format(@"({0})", string.Format(Resources.AbstractSpectrumGraphItem_GetLabel_rank__0__, rank))); } return(label.ToString()); }
private void AnnotatePeak(PlotModel model, LineSeries[] allIons, MsDataScan msDataScan, MatchedFragmentIon matchedIon, double[] spectrumIntensities, PsmFromTsv psmToDraw, bool annotateCharge, bool annotateMz, bool annotateBold, int annotateFontSize, bool isBetaPeptide) { OxyColor ionColor; if (psmToDraw.VariantCrossingIons.Contains(matchedIon)) { ionColor = variantCrossColor; } else if (productTypeDrawColors.ContainsKey(matchedIon.NeutralTheoreticalProduct.ProductType)) { ionColor = productTypeDrawColors[matchedIon.NeutralTheoreticalProduct.ProductType]; } else { ionColor = OxyColors.Turquoise; } int i = msDataScan.MassSpectrum.GetClosestPeakIndex(matchedIon.NeutralTheoreticalProduct.NeutralMass.ToMz(matchedIon.Charge)); // peak line allIons[i] = new LineSeries(); allIons[i].Color = ionColor; allIons[i].StrokeThickness = STROKE_THICKNESS_ANNOTATED; allIons[i].Points.Add(new DataPoint(matchedIon.Mz, 0)); allIons[i].Points.Add(new DataPoint(matchedIon.Mz, spectrumIntensities[i])); // peak annotation string prefix = ""; if (psmToDraw.BetaPeptideBaseSequence != null) { if (isBetaPeptide) { //prefix = "β"; prefix = "B-"; } else { //prefix = "α"; prefix = "A-"; } } string productType = matchedIon.NeutralTheoreticalProduct.ProductType.ToString().ToLower();//.Replace("star", "*").Replace("degree", "°").Replace("dot", ""); string productNumber = matchedIon.NeutralTheoreticalProduct.FragmentNumber.ToString(); string peakAnnotationText = prefix + productType + productNumber; if (matchedIon.NeutralTheoreticalProduct.NeutralLoss != 0) { peakAnnotationText += "-" + matchedIon.NeutralTheoreticalProduct.NeutralLoss.ToString("F2"); } if (annotateCharge) { peakAnnotationText += "+" + matchedIon.Charge; } if (annotateMz) { peakAnnotationText += " (" + matchedIon.Mz.ToString("F3") + ")"; } var peakAnnotation = new TextAnnotation(); peakAnnotation.Font = "Arial"; peakAnnotation.FontSize = annotateFontSize; peakAnnotation.FontWeight = annotateBold ? FontWeights.Bold : 2.0; peakAnnotation.TextColor = ionColor; peakAnnotation.StrokeThickness = 0; peakAnnotation.Text = peakAnnotationText; peakAnnotation.TextPosition = new DataPoint(allIons[i].Points[1].X, allIons[i].Points[1].Y); peakAnnotation.TextHorizontalAlignment = HorizontalAlignment.Center; model.Annotations.Add(peakAnnotation); model.Series.Add(allIons[i]); }
//draw the sequence coverage map: write out the sequence, overlay modifications, and display matched fragments public void DrawSequenceCoverageMap(PsmFromTsv psm, Canvas sequenceText, Canvas map) { map.Children.Clear(); sequenceText.Children.Clear(); int spacing = 20; const int textHeight = 140; const int heightIncrement = 5; const int xShift = 10; int peptideLength = psm.BaseSeq.Length; //intensity arrays for each ion type double[] nIntensityArray = new double[peptideLength - 1]; double[] cIntensityArray = new double[peptideLength - 1]; double[] internalIntensityArray = new double[peptideLength - 1]; //colors for annotation Color nColor = Colors.Blue; Color cColor = Colors.Red; Color internalColor = Colors.Purple; //draw sequence text for (int r = 0; r < psm.BaseSeq.Length; r++) { TextDrawing(sequenceText, new Point(r * spacing + xShift, textHeight - 30), (r + 1).ToString(), Brushes.Black, 8); TextDrawing(sequenceText, new Point(r * spacing + xShift, textHeight - 15), (psm.BaseSeq.Length - r).ToString(), Brushes.Black, 8); TextDrawing(sequenceText, new Point(r * spacing + xShift, textHeight), psm.BaseSeq[r].ToString(), Brushes.Black, 16); } //create circles for mods, if needed and able if (!psm.FullSequence.Contains("|")) //can't draw mods if not localized/identified { PeptideSpectrumMatchPlot.AnnotateModifications(psm, sequenceText, psm.FullSequence, textHeight - 4, spacing, xShift + 5); } //draw lines for each matched fragment List <bool[]> index = new List <bool[]>(); //N-terminal List <MatchedFragmentIon> nTermFragments = psm.MatchedIons.Where(x => x.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.N).ToList(); //C-terminal in reverse order List <MatchedFragmentIon> cTermFragments = psm.MatchedIons.Where(x => x.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.C).OrderByDescending(x => x.NeutralTheoreticalProduct.FragmentNumber).ToList(); //add internal fragments List <MatchedFragmentIon> internalFragments = psm.MatchedIons.Where(x => x.NeutralTheoreticalProduct.SecondaryProductType != null).OrderBy(x => x.NeutralTheoreticalProduct.FragmentNumber).ToList(); //indexes to navigate terminal ions int n = 0; int c = 0; int heightForThisFragment = 70; //location to draw a fragment //line up terminal fragments so that complementary ions are paired on the same line while (n < nTermFragments.Count && c < cTermFragments.Count) { MatchedFragmentIon nProduct = nTermFragments[n]; MatchedFragmentIon cProduct = cTermFragments[c]; int expectedComplementary = peptideLength - nProduct.NeutralTheoreticalProduct.FragmentNumber; //if complementary pair if (cProduct.NeutralTheoreticalProduct.FragmentNumber == expectedComplementary) { //plot sequences DrawHorizontalLine(0, nProduct.NeutralTheoreticalProduct.FragmentNumber, map, heightForThisFragment, nColor, spacing); DrawHorizontalLine(peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber, peptideLength, map, heightForThisFragment, cColor, spacing); //record intensities nIntensityArray[nProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += nProduct.Intensity; cIntensityArray[peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += cProduct.Intensity; //increment indexes n++; c++; } //if n-terminal ion is present without complementary else if (cProduct.NeutralTheoreticalProduct.FragmentNumber < expectedComplementary) { DrawHorizontalLine(0, nProduct.NeutralTheoreticalProduct.FragmentNumber, map, heightForThisFragment, nColor, spacing); nIntensityArray[nProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += nProduct.Intensity; n++; } //if c-terminal ion is present without complementary else { DrawHorizontalLine(peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber, peptideLength, map, heightForThisFragment, cColor, spacing); cIntensityArray[peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += cProduct.Intensity; c++; } heightForThisFragment += heightIncrement; } //wrap up leftover fragments without complementary pairs for (; n < nTermFragments.Count; n++) { MatchedFragmentIon nProduct = nTermFragments[n]; DrawHorizontalLine(0, nProduct.NeutralTheoreticalProduct.FragmentNumber, map, heightForThisFragment, nColor, spacing); nIntensityArray[nProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += nProduct.Intensity; heightForThisFragment += heightIncrement; } for (; c < cTermFragments.Count; c++) { MatchedFragmentIon cProduct = cTermFragments[c]; DrawHorizontalLine(peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber, peptideLength, map, heightForThisFragment, cColor, spacing); cIntensityArray[peptideLength - cProduct.NeutralTheoreticalProduct.FragmentNumber - 1] += cProduct.Intensity; heightForThisFragment += heightIncrement; } //internal fragments foreach (MatchedFragmentIon fragment in internalFragments) { DrawHorizontalLine(fragment.NeutralTheoreticalProduct.FragmentNumber, fragment.NeutralTheoreticalProduct.SecondaryFragmentNumber, map, heightForThisFragment, internalColor, spacing); internalIntensityArray[fragment.NeutralTheoreticalProduct.FragmentNumber - 1] += fragment.Intensity; internalIntensityArray[fragment.NeutralTheoreticalProduct.SecondaryFragmentNumber - 1] += fragment.Intensity; heightForThisFragment += heightIncrement; } map.Height = heightForThisFragment + 100; map.Width = spacing * psm.BaseSeq.Length + 100; sequenceText.Width = spacing * psm.BaseSeq.Length + 100; ////PLOT INTENSITY HISTOGRAM//// double[] intensityArray = new double[peptideLength - 1]; for (int i = 0; i < intensityArray.Length; i++) { intensityArray[i] = nIntensityArray[i] + cIntensityArray[i] + internalIntensityArray[i]; } double maxIntensity = intensityArray.Max(); //foreach cleavage site for (int i = 0; i < intensityArray.Length; i++) { //if anything if (intensityArray[i] > 0) { int x = (i + 1) * spacing + 7; //n-terminal int nY = 100 - (int)Math.Round(nIntensityArray[i] * 100 / maxIntensity, 0); if (nY != 100) { DrawVerticalLine(104, nY + 4, sequenceText, (i + 1) * spacing + 5, nColor); } //c-terminal int cY = nY - (int)Math.Round(cIntensityArray[i] * 100 / maxIntensity, 0); if (nY != cY) { DrawVerticalLine(nY + 2, cY + 2, sequenceText, (i + 1) * spacing + 5, cColor); } //internal int iY = cY - (int)Math.Round(internalIntensityArray[i] * 100 / maxIntensity, 0); if (cY != iY) { DrawVerticalLine(cY, iY, sequenceText, (i + 1) * spacing + 5, internalColor); } } } }
protected void AnnotatePeak(MatchedFragmentIon matchedIon, bool isBetaPeptide, bool useLiteralPassedValues = false) { OxyColor ionColor; if (SpectrumMatch.VariantCrossingIons.Contains(matchedIon)) { ionColor = MetaDrawSettings.VariantCrossColor; } else if (matchedIon.NeutralTheoreticalProduct.SecondaryProductType != null) //if internal fragment { ionColor = OxyColors.Purple; } else if (isBetaPeptide) { ionColor = MetaDrawSettings.BetaProductTypeToColor[matchedIon.NeutralTheoreticalProduct.ProductType]; } else { ionColor = MetaDrawSettings.ProductTypeToColor[matchedIon.NeutralTheoreticalProduct.ProductType]; } int i = Scan.MassSpectrum.GetClosestPeakIndex(matchedIon.NeutralTheoreticalProduct.NeutralMass.ToMz(matchedIon.Charge)); double mz = Scan.MassSpectrum.XArray[i]; double intensity = Scan.MassSpectrum.YArray[i]; if (useLiteralPassedValues) { mz = matchedIon.Mz; intensity = matchedIon.Intensity; } // peak annotation string prefix = ""; if (SpectrumMatch.BetaPeptideBaseSequence != null) { if (isBetaPeptide) { //prefix = "β"; prefix = "B-"; } else { //prefix = "α"; prefix = "A-"; } } string peakAnnotationText = prefix + matchedIon.NeutralTheoreticalProduct.Annotation; if (matchedIon.NeutralTheoreticalProduct.NeutralLoss != 0) { peakAnnotationText += "-" + matchedIon.NeutralTheoreticalProduct.NeutralLoss.ToString("F2"); } if (MetaDrawSettings.AnnotateCharges) { peakAnnotationText += "+" + matchedIon.Charge; } if (MetaDrawSettings.AnnotateMzValues) { peakAnnotationText += " (" + matchedIon.Mz.ToString("F3") + ")"; } var peakAnnotation = new TextAnnotation(); peakAnnotation.Font = "Arial"; peakAnnotation.FontSize = MetaDrawSettings.AnnotatedFontSize; peakAnnotation.FontWeight = MetaDrawSettings.AnnotationBold ? OxyPlot.FontWeights.Bold : 2.0; peakAnnotation.TextColor = ionColor; peakAnnotation.StrokeThickness = 0; peakAnnotation.Text = peakAnnotationText; peakAnnotation.TextPosition = new DataPoint(mz, intensity); peakAnnotation.TextVerticalAlignment = intensity < 0 ? OxyPlot.VerticalAlignment.Top : OxyPlot.VerticalAlignment.Bottom; peakAnnotation.TextHorizontalAlignment = OxyPlot.HorizontalAlignment.Center; if (!MetaDrawSettings.DisplayIonAnnotations) { peakAnnotation.Text = string.Empty; } DrawPeak(mz, intensity, MetaDrawSettings.StrokeThicknessAnnotated, ionColor, peakAnnotation); }