示例#1
0
        public IEnumerable <Peptide> Digest(FastaSequence fastaSeq, DigestSettings settings)
        {
            Regex regex = new Regex(Regex);
            int   begin = 0;
            int   len   = fastaSeq.Sequence.Length;

            while (begin < len)
            {
                int end      = begin;
                int endFirst = begin;
                int missed   = 0;
                do
                {
                    string sequence = fastaSeq.Sequence;
                    Match  m        = regex.Match(sequence, end);
                    end = (m.Success ? m.Index + 1 : len);

                    // Save the end of the first cleavage
                    if (missed == 0)
                    {
                        endFirst = end;
                    }

                    // Deal with 'ragged ends', or cleavages one amino acid apart
                    // i.e. KR, RR, etc. for trypsin
                    if (settings.ExcludeRaggedEnds && end < len)
                    {
                        Match mNext = regex.Match(sequence, end);
                        if (mNext.Success && mNext.Index == end)
                        {
                            // If there are no missed cleavages, then move the
                            // begin index to the next cleavage point that is
                            // not part of a run.
                            if (missed == 0)
                            {
                                endFirst = GetDiscontiguousCleavageIndex(regex, mNext, sequence);
                            }
                            break;
                        }
                    }

                    // Single amino acid peptides have no fragment ions.
                    int count = end - begin;
                    if (count > 1 && sequence.IndexOfAny(new[] { '*', '-' }, begin, count) == -1) // Not L10N
                    {
                        yield return(new Peptide(fastaSeq, sequence.Substring(begin, end - begin),
                                                 begin, end, missed));
                    }

                    // Increment missed cleavages for next loop.
                    missed++;
                }while (end < len && missed <= settings.MaxMissedCleavages);

                begin = endFirst;
            }
        }
示例#2
0
 public bool Equals(DigestSettings obj)
 {
     if (ReferenceEquals(null, obj))
     {
         return(false);
     }
     if (ReferenceEquals(this, obj))
     {
         return(true);
     }
     return(obj.MaxMissedCleavages == MaxMissedCleavages &&
            obj.ExcludeRaggedEnds.Equals(ExcludeRaggedEnds));
 }
示例#3
0
文件: Enzyme.cs 项目: zrolfs/pwiz
        public IEnumerable <Peptide> Digest(FastaSequence fastaSeq, DigestSettings settings, int?maxPeptideSequenceLength = null, int?minPeptideSequenceLength = null)
        {
            int begin     = 0;
            var sequence  = fastaSeq.Sequence;
            int len       = sequence.Length;
            int maxPepLen = maxPeptideSequenceLength ?? int.MaxValue;
            int minPepLen = minPeptideSequenceLength ?? 1;
            var matcher   = new Matcher(sequence, GetMatches(sequence));

            while (begin < len)
            {
                matcher.Reset();
                int end      = begin;
                int endFirst = begin;
                int missed   = 0;
                do
                {
                    int endLast = end;
                    var m       = matcher.Match(end);
                    end = m + 1 ?? len;

                    // Save the end of the first cleavage
                    if (missed == 0)
                    {
                        endFirst = end;
                    }

                    // Deal with 'ragged ends', or cleavages one amino acid apart
                    // i.e. KR, RR, etc. for trypsin
                    if (settings.ExcludeRaggedEnds && end < len)
                    {
                        var mNext = matcher.Match(end);
                        if (mNext.HasValue && mNext == end)
                        {
                            // If there are no missed cleavages, then move the
                            // begin index to the next cleavage point that is
                            // not part of a run.
                            if (missed == 0)
                            {
                                endFirst = GetDiscontiguousCleavageIndex(matcher, mNext);
                            }
                            break;
                        }
                    }

                    // If the sequence is longer than we care to consider, quit
                    int  count   = end - begin;
                    bool tooLong = maxPeptideSequenceLength.HasValue && count > maxPeptideSequenceLength;

                    if (!minPeptideSequenceLength.HasValue || count >= minPeptideSequenceLength.Value)
                    {
                        // Single amino acid peptides have no fragment ions.
                        if (count > 1 && sequence.IndexOfAny(nonAAs, begin, count) == -1) // Not L10N
                        {
                            if (!tooLong)
                            {
                                yield return(new Peptide(fastaSeq, sequence.Substring(begin, end - begin),
                                                         begin, end, missed));
                            }

                            if (IsSemiCleaving)
                            {
                                // Add N-terminal semi-cleavage, which excludes peptides already included in prior peptide,
                                // when missed cleavage occurs
                                for (int i = Math.Min(count - 1, maxPepLen); i >= Math.Max(endLast - begin + 1, minPepLen); i--)
                                {
                                    yield return(new Peptide(fastaSeq, sequence.Substring(begin, i), begin, begin + i, missed));
                                }
                                // Add C-terminal semi-cleavage, which excludes peptides to come in subsequent peptides,
                                // when missed cleavage occurs
                                for (int i = Math.Min(count - 1, maxPepLen); i >= Math.Max(end - endFirst + 1, minPepLen); i--)
                                {
                                    yield return(new Peptide(fastaSeq, sequence.Substring(end - i, i), end - i, end, missed));
                                }
                            }
                        }
                    }

                    if (tooLong)
                    {
                        break;
                    }

                    // Increment missed cleavages for next loop.
                    missed++;
                }while (end < len && missed <= settings.MaxMissedCleavages);

                begin = endFirst;
            }
        }
