Merge branch 'Jalview-JS/develop' into develop
[jalview.git] / src / jalview / io / StockholmFile.java
index 84e629e..8b26757 100644 (file)
  */
 package jalview.io;
 
-import jalview.analysis.Rna;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.DBRefEntry;
-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.Format;
-import jalview.util.MessageManager;
-
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
@@ -53,6 +39,21 @@ import com.stevesoft.pat.Regex;
 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
 import fr.orsay.lri.varna.factories.RNAFactory;
 import fr.orsay.lri.varna.models.rna.RNA;
+import jalview.analysis.Rna;
+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 org.apache.log4j.*;
 
@@ -332,17 +333,14 @@ public class StockholmFile extends AlignFile
 
           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 ?
@@ -527,6 +525,9 @@ 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));
           }
         }
@@ -755,6 +756,12 @@ public class StockholmFile extends AlignFile
         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";
@@ -930,6 +937,11 @@ 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)
   {
@@ -944,6 +956,7 @@ public class StockholmFile extends AlignFile
     int slen = s.length;
     SequenceI seq;
     Hashtable<String, String> dataRef = null;
+    boolean isAA = s[in].isProtein();
     while ((in < slen) && ((seq = s[in]) != null))
     {
       String tmp = printId(seq, jvSuffix);
@@ -961,14 +974,29 @@ public class StockholmFile extends AlignFile
         {
           dataRef = new Hashtable<>();
         }
-        for (int idb = 0; idb < ndb; idb++)
+        List<DBRefEntry> primrefs = seq.getPrimaryDBRefs();
+        if (primrefs.size() >= 1)
         {
-
-          DBRefEntry ref = seqrefs.get(idb);
-          String datAs1 = ref.getSource().toString()
-                  + " ; "
-                  + ref.getAccessionId().toString();
-          dataRef.put(tmp, datAs1);
+          dataRef.put(tmp, dbref_to_ac_record(primrefs.get(0)));
+        }
+        else
+        {
+          for (int idb = 0; idb < seq.getDBRefs().size(); idb++)
+          {
+            DBRefEntry dbref = seq.getDBRefs().get(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;
+            }
+          }
         }
       }
       in++;
@@ -998,10 +1026,11 @@ public class StockholmFile extends AlignFile
       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"))
+        if (isAA && type.contains("UNIPROT")
+                || (!isAA && type.contains("EMBL")))
         {
 
           out.append(" AC " + type.substring(type.indexOf(";") + 1));