/// <summary> /// Read FASTA db file. /// </summary> /// <param name="filePath">The path to the FASTA DB file.</param> /// <param name="parseSequence"></param> /// <returns>Enumerable of entries in the file.</returns> public static IEnumerable <FastaEntry> ReadFastaFile(string filePath, bool parseSequence = false) { FastaEntry fastaEntry = null; var entries = new List <FastaEntry>(); foreach (var line in File.ReadLines(filePath)) { if (line.Length == 0) { continue; } if (line[0] == '>') { if (fastaEntry != null) { entries.Add(fastaEntry); } fastaEntry = new FastaEntry(); var parts = line.Split(' '); if (parts[0].Length == 1) { throw new FormatException("Invalid Fasta file format."); } fastaEntry.ProteinName = parts[0].Substring(1, parts[0].Length - 1); if (parts.Length > 1) { fastaEntry.ProteinDescription = parts[1]; } } else { fastaEntry.ProteinSequenceText += line; } } if (fastaEntry != null) { if (parseSequence) { fastaEntry.ProteinSequence = new Sequence(fastaEntry.ProteinSequenceText, new AminoAcidSet()); } entries.Add(fastaEntry); } return(entries); }
/// <summary> /// Initializes a new instance of the <see cref="SearchSettingsViewModel"/> class. /// </summary> /// <param name="dialogService">Dialog service for opening dialogs from view model.</param> public SearchSettingsViewModel(IMainDialogService dialogService) { this.dialogService = dialogService; SearchModes = new[] { InternalCleavageType.MultipleInternalCleavages, InternalCleavageType.SingleInternalCleavage, InternalCleavageType.NoInternalCleavage }; ToleranceUnits = new[] { ToleranceUnit.Ppm, ToleranceUnit.Mz }; SelectedSequence = string.Empty; FastaEntries = new ReactiveList <FastaEntry>(); SequenceProteins = new FastaEntry[0]; SearchRunning = false; FromFastaEntry = true; FromSequence = false; // Browse Spectrum Files Command BrowseSpectrumFilesCommand = ReactiveCommand.Create(BrowseSpectrumFilesImplementation); // Browse Feature Files Command BrowseFeatureFilesCommand = ReactiveCommand.Create(BrowseFeatureFilesImplementation); // Browse Fasta DB Files Command BrowseFastaDbFilesCommand = ReactiveCommand.Create(BrowseFastaDbFilesImplementation); // Browse Output Directories Command BrowseOutputDirectoriesCommand = ReactiveCommand.Create(BrowseOutputDirectoriesImplementation); // Select All Proteins Command SelectAllProteinsCommand = ReactiveCommand.Create(() => SelectProteinsImplementation(true), FastaEntries.WhenAnyValue(x => x.Count).Select(count => count > 0)); // Select No Proteins Command SelectNoProteinsCommand = ReactiveCommand.Create(() => SelectProteinsImplementation(false), FastaEntries.WhenAnyValue(x => x.Count).Select(count => count > 0)); // Manage Modifications Command ManageModificationsCommand = ReactiveCommand.Create(ManageModificationsImplementation); // Add Modifications Command AddModificationCommand = ReactiveCommand.Create(AddModificationImplementation); // Run Command - Disabled when there is no SpectrumFilePath, FastaDbFilePath, or OutputFilePath selected RunCommand = ReactiveCommand.CreateFromTask(async _ => await RunImplementation(), this.WhenAnyValue( x => x.SpectrumFilePath, x => x.FastaDbFilePath, x => x.OutputFilePath) .Select(x => !string.IsNullOrWhiteSpace(x.Item1) && !string.IsNullOrWhiteSpace(x.Item2) && !string.IsNullOrWhiteSpace(x.Item3)) ); // Prev tab command PrevTabCommand = ReactiveCommand.Create(() => TabIndex--, Observable.Merge( new[] { this.WhenAnyValue(x => x.TabIndex).Select(tabIndex => tabIndex > 0), RunCommand.IsExecuting.Select(exec => !exec) })); // Next tab command NextTabCommand = ReactiveCommand.Create(() => TabIndex++, Observable.Merge( new[] { this.WhenAnyValue(x => x.TabIndex).Select(tabIndex => tabIndex < MaxTabIndex), RunCommand.IsExecuting.Select(exec => !exec) })); // Cancel Command CancelCommand = ReactiveCommand.Create(CancelImplementation); // Default values SelectedSearchMode = InternalCleavageType.SingleInternalCleavage; MinSequenceLength = 21; MaxSequenceLength = 300; MinPrecursorIonCharge = 2; MaxPrecursorIonCharge = 30; MinProductIonCharge = 1; MaxProductIonCharge = 15; MinSequenceMass = 3000.0; MaxSequenceMass = 50000.0; PrecursorIonToleranceValue = 10; PrecursorIonToleranceUnit = ToleranceUnit.Ppm; ProductIonToleranceValue = 10; PrecursorIonToleranceUnit = ToleranceUnit.Ppm; minScanNumber = 0; maxScanNumber = 0; maxDynamicModificationsPerSequence = 0; FixedNTerm = true; FixedCTerm = true; NumMatchesPerSpectrum = 1; // When search mode is selected, display correct search mode description this.WhenAnyValue(x => x.SelectedSearchMode) .Subscribe(searchMode => SearchModeDescription = searchModeDescriptions[(int)searchMode]); // When Spectrum file path is selected, use its directory for the output path by default if a output path // has not already been selected. this.WhenAnyValue(x => x.SpectrumFilePath) .Where(_ => string.IsNullOrWhiteSpace(OutputFilePath)) .Select(Path.GetDirectoryName) .Subscribe(specDir => OutputFilePath = specDir); SearchModifications = new ReactiveList <SearchModificationViewModel> { ChangeTrackingEnabled = true }; this.WhenAnyValue(x => x.FastaDbFilePath).Subscribe(_ => LoadFastaFile()); this.WhenAnyValue(x => x.FastaEntries.Count, x => x.SelectedSequence) .Select(x => FastaEntries.Where(entry => entry.ProteinSequenceText.Contains(x.Item2)).ToArray()) .Subscribe(entries => SequenceProteins = entries); // Remove search modification when its Remove property is set to true. SearchModifications.ItemChanged.Where(x => x.PropertyName == "Remove") .Select(x => x.Sender).Where(sender => sender.Remove) .Subscribe(searchMod => SearchModifications.Remove(searchMod)); ModificationsUpdated = false; }
/// <summary> /// Create a truncated FASTA file based on selected proteins. /// </summary> /// <returns>The path to the truncated FASTA database file.</returns> private string CreateTruncatedFastaFile() { var fastaFileName = Path.GetFileNameWithoutExtension(this.FastaDbFilePath); var filePath = string.Format("{0}\\{1}_truncated.fasta", this.OutputFilePath, fastaFileName); IEnumerable <FastaEntry> entries = new FastaEntry[0]; if (this.FromFastaEntry) { entries = this.FastaEntries.Where(entry => entry.Selected); } else if (this.FromSequence) { var selectedEntries = this.SequenceProteins.Where(entry => entry.Selected).ToArray(); if (this.FixedNTerm && this.FixedCTerm) { // Just use the selected sequence for every protein. entries = selectedEntries.Select( entry => new FastaEntry { ProteinName = entry.ProteinName, ProteinDescription = entry.ProteinDescription, ProteinSequenceText = this.SelectedSequence, Selected = true }); entries = new List <FastaEntry> { entries.FirstOrDefault() }; } else if (this.FixedNTerm) { entries = from entry in selectedEntries let startIndex = entry.ProteinSequenceText.IndexOf(this.SelectedSequence, StringComparison.Ordinal) where startIndex > -1 let sequence = entry.ProteinSequenceText.Substring(startIndex) select new FastaEntry { ProteinName = entry.ProteinName, ProteinDescription = entry.ProteinDescription, ProteinSequenceText = sequence }; } else if (this.FixedCTerm) { entries = from entry in selectedEntries let startIndex = entry.ProteinSequenceText.IndexOf(this.SelectedSequence, StringComparison.Ordinal) where startIndex > -1 let sequence = entry.ProteinSequenceText.Substring(0, startIndex + this.SelectedSequence.Length) select new FastaEntry { ProteinName = entry.ProteinName, ProteinDescription = entry.ProteinDescription, ProteinSequenceText = sequence }; } else { entries = selectedEntries; } } Console.WriteLine(@"Creating truncated fasta file at: {0}", filePath); FastaReaderWriter.Write(entries, filePath); return(filePath); }