示例#4
0
        public IEnumerable<Peptide> Digest(FastaSequence fastaSeq, DigestSettings settings)
        {
            Regex regex = new Regex(Regex);
            int begin = 0;
            int len = fastaSeq.Sequence.Length;
            while (begin < len)
            {
                int end = begin;
                int endFirst = begin;
                int missed = 0;
                do
                {
                    string sequence = fastaSeq.Sequence;
                    Match m = regex.Match(sequence, end);
                    end = (m.Success ? m.Index + 1 : len);

                    // Save the end of the first cleavage
                    if (missed == 0)
                        endFirst = end;

                    // Deal with 'ragged ends', or cleavages one amino acid apart
                    // i.e. KR, RR, etc. for trypsin
                    if (settings.ExcludeRaggedEnds && end < len)
                    {
                        Match mNext = regex.Match(sequence, end);
                        if (mNext.Success && mNext.Index == end)
                        {
                            // If there are no missed cleavages, then move the
                            // begin index to the next cleavage point that is
                            // not part of a run.
                            if (missed == 0)
                                endFirst = GetDiscontiguousCleavageIndex(regex, mNext, sequence);
                            break;
                        }
                    }

                    // Single amino acid peptides have no fragment ions.
                    int count = end - begin;
                    if (count > 1 && sequence.IndexOfAny(new[] { '*', '-' }, begin, count) == -1) // Not L10N
                    {
                        yield return new Peptide(fastaSeq, sequence.Substring(begin, end - begin),
                            begin, end, missed);
                    }

                    // Increment missed cleavages for next loop.
                    missed++;
                }
                while (end < len && missed <= settings.MaxMissedCleavages);

                begin = endFirst;
            }
        }
示例#5
0
 public bool Equals(DigestSettings obj)
 {
     if (ReferenceEquals(null, obj)) return false;
     if (ReferenceEquals(this, obj)) return true;
     return obj.MaxMissedCleavages == MaxMissedCleavages &&
            obj.ExcludeRaggedEnds.Equals(ExcludeRaggedEnds);
 }
示例#6
0
 public PeptideSettings ChangeDigestSettings(DigestSettings prop)
 {
     return ChangeProp(ImClone(this), im => im.DigestSettings = prop);
 }
