/// <summary> /// Main pregressive alignment algorithm aligns a set of sequences guided by /// a binary tree. /// </summary> /// <param name="sequences">input sequences</param> /// <param name="tree">a binary guide tree</param> public void Align(IList <ISequence> sequences, BinaryGuideTree tree) { SequenceWeighting sequenceWeighting = null; if (PAMSAMMultipleSequenceAligner.UseWeights) { sequenceWeighting = new SequenceWeighting(tree); /* * for (int i = 0; i < sequenceWeighting.Weights.Length; ++i) * { * sequenceWeighting.Weights[i] = 1; * } */ } if (sequences.Count == 0) { throw new ArgumentException("Empty set of sequences"); } IAlphabet alphabet = sequences[0].Alphabet; Parallel.For(1, sequences.Count, PAMSAMMultipleSequenceAligner.parallelOption, i => { if (!Alphabets.CheckIsFromSameBase(sequences[i].Alphabet, alphabet)) { throw new ArgumentException("Inconsistent sequence alphabet"); } }); if (PAMSAMMultipleSequenceAligner.UseWeights) { // Generate profile for leaf nodes Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.parallelOption, i => { tree.Nodes[i].ProfileAlignment = ProfileAlignment.GenerateProfileAlignment(sequences[i], sequenceWeighting.Weights[i]); tree.Nodes[i].Weight = sequenceWeighting.Weights[i]; }); } else { // Generate profile for leaf nodes Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.parallelOption, i => { tree.Nodes[i].ProfileAlignment = ProfileAlignment.GenerateProfileAlignment(sequences[i]); }); } // Iterate internal nodes; // as defined in the tree, the last node is the root for (int i = sequences.Count; i < tree.Nodes.Count; ++i) { if (tree.Nodes[i].NeedReAlignment) { // pull out its children _nodeA = tree.Nodes[i].LeftChildren; _nodeB = tree.Nodes[i].RightChildren; if (PAMSAMMultipleSequenceAligner.UseWeights) { _profileAligner.Weights = new float[2]; _profileAligner.Weights[0] = _nodeA.Weight; _profileAligner.Weights[1] = _nodeB.Weight; tree.Nodes[i].Weight = _nodeA.Weight + _nodeB.Weight; } // align two profiles ProfileAlignment result = null; if (_nodeA.ProfileAlignment.NumberOfSequences < _nodeB.ProfileAlignment.NumberOfSequences) { result = (ProfileAlignment)_profileAligner.Align( _nodeA.ProfileAlignment, _nodeB.ProfileAlignment); // assign aligned profiles to the current internal node tree.Nodes[i].ProfileAlignment = result; // generate eString for the children nodes _nodeA.EString = _profileAligner.GenerateEString(_profileAligner.AlignedA); _nodeB.EString = _profileAligner.GenerateEString(_profileAligner.AlignedB); } else { result = (ProfileAlignment)_profileAligner.Align( _nodeB.ProfileAlignment, _nodeA.ProfileAlignment); // assign aligned profiles to the current internal node tree.Nodes[i].ProfileAlignment = result; // generate eString for the children nodes _nodeA.EString = _profileAligner.GenerateEString(_profileAligner.AlignedB); _nodeB.EString = _profileAligner.GenerateEString(_profileAligner.AlignedA); } // children node profiles can be deleted _nodeA.ProfileAlignment.Clear(); _nodeB.ProfileAlignment.Clear(); } } // Convert original unaligned sequences to aligned ones by applying alignment paths in eStrings try { _alignedSequences = new List <ISequence>(sequences.Count); } catch (OutOfMemoryException ex) { throw new Exception("Out of memory", ex.InnerException); } for (int i = 0; i < sequences.Count; ++i) { _alignedSequences.Add(null); } Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.parallelOption, i => { ISequence seq = sequences[i]; BinaryGuideTreeNode node; node = tree.Nodes[i]; while (!node.IsRoot) { seq = _profileAligner.GenerateSequenceFromEString(node.EString, seq); node = node.Parent; } _alignedSequences[i] = seq; }); }
/// <summary> /// Main pregressive alignment algorithm aligns a set of sequences guided by /// a binary tree. /// </summary> /// <param name="sequences">input sequences</param> /// <param name="tree">a binary guide tree</param> public void Align(IList<ISequence> sequences, BinaryGuideTree tree) { SequenceWeighting sequenceWeighting = null; if (PAMSAMMultipleSequenceAligner.UseWeights) { sequenceWeighting = new SequenceWeighting(tree); /* for (int i = 0; i < sequenceWeighting.Weights.Length; ++i) { sequenceWeighting.Weights[i] = 1; } */ } if (sequences.Count==0) { throw new ArgumentException("Empty set of sequences"); } IAlphabet alphabet = sequences[0].Alphabet; Parallel.For(1, sequences.Count, PAMSAMMultipleSequenceAligner.ParallelOption, i => { if (!Alphabets.CheckIsFromSameBase(sequences[i].Alphabet, alphabet)) { throw new ArgumentException("Inconsistent sequence alphabet"); } }); if (PAMSAMMultipleSequenceAligner.UseWeights) { // Generate profile for leaf nodes Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.ParallelOption, i => { tree.Nodes[i].ProfileAlignment = ProfileAlignment.GenerateProfileAlignment(sequences[i], sequenceWeighting.Weights[i]); tree.Nodes[i].Weight = sequenceWeighting.Weights[i]; }); } else { // Generate profile for leaf nodes Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.ParallelOption, i => { tree.Nodes[i].ProfileAlignment = ProfileAlignment.GenerateProfileAlignment(sequences[i]); }); } // Iterate internal nodes; // as defined in the tree, the last node is the root for (int i = sequences.Count; i < tree.Nodes.Count; ++i) { if (tree.Nodes[i].NeedReAlignment) { // pull out its children _nodeA = tree.Nodes[i].LeftChildren; _nodeB = tree.Nodes[i].RightChildren; if (PAMSAMMultipleSequenceAligner.UseWeights) { _profileAligner.Weights = new float[2]; _profileAligner.Weights[0] = _nodeA.Weight; _profileAligner.Weights[1] = _nodeB.Weight; tree.Nodes[i].Weight = _nodeA.Weight + _nodeB.Weight; } // align two profiles ProfileAlignment result = null; if (_nodeA.ProfileAlignment.NumberOfSequences < _nodeB.ProfileAlignment.NumberOfSequences) { result = (ProfileAlignment)_profileAligner.Align( _nodeA.ProfileAlignment, _nodeB.ProfileAlignment); // assign aligned profiles to the current internal node tree.Nodes[i].ProfileAlignment = result; // generate eString for the children nodes _nodeA.EString = _profileAligner.GenerateEString(_profileAligner.AlignedA); _nodeB.EString = _profileAligner.GenerateEString(_profileAligner.AlignedB); } else { result = (ProfileAlignment)_profileAligner.Align( _nodeB.ProfileAlignment, _nodeA.ProfileAlignment); // assign aligned profiles to the current internal node tree.Nodes[i].ProfileAlignment = result; // generate eString for the children nodes _nodeA.EString = _profileAligner.GenerateEString(_profileAligner.AlignedB); _nodeB.EString = _profileAligner.GenerateEString(_profileAligner.AlignedA); } // children node profiles can be deleted _nodeA.ProfileAlignment.Clear(); _nodeB.ProfileAlignment.Clear(); } } // Convert original unaligned sequences to aligned ones by applying alignment paths in eStrings try { _alignedSequences = new List<ISequence>(sequences.Count); } catch (OutOfMemoryException ex) { throw new Exception("Out of memory", ex.InnerException); } for (int i=0; i<sequences.Count;++i) { _alignedSequences.Add(null); } Parallel.For(0, sequences.Count, PAMSAMMultipleSequenceAligner.ParallelOption, i => { ISequence seq = sequences[i]; BinaryGuideTreeNode node; node = tree.Nodes[i]; while (!node.IsRoot) { seq = _profileAligner.GenerateSequenceFromEString(node.EString, seq); node = node.Parent; } _alignedSequences[i] = seq; }); }