JAL-629 implementation of --tempfac options
[jalview.git] / src / jalview / analysis / AlignmentUtils.java
index 28f23b2..42c4b76 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.analysis;
 
-import java.util.Locale;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -31,6 +29,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.NoSuchElementException;
@@ -46,6 +45,7 @@ import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.GeneLociI;
 import jalview.datamodel.IncompleteCodonException;
@@ -184,10 +184,10 @@ public class AlignmentUtils
       // TODO use Character.toLowerCase to avoid creating String objects?
       char[] upstream = new String(ds
               .getSequence(s.getStart() - 1 - ustream_ds, s.getStart() - 1))
-                      .toLowerCase(Locale.ROOT).toCharArray();
+              .toLowerCase(Locale.ROOT).toCharArray();
       char[] downstream = new String(
-              ds.getSequence(s_end - 1, s_end + dstream_ds)).toLowerCase(Locale.ROOT)
-                      .toCharArray();
+              ds.getSequence(s_end - 1, s_end + dstream_ds))
+              .toLowerCase(Locale.ROOT).toCharArray();
       char[] coreseq = s.getSequence();
       char[] nseq = new char[offset + upstream.length + downstream.length
               + coreseq.length];
@@ -465,7 +465,8 @@ public class AlignmentUtils
     if (cdnaLength != mappedLength && cdnaLength > 2)
     {
       String lastCodon = String.valueOf(cdnaSeqChars,
-              cdnaLength - CODON_LENGTH, CODON_LENGTH).toUpperCase(Locale.ROOT);
+              cdnaLength - CODON_LENGTH, CODON_LENGTH)
+              .toUpperCase(Locale.ROOT);
       for (String stop : ResidueProperties.STOP_CODONS)
       {
         if (lastCodon.equals(stop))
@@ -482,7 +483,8 @@ public class AlignmentUtils
      */
     int startOffset = 0;
     if (cdnaLength != mappedLength && cdnaLength > 2
-            && String.valueOf(cdnaSeqChars, 0, CODON_LENGTH).toUpperCase(Locale.ROOT)
+            && String.valueOf(cdnaSeqChars, 0, CODON_LENGTH)
+                    .toUpperCase(Locale.ROOT)
                     .equals(ResidueProperties.START))
     {
       startOffset += CODON_LENGTH;
@@ -976,8 +978,8 @@ public class AlignmentUtils
             mapList = mapList.getInverse();
           }
           final int cdsLength = cdsDss.getLength();
-          int mappedFromLength = MappingUtils.getLength(mapList
-                  .getFromRanges());
+          int mappedFromLength = MappingUtils
+                  .getLength(mapList.getFromRanges());
           int mappedToLength = MappingUtils
                   .getLength(mapList.getToRanges());
           boolean addStopCodon = (cdsLength == mappedFromLength
@@ -1469,7 +1471,8 @@ public class AlignmentUtils
          */
         final Iterable<AlignmentAnnotation> matchedAlignmentAnnotations = al
                 .findAnnotations(seq, dsann.getCalcId(), dsann.label);
-        if (!matchedAlignmentAnnotations.iterator().hasNext())
+        if (matchedAlignmentAnnotations == null
+                || !matchedAlignmentAnnotations.iterator().hasNext())
         {
           result.add(dsann);
           if (labelForCalcId != null)
@@ -1515,7 +1518,7 @@ public class AlignmentUtils
           startRes = selectionGroup.getStartRes();
           endRes = selectionGroup.getEndRes();
         }
-        copyAnn.restrict(startRes, endRes);
+        copyAnn.restrict(startRes, endRes + 0);
 
         /*
          * Add to the sequence (sets copyAnn.datasetSequence), unless the
@@ -1523,6 +1526,12 @@ public class AlignmentUtils
          */
         if (!seq.hasAnnotation(ann))
         {
+          ContactMatrixI cm = seq.getDatasetSequence()
+                  .getContactMatrixFor(ann);
+          if (cm != null)
+          {
+            seq.addContactListFor(copyAnn, cm);
+          }
           seq.addAlignmentAnnotation(copyAnn);
         }
         // adjust for gaps
@@ -1532,6 +1541,7 @@ public class AlignmentUtils
         copyAnn.visible = true;
       }
     }