示例#7
0
        private PeptideSettings ValidateNewSettings(bool showMessages)
        {
            var helper = new MessageBoxHelper(this, showMessages);

            // Validate and hold digestion settings
            Enzyme enzyme = Settings.Default.GetEnzymeByName(comboEnzyme.SelectedItem.ToString());
            Helpers.AssignIfEquals(ref enzyme, _peptideSettings.Enzyme);

            int maxMissedCleavages =
                int.Parse(comboMissedCleavages.SelectedItem.ToString());
            bool excludeRaggedEnds = cbRaggedEnds.Checked;
            DigestSettings digest = new DigestSettings(maxMissedCleavages, excludeRaggedEnds);
            Helpers.AssignIfEquals(ref digest, Digest);

            var backgroundProteomeSpec = _driverBackgroundProteome.SelectedItem;
            BackgroundProteome backgroundProteome = BackgroundProteome.NONE;
            if (!backgroundProteomeSpec.IsNone)
            {
                backgroundProteome = new BackgroundProteome(backgroundProteomeSpec, true);
                if (backgroundProteome.DatabaseInvalid)
                {

                    var message = TextUtil.LineSeparate(string.Format(Resources.PeptideSettingsUI_ValidateNewSettings_Failed_to_load_background_proteome__0__,
                                                                      backgroundProteomeSpec.Name),
                                                        string.Format(Resources.PeptideSettingsUI_ValidateNewSettings_The_file__0__may_not_be_a_valid_proteome_file,
                                                                      backgroundProteomeSpec.DatabasePath));
                    MessageDlg.Show(this, message);
                    tabControl1.SelectedIndex = 0;
                    _driverBackgroundProteome.Combo.Focus();
                    return null;
                }
            }
            Helpers.AssignIfEquals(ref backgroundProteome, _peptideSettings.BackgroundProteome);

            // Validate and hold prediction settings
            string nameRT = comboRetentionTime.SelectedItem.ToString();
            RetentionTimeRegression retentionTime =
                Settings.Default.GetRetentionTimeByName(nameRT);
            if (retentionTime != null && retentionTime.Calculator != null)
            {
                RetentionScoreCalculatorSpec retentionCalc =
                    Settings.Default.GetCalculatorByName(retentionTime.Calculator.Name);
                // Just in case the calculator in use in the current documet got removed,
                // never set the calculator to null.  Just keep using the one we have.
                if (retentionCalc != null && !ReferenceEquals(retentionCalc, retentionTime.Calculator))
                    retentionTime = retentionTime.ChangeCalculator(retentionCalc);
            }
            bool useMeasuredRT = cbUseMeasuredRT.Checked;
            double? measuredRTWindow = null;
            if (!string.IsNullOrEmpty(textMeasureRTWindow.Text))
            {
                double measuredRTWindowOut;
                const double minWindow = PeptidePrediction.MIN_MEASURED_RT_WINDOW;
                const double maxWindow = PeptidePrediction.MAX_MEASURED_RT_WINDOW;
                if (!helper.ValidateDecimalTextBox(tabControl1, (int) TABS.Prediction,
                        textMeasureRTWindow, minWindow, maxWindow, out measuredRTWindowOut))
                    return null;
                measuredRTWindow = measuredRTWindowOut;
            }

            string nameDt = comboDriftTimePredictor.SelectedItem.ToString();
            DriftTimePredictor driftTimePredictor =
                Settings.Default.GetDriftTimePredictorByName(nameDt);
            if (driftTimePredictor != null && driftTimePredictor.IonMobilityLibrary != null)
            {
                IonMobilityLibrarySpec ionMobilityLibrary =
                    Settings.Default.GetIonMobilityLibraryByName(driftTimePredictor.IonMobilityLibrary.Name);
                // Just in case the library in use in the current documet got removed,
                // never set the library to null.  Just keep using the one we have.
                if (ionMobilityLibrary != null && !ReferenceEquals(ionMobilityLibrary, driftTimePredictor.IonMobilityLibrary))
                    driftTimePredictor = driftTimePredictor.ChangeLibrary(ionMobilityLibrary);
            }
            bool useLibraryDriftTime = cbUseSpectralLibraryDriftTimes.Checked;
            double? libraryDTResolvingPower = null;
            if (useLibraryDriftTime || !string.IsNullOrEmpty(textSpectralLibraryDriftTimesResolvingPower.Text))
            {
                double libraryDTWindowOut;
                if (!helper.ValidateDecimalTextBox(tabControl1, (int)TABS.Prediction,
                        textSpectralLibraryDriftTimesResolvingPower, null, null, out libraryDTWindowOut))
                    return null;
                string errmsg = EditDriftTimePredictorDlg.ValidateResolvingPower(libraryDTWindowOut);
                if (errmsg != null)
                {
                    helper.ShowTextBoxError(tabControl1, (int)TABS.Prediction, textSpectralLibraryDriftTimesResolvingPower, errmsg);
                    return null;
                }
                libraryDTResolvingPower = libraryDTWindowOut;
            }

            var prediction = new PeptidePrediction(retentionTime, driftTimePredictor, useMeasuredRT, measuredRTWindow, useLibraryDriftTime, libraryDTResolvingPower);
            Helpers.AssignIfEquals(ref prediction, Prediction);

            // Validate and hold filter settings
            int excludeNTermAAs;
            if (!helper.ValidateNumberTextBox(tabControl1, (int) TABS.Filter, textExcludeAAs,
                    PeptideFilter.MIN_EXCLUDE_NTERM_AA, PeptideFilter.MAX_EXCLUDE_NTERM_AA, out excludeNTermAAs))
                return null;
            int minPeptideLength;
            if (!helper.ValidateNumberTextBox(tabControl1, (int) TABS.Filter, textMinLength,
                    PeptideFilter.MIN_MIN_LENGTH, PeptideFilter.MAX_MIN_LENGTH, out minPeptideLength))
                return null;
            int maxPeptideLength;
            if (!helper.ValidateNumberTextBox(tabControl1, (int)TABS.Filter, textMaxLength,
                    Math.Max(PeptideFilter.MIN_MAX_LENGTH, minPeptideLength), PeptideFilter.MAX_MAX_LENGTH, out maxPeptideLength))
                return null;

            PeptideExcludeRegex[] exclusions = _driverExclusion.Chosen;

            bool autoSelect = cbAutoSelect.Checked;
            PeptideFilter filter;
            try
            {
                filter = new PeptideFilter(excludeNTermAAs,
                                           minPeptideLength,
                                           maxPeptideLength,
                                           exclusions,
                                           autoSelect);
            }
            catch (InvalidDataException x)
            {
                if (showMessages)
                    MessageDlg.ShowException(this, x);
                return null;
            }

            Helpers.AssignIfEquals(ref filter, Filter);

            // Validate and hold libraries
            PeptideLibraries libraries;
            IList<LibrarySpec> librarySpecs = _driverLibrary.Chosen;
            if (librarySpecs.Count == 0)
                libraries = new PeptideLibraries(PeptidePick.library, null, null, false, librarySpecs, new Library[0]);
            else
            {
                int? peptideCount = null;
                if (cbLimitPeptides.Checked)
                {
                    int peptideCountVal;
                    if (!helper.ValidateNumberTextBox(textPeptideCount, PeptideLibraries.MIN_PEPTIDE_COUNT,
                            PeptideLibraries.MAX_PEPTIDE_COUNT, out peptideCountVal))
                        return null;
                    peptideCount = peptideCountVal;
                }
                PeptidePick pick = (PeptidePick) comboMatching.SelectedIndex;

                IList<Library> librariesLoaded = new Library[librarySpecs.Count];
                bool documentLibrary = false;
                if (Libraries != null)
                {
                    // Use existing library spec's, if nothing was changed.
                    // Avoid changing the libraries, just because the the picking
                    // algorithm changed.
                    if (ArrayUtil.EqualsDeep(librarySpecs, Libraries.LibrarySpecs))
                    {
                        librarySpecs = Libraries.LibrarySpecs;
                        librariesLoaded = Libraries.Libraries;
                    }

                    documentLibrary = Libraries.HasDocumentLibrary;
                    // Otherwise, leave the list of loaded libraries empty,
                    // and let the LibraryManager refill it.  This ensures a
                    // clean save of library specs only in the user config, rather
                    // than a mix of library specs and libraries.
                }

                PeptideRankId rankId = (PeptideRankId) comboRank.SelectedItem;
                if (comboRank.SelectedIndex == 0)
                    rankId = null;

                libraries = new PeptideLibraries(pick, rankId, peptideCount, documentLibrary, librarySpecs, librariesLoaded);
            }
            Helpers.AssignIfEquals(ref libraries, Libraries);

            // Validate and hold modifications
            int maxVariableMods;
            if (!helper.ValidateNumberTextBox(tabControl1, (int)TABS.Modifications, textMaxVariableMods,
                    PeptideModifications.MIN_MAX_VARIABLE_MODS, PeptideModifications.MAX_MAX_VARIABLE_MODS, out maxVariableMods))
                return null;
            int maxNeutralLosses;
            if (!helper.ValidateNumberTextBox(tabControl1, (int)TABS.Modifications, textMaxNeutralLosses,
                    PeptideModifications.MIN_MAX_NEUTRAL_LOSSES, PeptideModifications.MAX_MAX_NEUTRAL_LOSSES, out maxNeutralLosses))
                return null;

            var standardTypes = _driverLabelType.InternalStandardTypes;
            PeptideModifications modifications = new PeptideModifications(
                _driverStaticMod.Chosen, maxVariableMods, maxNeutralLosses,
                _driverLabelType.GetHeavyModifications(), standardTypes);
            // Should not be possible to change explicit modifications in the background,
            // so this should be safe.  CONSIDER: Document structure because of a library load?
            modifications = modifications.DeclareExplicitMods(_parent.DocumentUI,
                Settings.Default.StaticModList, Settings.Default.HeavyModList);
            Helpers.AssignIfEquals(ref modifications, _peptideSettings.Modifications);

            PeptideIntegration integration = new PeptideIntegration(_driverPeakScoringModel.SelectedItem);
            Helpers.AssignIfEquals(ref integration, Integration);

            QuantificationSettings quantification = QuantificationSettings.DEFAULT
                .ChangeNormalizationMethod(comboNormalizationMethod.SelectedItem as NormalizationMethod ?? NormalizationMethod.NONE)
                .ChangeRegressionWeighting(comboWeighting.SelectedItem as RegressionWeighting)
                .ChangeRegressionFit(comboRegressionFit.SelectedItem as RegressionFit)
                .ChangeMsLevel(_quantMsLevels[comboQuantMsLevel.SelectedIndex])
                .ChangeUnits(tbxQuantUnits.Text);

            return new PeptideSettings(enzyme, digest, prediction, filter, libraries, modifications, integration, backgroundProteome)
                    .ChangeAbsoluteQuantification(quantification);
        }
