X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2FStockholmFile.java;h=6b60cd528e264978d6970521fea9b525e93a2695;hb=d904a499f1863e96cd699e0c5f7f0f81710e8ad9;hp=bac191643d4a312e20e17d64170357c71f88177e;hpb=a1115830030081f29593da857b28ec46581b6e09;p=jalview.git diff --git a/src/jalview/io/StockholmFile.java b/src/jalview/io/StockholmFile.java index bac1916..6b60cd5 100644 --- a/src/jalview/io/StockholmFile.java +++ b/src/jalview/io/StockholmFile.java @@ -1,20 +1,19 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer - * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle - * - * This program 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 2 - * of the License, or (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 + * + * 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. + * + * 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 . */ /* * This extension was written by Benjamin Schuster-Boeckler at sanger.ac.uk @@ -26,17 +25,18 @@ import java.util.*; import com.stevesoft.pat.*; import jalview.datamodel.*; +import jalview.analysis.Rna; // import org.apache.log4j.*; /** - * This class is supposed to parse a Stockholm format file into Jalview - * There are TODOs in this class: we do not know what the database source and - * version is for the file when parsing the #GS= AC tag which associates accessions - * with sequences. - * Database references are also not parsed correctly: a separate reference string - * parser must be added to parse the database reference form into Jalview's local - * representation. + * This class is supposed to parse a Stockholm format file into Jalview There + * are TODOs in this class: we do not know what the database source and version + * is for the file when parsing the #GS= AC tag which associates accessions with + * sequences. Database references are also not parsed correctly: a separate + * reference string parser must be added to parse the database reference form + * into Jalview's local representation. + * * @author bsb at sanger.ac.uk * @version 0.3 + jalview mods * @@ -54,6 +54,11 @@ public class StockholmFile extends AlignFile super(inFile, type); } + public StockholmFile(FileParse source) throws IOException + { + super(source); + } + public void initData() { super.initData(); @@ -78,6 +83,9 @@ public class StockholmFile extends AlignFile Hashtable seqs = new Hashtable(); Regex p, r, rend, s, x; + // Temporary line for processing RNA annotation + // String RNAannot = ""; + // ------------------ Parsing File ---------------------- // First, we have to check that this file has STOCKHOLM format, i.e. the // first line must match @@ -94,18 +102,27 @@ public class StockholmFile extends AlignFile } // We define some Regexes here that will be used regularily later - rend = new Regex("\\/\\/"); // Find the end of an alignment + rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in - // id/from/to + // 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 + // Convert all bracket types to parentheses (necessary for passing to VARNA) + Regex openparen = new Regex("(<|\\[)", "("); + Regex closeparen = new Regex("(>|\\])", ")"); + + // Detect if file is RNA by looking for bracket types + Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))"); + rend.optimize(); p.optimize(); s.optimize(); r.optimize(); x.optimize(); + openparen.optimize(); + closeparen.optimize(); while ((line = nextLine()) != null) { @@ -124,7 +141,7 @@ public class StockholmFile extends AlignFile { String acc = (String) accs.nextElement(); // logger.debug("Processing sequence " + acc); - String seq = (String) seqs.get(acc); + String seq = (String) seqs.remove(acc); if (maxLength < seq.length()) { maxLength = seq.length(); @@ -132,12 +149,16 @@ public class StockholmFile extends AlignFile int start = 1; int end = -1; String sid = acc; - // Retrieve hash of annotations for this accession + /* + * Retrieve hash of annotations for this accession + * Associate Annotation with accession + */ Hashtable accAnnotations = null; if (seqAnn != null && seqAnn.containsKey(acc)) { - accAnnotations = (Hashtable) seqAnn.get(acc); + accAnnotations = (Hashtable) seqAnn.remove(acc); + //TODO: add structures to sequence } // Split accession in id and from/to @@ -165,14 +186,26 @@ public class StockholmFile extends AlignFile String src = dbr.substring(0, dbr.indexOf(";")); String acn = dbr.substring(dbr.indexOf(";") + 1); jalview.util.DBRefUtils.parseToDbRef(seqO, src, "0", acn); - //seqO.addDBRef(dbref); + // seqO.addDBRef(dbref); } + } + if (accAnnotations != null && accAnnotations.containsKey("SS")) + { + Vector v = (Vector) accAnnotations.get("SS"); + + for (int i = 0; i < v.size(); i++) + { + AlignmentAnnotation an = (AlignmentAnnotation) v.elementAt(i); + seqO.addAlignmentAnnotation(an); + //annotations.add(an); + } } + Hashtable features = null; // We need to adjust the positions of all features to account for gaps try { - features = (Hashtable) accAnnotations.get("features"); + features = (Hashtable) accAnnotations.remove("features"); } catch (java.lang.NullPointerException e) { // loggerwarn("Getting Features for " + acc + ": " + @@ -182,6 +215,7 @@ public class StockholmFile extends AlignFile // if we have features if (features != null) { + int posmap[] = seqO.findPositionMap(); Enumeration i = features.keys(); while (i.hasMoreElements()) { @@ -190,8 +224,7 @@ public class StockholmFile extends AlignFile // TODO: parse out scores as annotation row // TODO: map coding region to core jalview feature types String type = i.nextElement().toString(); - Hashtable content = (Hashtable) features.get(type); - + Hashtable content = (Hashtable) features.remove(type); Enumeration j = content.keys(); while (j.hasMoreElements()) { @@ -201,9 +234,15 @@ public class StockholmFile extends AlignFile for (int k = 0; k < byChar.length; k++) { char c = byChar[k]; - if (!(c == ' ' || c == '_' || c == '-')) + if (!(c == ' ' || c == '_' || c == '-' || c == '.')) // PFAM + // uses + // '.' + // for + // feature + // background { - int new_pos = seqO.findPosition(k); + int new_pos = posmap[k]; // look up nearest seqeunce + // position to this column SequenceFeature feat = new SequenceFeature(type, desc, new_pos, new_pos, 0f, null); @@ -215,10 +254,13 @@ public class StockholmFile extends AlignFile } } + // garbage collect + // logger.debug("Adding seq " + acc + " from " + start + " to " + end // + ": " + seq); this.seqs.addElement(seqO); } + return; // finished parsing this segment of source } else if (!r.search(line)) { @@ -350,8 +392,8 @@ public class StockholmFile extends AlignFile if (x.search(annContent)) { // parse out and create alignment annotation directly. - parseAnnotationRow(annotations, x.stringMatched(1), x - .stringMatched(2)); + parseAnnotationRow(annotations, x.stringMatched(1), + x.stringMatched(2)); } } else if (annType.equals("GR")) @@ -370,14 +412,20 @@ public class StockholmFile extends AlignFile { String acc = s.stringMatched(1); String type = s.stringMatched(2); - String seq = s.stringMatched(3); - String description = new String(); - + String seq = new String(s.stringMatched(3)); + String description = null; // Check for additional information about the current annotation - if (x.search(seq)) + // We use a simple string tokenizer here for speed + StringTokenizer sep = new StringTokenizer(seq, " \t"); + description = sep.nextToken(); + if (sep.hasMoreTokens()) { - description = x.stringMatched(1); - seq = x.stringMatched(2); + seq = sep.nextToken(); + } + else + { + seq = description; + description = new String(); } // sequence id with from-to fields @@ -394,7 +442,7 @@ public class StockholmFile extends AlignFile ann = new Hashtable(); seqAnn.put(acc, ann); } - + //TODO test structure, call parseAnnotationRow with vector from hashtable for specific sequence Hashtable features; // Get an object with all the content for an annotation if (ann.containsKey("features")) @@ -428,11 +476,31 @@ public class StockholmFile extends AlignFile ns = ""; } ns += seq; - content.put(description, seq); + content.put(description, ns); + + if(type.equals("SS")){ + Hashtable strucAnn; + if (seqAnn.containsKey(acc)) + { + strucAnn = (Hashtable) seqAnn.get(acc); + } + else + { + strucAnn = new Hashtable(); + } + + Vector newStruc=new Vector(); + parseAnnotationRow(newStruc, type,ns); + + strucAnn.put(type, newStruc); + seqAnn.put(acc, strucAnn); + } } else { - System.err.println("Warning - couldn't parse sequence annotation row line:\n"+line); + System.err + .println("Warning - couldn't parse sequence annotation row line:\n" + + line); // throw new IOException("Error parsing " + line); } } @@ -453,9 +521,22 @@ public class StockholmFile extends AlignFile } } - private AlignmentAnnotation parseAnnotationRow(Vector annotation, + protected static AlignmentAnnotation parseAnnotationRow(Vector annotation, String label, String annots) { + String convert1, convert2 = null; + + // Convert all bracket types to parentheses + Regex openparen = new Regex("(<|\\[)", "("); + Regex closeparen = new Regex("(>|\\])", ")"); + + // Detect if file is RNA by looking for bracket types + Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))"); + + convert1 = openparen.replaceAll(annots); + convert2 = closeparen.replaceAll(convert1); + annots = convert2; + String type = (label.indexOf("_cons") == label.length() - 5) ? label .substring(0, label.length() - 5) : label; boolean ss = false; @@ -470,18 +551,28 @@ public class StockholmFile extends AlignFile { String pos = annots.substring(i, i + 1); Annotation ann; - ann = new Annotation(pos, "", ' ', Float.NaN); + ann = new Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not + // be written out if (ss) { - ann.secondaryStructure = jalview.schemes.ResidueProperties - .getDssp3state(pos).charAt(0); + if (detectbrackets.search(pos)) + { + ann.secondaryStructure = jalview.schemes.ResidueProperties + .getRNASecStrucState(pos).charAt(0); + } + else + { + ann.secondaryStructure = jalview.schemes.ResidueProperties + .getDssp3state(pos).charAt(0); + } + if (ann.secondaryStructure == pos.charAt(0) || pos.charAt(0) == 'C') { - ann.displayCharacter = ""; + ann.displayCharacter = ""; // null; // " "; } else { - ann.displayCharacter += " "; + ann.displayCharacter = " " + ann.displayCharacter; } } @@ -509,6 +600,7 @@ public class StockholmFile extends AlignFile annot.annotations.length); System.arraycopy(els, 0, anns, annot.annotations.length, els.length); annot.annotations = anns; + //System.out.println("else: "); } return annot; } @@ -548,7 +640,7 @@ public class StockholmFile extends AlignFile } } - private String id2type(String id) + protected static String id2type(String id) { if (typeIds.containsKey(id)) { @@ -558,4 +650,38 @@ public class StockholmFile extends AlignFile + id); return id; } + /** + * //ssline is complete secondary structure line private AlignmentAnnotation + * addHelices(Vector annotation, String label, String ssline) { + * + * // decide on secondary structure or not. Annotation[] els = new + * Annotation[ssline.length()]; for (int i = 0; i < ssline.length(); i++) { + * String pos = ssline.substring(i, i + 1); Annotation ann; ann = new + * Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not + * + * ann.secondaryStructure = + * jalview.schemes.ResidueProperties.getRNAssState(pos).charAt(0); + * + * ann.displayCharacter = "x" + ann.displayCharacter; + * + * System.out.println(ann.displayCharacter); + * + * els[i] = ann; } AlignmentAnnotation helicesAnnot = null; Enumeration e = + * annotation.elements(); while (e.hasMoreElements()) { helicesAnnot = + * (AlignmentAnnotation) e.nextElement(); if (helicesAnnot.label.equals(type)) + * break; helicesAnnot = null; } if (helicesAnnot == null) { helicesAnnot = + * new AlignmentAnnotation(type, type, els); + * annotation.addElement(helicesAnnot); } else { Annotation[] anns = new + * Annotation[helicesAnnot.annotations.length + els.length]; + * System.arraycopy(helicesAnnot.annotations, 0, anns, 0, + * helicesAnnot.annotations.length); System.arraycopy(els, 0, anns, + * helicesAnnot.annotations.length, els.length); helicesAnnot.annotations = + * anns; } + * + * helicesAnnot.features = Rna.GetBasePairs(ssline); + * Rna.HelixMap(helicesAnnot.features); + * + * + * return helicesAnnot; } + */ }