/// <summary> /// Generate all possible combinations of glycans and peptides within the constraints of number of glycosylations /// on a given peptide. Represent each combination as a GlycopeptideComposition. /// </summary> public void BuildCompositionHypothesis() { int peptideIter = 0; foreach (MSDigestPeptide peptide in Peptides) { peptideIter++; //Console.WriteLine("Working on Peptide {0}, {1}", peptideIter, peptide); //Creates the unglycosylated peptide composition row. GlycopeptideComposition rawPeptideComposition = new GlycopeptideComposition(peptide); int numGlycosylations = rawPeptideComposition.GlycosylationCount; rawPeptideComposition.GlycosylationCount = 0; //If there were no glycosylations on this peptide to begin with, this step is done! if (numGlycosylations == 0) { if (KeepUnglycosylatedPeptides) { GlycopeptideComposition.Compositions.Add(rawPeptideComposition); } continue; } //This is a combinations with replacement problem, meaning that the number of choices with each iteration does not shrink and order does not matter. //Since convergent glycan compositions cannot be distinguished, we may be able to reduce the total number generated. //Console.WriteLine("[{4}] This peptide has {0} (K) glycosylation sites, and there are {1} (N) glycans to choose from. Combinations = {2} new objects without convergent compositions. Current Memory Size: {3} ", numGlycosylations, GlycanCompositions.Compositions.Count, Numerics.Combinations(GlycanCompositions.Compositions.Count, numGlycosylations), GC.GetTotalMemory(false), peptideIter++); //Represent the iterative increase in glycosylation as a set of queues. Each possible glycoform //is generated incrementally from previously generated set of compositions. We only need the set of //compositions we created from the last iteration to build the next iteration. //I use a Queue here because C#'s List API doesn't have a notion of get-and-remove, and removing Queue<GlycopeptideComposition> previousCompositions = new Queue<GlycopeptideComposition>(); Queue<GlycopeptideComposition> nextCompositions = new Queue<GlycopeptideComposition>(); previousCompositions.Enqueue(rawPeptideComposition); for (int depthIter = 0; depthIter < numGlycosylations; depthIter++) { Dictionary<string, bool> glycanCompositionCache = new Dictionary<string, bool>(); int lengthOfPrevious = previousCompositions.Count; while (previousCompositions.Count > 0) { GlycopeptideComposition template = previousCompositions.Dequeue(); GlycopeptideComposition.Compositions.Add(template); foreach (GlycanComposition glycan in this.GlycanCompositions.Compositions) { GlycopeptideComposition instance = new GlycopeptideComposition(template); instance.AttachGlycan(glycan); string glycanTuple = instance.GlycanCompositionTuple(GlycopeptideComposition.MoleculeNames); if (glycanCompositionCache.ContainsKey(glycanTuple)) { continue; } else { glycanCompositionCache.Add(glycanTuple, true); } nextCompositions.Enqueue(instance); } } int lengthOfNext = nextCompositions.Count; Console.WriteLine("Length of run: {0:N}", lengthOfNext); previousCompositions = nextCompositions; nextCompositions = new Queue<GlycopeptideComposition>(); //Console.WriteLine("[{5}]{0} * {1} = {2}. Generated {3}. Saved {6}%\nMemory Size: {4}", lengthOfPrevious, GlycanCompositions.Compositions.Count, lengthOfPrevious * GlycanCompositions.Compositions.Count, lengthOfNext, GC.GetTotalMemory(false), depthIter, (1 - (lengthOfNext / (double)(lengthOfPrevious * GlycanCompositions.Compositions.Count))) * 100); } //After the last pass through the loop, previousComposition still holds all of the most recently generated values, //so we need to add them to the total list. GlycopeptideComposition.Compositions.AddRange(previousCompositions); } Console.WriteLine("Build complete."); }
/// <summary> /// Copy Constructor /// </summary> /// <param name="other"></param> public GlycopeptideComposition(GlycopeptideComposition other) : base(other as GlycanComposition) { this.MissedCleavages = other.MissedCleavages; this.GlycosylationCount = other.GlycosylationCount; this.StartAA = other.StartAA; this.EndAA = other.EndAA; this.PeptideSequence = other.PeptideSequence; this.PeptideModification = other.PeptideModification; this.ProteinID = other.ProteinID; }