示例#8
0
 public PeptideSettings(Enzyme enzyme,
     DigestSettings digestSettings,
     PeptidePrediction prediction,
     PeptideFilter filter,
     PeptideLibraries libraries,
     PeptideModifications modifications,
     PeptideIntegration integration,
     BackgroundProteome backgroundProteome
     )
 {
     Enzyme = enzyme;
     DigestSettings = digestSettings;
     Prediction = prediction;
     Filter = filter;
     Libraries = libraries;
     Modifications = modifications;
     Integration = integration;
     BackgroundProteome = backgroundProteome;
     Quantification = QuantificationSettings.DEFAULT;
 }
 public IEnumerable<DigestedPeptide> Digest(Protein protein)
 {
     if (string.IsNullOrEmpty(protein.Sequence))
     {
         yield break;
     }
     FastaSequence fastaSequence;
     try
     {
         fastaSequence = new FastaSequence("name", "description", new List<ProteinMetadata>(), protein.Sequence); // Not L10N
     }
     catch (InvalidDataException)
     {
         // It's possible that the peptide sequence in the fasta file was bogus, in which case we just don't digest it.
         yield break;
     }
     DigestSettings digestSettings = new DigestSettings(6, false);
     foreach (var digest in _enzyme.Digest(fastaSequence, digestSettings))
     {
         var digestedPeptide = new DigestedPeptide
         {
             Index = digest.Begin ?? 0,
             Sequence = digest.Sequence
         };
         yield return digestedPeptide;
     }
 }
 public Digestion Digest(Enzyme enzyme, DigestSettings digestSettings, ILoadMonitor loader)
 {
     ProgressStatus progressStatus = new ProgressStatus(string.Format(Resources.BackgroundProteomeSpec_Digest_Digesting__0__, enzyme.Name));
     using (var proteomeDb = OpenProteomeDb())
     {
         return proteomeDb.Digest(new ProteaseImpl(enzyme),
                                     (s, i) =>
                                     {
                                         loader.UpdateProgress(progressStatus.ChangePercentComplete(i));
                                         return !loader.IsCanceled;
                                     });
     }
 }