+
   }
 
   /**
@@ -1571,6 +1581,21 @@ public class AlignmentUtils
     }
   }
 
+  public static AlignmentAnnotation getFirstSequenceAnnotationOfType(
+          AlignmentI al, int graphType)
+  {
+    AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+    if (anns != null)
+    {
+      for (AlignmentAnnotation aa : anns)
+      {
+        if (aa.sequenceRef != null && aa.graph == graphType)
+          return aa;
+      }
+    }
+    return null;
+  }
+
   /**
    * Returns true if either sequence has a cross-reference to the other
    * 
@@ -1651,8 +1676,8 @@ public class AlignmentUtils
       productSeqs = new HashSet<>();
       for (SequenceI seq : products)
       {
-        productSeqs.add(seq.getDatasetSequence() == null ? seq : seq
-                .getDatasetSequence());
+        productSeqs.add(seq.getDatasetSequence() == null ? seq
+                : seq.getDatasetSequence());
       }
     }
 
@@ -1756,7 +1781,7 @@ public class AlignmentUtils
             dataset.addSequence(cdsSeqDss);
             AlignedCodonFrame cdsToProteinMapping = new AlignedCodonFrame();
             cdsToProteinMapping.addMap(cdsSeqDss, proteinProduct,
-                  cdsToProteinMap);
+                    cdsToProteinMap);
 
             /*
              * guard against duplicating the mapping if repeating this action
@@ -1809,20 +1834,21 @@ public class AlignmentUtils
           List<DBRefEntry> primrefs = dnaDss.getPrimaryDBRefs();
           for (int ip = 0, np = primrefs.size(); ip < np; ip++)
           {
-                 DBRefEntry primRef = primrefs.get(ip);
+            DBRefEntry primRef = primrefs.get(ip);
             /*
              * create a cross-reference from CDS to the source sequence's
              * primary reference and vice versa
              */
             String source = primRef.getSource();
             String version = primRef.getVersion();
-            DBRefEntry cdsCrossRef = new DBRefEntry(source, source + ":"
-                    + version, primRef.getAccessionId());
-            cdsCrossRef.setMap(new Mapping(dnaDss, new MapList(cdsToDnaMap)));
+            DBRefEntry cdsCrossRef = new DBRefEntry(source,
+                    source + ":" + version, primRef.getAccessionId());
+            cdsCrossRef
+                    .setMap(new Mapping(dnaDss, new MapList(cdsToDnaMap)));
             cdsSeqDss.addDBRef(cdsCrossRef);
 
-            dnaSeq.addDBRef(new DBRefEntry(source, version, cdsSeq
-                    .getName(), new Mapping(cdsSeqDss, dnaToCdsMap)));
+            dnaSeq.addDBRef(new DBRefEntry(source, version,
+                    cdsSeq.getName(), new Mapping(cdsSeqDss, dnaToCdsMap)));
             // problem here is that the cross-reference is synthesized -
             // cdsSeq.getName() may be like 'CDS|dnaaccession' or
             // 'CDS|emblcdsacc'
@@ -1831,8 +1857,8 @@ public class AlignmentUtils
             DBRefEntry proteinToCdsRef = new DBRefEntry(source, version,
                     cdsSeq.getName());
             //
