public PeptideSpectrumMatchPlot(OxyPlot.Wpf.PlotView plotView, Canvas sequenceDrawingCanvas, PsmFromTsv psm, MsDataScan scan, List <MatchedFragmentIon> matchedFragmentIons, bool annotateProperties = true, LibrarySpectrum librarySpectrum = null) : base(plotView) { Model.Title = string.Empty; Model.Subtitle = string.Empty; SpectrumMatch = psm; Scan = scan; SequenceDrawingCanvas = sequenceDrawingCanvas; SequenceDrawingCanvas.Height = 60; sequenceDrawingCanvas.Width = 600; ClearCanvas(SequenceDrawingCanvas); DrawSpectrum(); AnnotateBaseSequence(psm.BaseSeq, psm.FullSequence, 10, matchedFragmentIons); AnnotateMatchedIons(isBetaPeptide: false, matchedFragmentIons); if (annotateProperties) { AnnotateProperties(); } ZoomAxes(matchedFragmentIons); if (librarySpectrum != null) { AnnotateLibraryIons(isBetaPeptide: false, librarySpectrum.MatchedFragmentIons); } RefreshChart(); }
public static void AnnotateModifications(PsmFromTsv spectrumMatch, Canvas sequenceDrawingCanvas, string fullSequence, int yLoc, double?spacer = null, int xShift = 12) { var peptide = new PeptideWithSetModifications(fullSequence, GlobalVariables.AllModsKnownDictionary); // read glycans if applicable List <Tuple <int, string, double> > localGlycans = null; if (spectrumMatch.GlycanLocalizationLevel != null) { localGlycans = PsmFromTsv.ReadLocalizedGlycan(spectrumMatch.LocalizedGlycan); } // annotate mods foreach (var mod in peptide.AllModsOneIsNterminus) { double xLocation = (mod.Key - 1) * (spacer ?? MetaDrawSettings.AnnotatedSequenceTextSpacing) - xShift; double yLocation = yLoc + 2; if (mod.Value.ModificationType == "O-Glycosylation") { if (localGlycans.Where(p => p.Item1 + 1 == mod.Key).Count() > 0) { DrawCircle(sequenceDrawingCanvas, new Point(xLocation, yLocation), MetaDrawSettings.ModificationAnnotationColor); } else { DrawCircle(sequenceDrawingCanvas, new Point(xLocation, yLocation), Brushes.Gray); } } else { DrawCircle(sequenceDrawingCanvas, new Point(xLocation, yLocation), MetaDrawSettings.ModificationAnnotationColor); } } }
// add psm to corresponding peptide private void AddPsmToTreeView(ProteinForTreeView protein, PsmFromTsv psm) { PeptideForTreeView peptide = null; if (protein.AllPeptides.ContainsKey(psm.BaseSeq)) // retrieve corresponding peptide { peptide = protein.AllPeptides[psm.BaseSeq]; } else // psm doesnt match any peptide, create new peptide { peptide = new PeptideForTreeView(psm.BaseSeq, protein); protein.Children.Add(peptide); protein.AllPeptides.Add(psm.BaseSeq, peptide); } int i = 0; while (i < peptide.Children.Count) // O(N) { // add to sorted collection if (psm.Ms2ScanNumber < peptide.Children[i].ScanNo) { peptide.Children.Insert(i, new PsmForTreeView(psm.Ms2ScanNumber, psm, peptide)); return; } ++i; } peptide.Children.Add(new PsmForTreeView(psm.Ms2ScanNumber, psm, peptide)); }
public static void TestParenthesesRemovalForSilac() { string baseSequence = "ASDF(+8.01)ASDF"; string cleanedSequence = PsmFromTsv.RemoveParentheses(baseSequence); Assert.IsTrue(cleanedSequence.Equals("ASDFASDF")); }
private void OnSelectionChanged() { if (dataGridScanNums.SelectedItem == null) { return; } // draw the selected PSM propertyView.Clear(); PsmFromTsv row = (PsmFromTsv)dataGridScanNums.SelectedItem; System.Reflection.PropertyInfo[] temp = row.GetType().GetProperties(); for (int i = 0; i < temp.Length; i++) { if (temp[i].Name == nameof(row.MatchedIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", row.MatchedIons.Select(p => p.Annotation))); } else { propertyView.Rows.Add(temp[i].Name, temp[i].GetValue(row, null)); } } dataGridProperties.Items.Refresh(); itemsControlSampleViewModel.Data.Clear(); DrawPsm(row.Ms2ScanNumber, row.FullSequence); }
private PlotModel DrawPdf(MsDataScan msDataScan, PropertyInfo[] properties, PsmFromTsv psm, bool redraw) { if (redraw) { this.Model = Draw(msDataScan, psm); } var y = Model.DefaultYAxis.ActualMaximum - Model.DefaultYAxis.ActualMaximum * 0.03; var x = Model.DefaultXAxis.ActualMaximum - Model.DefaultXAxis.ActualMaximum * 0.01; var diff = (y - (Model.DefaultYAxis.ActualMaximum * 0.1)) / properties.Length; // properties to include string[] propertiesToWrite = { "Filename", "PrecursorCharge", "PrecursorMass", "PeptideMonoMass", "MassDiffDa", "MassDiffPpm", "Score", "DeltaScore", "ProteinAccession", "ProteinName", "GeneName", "DecoyContamTarget", "QValue", "QValueNotch" }; var propertiesList = properties.Where(p => propertiesToWrite.Contains(p.Name)).OrderBy(p => Array.IndexOf(propertiesToWrite, p.Name)).ToList(); var displayedProperties = propertiesList.Where(p => p.GetValue(psm) != null); // only display non-null properties foreach (PropertyInfo property in displayedProperties) { // trim property values > 50 characters var val = "" + property.GetValue(psm); if (val.Length > 50) { val = val.Substring(0, 50) + "..."; } var propertyAnnotation = new TextAnnotation { Text = property.Name + ": " + val, TextPosition = new DataPoint(x, y), FontSize = 9, StrokeThickness = 0, TextHorizontalAlignment = HorizontalAlignment.Right }; y -= diff; Model.Annotations.Add(propertyAnnotation); } return(Model); }
private void DrawPdfAnnotatedBaseSequence(PsmFromTsv psm, Canvas canvas, string path) { if (psm.CrossType == null) { DrawAnnotatedBaseSequence(psm); } string pathToBaseSeq = Path.Combine(Path.GetDirectoryName(path), "annotation.png"); CustomPdfWriter.RenderImage((int)canvas.Width, 600, pathToBaseSeq, canvas); }
/// <summary> /// Event triggers when a different cell is selected in the PSM data grid /// </summary> private void dataGridScanNums_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { if (dataGridScanNums.SelectedItem == null) { return; } PsmFromTsv psm = (PsmFromTsv)dataGridScanNums.SelectedItem; // draw the annotated spectrum MetaDrawLogic.DisplaySpectrumMatch(plotView, canvas, psm, itemsControlSampleViewModel, out var errors); //draw the sequence coverage if not crosslinked if (psm.ChildScanMatchedIons == null) { MetaDrawLogic.DrawSequenceCoverageMap(psm, sequenceText, map); //TODO: figure out how to show coverage on crosslinked peptides ParentChildScanView.Visibility = Visibility.Collapsed; SequenceCoverageAnnotationView.Visibility = Visibility.Visible; } else { ParentChildScanView.Visibility = Visibility.Visible; SequenceCoverageAnnotationView.Visibility = Visibility.Collapsed; } mapViewer.Width = map.Width; if (errors != null && errors.Any()) { MessageBox.Show(errors.First()); return; } // display PSM properties propertyView.Clear(); System.Reflection.PropertyInfo[] temp = psm.GetType().GetProperties(); for (int i = 0; i < temp.Length; i++) { if (temp[i].Name == nameof(psm.MatchedIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", psm.MatchedIons.Select(p => p.Annotation))); } else if (temp[i].Name == nameof(psm.VariantCrossingIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", psm.VariantCrossingIons.Select(p => p.Annotation))); } else { propertyView.Rows.Add(temp[i].Name, temp[i].GetValue(psm, null)); } } }
public static bool FilterAcceptsPsm(PsmFromTsv psm) { if (psm.QValue <= QValueFilter && (psm.QValueNotch == null || psm.QValueNotch <= QValueFilter) && (psm.DecoyContamTarget == "T" || (psm.DecoyContamTarget == "D" && ShowDecoys) || (psm.DecoyContamTarget == "C" && ShowContaminants)) && (psm.GlycanLocalizationLevel == null || psm.GlycanLocalizationLevel >= LocalizationLevelStart && psm.GlycanLocalizationLevel <= LocalizationLevelEnd)) { return(true); } return(false); }
private void PDFButton_Click(object sender, RoutedEventArgs e) { PsmFromTsv tempPsm = null; if (dataGridScanNums.SelectedCells.Count == 0) { MessageBox.Show("Please select at least one scan to export"); } else { int numberOfScansToExport = dataGridScanNums.SelectedItems.Count; foreach (object selectedItem in dataGridScanNums.SelectedItems) { PsmFromTsv psm = (PsmFromTsv)selectedItem; if (tempPsm == null) { tempPsm = psm; } MsDataScan msDataScanToDraw = MsDataFile.GetOneBasedScan(psm.Ms2ScanNumber); string myString = illegalInFileName.Replace(psm.FullSequence, ""); if (myString.Length > 30) { myString = myString.Substring(0, 30); } string filePath = Path.Combine(Path.GetDirectoryName(tsvResultsFilePath), "MetaDrawExport", psm.Ms2ScanNumber + "_" + myString + ".pdf"); string dir = Path.GetDirectoryName(filePath); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } DrawPdfAnnotatedBaseSequence(psm, canvas, filePath); // captures the annotation for the pdf mainViewModel.DrawPeptideSpectralMatchPdf(msDataScanToDraw, psm, filePath, numberOfScansToExport > 1); } dataGridScanNums.SelectedItem = dataGridScanNums.SelectedItem; DrawPsm(tempPsm.Ms2ScanNumber, tempPsm.FullSequence); MessageBox.Show(string.Format("{0} PDFs exported", numberOfScansToExport)); } }
/// <summary> /// Event triggers when a different cell is selected in the PSM data grid /// </summary> private void dataGridScanNums_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { if (dataGridScanNums.SelectedItem == null) { return; } PsmFromTsv psm = (PsmFromTsv)dataGridScanNums.SelectedItem; // draw the PSM MetaDrawLogic.DisplaySpectrumMatch(plotView, canvas, psm, itemsControlSampleViewModel, out var errors); if (psm.ChildScanMatchedIons != null) { ParentChildScanView.Visibility = Visibility.Visible; ParentScanView.Visibility = Visibility.Visible; } else { ParentChildScanView.Visibility = Visibility.Collapsed; ParentScanView.Visibility = Visibility.Collapsed; } if (errors != null && errors.Any()) { MessageBox.Show(errors.First()); return; } // display PSM properties propertyView.Clear(); System.Reflection.PropertyInfo[] temp = psm.GetType().GetProperties(); for (int i = 0; i < temp.Length; i++) { if (temp[i].Name == nameof(psm.MatchedIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", psm.MatchedIons.Select(p => p.Annotation))); } else if (temp[i].Name == nameof(psm.VariantCrossingIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", psm.VariantCrossingIons.Select(p => p.Annotation))); } else { propertyView.Rows.Add(temp[i].Name, temp[i].GetValue(psm, null)); } } }
// filter psms based on settings and group psms by protein private void FilterPsm(PsmFromTsv psm) { if (psm.QValue <= metaDrawFilterSettings.QValueFilter && (psm.QValueNotch < metaDrawFilterSettings.QValueFilter || psm.QValueNotch == null) && (psm.DecoyContamTarget == "T" || (psm.DecoyContamTarget == "D" && metaDrawFilterSettings.ShowDecoys) || (psm.DecoyContamTarget == "C" && metaDrawFilterSettings.ShowContaminants))) { filteredListOfPsms.Add(psm); // group psms by protein foreach (var protein in proteinGroupsForTreeView.Where(x => psm.ProteinAccession.Contains(x.Key) || x.Key.Contains(psm.ProteinAccession)).Select(x => x.Value)) { AddPsmToTreeView(protein, psm); psmsWithMatch.Add(psm); } } }
public void FilterPsmsByString(string searchString) { if (searchString == "") { PeptideSpectralMatchesView.Filter = null; } else { PeptideSpectralMatchesView.Filter = obj => { PsmFromTsv psm = obj as PsmFromTsv; return((psm.Ms2ScanNumber.ToString()).StartsWith(searchString) || psm.FullSequence.ToUpper().Contains(searchString.ToUpper())); }; } }
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { string txt = (sender as TextBox).Text; if (txt == "") { peptideSpectralMatchesView.Filter = null; } else { peptideSpectralMatchesView.Filter = obj => { PsmFromTsv psm = obj as PsmFromTsv; return ((psm.Ms2ScanNumber.ToString()).StartsWith(txt) || psm.FullSequence.ToUpper().Contains(txt.ToUpper())); }; } }
// displays psm spectrum annotation private void displayPsm(PsmForTreeView selection) { PsmFromTsv row = selection.Psm; System.Reflection.PropertyInfo[] temp = row.GetType().GetProperties(); for (int i = 0; i < temp.Length; i++) { if (temp[i].Name == nameof(row.MatchedIons)) { propertyView.Rows.Add(temp[i].Name, string.Join(", ", row.MatchedIons.Select(p => p.Annotation))); } else { propertyView.Rows.Add(temp[i].Name, temp[i].GetValue(row, null)); } } dataGridProperties.Items.Refresh(); itemsControlSampleViewModel.Data.Clear(); DrawPsm(row.Ms2ScanNumber, row.FullSequence); }
private void DrawPdfAnnotatedBaseSequence(PsmFromTsv psm, Canvas canvas, string path) { if (psm.CrossType == null) { DrawAnnotatedBaseSequence(psm); } canvas.Measure(new Size((int)canvas.Width, 600)); canvas.Arrange(new Rect(new Size((int)canvas.Width, 600))); RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)(canvas.Width), 600, 96, 96, PixelFormats.Pbgra32); renderBitmap.Render(canvas); PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); string tempPath = Path.Combine(Path.GetDirectoryName(tsvResultsFilePath), "MetaDrawExport", "annotation.png"); using (FileStream file = File.Create(tempPath)) { encoder.Save(file); } }
public void DrawPeptideSpectralMatchPdf(MsDataScan msDataScan, PsmFromTsv psm, string fileName, bool redraw) { var properties = psm.GetType().GetProperties(); var pdfModel = DrawPdf(msDataScan, properties, psm, redraw); string tempPath = Path.Combine(Path.GetDirectoryName(fileName), "sequence.pdf"); string baseSeqTempPath = Path.Combine(Path.GetDirectoryName(fileName), "annotation.png"); // exports plot to pdf using (var stream = File.Create(tempPath)) { PdfExporter pdf = new PdfExporter { Width = 800, Height = 500 }; pdf.Export(pdfModel, stream); } // adds base seq annotation to pdf using (Stream inputPdfStream = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (Stream inputImageStream = new FileStream(baseSeqTempPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (Stream outputPdfStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { var reader = new PdfReader(inputPdfStream); var stamper = new PdfStamper(reader, outputPdfStream); var pdfContentByte = stamper.GetOverContent(1); var image = iTextSharp.text.Image.GetInstance(inputImageStream); image.ScaleAbsoluteHeight(500); image.ScaleAbsoluteWidth(500); image.SetAbsolutePosition(95, 190); pdfContentByte.AddImage(image); stamper.Close(); } File.Delete(tempPath); File.Delete(baseSeqTempPath); }
public CrosslinkSpectrumMatchPlot(OxyPlot.Wpf.PlotView plotView, Canvas sequenceDrawingCanvas, PsmFromTsv csm, MsDataScan scan) : base(plotView, sequenceDrawingCanvas, csm, scan, csm.MatchedIons) { SequenceDrawingCanvas.Height = 150; // annotate beta peptide base sequence AnnotateBaseSequence(csm.BetaPeptideBaseSequence, csm.BetaPeptideFullSequence, 100, csm.BetaPeptideMatchedIons); // annotate beta peptide matched ions AnnotateMatchedIons(isBetaPeptide: true, csm.BetaPeptideMatchedIons); // annotate crosslinker int alphaSite = int.Parse(Regex.Match(SpectrumMatch.FullSequence, @"\d+").Value); int betaSite = int.Parse(Regex.Match(SpectrumMatch.BetaPeptideFullSequence, @"\d+").Value); AnnotateCrosslinker(SequenceDrawingCanvas, new Point(alphaSite * MetaDrawSettings.AnnotatedSequenceTextSpacing, 50), new Point(betaSite * MetaDrawSettings.AnnotatedSequenceTextSpacing, 90), Colors.Black); ZoomAxes(csm.MatchedIons.Concat(csm.BetaPeptideMatchedIons), yZoom: 1.5); RefreshChart(); }
public PsmForTreeView(int scan, PsmFromTsv psm, PeptideForTreeView parent) { Parent = parent; Psm = psm; ScanNo = scan; }
private void PDFButton_Click(object sender, RoutedEventArgs e) { PsmFromTsv tempPsm = null; if (dataGridScanNums.SelectedCells.Count == 0) { MessageBox.Show("Please select at least one scan to export"); } else { int numberOfScansToExport = dataGridScanNums.SelectedItems.Count; foreach (object selectedItem in dataGridScanNums.SelectedItems) { PsmFromTsv psm = (PsmFromTsv)selectedItem; if (tempPsm == null) { tempPsm = psm; } MsDataScan msDataScanToDraw = MsDataFile.GetOneBasedScan(psm.Ms2ScanNumber); string myString = illegalInFileName.Replace(psm.FullSequence, ""); if (myString.Length > 30) { myString = myString.Substring(0, 30); } string filePath = Path.Combine(Path.GetDirectoryName(tsvResultsFilePath), "MetaDrawExport", psm.Ms2ScanNumber + "_" + myString + ".pdf"); string dir = Path.GetDirectoryName(filePath); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } DrawPdfAnnotatedBaseSequence(psm, canvas, filePath); // captures the annotation for the pdf mainViewModel.DrawPeptideSpectralMatchPdf(msDataScanToDraw, psm, filePath, numberOfScansToExport > 1); // if this spectrum has child scans, draw them in the "advanced" tab if ((psm.ChildScanMatchedIons != null && psm.ChildScanMatchedIons.Count > 0) || (psm.BetaPeptideChildScanMatchedIons != null && psm.BetaPeptideChildScanMatchedIons.Count > 0)) { // draw child scans HashSet <int> scansDrawn = new HashSet <int>(); var allChildScanMatchedIons = psm.ChildScanMatchedIons; if (psm.BetaPeptideChildScanMatchedIons != null) { allChildScanMatchedIons = allChildScanMatchedIons.Concat(psm.BetaPeptideChildScanMatchedIons).ToDictionary(p => p.Key, q => q.Value); } foreach (var childScanMatchedIons in allChildScanMatchedIons) { int scanNumber = childScanMatchedIons.Key; if (scansDrawn.Contains(scanNumber)) { continue; } scansDrawn.Add(scanNumber); List <MatchedFragmentIon> matchedIons = childScanMatchedIons.Value; var childPsmModel = new PsmAnnotationViewModel(); MsDataScan childScan = MsDataFile.GetOneBasedScan(scanNumber); childPsmModel.DrawPeptideSpectralMatch(childScan, psm, metaDrawGraphicalSettings.ShowMzValues, metaDrawGraphicalSettings.ShowAnnotationCharges, metaDrawGraphicalSettings.AnnotatedFontSize, metaDrawGraphicalSettings.BoldText); string childfilePath = Path.Combine(Path.GetDirectoryName(tsvResultsFilePath), "MetaDrawExport", childScan.OneBasedScanNumber + "_" + myString + ".pdf"); DrawPdfAnnotatedBaseSequence(psm, canvas, childfilePath); // captures the annotation for the pdf childPsmModel.DrawPeptideSpectralMatchPdf(childScan, psm, childfilePath, false); } } } dataGridScanNums.SelectedItem = dataGridScanNums.SelectedItem; itemsControlSampleViewModel.Data.Clear(); DrawPsm(tempPsm.Ms2ScanNumber, tempPsm.FullSequence); MessageBox.Show(string.Format("{0} PDFs exported", numberOfScansToExport)); } }
private void DrawAnnotatedBaseSequence(Canvas canvas, PsmFromTsv psm, bool ToAnnotateChildScan = false) { double spacing = 22; BaseDraw.clearCanvas(canvas); // don't draw ambiguous sequences if (psm.FullSequence.Contains("|")) { return; } // draw base sequence for (int r = 0; r < psm.BaseSeq.Length; r++) { BaseDraw.txtDrawing(canvas, new Point(r * spacing + 10, 10), psm.BaseSeq[r].ToString(), Brushes.Black); } var matchIons = psm.MatchedIons; if (ToAnnotateChildScan) { matchIons = new List <MatchedFragmentIon>(); foreach (var x in psm.ChildScanMatchedIons) { matchIons.AddRange(x.Value); } } // draw the fragment ion annotations on the base sequence foreach (var ion in matchIons) { int residue = ion.NeutralTheoreticalProduct.AminoAcidPosition; string annotation = ion.NeutralTheoreticalProduct.ProductType + "" + ion.NeutralTheoreticalProduct.FragmentNumber; Color color = psm.VariantCrossingIons.Contains(ion) ? variantCrossColor : productTypeToColor[ion.NeutralTheoreticalProduct.ProductType]; if (ion.NeutralTheoreticalProduct.NeutralLoss != 0) { annotation += "-" + ion.NeutralTheoreticalProduct.NeutralLoss; } if (ion.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.C) { BaseDraw.topSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType]), color, annotation); } else if (ion.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.N) { BaseDraw.botSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType]), color, annotation); } // don't draw diagnostic ions, precursor ions, etc } // draw modifications var peptide = new PeptideWithSetModifications(psm.FullSequence, GlobalVariables.AllModsKnownDictionary); if (psm.GlycanLocalizationLevel != null) { var localGlycans = PsmFromTsv.ReadLocalizedGlycan(psm.LocalizedGlycan); foreach (var mod in peptide.AllModsOneIsNterminus) { if (mod.Value.ModificationType == "O-Glycosylation") { if (localGlycans.Where(p => p.Item1 + 1 == mod.Key).Count() > 0) { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12), modificationAnnotationColor); } else { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12), Brushes.Gray); } } } } else { foreach (var mod in peptide.AllModsOneIsNterminus) { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12), modificationAnnotationColor); } } if (psm.BetaPeptideBaseSequence != null) { for (int r = 0; r < psm.BetaPeptideBaseSequence.Length; r++) { BaseDraw.txtDrawing(canvas, new Point(r * spacing + 10, 100), psm.BetaPeptideBaseSequence[r].ToString(), Brushes.Black); } foreach (var ion in psm.BetaPeptideMatchedIons) { int residue = ion.NeutralTheoreticalProduct.AminoAcidPosition; string annotation = ion.NeutralTheoreticalProduct.ProductType + "" + ion.NeutralTheoreticalProduct.FragmentNumber; if (ion.NeutralTheoreticalProduct.NeutralLoss != 0) { annotation += "-" + ion.NeutralTheoreticalProduct.NeutralLoss; } if (ion.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.C) { BaseDraw.topSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType] + 90), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } else if (ion.NeutralTheoreticalProduct.Terminus == FragmentationTerminus.N) { BaseDraw.botSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType] + 90), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } // don't draw diagnostic ions, precursor ions, etc } var betaPeptide = new PeptideWithSetModifications(psm.BetaPeptideFullSequence, GlobalVariables.AllModsKnownDictionary); foreach (var mod in betaPeptide.AllModsOneIsNterminus) { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12 + 90), modificationAnnotationColor); } int alphaSite = Int32.Parse(Regex.Match(psm.FullSequence, @"\d+").Value); int betaSite = Int32.Parse(Regex.Match(psm.BetaPeptideFullSequence, @"\d+").Value); BaseDraw.DrawCrosslinker(canvas, new Point(alphaSite * spacing, 50), new Point(betaSite * spacing, 90), Colors.Black); } }
private void DrawPsm(int oneBasedScanNumber, string fullSequence = null, string fileName = null) { MsDataScan msDataScanToDraw = MsDataFile.GetOneBasedScan(oneBasedScanNumber); IEnumerable <PsmFromTsv> scanPsms = filteredListOfPsms.Where(p => p.Ms2ScanNumber == oneBasedScanNumber); if (fullSequence != null) { scanPsms = scanPsms.Where(p => p.FullSequence == fullSequence); } PsmFromTsv psmToDraw = scanPsms.FirstOrDefault(); // if this spectrum has child scans, draw them in the "advanced" tab if ((psmToDraw.ChildScanMatchedIons != null && psmToDraw.ChildScanMatchedIons.Count > 0) || (psmToDraw.BetaPeptideChildScanMatchedIons != null && psmToDraw.BetaPeptideChildScanMatchedIons.Count > 0)) { ParentChildScanView.Visibility = Visibility.Visible; ParentScanView.Visibility = Visibility.Visible; // draw parent scans var parentPsmModel = new PsmAnnotationViewModel(); MsDataScan parentScan = MsDataFile.GetOneBasedScan(psmToDraw.Ms2ScanNumber); parentPsmModel.DrawPeptideSpectralMatch(parentScan, psmToDraw, metaDrawGraphicalSettings.ShowMzValues, metaDrawGraphicalSettings.ShowAnnotationCharges, metaDrawGraphicalSettings.AnnotatedFontSize, metaDrawGraphicalSettings.BoldText); string parentAnnotation = "Scan: " + parentScan.OneBasedScanNumber.ToString() + " Dissociation Type: " + parentScan.DissociationType.ToString() + " MsOrder: " + parentScan.MsnOrder.ToString() + " Selected Mz: " + parentScan.SelectedIonMZ.Value.ToString("0.##") + " Retention Time: " + parentScan.RetentionTime.ToString("0.##"); itemsControlSampleViewModel.AddNewRow(parentPsmModel, parentAnnotation, null); // draw child scans HashSet <int> scansDrawn = new HashSet <int>(); var allChildScanMatchedIons = psmToDraw.ChildScanMatchedIons; if (psmToDraw.BetaPeptideChildScanMatchedIons != null) { allChildScanMatchedIons = allChildScanMatchedIons.Concat(psmToDraw.BetaPeptideChildScanMatchedIons).ToDictionary(p => p.Key, q => q.Value); } foreach (var childScanMatchedIons in allChildScanMatchedIons) { int scanNumber = childScanMatchedIons.Key; if (scansDrawn.Contains(scanNumber)) { continue; } scansDrawn.Add(scanNumber); List <MatchedFragmentIon> matchedIons = childScanMatchedIons.Value; var childPsmModel = new PsmAnnotationViewModel(); MsDataScan childScan = MsDataFile.GetOneBasedScan(scanNumber); childPsmModel.DrawPeptideSpectralMatch(childScan, psmToDraw, metaDrawGraphicalSettings.ShowMzValues, metaDrawGraphicalSettings.ShowAnnotationCharges, metaDrawGraphicalSettings.AnnotatedFontSize, metaDrawGraphicalSettings.BoldText); string childAnnotation = "Scan: " + scanNumber.ToString() + " Dissociation Type: " + childScan.DissociationType.ToString() + " MsOrder: " + childScan.MsnOrder.ToString() + " Selected Mz: " + childScan.SelectedIonMZ.Value.ToString("0.##") + " RetentionTime: " + childScan.RetentionTime.ToString("0.##"); Canvas aCanvas = new Canvas { Height = 60 }; DrawAnnotatedBaseSequence(aCanvas, psmToDraw, true); itemsControlSampleViewModel.AddNewRow(childPsmModel, childAnnotation, aCanvas); } } else { ParentChildScanView.Visibility = Visibility.Collapsed; ParentScanView.Visibility = Visibility.Collapsed; } // if this is a crosslink spectrum match, there are two base sequence annotations to draw // this makes the canvas taller to fit both of these peptide sequences if (psmToDraw.BetaPeptideBaseSequence != null) { int height = 150; canvas.Height = height; PsmAnnotationGrid.RowDefinitions[1].Height = new GridLength(height); } else { int height = 60; canvas.Height = height; PsmAnnotationGrid.RowDefinitions[1].Height = new GridLength(height); } // draw annotated spectrum mainViewModel.DrawPeptideSpectralMatch(msDataScanToDraw, psmToDraw, metaDrawGraphicalSettings.ShowMzValues, metaDrawGraphicalSettings.ShowAnnotationCharges, metaDrawGraphicalSettings.AnnotatedFontSize, metaDrawGraphicalSettings.BoldText); // draw annotated base sequence DrawAnnotatedBaseSequence(canvas, psmToDraw); }
public void DisplaySpectrumMatch(PlotView plotView, Canvas canvas, PsmFromTsv psm, ParentChildScanPlotsView parentChildScanPlotsView, out List <string> errors) { errors = null; // clear old parent/child scans parentChildScanPlotsView.Plots.Clear(); CurrentlyDisplayedPlots.Clear(); // get the scan if (!MsDataFiles.TryGetValue(psm.FileNameWithoutExtension, out DynamicDataConnection spectraFile)) { errors = new List <string>(); errors.Add("The spectra file could not be found for this PSM: " + psm.FileNameWithoutExtension); return; } MsDataScan scan = spectraFile.GetOneBasedScanFromDynamicConnection(psm.Ms2ScanNumber); LibrarySpectrum librarySpectrum = null; // plot the annotated spectrum match PeptideSpectrumMatchPlot plot; //if not crosslinked if (psm.BetaPeptideBaseSequence == null) { // get the library spectrum if relevant if (SpectralLibrary != null) { SpectralLibrary.TryGetSpectrum(psm.FullSequence, psm.PrecursorCharge, out var librarySpectrum1); librarySpectrum = librarySpectrum1; } plot = new PeptideSpectrumMatchPlot(plotView, canvas, psm, scan, psm.MatchedIons, librarySpectrum: librarySpectrum); } else //crosslinked { plot = new CrosslinkSpectrumMatchPlot(plotView, canvas, psm, scan); } CurrentlyDisplayedPlots.Add(plot); // plot parent/child scans if (psm.ChildScanMatchedIons != null) { // draw parent scan string parentAnnotation = "Scan: " + scan.OneBasedScanNumber + " Dissociation Type: " + scan.DissociationType + " MsOrder: " + scan.MsnOrder + " Selected Mz: " + scan.SelectedIonMZ.Value.ToString("0.##") + " Retention Time: " + scan.RetentionTime.ToString("0.##"); var parentPlotView = new PlotView(); // placeholder var parentCanvas = new Canvas(); var item = new ParentChildScanPlotTemplate() { Plot = new PeptideSpectrumMatchPlot(parentPlotView, parentCanvas, psm, scan, psm.MatchedIons), SpectrumLabel = parentAnnotation, TheCanvas = parentCanvas }; parentChildScanPlotsView.Plots.Add(item); // remove model from placeholder (the model can only be referenced by 1 plotview at a time) parentPlotView.Model = null; // draw child scans HashSet <int> scansDrawn = new HashSet <int>(); var allChildScanMatchedIons = psm.ChildScanMatchedIons; if (psm.BetaPeptideChildScanMatchedIons != null) { allChildScanMatchedIons = allChildScanMatchedIons.Concat(psm.BetaPeptideChildScanMatchedIons) .GroupBy(p => p.Key) .ToDictionary(p => p.Key, q => q.SelectMany(p => p.Value).ToList()); } foreach (var childScanMatchedIons in allChildScanMatchedIons) { int childScanNumber = childScanMatchedIons.Key; if (scansDrawn.Contains(childScanNumber)) { continue; } scansDrawn.Add(childScanNumber); List <MatchedFragmentIon> matchedIons = childScanMatchedIons.Value; MsDataScan childScan = spectraFile.GetOneBasedScanFromDynamicConnection(childScanNumber); string childAnnotation = "Scan: " + childScan.OneBasedScanNumber + " Dissociation Type: " + childScan.DissociationType + " MsOrder: " + childScan.MsnOrder + " Selected Mz: " + childScan.SelectedIonMZ.Value.ToString("0.##") + " RetentionTime: " + childScan.RetentionTime.ToString("0.##"); Canvas childCanvas = new Canvas(); PlotView childPlotView = new PlotView(); // placeholder // make the plot var childPlot = new PeptideSpectrumMatchPlot(childPlotView, childCanvas, psm, childScan, matchedIons, annotateProperties: false); childPlot.Model.Title = null; childPlot.Model.Subtitle = null; item = new ParentChildScanPlotTemplate() { Plot = childPlot, SpectrumLabel = childAnnotation, TheCanvas = childCanvas }; // remove model from placeholder (the model can only be referenced by 1 plotview at a time) childPlotView.Model = null; parentChildScanPlotsView.Plots.Add(item); CurrentlyDisplayedPlots.Add(childPlot); } } }
//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); } } } }
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]); }
// single peptides (not crosslink) public void DrawPeptideSpectralMatch(MsDataScan msDataScan, PsmFromTsv psmToDraw, bool annotateMz = false, bool annotateCharge = false, int annotateFontSize = 12, bool annotateBold = false) { // Set the Model property, the INotifyPropertyChanged event will make the WPF Plot control update its content this.Model = Draw(msDataScan, psmToDraw, annotateMz, annotateCharge, annotateFontSize, annotateBold); }
private PlotModel Draw(MsDataScan msDataScan, PsmFromTsv psmToDraw, bool annotateMz = false, bool annotateCharge = false, int annotateFontSize = 12, bool annotateBold = false) { // x is m/z, y is intensity var spectrumMzs = msDataScan.MassSpectrum.XArray; var spectrumIntensities = msDataScan.MassSpectrum.YArray; string subtitle = psmToDraw.FullSequence; if (psmToDraw != null && psmToDraw.BetaPeptideBaseSequence != null) { subtitle = psmToDraw.FullSequence + "\n" + psmToDraw.BetaPeptideFullSequence; } PlotModel model = new PlotModel { Title = "Spectrum Annotation of Scan #" + msDataScan.OneBasedScanNumber, DefaultFontSize = 15, Subtitle = subtitle }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "m/z", Minimum = msDataScan.ScanWindowRange.Minimum, Maximum = msDataScan.ScanWindowRange.Maximum, AbsoluteMinimum = 0, AbsoluteMaximum = msDataScan.ScanWindowRange.Maximum * 2, MajorStep = Math.Round(msDataScan.ScanWindowRange.Maximum / 2), MinorStep = Math.Round(msDataScan.ScanWindowRange.Maximum / 4) }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Intensity", Minimum = 0, Maximum = spectrumIntensities.Max(), AbsoluteMinimum = 0, AbsoluteMaximum = spectrumIntensities.Max() * 2, MajorStep = spectrumIntensities.Max(), MinorStep = spectrumIntensities.Max() / 2, StringFormat = "0e-0", }); model.Axes[1].Zoom(0, spectrumIntensities.Max() * 1.1); LineSeries[] allIons = new LineSeries[spectrumMzs.Length]; // draw the remaining unmatched peaks for (int i = 0; i < spectrumMzs.Length; i++) { // peak has already been drawn (it is a matched peak) if (allIons[i] != null) { continue; } allIons[i] = new LineSeries(); allIons[i].Color = OxyColors.DimGray; allIons[i].StrokeThickness = STROKE_THICKNESS_UNANNOTATED; allIons[i].Points.Add(new DataPoint(spectrumMzs[i], 0)); allIons[i].Points.Add(new DataPoint(spectrumMzs[i], spectrumIntensities[i])); model.Series.Add(allIons[i]); } // draw the matched peaks; if the PSM is null, we're just drawing the peaks in the scan without annotation, so skip this part if (psmToDraw != null) { List <MatchedFragmentIon> ionsToDraw = new List <MatchedFragmentIon>(); // check to see if we're drawing a child scan or a parent scan if (psmToDraw.Ms2ScanNumber == msDataScan.OneBasedScanNumber) { // parent scan ionsToDraw = psmToDraw.MatchedIons; } else if (msDataScan.OneBasedScanNumber != psmToDraw.Ms2ScanNumber && psmToDraw.ChildScanMatchedIons.Keys.Any(p => p == msDataScan.OneBasedScanNumber)) { // child scan var scan = psmToDraw.ChildScanMatchedIons.FirstOrDefault(p => p.Key == msDataScan.OneBasedScanNumber); ionsToDraw = scan.Value; } // annotate peaks (typical PSM, or alpha peptide of CSM) foreach (MatchedFragmentIon matchedIon in ionsToDraw) { AnnotatePeak(model, allIons, msDataScan, matchedIon, spectrumIntensities, psmToDraw, annotateCharge, annotateMz, annotateBold, annotateFontSize, false); } // annotate peaks of beta peptide of CSM if (psmToDraw.BetaPeptideBaseSequence != null) { ionsToDraw = new List <MatchedFragmentIon>(); // check to see if we're drawing a child scan or a parent scan if (psmToDraw.Ms2ScanNumber == msDataScan.OneBasedScanNumber) { // parent scan ionsToDraw = psmToDraw.BetaPeptideMatchedIons; } else if (msDataScan.OneBasedScanNumber != psmToDraw.Ms2ScanNumber && psmToDraw.BetaPeptideChildScanMatchedIons.Keys.Any(p => p == msDataScan.OneBasedScanNumber)) { // child scan var scan = psmToDraw.BetaPeptideChildScanMatchedIons.FirstOrDefault(p => p.Key == msDataScan.OneBasedScanNumber); ionsToDraw = scan.Value; } foreach (MatchedFragmentIon matchedIon in ionsToDraw) { AnnotatePeak(model, allIons, msDataScan, matchedIon, spectrumIntensities, psmToDraw, annotateCharge, annotateMz, annotateBold, annotateFontSize, true); } } } // Axes are created automatically if they are not defined return(model); }
private void DrawAnnotatedBaseSequence(PsmFromTsv psm) { double spacing = 22; BaseDraw.clearCanvas(canvas); // don't draw ambiguous sequences if (psm.FullSequence.Contains("|")) { return; } // draw base sequence for (int r = 0; r < psm.BaseSeq.Length; r++) { BaseDraw.txtDrawing(canvas, new Point(r * spacing + 10, 10), psm.BaseSeq[r].ToString(), Brushes.Black); } // draw the fragment ion annotations on the base sequence foreach (var ion in psm.MatchedIons) { int residue = ion.NeutralTheoreticalProduct.TerminusFragment.AminoAcidPosition; string annotation = ion.NeutralTheoreticalProduct.ProductType + "" + ion.NeutralTheoreticalProduct.TerminusFragment.FragmentNumber; if (ion.NeutralTheoreticalProduct.NeutralLoss != 0) { annotation += "-" + ion.NeutralTheoreticalProduct.NeutralLoss; } if (ion.NeutralTheoreticalProduct.TerminusFragment.Terminus == FragmentationTerminus.C) { BaseDraw.topSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType]), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } else if (ion.NeutralTheoreticalProduct.TerminusFragment.Terminus == FragmentationTerminus.N) { BaseDraw.botSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType]), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } // don't draw diagnostic ions, precursor ions, etc } // draw modifications var peptide = new PeptideWithSetModifications(psm.FullSequence, GlobalVariables.AllModsKnownDictionary); foreach (var mod in peptide.AllModsOneIsNterminus) { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12), modificationAnnotationColor); } if (psm.BetaPeptideBaseSequence != null) { for (int r = 0; r < psm.BetaPeptideBaseSequence.Length; r++) { BaseDraw.txtDrawing(canvas, new Point(r * spacing + 10, 100), psm.BetaPeptideBaseSequence[r].ToString(), Brushes.Black); } foreach (var ion in psm.BetaPeptideMatchedIons) { int residue = ion.NeutralTheoreticalProduct.TerminusFragment.AminoAcidPosition; string annotation = ion.NeutralTheoreticalProduct.ProductType + "" + ion.NeutralTheoreticalProduct.TerminusFragment.FragmentNumber; if (ion.NeutralTheoreticalProduct.NeutralLoss != 0) { annotation += "-" + ion.NeutralTheoreticalProduct.NeutralLoss; } if (ion.NeutralTheoreticalProduct.TerminusFragment.Terminus == FragmentationTerminus.C) { BaseDraw.topSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType] + 90), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } else if (ion.NeutralTheoreticalProduct.TerminusFragment.Terminus == FragmentationTerminus.N) { BaseDraw.botSplittingDrawing(canvas, new Point(residue * spacing + 8, productTypeToYOffset[ion.NeutralTheoreticalProduct.ProductType] + 90), productTypeToColor[ion.NeutralTheoreticalProduct.ProductType], annotation); } // don't draw diagnostic ions, precursor ions, etc } var betaPeptide = new PeptideWithSetModifications(psm.BetaPeptideFullSequence, GlobalVariables.AllModsKnownDictionary); foreach (var mod in betaPeptide.AllModsOneIsNterminus) { BaseDraw.circledTxtDraw(canvas, new Point((mod.Key - 1) * spacing - 17, 12 + 90), modificationAnnotationColor); } int alphaSite = Int32.Parse(Regex.Match(psm.FullSequence, @"\d+").Value); int betaSite = Int32.Parse(Regex.Match(psm.BetaPeptideFullSequence, @"\d+").Value); BaseDraw.DrawCrosslinker(canvas, new Point(alphaSite * spacing, 50), new Point(betaSite * spacing, 90), Colors.Black); } }