public PeptideForTreeView(string displayName, ProteinForTreeView parent)
 {
     Children    = new ObservableCollection <PsmForTreeView>();
     Parent      = parent;
     DisplayName = displayName;
     Expanded    = false;
 }
        // 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));
        }
        // create a new instance of a protein group
        private ProteinForTreeView CreateNewProtein(string accession, string sequence, string name, Dictionary <string, PeptideForTreeView> unique = null, Dictionary <string, PeptideForTreeView> shared = null)
        {
            proteinGroups.Add(accession, sequence);
            var ptv = new ProteinForTreeView(name, accession, unique, shared, new Dictionary <string, PeptideForTreeView>());

            proteinGroupsForTreeView.Add(accession, ptv);
            proteinTree.Add(ptv);

            return(ptv);
        }
        private void OnSelectionChanged()
        {
            // can select protein or peptide only at a time (not both)
            if (proteinTreeView.SelectedItem == null)
            {
                return;
            }

            // draw the selected PSM
            propertyView.Clear();

            // differentiate item click protein VS psm
            var            selection    = proteinTreeView.SelectedItem.GetType().Name;
            PsmForTreeView psmToDisplay = null;

            switch (selection)
            {
            case "ProteinForTreeView":
            {
                ProteinForTreeView selectedItem = (ProteinForTreeView)proteinTreeView.SelectedItem;
                itemsControlSampleViewModel.Data.Clear();

                if (proteinGroups[selectedItem.Accession] != null)
                {
                    DrawSequenceCoverageMap(selectedItem);
                    ChangeMapScrollViewVisibility();
                }
            }
            break;

            case "PeptideForTreeView":
            {
                // find psm with best score
                PeptideForTreeView selectedItem = (PeptideForTreeView)proteinTreeView.SelectedItem;
                psmToDisplay = selectedItem.Children.OrderByDescending(psm => psm.Psm.Score).First();
                goto case "display";
            }

            case "PsmForTreeView":
            {
                psmToDisplay = (PsmForTreeView)proteinTreeView.SelectedItem;
                goto case "display";
            }

            case "display":
            {
                mapViewer.Visibility = Visibility.Collapsed;
                legend.Visibility    = Visibility.Collapsed;
                displayPsm(psmToDisplay);
            }
            break;
            }
        }
        private void DrawPdfCoverageMap(ProteinForTreeView protein, Grid mapGrid, string path)
        {
            // draw coverage map
            mapGrid.Width = 1000;
            DrawSequenceCoverageMap(protein);

            string pathToCoverageMap = Path.Combine(Path.GetDirectoryName(path), "map.png");

            CustomPdfWriter.RenderImage((int)mapGrid.Width, (int)mapGrid.Height, pathToCoverageMap, map);

            // draw legend
            SequenceCoverageMap.drawLegend(legend, proteaseByColor, proteases, legendGrid);
            string pathToLegend = Path.Combine(Path.GetDirectoryName(path), "legend.png");

            CustomPdfWriter.RenderImage((int)(legend.Width), 50, pathToLegend, legend);

            CustomPdfWriter.WriteToPdfMetaDraw(mapGrid.Width, mapGrid.Height, pathToCoverageMap, pathToLegend, path);
        }
        // search through psm list based on user input
        private ProteinForTreeView searchPsm(ProteinForTreeView prot, PeptideForTreeView peptide, string txt)
        {
            // create copy of peptide
            var pep = new PeptideForTreeView(peptide.DisplayName, peptide.Parent);

            foreach (var psm in peptide.Children)
            {
                if (psm.ScanNo.ToString().StartsWith(txt))
                {
                    pep.Expanded = true;
                    pep.Children.Add(psm);
                }
            }

            if (pep.Children.Count() > 0)
            {
                prot.Children.Add(pep);
            }

            return(prot);
        }
        // redraw display based on first selection
        private void RestoreDefault(object defaultSelection)
        {
            mapGrid.Width = 485;
            var selection = defaultSelection.GetType().Name;

            switch (selection)
            {
            case "ProteinForTreeView":
            {
                ProteinForTreeView protein = (ProteinForTreeView)defaultSelection;
                DrawSequenceCoverageMap(protein);
            }
            break;

            case "PsmForTreeView":
            {
                PsmForTreeView psm = (PsmForTreeView)defaultSelection;
                DrawPsm(psm.Psm.Ms2ScanNumber, psm.Psm.FullSequence);
            }
            break;
            }
        }
        // search through peptide list based on user input
        private void searchPeptide(ProteinForTreeView protein, string txt)
        {
            // create copy of protein
            var prot = new ProteinForTreeView(protein.DisplayName, protein.Accession, protein.UniquePeptides, protein.SharedPeptides, protein.AllPeptides);

            foreach (var peptide in protein.Children)
            {
                if (peptide.DisplayName.ToUpper().Contains(txt.ToUpper()))
                {
                    prot.Children.Add(peptide);
                }
                else
                {
                    prot = searchPsm(prot, peptide, txt);
                }
            }

            if (prot.Children.Count() > 0)
            {
                prot.Expanded = true;
                filteredTree.Add(prot);
            }
        }
        private void DrawSequenceCoverageMap(ProteinForTreeView protein) //string accession, Dictionary<string, PeptideForTreeView> uniquePeptides, Dictionary<string, PeptideForTreeView> sharedPeptides)
        {
            string protease    = "trypsin";                              // only works for single protease for now
            string seqCoverage = proteinGroups[protein.Accession];

            mapViewer.Visibility = Visibility.Visible;

            BaseDraw.clearCanvas(map);
            mainViewModel.Model = null; // clear plot
            BaseDraw.clearCanvas(canvas);

            double spacing     = 22;
            int    height      = 10;
            int    totalHeight = 0;
            int    accumIndex  = 0;

            foreach (string seq in seqCoverage.Split('|'))
            {
                var splitSeq = Split(seq, spacing);

                var allPeptides = new List <string>(protein.AllPeptides.Keys);
                foreach (var line in splitSeq)
                {
                    List <int> indices = new List <int>();

                    // draw sequence
                    for (int r = 0; r < line.Length; r++)
                    {
                        SequenceCoverageMap.txtDrawing(map, new Point(r * spacing + 10, height), line[r].ToString().ToUpper(), Brushes.Black);
                    }

                    // highlight partial peptide sequences (broken off into multiple lines)
                    if (partialPeptideMatches.Count > 0)
                    {
                        var temp = new Dictionary <string, int>(partialPeptideMatches);
                        partialPeptideMatches.Clear();

                        foreach (var peptide in temp)
                        {
                            if (MatchPeptideSequence(peptide.Key, line, 0, peptide.Value, accumIndex - peptide.Value == seq.IndexOf(peptide.Key)))
                            {
                                int start = 0;
                                int end   = Math.Min(start + peptide.Key.Length - peptide.Value - 1, line.Length - 1);
                                SequenceCoverageMap.Highlight(start, end, map, indices, height, proteaseByColor[protease], protein.UniquePeptides.Keys.Any(u => u.Contains(peptide.Key))); // draw line for peptide sequence
                            }
                        }
                    }

                    // highlight full peptide sequences
                    for (int i = 0; i < line.Length; ++i)
                    {
                        var temp = new List <string>(allPeptides);
                        foreach (string peptide in temp)
                        {
                            if (MatchPeptideSequence(peptide, line, i, 0, accumIndex + i == seq.IndexOf(peptide)))
                            {
                                int start = i;
                                int end   = Math.Min(start + peptide.Length - 1, line.Length - 1);
                                SequenceCoverageMap.Highlight(start, end, map, indices, height, proteaseByColor[protease], protein.UniquePeptides.Keys.Any(u => u.Contains(peptide)));
                                allPeptides.Remove(peptide);
                            }
                        }
                    }

                    height     += 50;
                    accumIndex += line.Length;
                }

                totalHeight += splitSeq.Count() * 50;
                height      += 50;
            }

            mapGrid.Height = totalHeight + 50 * seqCoverage.Split('|').Count();
            SequenceCoverageMap.drawLegend(legend, proteaseByColor, proteases, legendGrid);
        }
        private void PDFButton_Click(object sender, RoutedEventArgs e)
        {
            object temp       = null;
            var    selections = new List <object>();

            // select best scoring psm for any peptide selections
            foreach (object selectedItem in proteinTreeView.SelectedItems)
            {
                if (selectedItem.GetType().Name.Equals("PeptideForTreeView"))
                {
                    PeptideForTreeView peptide        = (PeptideForTreeView)selectedItem;
                    PsmForTreeView     bestScoringPsm = peptide.Children.OrderByDescending(psm => psm.Psm.Score).First();
                    selections.Add(bestScoringPsm);
                    continue;
                }

                selections.Add(selectedItem);
            }

            if (proteinTreeView.SelectedItems.Count == 0)
            {
                MessageBox.Show("Please select at least one scan or coverage map to export");
            }
            else
            {
                int numberOfScansToExport = selections.Distinct().Count();

                foreach (object selectedItem in selections.Distinct())
                {
                    if (temp == null)
                    {
                        temp = selectedItem;
                    }

                    var selection = selectedItem.GetType().Name;
                    switch (selection)
                    {
                    case "ProteinForTreeView":
                    {
                        ProteinForTreeView protein  = (ProteinForTreeView)selectedItem;
                        string             myString = illegalInFileName.Replace(protein.DisplayName, "");
                        myString = myString.Length > 30 ? myString.Substring(0, 30) : myString;

                        string filePath = Path.Combine(Path.GetDirectoryName(psmFilePath), "MetaDrawExport", myString.Trim(), myString + ".pdf");
                        string dir      = Path.GetDirectoryName(filePath);

                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        DrawPdfCoverageMap(protein, mapGrid, filePath);
                    }
                    break;

                    case "PsmForTreeView":
                    {
                        PsmForTreeView psm           = (PsmForTreeView)selectedItem;
                        var            proteinFolder = illegalInFileName.Replace(psm.Parent.Parent.DisplayName, "");
                        proteinFolder = proteinFolder.Length > 30 ? proteinFolder.Substring(0, 30) : proteinFolder;

                        string peptideFolder = illegalInFileName.Replace(psm.Parent.DisplayName, "");
                        peptideFolder = peptideFolder.Length > 30 ? peptideFolder.Substring(0, 30) : peptideFolder;

                        string filePath = Path.Combine(Path.GetDirectoryName(psmFilePath), "MetaDrawExport", proteinFolder.Trim(), peptideFolder.Trim(), psm.ScanNo + ".pdf");
                        string dir      = Path.GetDirectoryName(filePath);

                        MsDataScan msDataScanToDraw = MsDataFile.GetOneBasedScan(psm.ScanNo);

                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        DrawPdfAnnotatedBaseSequence(psm.Psm, canvas, filePath);         // captures the annotation for the pdf
                        mainViewModel.DrawPeptideSpectralMatchPdf(msDataScanToDraw, psm.Psm, filePath, numberOfScansToExport > 1);
                    }
                    break;
                    }
                }

                RestoreDefault(temp);
                MessageBox.Show(string.Format("{0} PDFs exported", numberOfScansToExport));
            }
        }