X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FRna.java;h=6b93dcb3d3c5bf371fe641be6403c90bf56dfdb5;hb=refs%2Fheads%2Fj2s%2Fdevelop-bh;hp=ba18732a982dd8cad4e18aa9f828a83dddd55e8a;hpb=d5c5166fcfbdaec2297d68e1e47a869e3bf2049b;p=jalview.git diff --git a/src/jalview/analysis/Rna.java b/src/jalview/analysis/Rna.java index ba18732..6b93dcb 100644 --- a/src/jalview/analysis/Rna.java +++ b/src/jalview/analysis/Rna.java @@ -1,37 +1,96 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) - * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ - /* Author: Lauren Michelle Lui * Methods are based on RALEE methods http://personalpages.manchester.ac.uk/staff/sam.griffiths-jones/software/ralee/ + * Additional Author: Jan Engelhart (2011) - Structure consensus and bug fixing + * Additional Author: Anne Menard (2012) - Pseudoknot support and secondary structure consensus * */ package jalview.analysis; +import jalview.analysis.SecStrConsensus.SimpleBP; +import jalview.datamodel.SequenceFeature; +import jalview.util.MessageManager; + import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.Hashtable; import java.util.Stack; import java.util.Vector; -import jalview.datamodel.SequenceFeature; - public class Rna { - static Hashtable pairHash = new Hashtable(); + + static Hashtable pairHash = new Hashtable(); + + private static final Character[] openingPars = + { '(', '[', '{', '<', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z' }; + + private static final Character[] closingPars = + { ')', ']', '}', '>', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z' }; + + private static HashSet openingParsSet = new HashSet( + Arrays.asList(openingPars)); + + private static HashSet closingParsSet = new HashSet( + Arrays.asList(closingPars)); + + private static Hashtable closingToOpening = new Hashtable(); + + + static { + // Initializing final data structure + for (int i = 0; i < openingPars.length; i++) + { + // System.out.println(closingPars[i] + "->" + openingPars[i]); + closingToOpening.put(closingPars[i], openingPars[i]); + } + }; + + private static boolean isOpeningParenthesis(char c) + { + return openingParsSet.contains(c); + } + + private static boolean isClosingParenthesis(char c) + { + return closingParsSet.contains(c); + } + + private static char matchingOpeningParenthesis(char closingParenthesis) + throws WUSSParseException + { + if (!isClosingParenthesis(closingParenthesis)) + { + throw new WUSSParseException(MessageManager.formatMessage("exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis", new String[]{new StringBuffer(closingParenthesis).toString()}), -1); + } + + return closingToOpening.get(closingParenthesis); + } + /** * Based off of RALEE code ralee-get-base-pairs. Keeps track of open bracket * positions in "stack" vector. When a close bracket is reached, pair this @@ -44,69 +103,92 @@ public class Rna * @return Array of SequenceFeature; type = RNA helix, begin is open base * pair, end is close base pair */ - public static SequenceFeature[] GetBasePairs(CharSequence line) throws WUSSParseException + public static Vector GetSimpleBPs(CharSequence line) + throws WUSSParseException { - Stack stack = new Stack(); - Vector pairs = new Vector(); - + Hashtable> stacks = new Hashtable>(); + Vector pairs = new Vector(); int i = 0; while (i < line.length()) { char base = line.charAt(i); - if ((base == '<') || (base == '(') || (base == '{') || (base == '[')) + if (isOpeningParenthesis(base)) { - stack.push(i); + if (!stacks.containsKey(base)) + { + stacks.put(base, new Stack()); + } + stacks.get(base).push(i); + } - else if ((base == '>') || (base == ')') || (base == '}') - || (base == ']')) + else if (isClosingParenthesis(base)) { + char opening = matchingOpeningParenthesis(base); + + if (!stacks.containsKey(opening)) + { + throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_unseen_closing_char", new String[]{new StringBuffer(base).toString()}), i); + } + + Stack stack = stacks.get(opening); if (stack.isEmpty()) { // error whilst parsing i'th position. pass back - throw new WUSSParseException("Mismatched closing bracket", i); + throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_closing_char", new String[]{new StringBuffer(base).toString()}), i); } - Object temp = stack.pop(); - pairs.addElement(temp); - pairs.addElement(i); - } + int temp = stack.pop(); + pairs.add(new SimpleBP(temp, i)); + } i++; } - - int numpairs = pairs.size() / 2; - SequenceFeature[] outPairs = new SequenceFeature[numpairs]; - - // Convert pairs to array - for (int p = 0; p < pairs.size(); p += 2) + for (char opening : stacks.keySet()) { - int begin = Integer.parseInt(pairs.elementAt(p).toString()); - int end = Integer.parseInt(pairs.elementAt(p + 1).toString()); - - outPairs[p / 2] = new SequenceFeature("RNA helix", "", "", begin, - end, ""); - //pairHash.put(begin, end); - + Stack stack = stacks.get(opening); + if (!stack.empty()) + { + throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_opening_char", new String[]{new StringBuffer(opening).toString(),Integer.valueOf(stack.pop()).toString()}), i); + } } + return pairs; + } + public static SequenceFeature[] GetBasePairs(CharSequence line) + throws WUSSParseException + { + Vector bps = GetSimpleBPs(line); + SequenceFeature[] outPairs = new SequenceFeature[bps.size()]; + for (int p = 0; p < bps.size(); p++) + { + SimpleBP bp = bps.elementAt(p); + outPairs[p] = new SequenceFeature("RNA helix", "", "", bp.getBP5(), + bp.getBP3(), ""); + } return outPairs; } - - + + public static ArrayList GetModeleBP(CharSequence line) + throws WUSSParseException + { + Vector bps = GetSimpleBPs(line); + return new ArrayList(bps); + } + /** * Function to get the end position corresponding to a given start position - * @param indice - start position of a base pair + * + * @param indice + * - start position of a base pair * @return - end position of a base pair */ - /*makes no sense at the moment :( - public int findEnd(int indice){ - //TODO: Probably extend this to find the start to a given end? - //could be done by putting everything twice to the hash - ArrayList pair = new ArrayList(); - return pairHash.get(indice); - }*/ - + /* + * makes no sense at the moment :( public int findEnd(int indice){ //TODO: + * Probably extend this to find the start to a given end? //could be done by + * putting everything twice to the hash ArrayList pair = new + * ArrayList(); return pairHash.get(indice); } + */ /** * Figures out which helix each position belongs to and stores the helix @@ -190,4 +272,3 @@ public class Rna } } } -