import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
import jalview.util.Format;
import jalview.util.MessageManager;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
import java.util.Vector;
import com.stevesoft.pat.Regex;
*/
public class StockholmFile extends AlignFile
{
+ private static final String ANNOTATION = "annotation";
+
private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
- private static final Regex DETECT_BRACKETS = new Regex(
- "(<|>|\\[|\\]|\\(|\\))");
+ public static final Regex DETECT_BRACKETS = new Regex(
+ "(<|>|\\[|\\]|\\(|\\)|\\{|\\})");
StringBuffer out; // output buffer
// add alignment annotation for this feature
String key = type2id(type);
+
+ /*
+ * have we added annotation rows for this type ?
+ */
+ boolean annotsAdded = false;
if (key != null)
{
if (accAnnotations != null
Vector vv = (Vector) accAnnotations.get(key);
for (int ii = 0; ii < vv.size(); ii++)
{
+ annotsAdded = true;
AlignmentAnnotation an = (AlignmentAnnotation) vv
.elementAt(ii);
seqO.addAlignmentAnnotation(an);
while (j.hasMoreElements())
{
String desc = j.nextElement().toString();
+ if (ANNOTATION.equals(desc) && annotsAdded)
+ {
+ // don't add features if we already added an annotation row
+ continue;
+ }
String ns = content.get(desc).toString();
char[] byChar = ns.toCharArray();
for (int k = 0; k < byChar.length; 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);
+ new_pos, new_pos, null);
seqO.addSequenceFeature(feat);
}
{
String acc = s.stringMatched(1);
String type = s.stringMatched(2);
- String seq = new String(s.stringMatched(3));
- String description = null;
- // Check for additional information about the current annotation
- // We use a simple string tokenizer here for speed
- StringTokenizer sep = new StringTokenizer(seq, " \t");
- description = sep.nextToken();
- if (sep.hasMoreTokens())
- {
- seq = sep.nextToken();
- }
- else
- {
- seq = description;
- description = new String();
- }
- // sequence id with from-to fields
+ String oseq = s.stringMatched(3);
+ /*
+ * copy of annotation field that may be processed into whitespace chunks
+ */
+ String seq = new String(oseq);
Hashtable ann;
// Get an object with all the annotations for this sequence
ann = new Hashtable();
seqAnn.put(acc, ann);
}
+
+ // // start of block for appending annotation lines for wrapped
+ // stokchholm file
// 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"))
content = new Hashtable();
features.put(this.id2type(type), content);
}
- String ns = (String) content.get(description);
+ String ns = (String) content.get(ANNOTATION);
+
if (ns == null)
{
ns = "";
}
+ // finally, append the annotation line
ns += seq;
- content.put(description, ns);
+ content.put(ANNOTATION, ns);
+ // // end of wrapped annotation block.
+ // // Now a new row is created with the current set of data
- // if(type.equals("SS")){
Hashtable strucAnn;
if (seqAnn.containsKey(acc))
{
{
alan.visible = false;
}
- // annotations.addAll(newStruc);
+ // new annotation overwrites any existing annotation...
+
strucAnn.put(type, newStruc);
seqAnn.put(acc, strucAnn);
}
{
String convert1, convert2 = null;
- convert1 = OPEN_PAREN.replaceAll(annots);
- convert2 = CLOSE_PAREN.replaceAll(convert1);
- annots = convert2;
+ // convert1 = OPEN_PAREN.replaceAll(annots);
+ // convert2 = CLOSE_PAREN.replaceAll(convert1);
+ // annots = convert2;
String type = label;
if (label.contains("_cons"))
type = (label.indexOf("_cons") == label.length() - 5) ? label
.substring(0, label.length() - 5) : label;
}
- boolean ss = false;
+ boolean ss = false, posterior = false;
type = id2type(type);
- if (type.equals("secondary structure"))
+ if (type.equalsIgnoreCase("secondary structure"))
{
ss = true;
}
+ if (type.equalsIgnoreCase("posterior probability"))
+ {
+ posterior = true;
+ }
// decide on secondary structure or not.
Annotation[] els = new Annotation[annots.length()];
for (int i = 0; i < annots.length(); i++)
{
if (DETECT_BRACKETS.search(pos))
{
- ann.secondaryStructure = Rna.getRNASecStrucState(
- pos).charAt(0);
+ ann.secondaryStructure = Rna.getRNASecStrucState(pos).charAt(0);
+ ann.displayCharacter = "" + pos.charAt(0);
}
else
{
ann.secondaryStructure = ResidueProperties.getDssp3state(pos)
.charAt(0);
- }
if (ann.secondaryStructure == pos.charAt(0))
{
{
ann.displayCharacter = " " + ann.displayCharacter;
}
+ }
}
}
+ if (posterior && !ann.isWhitespace()
+ && !Comparison.isGap(pos.charAt(0)))
+ {
+ float val = 0;
+ // symbol encodes values - 0..*==0..10
+ if (pos.charAt(0) == '*')
+ {
+ val = 10;
+ }
+ else
+ {
+ val = pos.charAt(0) - '0';
+ if (val > 9)
+ {
+ val = 10;
+ }
+ }
+ ann.value = val;
+ }
els[i] = ann;
}
// output annotations
while (i < s.length && s[i] != null)
{
- if (s[i].getDatasetSequence() != null)
+ AlignmentAnnotation[] alAnot = s[i].getAnnotation();
+ if (alAnot != null)
{
- SequenceI ds = s[i].getDatasetSequence();
- AlignmentAnnotation[] alAnot;
Annotation[] ann;
- Annotation annot;
- alAnot = s[i].getAnnotation();
- String feature = "";
- if (alAnot != null)
+ for (int j = 0; j < alAnot.length; j++)
{
- for (int j = 0; j < alAnot.length; j++)
+
+ String key = type2id(alAnot[j].label);
+ boolean isrna = alAnot[j].isValidStruc();
+
+ if (isrna)
+ {
+ // hardwire to secondary structure if there is RNA secondary
+ // structure on the annotation
+ key = "SS";
+ }
+ if (key == null)
{
- if (ds.getSequenceFeatures() != null)
- {
- feature = ds.getSequenceFeatures()[0].type;
- }
- // ?bug - feature may still have previous loop value
- String key = type2id(feature);
- if (key == null)
- {
- continue;
- }
+ continue;
+ }
- // out.append("#=GR ");
- out.append(new Format("%-" + maxid + "s").form("#=GR "
- + printId(s[i], jvSuffix) + " " + key + " "));
- ann = alAnot[j].annotations;
- boolean isrna = alAnot[j].isValidStruc();
- String seq = "";
- for (int k = 0; k < ann.length; k++)
- {
- seq += outputCharacter(key, k, isrna, ann, s[i]);
- }
- out.append(seq);
- out.append(newline);
+ // out.append("#=GR ");
+ out.append(new Format("%-" + maxid + "s").form("#=GR "
+ + printId(s[i], jvSuffix) + " " + key + " "));
+ ann = alAnot[j].annotations;
+ String seq = "";
+ for (int k = 0; k < ann.length; k++)
+ {
+ seq += outputCharacter(key, k, isrna, ann, s[i]);
}
+ out.append(seq);
+ out.append(newline);
}
}
{
if (annot == null)
{
- // sensible gap character if one is available or make one up
- return sequenceI == null ? '-' : sequenceI.getCharAt(k);
+ // sensible gap character
+ return ' ';
}
else
{
if (typeIds == null)
{
typeIds = new Hashtable();
- typeIds.put("SS", "secondary structure");
- typeIds.put("SA", "surface accessibility");
+ typeIds.put("SS", "Secondary Structure");
+ typeIds.put("SA", "Surface Accessibility");
typeIds.put("TM", "transmembrane");
- typeIds.put("PP", "posterior probability");
+ typeIds.put("PP", "Posterior Probability");
typeIds.put("LI", "ligand binding");
typeIds.put("AS", "active site");
typeIds.put("IN", "intron");
typeIds.put("DE", "description");
typeIds.put("DR", "reference");
typeIds.put("LO", "look");
- typeIds.put("RF", "reference positions");
+ typeIds.put("RF", "Reference Positions");
}
}
while (e.hasMoreElements())
{
Object ll = e.nextElement();
- if (typeIds.get(ll).toString().equals(type))
+ if (typeIds.get(ll).toString().equalsIgnoreCase(type))
{
key = (String) ll;
break;