示例#11
0
        public IEnumerable <Peptide> Digest(FastaSequence fastaSeq, DigestSettings settings, int?maxPeptideSequenceLength = null)
        {
            int begin    = 0;
            var sequence = fastaSeq.Sequence;
            int len      = sequence.Length;
            var matcher  = new Matcher(sequence, GetMatches(sequence));

            while (begin < len)
            {
                matcher.Reset();
                int end      = begin;
                int endFirst = begin;
                int missed   = 0;
                do
                {
                    var m = matcher.Match(end);
                    end = m + 1 ?? len;
                    // Save the end of the first cleavage
                    if (missed == 0)
                    {
                        endFirst = end;
                    }

                    // Deal with 'ragged ends', or cleavages one amino acid apart
                    // i.e. KR, RR, etc. for trypsin
                    if (settings.ExcludeRaggedEnds && end < len)
                    {
                        var mNext = matcher.Match(end);
                        if (mNext.HasValue && mNext == end)
                        {
                            // If there are no missed cleavages, then move the
                            // begin index to the next cleavage point that is
                            // not part of a run.
                            if (missed == 0)
                            {
                                endFirst = GetDiscontiguousCleavageIndex(matcher, mNext);
                            }
                            break;
                        }
                    }

                    // Single amino acid peptides have no fragment ions.
                    int count = end - begin;
                    // If the sequence is longer than we care to consider, quit
                    if (maxPeptideSequenceLength.HasValue && count > maxPeptideSequenceLength)
                    {
                        break;
                    }

                    if (count > 1 && sequence.IndexOfAny(nonAAs, begin, count) == -1) // Not L10N
                    {
                        yield return(new Peptide(fastaSeq, sequence.Substring(begin, end - begin),
                                                 begin, end, missed));
                    }

                    // Increment missed cleavages for next loop.
                    missed++;
                }while (end < len && missed <= settings.MaxMissedCleavages);

                begin = endFirst;
            }
        }