-            proteinToCdsRef.setMap(new Mapping(cdsSeqDss, cdsToProteinMap
-                    .getInverse()));
+            proteinToCdsRef.setMap(
+                    new Mapping(cdsSeqDss, cdsToProteinMap.getInverse()));
             proteinProduct.addDBRef(proteinToCdsRef);
           }
           /*
@@ -1844,8 +1870,8 @@ public class AlignmentUtils
       }
     }
 
-    AlignmentI cds = new Alignment(cdsSeqs.toArray(new SequenceI[cdsSeqs
-            .size()]));
+    AlignmentI cds = new Alignment(
+            cdsSeqs.toArray(new SequenceI[cdsSeqs.size()]));
     cds.setDataset(dataset);
 
     return cds;
@@ -2057,7 +2083,8 @@ public class AlignmentUtils
           else
           {
             Console.error(
-                    "JAL-2154 regression: warning - found (and ignored) a duplicate CDS sequence:" + mtch.toString());
+                    "JAL-2154 regression: warning - found (and ignored) a duplicate CDS sequence:"
+                            + mtch.toString());
           }
         }
       }
@@ -2181,9 +2208,9 @@ public class AlignmentUtils
     /*
      * get features, optionally restricted by an ontology term
      */
-    List<SequenceFeature> sfs = select == null ? fromSeq.getFeatures()
-            .getPositionalFeatures() : fromSeq.getFeatures()
-            .getFeaturesByOntology(select);
+    List<SequenceFeature> sfs = select == null
+            ? fromSeq.getFeatures().getPositionalFeatures()
+            : fromSeq.getFeatures().getFeaturesByOntology(select);
 
     int count = 0;
     for (SequenceFeature sf : sfs)
@@ -2328,8 +2355,8 @@ public class AlignmentUtils
   {
     List<int[]> result = new ArrayList<>();
 
-    List<SequenceFeature> sfs = dnaSeq.getFeatures().getFeaturesByOntology(
-            SequenceOntologyI.CDS);
+    List<SequenceFeature> sfs = dnaSeq.getFeatures()
+            .getFeaturesByOntology(SequenceOntologyI.CDS);
     if (sfs.isEmpty())
     {
       return result;
@@ -2341,11 +2368,11 @@ public class AlignmentUtils
       int phase = 0;
       try
       {
-       String s = sf.getPhase();
-       if (s != null) 
-       {
-               phase = Integer.parseInt(s);
-       }
+        String s = sf.getPhase();
+        if (s != null)
+        {
+          phase = Integer.parseInt(s);
+        }
       } catch (NumberFormatException e)
       {
         // leave as zero
@@ -2401,11 +2428,11 @@ public class AlignmentUtils
     SequenceIdMatcher matcher = new SequenceIdMatcher(seqs);
     if (xrefs != null)
     {
-       // BH 2019.01.25 recoded to remove iterators
-       
+      // BH 2019.01.25 recoded to remove iterators
+
       for (int ix = 0, nx = xrefs.length; ix < nx; ix++)
       {
-       SequenceI xref = xrefs[ix];
+        SequenceI xref = xrefs[ix];
         List<DBRefEntry> dbrefs = xref.getDBRefs();
         if (dbrefs != null)
         {
@@ -2520,10 +2547,10 @@ public class AlignmentUtils
    * true; else returns false
    * 
    * @param unaligned
-   *                    - sequences to be aligned based on aligned
+   *          - sequences to be aligned based on aligned
    * @param aligned
-   *                    - 'guide' alignment containing sequences derived from same
-   *                    dataset as unaligned
+   *          - 'guide' alignment containing sequences derived from same dataset
+   *          as unaligned
    * @return
    */
   static boolean alignAsSameSequences(AlignmentI unaligned,
@@ -2559,8 +2586,7 @@ public class AlignmentUtils
       {
         return false;
       }
-      SequenceI alignedSeq = alignedDatasets.get(ds)
-              .get(0);
+      SequenceI alignedSeq = alignedDatasets.get(ds).get(0);
       int startCol = alignedSeq.findIndex(seq.getStart()); // 1..
       leftmost = Math.min(leftmost, startCol);
     }