JAL-4028 experiment - THISISAPLACEHOLDER sequences get additional sequence data ... spike/GFF_as_first_class_filetype_improvements_JAL-4028/placeholders_get_additional_sequence_data
authorJim Procter <j.procter@dundee.ac.uk>
Thu, 16 Jun 2022 11:19:01 +0000 (12:19 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Thu, 16 Jun 2022 11:19:01 +0000 (12:19 +0100)
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceDummy.java
src/jalview/datamodel/features/FeatureStore.java
src/jalview/datamodel/features/SequenceFeatures.java
src/jalview/datamodel/features/SequenceFeaturesI.java

index f8e70b1..1563dff 100755 (executable)
  */
 package jalview.datamodel;
 
-import jalview.analysis.AlignSeq;
-import jalview.datamodel.features.SequenceFeatures;
-import jalview.datamodel.features.SequenceFeaturesI;
-import jalview.util.Comparison;
-import jalview.util.DBRefUtils;
-import jalview.util.MapList;
-import jalview.util.StringUtils;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
@@ -39,6 +31,13 @@ import java.util.ListIterator;
 import java.util.Vector;
 
 import fr.orsay.lri.varna.models.rna.RNA;
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.features.SequenceFeatures;
+import jalview.datamodel.features.SequenceFeaturesI;
+import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
+import jalview.util.MapList;
+import jalview.util.StringUtils;
 
 /**
  * 
@@ -1602,33 +1601,46 @@ public class Sequence extends ASequence implements SequenceI
               getStart(), getEnd());
 
       datasetSequence = dsseq;
+      updateDatasetFrom(dsseq, this);
+    }
+    return datasetSequence;
+  }
 
-      dsseq.setDescription(description);
-      // move features and database references onto dataset sequence
-      dsseq.sequenceFeatureStore = sequenceFeatureStore;
-      sequenceFeatureStore = null;
-      dsseq.dbrefs = dbrefs;
-      dbrefs = null;
-      // TODO: search and replace any references to this sequence with
-      // references to the dataset sequence in Mappings on dbref
-      dsseq.pdbIds = pdbIds;
-      pdbIds = null;
-      datasetSequence.updatePDBIds();
-      if (annotation != null)
+  /**
+   * used by createDatasetSequence - transfers dataset-only properties to dsseq
+   * from sequence2
+   * 
+   * @param dsseq
+   *          - newly created dataset sequenceI for sequence
+   * @param sequence2
+   *          - sequence object that needs a dataset
+   */
+  protected void updateDatasetFrom(Sequence dsseq, Sequence sequence2)
+  {
+    dsseq.setDescription(description);
+    // move features and database references onto dataset sequence
+    dsseq.sequenceFeatureStore = sequenceFeatureStore;
+    sequenceFeatureStore = null;
+    dsseq.dbrefs = dbrefs;
+    dbrefs = null;
+    // TODO: search and replace any references to this sequence with
+    // references to the dataset sequence in Mappings on dbref
+    dsseq.pdbIds = pdbIds;
+    pdbIds = null;
+    datasetSequence.updatePDBIds();
+    if (annotation != null)
+    {
+      // annotation is cloned rather than moved, to preserve what's currently
+      // on the alignment
+      for (AlignmentAnnotation aa : annotation)
       {
-        // annotation is cloned rather than moved, to preserve what's currently
-        // on the alignment
-        for (AlignmentAnnotation aa : annotation)
-        {
-          AlignmentAnnotation _aa = new AlignmentAnnotation(aa);
-          _aa.sequenceRef = datasetSequence;
-          _aa.adjustForAlignment(); // uses annotation's own record of
-                                    // sequence-column mapping
-          datasetSequence.addAlignmentAnnotation(_aa);
-        }
+        AlignmentAnnotation _aa = new AlignmentAnnotation(aa);
+        _aa.sequenceRef = datasetSequence;
+        _aa.adjustForAlignment(); // uses annotation's own record of
+                                  // sequence-column mapping
+        datasetSequence.addAlignmentAnnotation(_aa);
       }
     }
-    return datasetSequence;
   }
 
   /*
index 172c25f..af8ba3e 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.datamodel;
 
+import org.apache.logging.log4j.util.Strings;
+
 public class SequenceDummy extends Sequence
 {
   public SequenceDummy(String sequenceId)
@@ -60,4 +62,71 @@ public class SequenceDummy extends Sequence
     // required for correct behaviour of SequenceIdMatcher
     return super.getDisplayId(false);
   }
+
+  @Override
+  public int getStart()
+  {
+    return super.getStart();
+  }
+
+  @Override
+  public int getEnd()
+  {
+    if (datasetSequence == null && dummy && getFeatures() != null
+            && getFeatures().hasFeatures())
+    {
+      return getFeatures().getFeatureExtent().get(1);
+    }
+    return super.getEnd();
+  }
+
+  @Override
+  public char[] getSequence()
+  {
+    checkSeqData();
+    return super.getSequence();
+  }
+
+  @Override
+  public String getSequenceAsString(int start, int end)
+  {
+    checkSeqData();
+    return super.getSequenceAsString(start, end);
+  }
+
+  private void checkSeqData()
+  {
+    // materialise a dummy sequence of the correct length
+    if (datasetSequence == null && dummy && getFeatures() != null
+            && getFeatures().hasFeatures())
+    {
+      int endS = getEnd();
+      char[] sq = super.getSequence();
+      if (endS > sq.length)
+      {
+        setSequence(
+                String.valueOf(sq) + Strings.repeat("X", endS - sq.length));
+      }
+    }
+  }
+
+  @Override
+  public String getSequenceAsString()
+  {
+    checkSeqData();
+    return super.getSequenceAsString();
+  }
+
+  @Override
+  public SequenceI createDatasetSequence()
+  {
+    if (dummy && datasetSequence == null)
+    {
+      checkSeqData();
+      datasetSequence = new SequenceDummy(this.getName());
+      super.updateDatasetFrom((Sequence) datasetSequence, this);
+      super.setEnd(datasetSequence.getEnd());
+    }
+    return super.createDatasetSequence();
+  }
 }
index eb5688c..c9a12f2 100644 (file)
@@ -82,6 +82,11 @@ public class FeatureStore
    */
   int totalExtent;
 
+  /*
+   * range covered by positional features
+   */
+  int minExtent, maxExtent;
+
   float positionalMinScore;
 
   float positionalMaxScore;
@@ -102,6 +107,8 @@ public class FeatureStore
     positionalMaxScore = Float.NaN;
     nonPositionalMinScore = Float.NaN;
     nonPositionalMaxScore = Float.NaN;
+    minExtent = 0;
+    maxExtent = 0;
 
     // we only construct nonPositionalFeatures, contactFeatures if we need to
   }