示例#12
0
        public bool ImportFasta()
        {
            var settings = SkylineWindow.Document.Settings;
            var peptideSettings = settings.PeptideSettings;
            int missedCleavages = MaxMissedCleavages;
            var enzyme = Enzyme;
            if (!Equals(missedCleavages, peptideSettings.DigestSettings.MaxMissedCleavages) || !Equals(enzyme, peptideSettings.Enzyme))
            {
                var digest = new DigestSettings(missedCleavages, peptideSettings.DigestSettings.ExcludeRaggedEnds);
                peptideSettings = peptideSettings.ChangeDigestSettings(digest).ChangeEnzyme(enzyme);
                SkylineWindow.ModifyDocument(string.Format(Resources.ImportFastaControl_ImportFasta_Change_digestion_settings), doc =>
                    doc.ChangeSettings(settings.ChangePeptideSettings(peptideSettings)));
            }

            if (!ContainsFastaContent) // The user didn't specify any FASTA content
            {
                var docCurrent = SkylineWindow.DocumentUI;
                // If the document has precursor transitions already, then just trust the user
                // knows what they are doing, and this document is already set up for MS1 filtering
                if (HasPrecursorTransitions(docCurrent))
                    return true;

                if (docCurrent.PeptideCount == 0)
                {
                    MessageDlg.Show(WizardForm, TextUtil.LineSeparate(Resources.ImportFastaControl_ImportFasta_The_document_does_not_contain_any_peptides_,
                                                                      Resources.ImportFastaControl_ImportFasta_Please_import_FASTA_to_add_peptides_to_the_document_));
                    return false;
                }

                if (MessageBox.Show(WizardForm, TextUtil.LineSeparate(Resources.ImportFastaControl_ImportFasta_The_document_does_not_contain_any_precursor_transitions_,
                                                                      Resources.ImportFastaControl_ImportFasta_Would_you_like_to_change_the_document_settings_to_automatically_pick_the_precursor_transitions_specified_in_the_full_scan_settings_),
                                    Program.Name, MessageBoxButtons.OKCancel) != DialogResult.OK)
                    return false;

                SkylineWindow.ModifyDocument(Resources.ImportFastaControl_ImportFasta_Change_settings_to_add_precursors, doc => ImportPeptideSearch.ChangeAutoManageChildren(doc, PickLevel.transitions, true));
            }
            else // The user specified some FASTA content
            {
                // If the user is about to add any new transitions by importing
                // FASTA, set FragmentType='p' and AutoSelect=true
                var docCurrent = SkylineWindow.Document;
                var docNew = ImportPeptideSearch.PrepareImportFasta(docCurrent);

                var nodeInsert = SkylineWindow.SequenceTree.SelectedNode as SrmTreeNode;
                IdentityPath selectedPath = nodeInsert != null ? nodeInsert.Path : null;
                int emptyPeptideGroups = 0;

                if (!_fastaFile)
                {
                    // Import FASTA as content
                    docNew = ImportFastaHelper.AddFasta(docNew, ref selectedPath, out emptyPeptideGroups);
                    // Document will be null if there was an error
                    if (docNew == null)
                        return false;
                }
                else
                {
                    // Import FASTA as file
                    var fastaPath = tbxFasta.Text;
                    try
                    {
                        using (var longWaitDlg = new LongWaitDlg(SkylineWindow) { Text = Resources.ImportFastaControl_ImportFasta_Insert_FASTA })
                        {
                            IdentityPath to = selectedPath;
                            var docImportFasta = docNew;
                            longWaitDlg.PerformWork(WizardForm, 1000, longWaitBroker =>
                                {
                                    IdentityPath nextAdd;
                                    docImportFasta = ImportPeptideSearch.ImportFasta(docImportFasta, fastaPath,
                                        longWaitBroker, to, out selectedPath, out nextAdd, out emptyPeptideGroups);
                                });
                            docNew = docImportFasta;
                        }
                    }
                    catch (Exception x)
                    {
                        MessageDlg.ShowWithException(this, string.Format(Resources.SkylineWindow_ImportFastaFile_Failed_reading_the_file__0__1__,
                                                            fastaPath, x.Message), x);
                        return false;
                    }
                }

                // Check for empty proteins
                docNew = ImportFastaHelper.HandleEmptyPeptideGroups(WizardForm, emptyPeptideGroups, docNew);
                // Document will be null if user was given option to keep or remove empty proteins and pressed cancel
                if (docNew == null)
                    return false;

                SkylineWindow.ModifyDocument(Resources.ImportFastaControl_ImportFasta_Insert_FASTA, doc =>
                {
                    if (!ReferenceEquals(doc, docCurrent))
                        throw new InvalidDataException(Resources.SkylineWindow_ImportFasta_Unexpected_document_change_during_operation);
                    return docNew;
                });

                if (!VerifyAtLeastOnePrecursorTransition(SkylineWindow.Document))
                    return false;
            }

            return true;
        }