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;
{
private static final String ANNOTATION = "annotation";
+ private static final char UNDERSCORE = '_';
+
private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
+ // private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
+ // private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
+
public static final Regex DETECT_BRACKETS = new Regex(
"(<|>|\\[|\\]|\\(|\\)|\\{|\\})");
StringBuffer out; // output buffer
- AlignmentI al;
+ private AlignmentI al;
public StockholmFile()
{
}
/**
- * Creates a new StockholmFile object for output.
+ * Creates a new StockholmFile object for output
*/
public StockholmFile(AlignmentI al)
{
String version;
// String id;
Hashtable seqAnn = new Hashtable(); // Sequence related annotations
- LinkedHashMap<String, String> seqs = new LinkedHashMap<String, String>();
+ LinkedHashMap<String, String> seqs = new LinkedHashMap<>();
Regex p, r, rend, s, x;
// Temporary line for processing RNA annotation
// String RNAannot = "";
// logger.debug("Stockholm version: " + version);
}
- // We define some Regexes here that will be used regularily later
+ // We define some Regexes here that will be used regularly later
rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment
p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in
// id/from/to
if (accAnnotations != null && accAnnotations.containsKey("AC"))
{
- if (dbsource != null)
+ String dbr = (String) accAnnotations.get("AC");
+ if (dbr != null)
{
- String dbr = (String) accAnnotations.get("AC");
- if (dbr != null)
- {
- // we could get very clever here - but for now - just try to
- // guess accession type from source of alignment plus structure
- // of accession
- guessDatabaseFor(seqO, dbr, dbsource);
-
- }
+ // we could get very clever here - but for now - just try to
+ // guess accession type from type of sequence, source of alignment plus
+ // structure
+ // of accession
+ guessDatabaseFor(seqO, dbr, dbsource);
}
// else - do what ? add the data anyway and prompt the user to
// specify what references these are ?
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));
}
}
if (features.containsKey(this.id2type(type)))
{
// logger.debug("Found content for " + this.id2type(type));
- content = (Hashtable) features.get(this.id2type(type));
+ content = (Hashtable) features
+ .get(this.id2type(type));
}
else
{
// logger.debug("Creating new content holder for " +
// this.id2type(type));
content = new Hashtable();
- features.put(this.id2type(type), content);
+ features.put(id2type(type), content);
}
String ns = (String) content.get(ANNOTATION);
strucAnn = new Hashtable();
}
- Vector<AlignmentAnnotation> newStruc = new Vector<AlignmentAnnotation>();
+ Vector<AlignmentAnnotation> newStruc = new Vector<>();
parseAnnotationRow(newStruc, type, ns);
for (AlignmentAnnotation alan : newStruc)
{
private void guessDatabaseFor(Sequence seqO, String dbr, String dbsource)
{
DBRefEntry dbrf = null;
- List<DBRefEntry> dbrs = new ArrayList<DBRefEntry>();
+ List<DBRefEntry> dbrs = new ArrayList<>();
String seqdb = "Unknown", sdbac = "" + dbr;
int st = -1, en = -1, p;
if ((st = sdbac.indexOf("/")) > -1)
st = -1;
}
}
+ if (dbsource == null)
+ {
+ // make up an origin based on whether the sequence looks like it is nucleotide
+ // or protein
+ dbsource = (seqO.isProtein()) ? "PFAM" : "RFAM";
+ }
if (dbsource.equals("PFAM"))
{
seqdb = "UNIPROT";
Vector<AlignmentAnnotation> annotation, String label,
String annots)
{
- String convert1, convert2 = null;
-
- // convert1 = OPEN_PAREN.replaceAll(annots);
- // convert2 = CLOSE_PAREN.replaceAll(convert1);
+ String convert1, convert2 = null;
+ // String convert1 = OPEN_PAREN.replaceAll(annots);
+ // String convert2 = CLOSE_PAREN.replaceAll(convert1);
// annots = convert2;
String type = label;
type = id2type(type);
boolean isrnass = false;
+
if (type.equalsIgnoreCase("secondary structure"))
{
ss = true;
for (int i = 0; i < annots.length(); i++)
{
String pos = annots.substring(i, i + 1);
+ if (UNDERSCORE == pos.charAt(0))
+ {
+ pos = " ";
+ }
Annotation ann;
ann = new Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not
// be written out
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)
{
int maxid = 0;
int in = 0;
Hashtable dataRef = null;
+ boolean isAA = s[in].isProtein();
while ((in < s.length) && (s[in] != null))
{
+
String tmp = printId(s[in], jvSuffix);
max = Math.max(max, s[in].getLength());
}
if (s[in].getDBRefs() != null)
{
- for (int idb = 0; idb < s[in].getDBRefs().length; idb++)
+ if (dataRef == null)
+ {
+ dataRef = new Hashtable();
+ }
+ List<DBRefEntry> primrefs = s[in].getPrimaryDBRefs();
+ if (primrefs.size() >= 1)
+ {
+ dataRef.put(tmp, dbref_to_ac_record(primrefs.get(0)));
+ }
+ else
{
- if (dataRef == null)
+ for (int idb = 0; idb < s[in].getDBRefs().length; idb++)
{
- dataRef = new Hashtable();
+ 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;
+ }
}
-
- String datAs1 = s[in].getDBRefs()[idb].getSource().toString()
- + " ; "
- + s[in].getDBRefs()[idb].getAccessionId().toString();
- dataRef.put(tmp, datAs1);
}
}
in++;
String type = (String) dataRef.remove(idd);
out.append(new Format("%-" + (maxid - 2) + "s")
.form("#=GS " + idd.toString() + " "));
- if (type.contains("PFAM") || type.contains("RFAM"))
+ if (isAA && type.contains("UNIPROT")
+ || (!isAA && type.contains("EMBL")))
{
out.append(" AC " + type.substring(type.indexOf(";") + 1));
if (alAnot != null)
{
Annotation[] ann;
+
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 (alAnot[j].annotations != null)
{
+ String key = type2id(alAnot[j].label);
+ boolean isrna = alAnot[j].isValidStruc();
- continue;
- }
+ if (isrna)
+ {
+ // hardwire to secondary structure if there is RNA secondary
+ // structure on the annotation
+ key = "SS";
+ }
+ if (key == null)
+ {
- // 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]);
+ continue;
+ }
+
+ // 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);
}
- out.append(seq);
- out.append(newline);
}
+
}
out.append(new Format("%-" + maxid + "s")
return out.toString();
}
+
/**
* add an annotation character to the output row
*
String ch = (annot == null)
? ((sequenceI == null) ? "-"
: Character.toString(sequenceI.getCharAt(k)))
- : annot.displayCharacter;
+ : (annot.displayCharacter == null
+ ? String.valueOf(annot.secondaryStructure)
+ : annot.displayCharacter);
+ if (ch == null)
+ {
+ ch = " ";
+ }
if (key != null && key.equals("SS"))
{
char ssannotchar = ' ';
}
if (charset)
{
- if (ssannotchar == ' ' && isrna)
- {
- ssannotchar = '.';
- }
- return ssannotchar;
+ return (ssannotchar == ' ' && isrna) ? '.' : ssannotchar;
}
}
: seq;
}
+ /**
+ * make a friendly ID string.
+ *
+ * @param dataName
+ * @return truncated dataName to after last '/'
+ */
+ private String safeName(String dataName)
+ {
+ int b = 0;
+ while ((b = dataName.indexOf("/")) > -1 && b < dataName.length())
+ {
+ dataName = dataName.substring(b + 1).trim();
+
+ }
+ int e = (dataName.length() - dataName.indexOf(".")) + 1;
+ dataName = dataName.substring(1, e).trim();
+ return dataName;
+ }
+
+
public String print()
{
out = new StringBuffer();
}
}
-
+
protected static String id2type(String id)
{
if (typeIds.containsKey(id))
"Warning : Unknown Stockholm annotation type: " + type);
return key;
}
-
- /**
- * make a friendly ID string.
- *
- * @param dataName
- * @return truncated dataName to after last '/'
- */
- private String safeName(String dataName)
- {
- int b = 0;
- while ((b = dataName.indexOf("/")) > -1 && b < dataName.length())
- {
- dataName = dataName.substring(b + 1).trim();
-
- }
- int e = (dataName.length() - dataName.indexOf(".")) + 1;
- dataName = dataName.substring(1, e).trim();
- return dataName;
- }
}