@@ -127,6 +134,16 @@ public class FeatureStore
     if (!feature.isNonPositional())
     {
       positionalFeatureGroups.add(feature.getFeatureGroup());
+      if (minExtent == 0)
+      {
+        minExtent = feature.begin;
+        maxExtent = feature.end;
+      }
+      else
+      {
+        minExtent = Math.min(feature.begin, minExtent);
+        maxExtent = Math.max(feature.end, maxExtent);
+      }
     }
 
     if (feature.isContactFeature())
@@ -621,6 +638,16 @@ public class FeatureStore
       float score = sf.getScore();
       positionalMinScore = min(positionalMinScore, score);
       positionalMaxScore = max(positionalMaxScore, score);
+      if (totalExtent == 0)
+      {
+        minExtent = sf.begin;
+        maxExtent = sf.begin;
+      }
+      else
+      {
+        minExtent = Math.min(sf.begin, minExtent);
+        maxExtent = Math.max(sf.end, maxExtent);
+      }
       totalExtent += getFeatureLength(sf);
     }
   }
@@ -848,4 +875,14 @@ public class FeatureStore
     }
     return modified;
   }
+
+  public int getBegin()
+  {
+    return minExtent;
+  }
+
+  public int getEnd()
+  {
+    return maxExtent;
+  }
 }
index 905fd8b..4928f18 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.datamodel.features;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -189,6 +190,30 @@ public class SequenceFeatures implements SequenceFeaturesI
    * {@inheritDoc}
    */
   @Override
+  public List<Integer> getFeatureExtent(String... type)
+  {
+    Integer from = 0, to = 0;
+
+    for (FeatureStore featureSet : varargToTypes(type))
+    {
+      if (from == 0)
+      {
+        from = featureSet.getBegin();
+        to = featureSet.getEnd();
+      }
+      else
+      {
+        from = Math.min(from, featureSet.getBegin());
+        to = Math.max(to, featureSet.getEnd());
+      }
+    }
+    return Arrays.asList(from, to);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public List<SequenceFeature> getPositionalFeatures(String... type)
   {
     List<SequenceFeature> result = new ArrayList<>();
index ca14278..4284f2d 100644 (file)
  */
 package jalview.datamodel.features;
 
-import jalview.datamodel.SequenceFeature;
-
 import java.util.List;
 import java.util.Set;
 
+import jalview.datamodel.SequenceFeature;
+
 public interface SequenceFeaturesI
 {
 
@@ -225,4 +225,9 @@ public interface SequenceFeaturesI
    * Deletes all positional and non-positional features
    */
   void deleteAll();
+
+  /**
+   * @return lowest and highest positions for positional features in this store
+   */
+  List<Integer> getFeatureExtent(String... type);
 }