From 5eec392de3099482d771ab078f0db57f9c47e81c Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Thu, 16 Jun 2022 12:19:01 +0100 Subject: [PATCH] =?utf8?q?JAL-4028=20experiment=20-=20THISISAPLACEHOLDER=20s?= =?utf8?q?equences=20get=20additional=20sequence=20data=20(as=20=E2=80=98X=E2?= =?utf8?q?=80=99)=20to=20cover=20the=20extent=20of=20features=20on=20the=20s?= =?utf8?q?equence.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/jalview/datamodel/Sequence.java | 74 ++++++++++++-------- src/jalview/datamodel/SequenceDummy.java | 69 ++++++++++++++++++ src/jalview/datamodel/features/FeatureStore.java | 37 ++++++++++ .../datamodel/features/SequenceFeatures.java | 25 +++++++ .../datamodel/features/SequenceFeaturesI.java | 9 ++- 5 files changed, 181 insertions(+), 33 deletions(-) diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index f8e70b1..1563dff 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -20,14 +20,6 @@ */ 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; } /* diff --git a/src/jalview/datamodel/SequenceDummy.java b/src/jalview/datamodel/SequenceDummy.java index 172c25f..af8ba3e 100644 --- a/src/jalview/datamodel/SequenceDummy.java +++ b/src/jalview/datamodel/SequenceDummy.java @@ -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(); + } } diff --git a/src/jalview/datamodel/features/FeatureStore.java b/src/jalview/datamodel/features/FeatureStore.java index eb5688c..c9a12f2 100644 --- a/src/jalview/datamodel/features/FeatureStore.java +++ b/src/jalview/datamodel/features/FeatureStore.java @@ -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; + } } diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index 905fd8b..4928f18 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -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 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 getPositionalFeatures(String... type) { List result = new ArrayList<>(); diff --git a/src/jalview/datamodel/features/SequenceFeaturesI.java b/src/jalview/datamodel/features/SequenceFeaturesI.java index ca14278..4284f2d 100644 --- a/src/jalview/datamodel/features/SequenceFeaturesI.java +++ b/src/jalview/datamodel/features/SequenceFeaturesI.java @@ -20,11 +20,11 @@ */ 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 getFeatureExtent(String... type); } -- 1.7.10.2