Example #1
0
        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);
                }
            }
        }
Example #2
0
        //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);
                    }
                }
            }
        }