JAL-2110 work in progress
[jalview.git] / src / jalview / analysis / AlignmentUtils.java
index fa135f8..949c47a 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.analysis;
 
+import static jalview.io.gff.GffConstants.CLINICAL_SIGNIFICANCE;
+
 import jalview.datamodel.AlignedCodon;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
@@ -38,6 +40,7 @@ import jalview.schemes.ResidueProperties;
 import jalview.util.Comparison;
 import jalview.util.MapList;
 import jalview.util.MappingUtils;
+import jalview.util.StringUtils;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
@@ -69,7 +72,6 @@ public class AlignmentUtils
 
   private static final String SEQUENCE_VARIANT = "sequence_variant:";
   private static final String ID = "ID";
-  private static final String CLINICAL_SIGNIFICANCE = "clinical_significance";
 
   /**
    * A data model to hold the 'normal' base value at a position, and an optional
@@ -1409,6 +1411,12 @@ public class AlignmentUtils
   {
     List<SequenceI> cdsSeqs = new ArrayList<SequenceI>();
     
+    /*
+     * construct CDS sequences from the (cds-to-protein) mappings made earlier;
+     * this makes it possible to model multiple products from dna (e.g. EMBL); 
+     * however it does mean we don't have the EMBL protein_id (a property on 
+     * the CDS features) in order to make the CDS sequence name :-( 
+     */
     for (SequenceI seq : dna)
     {
       AlignedCodonFrame cdsMappings = new AlignedCodonFrame();
@@ -1793,17 +1801,20 @@ public class AlignmentUtils
      * sort to get sequence features in start position order
      * - would be better to store in Sequence as a TreeSet or NCList?
      */
-    Arrays.sort(peptide.getSequenceFeatures(),
-            new Comparator<SequenceFeature>()
-            {
-              @Override
-              public int compare(SequenceFeature o1, SequenceFeature o2)
+    if (peptide.getSequenceFeatures() != null)
+    {
+      Arrays.sort(peptide.getSequenceFeatures(),
+              new Comparator<SequenceFeature>()
               {
-                int c = Integer.compare(o1.getBegin(), o2.getBegin());
-                return c == 0 ? Integer.compare(o1.getEnd(), o2.getEnd())
-                        : c;
-              }
-            });
+                @Override
+                public int compare(SequenceFeature o1, SequenceFeature o2)
+                {
+                  int c = Integer.compare(o1.getBegin(), o2.getBegin());
+                  return c == 0 ? Integer.compare(o1.getEnd(), o2.getEnd())
+                          : c;
+                }
+              });
+    }
     return count;
   }
 
@@ -1926,11 +1937,16 @@ public class AlignmentUtils
                     .codonTranslate(codon));
     if (trans != null && !trans.equals(residue))
     {
-      String desc = residue + "->" + trans;
-      // set score to 0f so 'graduated colour' option is offered!
+      String residue3Char = StringUtils
+              .toSentenceCase(ResidueProperties.aa2Triplet.get(residue));
+      String trans3Char = StringUtils
+              .toSentenceCase(ResidueProperties.aa2Triplet.get(trans));
+      String desc = "p." + residue3Char + peptidePos + trans3Char;
+      // set score to 0f so 'graduated colour' option is offered! JAL-2060
       SequenceFeature sf = new SequenceFeature(
               SequenceOntologyI.SEQUENCE_VARIANT, desc, peptidePos,
-              peptidePos, 0f, null);
+              peptidePos, 0f, "Jalview");
+      StringBuilder attributes = new StringBuilder(32);
       String id = (String) var.variant.getValue(ID);
       if (id != null)
       {
@@ -1939,6 +1955,7 @@ public class AlignmentUtils
           id = id.substring(SEQUENCE_VARIANT.length());
         }
         sf.setValue(ID, id);
+        attributes.append(ID).append("=").append(id);
         // TODO handle other species variants
         StringBuilder link = new StringBuilder(32);
         try
@@ -1957,8 +1974,14 @@ public class AlignmentUtils
       if (clinSig != null)
       {
         sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
+        attributes.append(";").append(CLINICAL_SIGNIFICANCE).append("=")
+                .append(clinSig);
       }
       peptide.addSequenceFeature(sf);
+      if (attributes.length() > 0)
+      {
+        sf.setAttributes(attributes.toString());
+      }
       return true;
     }
     return false;
@@ -2100,6 +2123,26 @@ public class AlignmentUtils
   {
     AlignmentI copy = new Alignment(new Alignment(seqs));
 
+    /*
+     * add mappings between sequences to the new alignment
+     */
+    AlignedCodonFrame mappings = new AlignedCodonFrame();
+    copy.addCodonFrame(mappings);
+    for (int i = 0; i < copy.getHeight(); i++)
+    {
+      SequenceI from = seqs[i];
+      SequenceI to = copy.getSequenceAt(i);
+      if (to.getDatasetSequence() != null)
+      {
+        to = to.getDatasetSequence();
+      }
+      int start = from.getStart();
+      int end = from.getEnd();
+      MapList map = new MapList(new int[] { start, end }, new int[] {
+          start, end }, 1, 1);
+      mappings.addMap(to, from, map);
+    }
+
     SequenceIdMatcher matcher = new SequenceIdMatcher(seqs);
     if (xrefs != null)
     {