X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fio%2FStockholmFile.java;h=92f73f4efa26680c09703bbd4bb9ba766b6a2e44;hb=564c47bdd60cf84046269e45d2f85f39408e4441;hp=b9f127422970240e15a05b4cf0325aa776826226;hpb=d284df057dccb23cccc3609532406b876c3e2e2f;p=jalview.git diff --git a/src/jalview/io/StockholmFile.java b/src/jalview/io/StockholmFile.java index b9f1274..92f73f4 100644 --- a/src/jalview/io/StockholmFile.java +++ b/src/jalview/io/StockholmFile.java @@ -28,16 +28,15 @@ import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.DBRefEntry; -import jalview.datamodel.DBRefSource; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.schemes.ResidueProperties; import jalview.util.Comparison; -import jalview.util.DBRefUtils; import jalview.util.Format; import jalview.util.MessageManager; +import jalview.util.Platform; import java.io.BufferedReader; import java.io.FileReader; @@ -78,20 +77,105 @@ public class StockholmFile extends AlignFile { private static final String ANNOTATION = "annotation"; - private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "("); + // WUSS extended symbols. Avoid ambiguity with protein SS annotations by using + // NOT_RNASS first. - private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")"); + public static final String RNASS_BRACKETS = "<>[](){}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; - public static final Regex DETECT_BRACKETS = new Regex( - "(<|>|\\[|\\]|\\(|\\)|\\{|\\})"); + public static final int REGEX_STOCKHOLM = 0; - // WUSS extended symbols. Avoid ambiguity with protein SS annotations by using NOT_RNASS first. - public static final String RNASS_BRACKETS = "<>[](){}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; + public static final int REGEX_BRACKETS = 1; // use the following regex to decide an annotations (whole) line is NOT an RNA // SS (it contains only E,H,e,h and other non-brace/non-alpha chars) - private static final Regex NOT_RNASS = new Regex( - "^[^<>[\\](){}A-DF-Za-df-z]*$"); + public static final int REGEX_NOT_RNASS = 2; + + private static final int REGEX_ANNOTATION = 3; + + private static final int REGEX_PFAM = 4; + + private static final int REGEX_RFAM = 5; + + private static final int REGEX_ALIGN_END = 6; + + private static final int REGEX_SPLIT_ID = 7; + + private static final int REGEX_SUBTYPE = 8; + + private static final int REGEX_ANNOTATION_LINE = 9; + + private static final int REGEX_REMOVE_ID = 10; + + private static final int REGEX_OPEN_PAREN = 11; + + private static final int REGEX_CLOSE_PAREN = 12; + + public static final int REGEX_MAX = 13; + + private static Regex REGEX[] = new Regex[REGEX_MAX]; + + /** + * Centralize all actual Regex instantialization in Platform. + * + * @param id + * @return + */ + private static Regex getRegex(int id) + { + if (REGEX[id] == null) + { + String pat = null, pat2 = null; + switch (id) + { + case REGEX_STOCKHOLM: + pat = "# STOCKHOLM ([\\d\\.]+)"; + break; + case REGEX_BRACKETS: + // for reference; not used + pat = "(<|>|\\[|\\]|\\(|\\)|\\{|\\})"; + break; + case REGEX_NOT_RNASS: + pat = "^[^<>[\\](){}A-DF-Za-df-z]*$"; + break; + case REGEX_ANNOTATION: + pat = "(\\w+)\\s*(.*)"; + break; + case REGEX_PFAM: + pat = "PF[0-9]{5}(.*)"; + break; + case REGEX_RFAM: + pat = "RF[0-9]{5}(.*)"; + break; + case REGEX_ALIGN_END: + pat = "^\\s*\\/\\/"; + break; + case REGEX_SPLIT_ID: + pat = "(\\S+)\\/(\\d+)\\-(\\d+)"; + break; + case REGEX_SUBTYPE: + pat = "(\\S+)\\s+(\\S*)\\s+(.*)"; + break; + case REGEX_ANNOTATION_LINE: + pat = "#=(G[FSRC]?)\\s+(.*)"; + break; + case REGEX_REMOVE_ID: + pat = "(\\S+)\\s+(\\S+)"; + break; + case REGEX_OPEN_PAREN: + pat = "(<|\\[)"; + pat2 = "("; + break; + case REGEX_CLOSE_PAREN: + pat = "(>|\\])"; + pat2 = ")"; + break; + default: + return null; + } + REGEX[id] = Platform.newRegex(pat, pat2); + } + return REGEX[id]; + } StringBuffer out; // output buffer @@ -216,7 +300,7 @@ public class StockholmFile extends AlignFile // First, we have to check that this file has STOCKHOLM format, i.e. the // first line must match - r = new Regex("# STOCKHOLM ([\\d\\.]+)"); + r = getRegex(REGEX_STOCKHOLM); if (!r.search(nextLine())) { throw new IOException(MessageManager @@ -230,19 +314,22 @@ public class StockholmFile extends AlignFile } // We define some Regexes here that will be used regularily later - rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment - p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in + rend = getRegex(REGEX_ALIGN_END);//"^\\s*\\/\\/"); // Find the end of an alignment + p = getRegex(REGEX_SPLIT_ID);//"(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in // id/from/to - s = new Regex("(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses annotation subtype - r = new Regex("#=(G[FSRC]?)\\s+(.*)"); // Finds any annotation line - x = new Regex("(\\S+)\\s+(\\S+)"); // split id from sequence + s = getRegex(REGEX_SUBTYPE);// "(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses + // annotation subtype + r = getRegex(REGEX_ANNOTATION_LINE);// "#=(G[FSRC]?)\\s+(.*)"); // Finds any + // annotation line + x = getRegex(REGEX_REMOVE_ID);// "(\\S+)\\s+(\\S+)"); // split id from + // sequence // Convert all bracket types to parentheses (necessary for passing to VARNA) - Regex openparen = new Regex("(<|\\[)", "("); - Regex closeparen = new Regex("(>|\\])", ")"); + Regex openparen = getRegex(REGEX_OPEN_PAREN);//"(<|\\[)", "("); + Regex closeparen = getRegex(REGEX_CLOSE_PAREN);//"(>|\\])", ")"); - // Detect if file is RNA by looking for bracket types - Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))"); +// // Detect if file is RNA by looking for bracket types + // Regex detectbrackets = getRegex("(<|>|\\[|\\]|\\(|\\))"); rend.optimize(); p.optimize(); @@ -263,9 +350,9 @@ public class StockholmFile extends AlignFile // End of the alignment, pass stuff back this.noSeqs = seqs.size(); - String seqdb, dbsource = null; - Regex pf = new Regex("PF[0-9]{5}(.*)"); // Finds AC for Pfam - Regex rf = new Regex("RF[0-9]{5}(.*)"); // Finds AC for Rfam + String dbsource = null; + Regex pf = getRegex(REGEX_PFAM); // Finds AC for Pfam + Regex rf = getRegex(REGEX_RFAM); // Finds AC for Rfam if (getAlignmentProperty("AC") != null) { String dbType = getAlignmentProperty("AC").toString(); @@ -509,7 +596,7 @@ public class StockholmFile extends AlignFile */ // Let's save the annotations, maybe we'll be able to do something // with them later... - Regex an = new Regex("(\\w+)\\s*(.*)"); + Regex an = getRegex(REGEX_ANNOTATION); if (an.search(annContent)) { if (an.stringMatched(1).equals("NH")) @@ -529,9 +616,6 @@ public class StockholmFile extends AlignFile treeName = an.stringMatched(2); treeString = new StringBuffer(); } - // TODO: JAL-3532 - this is where GF comments and database references are lost - // suggest overriding this method for Stockholm files to catch and properly - // process CC, DR etc into multivalued properties setAlignmentProperty(an.stringMatched(1), an.stringMatched(2)); } } @@ -842,7 +926,8 @@ public class StockholmFile extends AlignFile if (type.equalsIgnoreCase("secondary structure")) { ss = true; - isrnass = !NOT_RNASS.search(annots); // sorry about the double negative + isrnass = !getRegex(REGEX_NOT_RNASS).search(annots); // sorry about the double + // negative // here (it's easier for dealing with // other non-alpha-non-brace chars) } @@ -935,11 +1020,6 @@ public class StockholmFile extends AlignFile return annot; } - private String dbref_to_ac_record(DBRefEntry ref) - { - return ref.getSource().toString() + " ; " - + ref.getAccessionId().toString(); - } @Override public String print(SequenceI[] s, boolean jvSuffix) { @@ -951,46 +1031,34 @@ public class StockholmFile extends AlignFile int max = 0; int maxid = 0; int in = 0; - Hashtable dataRef = null; - while ((in < s.length) && (s[in] != null)) + int slen = s.length; + SequenceI seq; + Hashtable dataRef = null; + while ((in < slen) && ((seq = s[in]) != null)) { - boolean isAA = s[in].isProtein(); - String tmp = printId(s[in], jvSuffix); - max = Math.max(max, s[in].getLength()); + String tmp = printId(seq, jvSuffix); + max = Math.max(max, seq.getLength()); if (tmp.length() > maxid) { maxid = tmp.length(); } - if (s[in].getDBRefs() != null) + List seqrefs = seq.getDBRefs(); + int ndb; + if (seqrefs != null && (ndb = seqrefs.size()) > 0) { if (dataRef == null) { - dataRef = new Hashtable(); - } - List primrefs = s[in].getPrimaryDBRefs(); - if (primrefs.size() >= 1) - { - dataRef.put(tmp, dbref_to_ac_record(primrefs.get(0))); + dataRef = new Hashtable<>(); } - else + for (int idb = 0; idb < ndb; idb++) { - for (int idb = 0; idb < s[in].getDBRefs().length; idb++) - { - DBRefEntry dbref = s[in].getDBRefs()[idb]; - dataRef.put(tmp, dbref_to_ac_record(dbref)); - // if we put in a uniprot or EMBL record then we're done: - if (isAA && DBRefSource.UNIPROT - .equals(DBRefUtils.getCanonicalName(dbref.getSource()))) - { - break; - } - if (!isAA && DBRefSource.EMBL - .equals(DBRefUtils.getCanonicalName(dbref.getSource()))) - { - break; - } - } + + DBRefEntry ref = seqrefs.get(idb); + String datAs1 = ref.getSource().toString() + + " ; " + + ref.getAccessionId().toString(); + dataRef.put(tmp, datAs1); } } in++; @@ -1016,11 +1084,11 @@ public class StockholmFile extends AlignFile // output database accessions if (dataRef != null) { - Enumeration en = dataRef.keys(); + Enumeration en = dataRef.keys(); while (en.hasMoreElements()) { Object idd = en.nextElement(); - String type = (String) dataRef.remove(idd); + String type = dataRef.remove(idd); out.append(new Format("%-" + (maxid - 2) + "s") .form("#=GS " + idd.toString() + " ")); if (type.contains("PFAM") || type.contains("RFAM")) @@ -1037,13 +1105,13 @@ public class StockholmFile extends AlignFile } // output annotations - while (i < s.length && s[i] != null) + while (i < slen && (seq = s[i]) != null) { - AlignmentAnnotation[] alAnot = s[i].getAnnotation(); + AlignmentAnnotation[] alAnot = seq.getAnnotation(); if (alAnot != null) { Annotation[] ann; - for (int j = 0; j < alAnot.length; j++) + for (int j = 0, nj = alAnot.length; j < nj; j++) { String key = type2id(alAnot[j].label); @@ -1063,37 +1131,38 @@ public class StockholmFile extends AlignFile // out.append("#=GR "); out.append(new Format("%-" + maxid + "s").form( - "#=GR " + printId(s[i], jvSuffix) + " " + key + " ")); + "#=GR " + printId(seq, jvSuffix) + " " + key + " ")); ann = alAnot[j].annotations; - String seq = ""; - for (int k = 0; k < ann.length; k++) + String sseq = ""; + for (int k = 0, nk = ann.length; k < nk; k++) { - seq += outputCharacter(key, k, isrna, ann, s[i]); + sseq += outputCharacter(key, k, isrna, ann, seq); } - out.append(seq); + out.append(sseq); out.append(newline); } } out.append(new Format("%-" + maxid + "s") - .form(printId(s[i], jvSuffix) + " ")); - out.append(s[i].getSequenceAsString()); + .form(printId(seq, jvSuffix) + " ")); + out.append(seq.getSequenceAsString()); out.append(newline); i++; } // alignment annotation AlignmentAnnotation aa; - if (al.getAlignmentAnnotation() != null) + AlignmentAnnotation[] an = al.getAlignmentAnnotation(); + if (an != null) { - for (int ia = 0; ia < al.getAlignmentAnnotation().length; ia++) + for (int ia = 0, na = an.length; ia < na; ia++) { - aa = al.getAlignmentAnnotation()[ia]; + aa = an[ia]; if (aa.autoCalculated || !aa.visible || aa.sequenceRef != null) { continue; } - String seq = ""; + String sseq = ""; String label; String key = ""; if (aa.label.equals("seq")) @@ -1121,11 +1190,11 @@ public class StockholmFile extends AlignFile out.append( new Format("%-" + maxid + "s").form("#=GC " + label + " ")); boolean isrna = aa.isValidStruc(); - for (int j = 0; j < aa.annotations.length; j++) + for (int j = 0, nj = aa.annotations.length; j < nj; j++) { - seq += outputCharacter(key, j, isrna, aa.annotations, null); + sseq += outputCharacter(key, j, isrna, aa.annotations, null); } - out.append(seq); + out.append(sseq); out.append(newline); } }