From df2bf54c7050c42db156e96e73bbabce63e718d7 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Thu, 25 May 2017 17:52:12 +0100 Subject: [PATCH] JAL-2557 removal of Sequence.sequenceFeatures --- src/MCview/PDBChain.java | 21 ++- src/jalview/analysis/CrossRef.java | 33 ++--- src/jalview/analysis/Dna.java | 32 +---- src/jalview/analysis/SeqsetUtils.java | 27 ++-- src/jalview/commands/EditCommand.java | 85 ++++++----- src/jalview/datamodel/Sequence.java | 147 +++++--------------- src/jalview/datamodel/SequenceI.java | 15 +- .../datamodel/features/SequenceFeatures.java | 17 ++- src/jalview/gui/Jalview2XML.java | 65 ++++----- src/jalview/io/StockholmFile.java | 8 +- src/jalview/io/vamsas/Datasetsequence.java | 27 ++-- test/MCview/PDBChainTest.java | 27 ++-- test/jalview/analysis/AlignmentUtilsTests.java | 91 ++++++------ test/jalview/analysis/SeqsetUtilsTest.java | 18 +-- test/jalview/commands/EditCommandTest.java | 40 +++--- test/jalview/datamodel/SequenceTest.java | 48 +++---- test/jalview/ext/jmol/JmolParserTest.java | 8 +- test/jalview/io/AnnotatedPDBFileInputTest.java | 37 ++--- test/jalview/io/FeaturesFileTest.java | 97 +++++++------ test/jalview/io/StockholmFileTest.java | 20 ++- test/jalview/io/gff/InterProScanHelperTest.java | 4 +- .../seqfeatures/FeatureColourFinderTest.java | 10 +- .../structure/StructureSelectionManagerTest.java | 4 +- test/jalview/ws/seqfetcher/DbRefFetcherTest.java | 9 +- 24 files changed, 400 insertions(+), 490 deletions(-) diff --git a/src/MCview/PDBChain.java b/src/MCview/PDBChain.java index ef86cfd..8285d88 100755 --- a/src/MCview/PDBChain.java +++ b/src/MCview/PDBChain.java @@ -167,15 +167,14 @@ public class PDBChain } /** - * copy over the RESNUM seqfeatures from the internal chain sequence to the + * Copies over the RESNUM seqfeatures from the internal chain sequence to the * mapped sequence * * @param seq * @param status * The Status of the transferred annotation - * @return the features added to sq (or its dataset) */ - public SequenceFeature[] transferRESNUMFeatures(SequenceI seq, + public void transferRESNUMFeatures(SequenceI seq, String status) { SequenceI sq = seq; @@ -184,10 +183,11 @@ public class PDBChain sq = sq.getDatasetSequence(); if (sq == sequence) { - return null; + return; } } - /** + + /* * Remove any existing features for this chain if they exist ? * SequenceFeature[] seqsfeatures=seq.getSequenceFeatures(); int * totfeat=seqsfeatures.length; // Remove any features for this exact chain @@ -197,14 +197,10 @@ public class PDBChain { status = PDBChain.IEASTATUS; } - SequenceFeature[] features = sequence.getSequenceFeatures(); - if (features == null) - { - return null; - } - for (int i = 0; i < features.length; i++) + + List features = sequence.getSequenceFeatures(); + for (SequenceFeature feature : features) { - SequenceFeature feature = features[i]; if (feature.getFeatureGroup() != null && feature.getFeatureGroup().equals(pdbid)) { @@ -223,7 +219,6 @@ public class PDBChain } } } - return features; } /** diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index 4ba7e41..103025c 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -619,28 +619,25 @@ public class CrossRef * duplication (e.g. same variation from two * transcripts) */ - SequenceFeature[] sfs = ms.getSequenceFeatures(); - if (sfs != null) + List sfs = ms.getFeatures() + .getAllFeatures(); + for (SequenceFeature feat : sfs) { - for (SequenceFeature feat : sfs) + /* + * make a flyweight feature object which ignores Parent + * attribute in equality test; this avoids creating many + * otherwise duplicate exon features on genomic sequence + */ + SequenceFeature newFeature = new SequenceFeature(feat) { - /* - * make a flyweight feature object which ignores Parent - * attribute in equality test; this avoids creating many - * otherwise duplicate exon features on genomic sequence - */ - SequenceFeature newFeature = new SequenceFeature(feat) + @Override + public boolean equals(Object o) { - @Override - public boolean equals(Object o) - { - return super.equals(o, true); - } - }; - matched.addSequenceFeature(newFeature); - } + return super.equals(o, true); + } + }; + matched.addSequenceFeature(newFeature); } - } cf.addMap(retrievedSequence, map.getTo(), map.getMap()); } catch (Exception e) diff --git a/src/jalview/analysis/Dna.java b/src/jalview/analysis/Dna.java index 799a8ed..2106dc2 100644 --- a/src/jalview/analysis/Dna.java +++ b/src/jalview/analysis/Dna.java @@ -45,7 +45,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; -import java.util.Map; public class Dna { @@ -685,7 +684,7 @@ public class Dna */ MapList map = new MapList(scontigs, new int[] { 1, resSize }, 3, 1); - transferCodedFeatures(selection, newseq, map, null, null); + transferCodedFeatures(selection, newseq, map); /* * Construct a dataset sequence for our new peptide. @@ -754,25 +753,15 @@ public class Dna /** * Given a peptide newly translated from a dna sequence, copy over and set any - * features on the peptide from the DNA. If featureTypes is null, all features - * on the dna sequence are searched (rather than just the displayed ones), and - * similarly for featureGroups. + * features on the peptide from the DNA. * * @param dna * @param pep * @param map - * @param featureTypes - * hash whose keys are the displayed feature type strings - * @param featureGroups - * hash where keys are feature groups and values are Boolean objects - * indicating if they are displayed. */ private static void transferCodedFeatures(SequenceI dna, SequenceI pep, - MapList map, Map featureTypes, - Map featureGroups) + MapList map) { - SequenceFeature[] sfs = dna.getSequenceFeatures(); - Boolean fgstate; DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRefs(), DBRefSource.DNACODINGDBS); if (dnarefs != null) @@ -786,24 +775,15 @@ public class Dna } } } - if (sfs != null) + for (SequenceFeature sf : dna.getFeatures().getAllFeatures()) { - for (SequenceFeature sf : sfs) - { - fgstate = (featureGroups == null) ? null : featureGroups - .get(sf.featureGroup); - if ((featureTypes == null || featureTypes.containsKey(sf.getType())) - && (fgstate == null || fgstate.booleanValue())) + if (FeatureProperties.isCodingFeature(null, sf.getType())) { - if (FeatureProperties.isCodingFeature(null, sf.getType())) + // if (map.intersectsFrom(sf[f].begin, sf[f].end)) { - // if (map.intersectsFrom(sf[f].begin, sf[f].end)) - { - } } } - } } } diff --git a/src/jalview/analysis/SeqsetUtils.java b/src/jalview/analysis/SeqsetUtils.java index 21ad1cc..27b3041 100755 --- a/src/jalview/analysis/SeqsetUtils.java +++ b/src/jalview/analysis/SeqsetUtils.java @@ -27,6 +27,7 @@ import jalview.datamodel.SequenceI; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Vector; public class SeqsetUtils @@ -50,15 +51,11 @@ public class SeqsetUtils { sqinfo.put("Description", seq.getDescription()); } - Vector sfeat = new Vector(); - jalview.datamodel.SequenceFeature[] sfarray = seq.getSequenceFeatures(); - if (sfarray != null && sfarray.length > 0) - { - for (int i = 0; i < sfarray.length; i++) - { - sfeat.addElement(sfarray[i]); - } - } + + Vector sfeat = new Vector(); + List sfs = seq.getFeatures().getAllFeatures(); + sfeat.addAll(sfs); + if (seq.getDatasetSequence() == null) { sqinfo.put("SeqFeatures", sfeat); @@ -95,7 +92,8 @@ public class SeqsetUtils String oldname = (String) sqinfo.get("Name"); Integer start = (Integer) sqinfo.get("Start"); Integer end = (Integer) sqinfo.get("End"); - Vector sfeatures = (Vector) sqinfo.get("SeqFeatures"); + Vector sfeatures = (Vector) sqinfo + .get("SeqFeatures"); Vector pdbid = (Vector) sqinfo.get("PdbId"); String description = (String) sqinfo.get("Description"); Sequence seqds = (Sequence) sqinfo.get("datasetSequence"); @@ -118,14 +116,9 @@ public class SeqsetUtils sq.setEnd(end.intValue()); } - if ((sfeatures != null) && (sfeatures.size() > 0)) + if (sfeatures != null && !sfeatures.isEmpty()) { - SequenceFeature[] sfarray = new SequenceFeature[sfeatures.size()]; - for (int is = 0, isize = sfeatures.size(); is < isize; is++) - { - sfarray[is] = (SequenceFeature) sfeatures.elementAt(is); - } - sq.setSequenceFeatures(sfarray); + sq.setSequenceFeatures(sfeatures); } if (description != null) { diff --git a/src/jalview/commands/EditCommand.java b/src/jalview/commands/EditCommand.java index f36b55f..bba0dfb 100644 --- a/src/jalview/commands/EditCommand.java +++ b/src/jalview/commands/EditCommand.java @@ -122,15 +122,15 @@ public class EditCommand implements CommandI { } - public EditCommand(String description) + public EditCommand(String desc) { - this.description = description; + this.description = desc; } - public EditCommand(String description, Action command, SequenceI[] seqs, + public EditCommand(String desc, Action command, SequenceI[] seqs, int position, int number, AlignmentI al) { - this.description = description; + this.description = desc; if (command == Action.CUT || command == Action.PASTE) { setEdit(new Edit(command, seqs, position, number, al)); @@ -139,10 +139,10 @@ public class EditCommand implements CommandI performEdit(0, null); } - public EditCommand(String description, Action command, String replace, + public EditCommand(String desc, Action command, String replace, SequenceI[] seqs, int position, int number, AlignmentI al) { - this.description = description; + this.description = desc; if (command == Action.REPLACE) { setEdit(new Edit(command, seqs, position, number, al, replace)); @@ -548,7 +548,7 @@ public class EditCommand implements CommandI { // modify the oldds if necessary if (oldds != sequence.getDatasetSequence() - || sequence.getSequenceFeatures() != null) + || sequence.getFeatures().hasFeatures()) { if (command.oldds == null) { @@ -1131,16 +1131,15 @@ public class EditCommand implements CommandI return; } - SequenceFeature[] oldsf = new SequenceFeature[sf.size()]; + List oldsf = new ArrayList(); int cSize = j - i; - int s = 0; for (SequenceFeature feature : sf) { SequenceFeature copy = new SequenceFeature(feature); - oldsf[s++] = copy; + oldsf.add(copy); if (feature.getEnd() < i) { @@ -1190,7 +1189,7 @@ public class EditCommand implements CommandI if (command.editedFeatures == null) { - command.editedFeatures = new Hashtable(); + command.editedFeatures = new Hashtable>(); } command.editedFeatures.put(seq, oldsf); @@ -1317,7 +1316,7 @@ public class EditCommand implements CommandI Hashtable deletedAnnotations; - Hashtable editedFeatures; + Hashtable> editedFeatures; AlignmentI al; @@ -1333,51 +1332,51 @@ public class EditCommand implements CommandI char gapChar; - public Edit(Action command, SequenceI[] seqs, int position, int number, - char gapChar) + public Edit(Action cmd, SequenceI[] sqs, int pos, int count, + char gap) { - this.command = command; - this.seqs = seqs; - this.position = position; - this.number = number; - this.gapChar = gapChar; + this.command = cmd; + this.seqs = sqs; + this.position = pos; + this.number = count; + this.gapChar = gap; } - Edit(Action command, SequenceI[] seqs, int position, int number, - AlignmentI al) + Edit(Action cmd, SequenceI[] sqs, int pos, int count, + AlignmentI align) { - this.gapChar = al.getGapCharacter(); - this.command = command; - this.seqs = seqs; - this.position = position; - this.number = number; - this.al = al; - - alIndex = new int[seqs.length]; - for (int i = 0; i < seqs.length; i++) + this.gapChar = align.getGapCharacter(); + this.command = cmd; + this.seqs = sqs; + this.position = pos; + this.number = count; + this.al = align; + + alIndex = new int[sqs.length]; + for (int i = 0; i < sqs.length; i++) { - alIndex[i] = al.findIndex(seqs[i]); + alIndex[i] = align.findIndex(sqs[i]); } - fullAlignmentHeight = (al.getHeight() == seqs.length); + fullAlignmentHeight = (align.getHeight() == sqs.length); } - Edit(Action command, SequenceI[] seqs, int position, int number, - AlignmentI al, String replace) + Edit(Action cmd, SequenceI[] sqs, int pos, int count, + AlignmentI align, String replace) { - this.command = command; - this.seqs = seqs; - this.position = position; - this.number = number; - this.al = al; - this.gapChar = al.getGapCharacter(); - string = new char[seqs.length][]; - for (int i = 0; i < seqs.length; i++) + this.command = cmd; + this.seqs = sqs; + this.position = pos; + this.number = count; + this.al = align; + this.gapChar = align.getGapCharacter(); + string = new char[sqs.length][]; + for (int i = 0; i < sqs.length; i++) { string[i] = replace.toCharArray(); } - fullAlignmentHeight = (al.getHeight() == seqs.length); + fullAlignmentHeight = (align.getHeight() == sqs.length); } public SequenceI[] getSequences() diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 9f3e7b8..d7ac7a7 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -87,9 +87,6 @@ public class Sequence extends ASequence implements SequenceI */ int index = -1; - /** array of sequence features - may not be null for a valid sequence object */ - public SequenceFeature[] sequenceFeatures; - private SequenceFeatures sequenceFeatureStore; /** @@ -107,11 +104,13 @@ public class Sequence extends ASequence implements SequenceI */ public Sequence(String name, String sequence, int start, int end) { + this(); initSeqAndName(name, sequence.toCharArray(), start, end); } public Sequence(String name, char[] sequence, int start, int end) { + this(); initSeqAndName(name, sequence, start, end); } @@ -131,7 +130,6 @@ public class Sequence extends ASequence implements SequenceI this.sequence = sequence2; this.start = start2; this.end = end2; - sequenceFeatureStore = new SequenceFeatures(); parseId(); checkValidRange(); } @@ -182,6 +180,14 @@ public class Sequence extends ASequence implements SequenceI } /** + * default constructor + */ + private Sequence() + { + sequenceFeatureStore = new SequenceFeatures(); + } + + /** * Creates a new Sequence object. * * @param name @@ -220,8 +226,8 @@ public class Sequence extends ASequence implements SequenceI */ public Sequence(SequenceI seq, AlignmentAnnotation[] alAnnotation) { + this(); initSeqFrom(seq, alAnnotation); - } /** @@ -260,13 +266,13 @@ public class Sequence extends ASequence implements SequenceI addDBRef(new DBRefEntry(dbr[i])); } } - if (seq.getSequenceFeatures() != null) + + /* + * make copies of any sequence features + */ + for (SequenceFeature sf : seq.getSequenceFeatures()) { - SequenceFeature[] sf = seq.getSequenceFeatures(); - for (int i = 0; i < sf.length; i++) - { - addSequenceFeature(new SequenceFeature(sf[i])); - } + addSequenceFeature(new SequenceFeature(sf)); } } @@ -306,24 +312,14 @@ public class Sequence extends ASequence implements SequenceI } @Override - public void setSequenceFeatures(SequenceFeature[] features) + public void setSequenceFeatures(List features) { - if (datasetSequence == null) - { - sequenceFeatures = features; - } - else + if (datasetSequence != null) { - if (datasetSequence.getSequenceFeatures() != features - && datasetSequence.getSequenceFeatures() != null - && datasetSequence.getSequenceFeatures().length > 0) - { - new Exception( - "Warning: JAL-2046 side effect ? Possible implementation error: overwriting dataset sequence features by setting sequence features on alignment") - .printStackTrace(); - } datasetSequence.setSequenceFeatures(features); + return; } + sequenceFeatureStore = new SequenceFeatures(features); } @Override @@ -336,109 +332,40 @@ public class Sequence extends ASequence implements SequenceI return false; } - if (sequenceFeatures == null && datasetSequence != null) + if (datasetSequence != null) { return datasetSequence.addSequenceFeature(sf); } - if (sequenceFeatures == null) - { - sequenceFeatures = new SequenceFeature[0]; - } - - for (int i = 0; i < sequenceFeatures.length; i++) - { - if (sequenceFeatures[i].equals(sf)) - { - return false; - } - } - - SequenceFeature[] temp = new SequenceFeature[sequenceFeatures.length + 1]; - System.arraycopy(sequenceFeatures, 0, temp, 0, sequenceFeatures.length); - temp[sequenceFeatures.length] = sf; - sequenceFeatures = temp; - - sequenceFeatureStore.add(sf); - return true; + return sequenceFeatureStore.add(sf); } @Override public void deleteFeature(SequenceFeature sf) { - if (sequenceFeatures == null) - { - if (datasetSequence != null) - { - datasetSequence.deleteFeature(sf); - } - return; - } - - /* - * new way - */ - sequenceFeatureStore.delete(sf); - - /* - * old way - to be removed - */ - int index = 0; - for (index = 0; index < sequenceFeatures.length; index++) - { - if (sequenceFeatures[index].equals(sf)) - { - break; - } - } - - if (index == sequenceFeatures.length) - { - return; - } - - int sfLength = sequenceFeatures.length; - if (sfLength < 2) + if (datasetSequence != null) { - sequenceFeatures = null; + datasetSequence.deleteFeature(sf); } else { - SequenceFeature[] temp = new SequenceFeature[sfLength - 1]; - System.arraycopy(sequenceFeatures, 0, temp, 0, index); - - if (index < sfLength) - { - System.arraycopy(sequenceFeatures, index + 1, temp, index, - sequenceFeatures.length - index - 1); - } - - sequenceFeatures = temp; + sequenceFeatureStore.delete(sf); } } /** - * Returns the sequence features (if any), looking first on the sequence, then - * on its dataset sequence, and so on until a non-null value is found (or - * none). This supports retrieval of sequence features stored on the sequence - * (as in the applet) or on the dataset sequence (as in the Desktop version). + * {@inheritDoc} * * @return */ @Override - public SequenceFeature[] getSequenceFeatures() + public List getSequenceFeatures() { - SequenceFeature[] features = sequenceFeatures; - - SequenceI seq = this; - int count = 0; // failsafe against loop in sequence.datasetsequence... - while (features == null && seq.getDatasetSequence() != null - && count++ < 10) + if (datasetSequence != null) { - seq = seq.getDatasetSequence(); - features = ((Sequence) seq).sequenceFeatures; + return datasetSequence.getSequenceFeatures(); } - return features; + return sequenceFeatureStore.getAllFeatures(); } @Override @@ -1191,8 +1118,6 @@ public class Sequence extends ASequence implements SequenceI dsseq.setDescription(description); // move features and database references onto dataset sequence - dsseq.sequenceFeatures = sequenceFeatures; - sequenceFeatures = null; dsseq.sequenceFeatureStore = sequenceFeatureStore; sequenceFeatureStore = null; dsseq.dbrefs = dbrefs; @@ -1325,12 +1250,12 @@ public class Sequence extends ASequence implements SequenceI if (entry.getSequenceFeatures() != null) { - SequenceFeature[] sfs = entry.getSequenceFeatures(); - for (int si = 0; si < sfs.length; si++) + List sfs = entry.getSequenceFeatures(); + for (SequenceFeature feature : sfs) { - SequenceFeature sf[] = (mp != null) ? mp.locateFeature(sfs[si]) - : new SequenceFeature[] { new SequenceFeature(sfs[si]) }; - if (sf != null && sf.length > 0) + SequenceFeature sf[] = (mp != null) ? mp.locateFeature(feature) + : new SequenceFeature[] { new SequenceFeature(feature) }; + if (sf != null) { for (int sfi = 0; sfi < sf.length; sfi++) { diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 6c82bf3..e4be5ee 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -261,12 +261,12 @@ public interface SequenceI extends ASequenceI public void insertCharAt(int position, int count, char ch); /** - * Gets array holding sequence features associated with this sequence. The - * array may be held by the sequence's dataset sequence if that is defined. + * Answers a list of all sequence features associated with this sequence. The + * list may be held by the sequence's dataset sequence if that is defined. * * @return hard reference to array */ - public SequenceFeature[] getSequenceFeatures(); + public List getSequenceFeatures(); /** * Answers the object holding features for the sequence @@ -276,14 +276,13 @@ public interface SequenceI extends ASequenceI SequenceFeaturesI getFeatures(); /** - * Replaces the array of sequence features associated with this sequence with - * a new array reference. If this sequence has a dataset sequence, then this - * method will update the dataset sequence's feature array + * Replaces the sequence features associated with this sequence with the given + * features. If this sequence has a dataset sequence, then this method will + * update the dataset sequence's features instead. * * @param features - * New array of sequence features */ - public void setSequenceFeatures(SequenceFeature[] features); + public void setSequenceFeatures(List features); /** * DOCUMENT ME! diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index f263938..6955ade 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -62,7 +62,7 @@ public class SequenceFeatures implements SequenceFeaturesI { /* * use a TreeMap so that features are returned in alphabetical order of type - * wrap as a synchronized map for add and delete operations + * ? wrap as a synchronized map for add and delete operations */ // featureStore = Collections // .synchronizedSortedMap(new TreeMap()); @@ -70,6 +70,21 @@ public class SequenceFeatures implements SequenceFeaturesI } /** + * Constructor given a list of features + */ + public SequenceFeatures(List features) + { + this(); + if (features != null) + { + for (SequenceFeature feature : features) + { + add(feature); + } + } + } + + /** * {@inheritDoc} */ @Override diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index d6e0123..877d3c0 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -883,48 +883,43 @@ public class Jalview2XML // TODO: omit sequence features from each alignment view's XML dump if we // are storing dataset - if (jds.getSequenceFeatures() != null) + List sfs = jds + .getSequenceFeatures(); + for (SequenceFeature sf : sfs) { - jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures(); - int index = 0; - while (index < sf.length) - { - Features features = new Features(); + Features features = new Features(); - features.setBegin(sf[index].getBegin()); - features.setEnd(sf[index].getEnd()); - features.setDescription(sf[index].getDescription()); - features.setType(sf[index].getType()); - features.setFeatureGroup(sf[index].getFeatureGroup()); - features.setScore(sf[index].getScore()); - if (sf[index].links != null) + features.setBegin(sf.getBegin()); + features.setEnd(sf.getEnd()); + features.setDescription(sf.getDescription()); + features.setType(sf.getType()); + features.setFeatureGroup(sf.getFeatureGroup()); + features.setScore(sf.getScore()); + if (sf.links != null) + { + for (int l = 0; l < sf.links.size(); l++) { - for (int l = 0; l < sf[index].links.size(); l++) - { - OtherData keyValue = new OtherData(); - keyValue.setKey("LINK_" + l); - keyValue.setValue(sf[index].links.elementAt(l).toString()); - features.addOtherData(keyValue); - } + OtherData keyValue = new OtherData(); + keyValue.setKey("LINK_" + l); + keyValue.setValue(sf.links.elementAt(l).toString()); + features.addOtherData(keyValue); } - if (sf[index].otherDetails != null) + } + if (sf.otherDetails != null) + { + String key; + Iterator keys = sf.otherDetails.keySet().iterator(); + while (keys.hasNext()) { - String key; - Iterator keys = sf[index].otherDetails.keySet() - .iterator(); - while (keys.hasNext()) - { - key = keys.next(); - OtherData keyValue = new OtherData(); - keyValue.setKey(key); - keyValue.setValue(sf[index].otherDetails.get(key).toString()); - features.addOtherData(keyValue); - } + key = keys.next(); + OtherData keyValue = new OtherData(); + keyValue.setKey(key); + keyValue.setValue(sf.otherDetails.get(key).toString()); + features.addOtherData(keyValue); } - - jseq.addFeatures(features); - index++; } + + jseq.addFeatures(features); } if (jdatasq.getAllPDBEntries() != null) diff --git a/src/jalview/io/StockholmFile.java b/src/jalview/io/StockholmFile.java index 8fe7f82..936d2b9 100644 --- a/src/jalview/io/StockholmFile.java +++ b/src/jalview/io/StockholmFile.java @@ -74,6 +74,8 @@ import fr.orsay.lri.varna.models.rna.RNA; */ public class StockholmFile extends AlignFile { + private static final String ANNOTATION = "annotation"; + private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "("); private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")"); @@ -392,7 +394,7 @@ public class StockholmFile extends AlignFile while (j.hasMoreElements()) { String desc = j.nextElement().toString(); - if ("annotations".equals(desc) && annotsAdded) + if (ANNOTATION.equals(desc) && annotsAdded) { // don't add features if we already added an annotation row continue; @@ -635,7 +637,7 @@ public class StockholmFile extends AlignFile content = new Hashtable(); features.put(this.id2type(type), content); } - String ns = (String) content.get("annotation"); + String ns = (String) content.get(ANNOTATION); if (ns == null) { @@ -643,7 +645,7 @@ public class StockholmFile extends AlignFile } // finally, append the annotation line ns += seq; - content.put("annotation", ns); + content.put(ANNOTATION, ns); // // end of wrapped annotation block. // // Now a new row is created with the current set of data diff --git a/src/jalview/io/vamsas/Datasetsequence.java b/src/jalview/io/vamsas/Datasetsequence.java index 9db7a8e..e1340e2 100644 --- a/src/jalview/io/vamsas/Datasetsequence.java +++ b/src/jalview/io/vamsas/Datasetsequence.java @@ -21,9 +21,12 @@ package jalview.io.vamsas; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.io.VamsasAppDatastore; +import java.util.List; + import uk.ac.vamsas.objects.core.DataSet; import uk.ac.vamsas.objects.core.DbRef; import uk.ac.vamsas.objects.core.Sequence; @@ -61,6 +64,7 @@ public class Datasetsequence extends DatastoreItem doJvUpdate(); } + @Override public void addFromDocument() { Sequence vseq = (Sequence) vobj; @@ -73,6 +77,7 @@ public class Datasetsequence extends DatastoreItem modified = true; } + @Override public void updateFromDoc() { Sequence sq = (Sequence) vobj; @@ -128,25 +133,21 @@ public class Datasetsequence extends DatastoreItem */ private boolean updateSqFeatures() { - boolean modified = false; + boolean changed = false; SequenceI sq = (SequenceI) jvobj; // add or update any new features/references on dataset sequence - if (sq.getSequenceFeatures() != null) + List sfs = sq.getSequenceFeatures(); + for (SequenceFeature sf : sfs) { - int sfSize = sq.getSequenceFeatures().length; - - for (int sf = 0; sf < sfSize; sf++) - { - modified |= new jalview.io.vamsas.Sequencefeature(datastore, - (jalview.datamodel.SequenceFeature) sq - .getSequenceFeatures()[sf], dataset, - (Sequence) vobj).docWasUpdated(); - } + changed |= new jalview.io.vamsas.Sequencefeature(datastore, sf, + dataset, (Sequence) vobj).docWasUpdated(); } - return modified; + + return changed; } + @Override public void addToDocument() { SequenceI sq = (SequenceI) jvobj; @@ -217,6 +218,7 @@ public class Datasetsequence extends DatastoreItem return modifiedtheseq; } + @Override public void conflict() { log.warn("Conflict in dataset sequence update to document. Overwriting document"); @@ -226,6 +228,7 @@ public class Datasetsequence extends DatastoreItem boolean modified = false; + @Override public void updateToDoc() { SequenceI sq = (SequenceI) jvobj; diff --git a/test/MCview/PDBChainTest.java b/test/MCview/PDBChainTest.java index 7132939..defcdbc 100644 --- a/test/MCview/PDBChainTest.java +++ b/test/MCview/PDBChainTest.java @@ -36,6 +36,7 @@ import jalview.schemes.TaylorColourScheme; import jalview.structure.StructureImportSettings; import java.awt.Color; +import java.util.List; import java.util.Vector; import org.testng.annotations.BeforeClass; @@ -258,19 +259,19 @@ public class PDBChainTest /* * check sequence features */ - SequenceFeature[] sfs = c.sequence.getSequenceFeatures(); - assertEquals(3, sfs.length); - assertEquals("RESNUM", sfs[0].type); - assertEquals("MET:4 1gaqA", sfs[0].description); - assertEquals(4, sfs[0].begin); - assertEquals(4, sfs[0].end); - assertEquals("RESNUM", sfs[0].type); - assertEquals("LYS:5 1gaqA", sfs[1].description); - assertEquals(5, sfs[1].begin); - assertEquals(5, sfs[1].end); - assertEquals("LEU:6 1gaqA", sfs[2].description); - assertEquals(6, sfs[2].begin); - assertEquals(6, sfs[2].end); + List sfs = c.sequence.getSequenceFeatures(); + assertEquals(3, sfs.size()); + assertEquals("RESNUM", sfs.get(0).type); + assertEquals("MET:4 1gaqA", sfs.get(0).description); + assertEquals(4, sfs.get(0).begin); + assertEquals(4, sfs.get(0).end); + assertEquals("RESNUM", sfs.get(0).type); + assertEquals("LYS:5 1gaqA", sfs.get(1).description); + assertEquals(5, sfs.get(1).begin); + assertEquals(5, sfs.get(1).end); + assertEquals("LEU:6 1gaqA", sfs.get(2).description); + assertEquals(6, sfs.get(2).begin); + assertEquals(6, sfs.get(2).end); } private Atom makeAtom(int resnum, String name, String resname) diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index bada3ca..4439bb9 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -40,6 +40,7 @@ import jalview.datamodel.SearchResultsI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.SequenceFeatures; import jalview.gui.JvOptionPane; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; @@ -1179,12 +1180,12 @@ public class AlignmentUtilsTests /* * check cds2 acquired a variant feature in position 5 */ - SequenceFeature[] sfs = cds2Dss.getSequenceFeatures(); + List sfs = cds2Dss.getSequenceFeatures(); assertNotNull(sfs); - assertEquals(1, sfs.length); - assertEquals("variant", sfs[0].type); - assertEquals(5, sfs[0].begin); - assertEquals(5, sfs[0].end); + assertEquals(1, sfs.size()); + assertEquals("variant", sfs.get(0).type); + assertEquals(5, sfs.get(0).begin); + assertEquals(5, sfs.get(0).end); } /** @@ -1489,39 +1490,39 @@ public class AlignmentUtilsTests * that partially overlap 5' or 3' (start or end) of target sequence */ AlignmentUtils.transferFeatures(dna, cds, map, null); - SequenceFeature[] sfs = cds.getSequenceFeatures(); - assertEquals(6, sfs.length); + List sfs = cds.getSequenceFeatures(); + assertEquals(6, sfs.size()); - SequenceFeature sf = sfs[0]; + SequenceFeature sf = sfs.get(0); assertEquals("type2", sf.getType()); assertEquals("desc2", sf.getDescription()); assertEquals(2f, sf.getScore()); assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); - sf = sfs[1]; + sf = sfs.get(1); assertEquals("type3", sf.getType()); assertEquals("desc3", sf.getDescription()); assertEquals(3f, sf.getScore()); assertEquals(1, sf.getBegin()); assertEquals(3, sf.getEnd()); - sf = sfs[2]; + sf = sfs.get(2); assertEquals("type4", sf.getType()); assertEquals(2, sf.getBegin()); assertEquals(5, sf.getEnd()); - sf = sfs[3]; + sf = sfs.get(3); assertEquals("type5", sf.getType()); assertEquals(1, sf.getBegin()); assertEquals(6, sf.getEnd()); - sf = sfs[4]; + sf = sfs.get(4); assertEquals("type8", sf.getType()); assertEquals(6, sf.getBegin()); assertEquals(6, sf.getEnd()); - sf = sfs[5]; + sf = sfs.get(5); assertEquals("type9", sf.getType()); assertEquals(6, sf.getBegin()); assertEquals(6, sf.getEnd()); @@ -1551,10 +1552,10 @@ public class AlignmentUtilsTests // desc4 and desc8 are the 'omit these' varargs AlignmentUtils.transferFeatures(dna, cds, map, null, "type4", "type8"); - SequenceFeature[] sfs = cds.getSequenceFeatures(); - assertEquals(1, sfs.length); + List sfs = cds.getSequenceFeatures(); + assertEquals(1, sfs.size()); - SequenceFeature sf = sfs[0]; + SequenceFeature sf = sfs.get(0); assertEquals("type5", sf.getType()); assertEquals(1, sf.getBegin()); assertEquals(6, sf.getEnd()); @@ -1584,10 +1585,10 @@ public class AlignmentUtilsTests // "type5" is the 'select this type' argument AlignmentUtils.transferFeatures(dna, cds, map, "type5"); - SequenceFeature[] sfs = cds.getSequenceFeatures(); - assertEquals(1, sfs.length); + List sfs = cds.getSequenceFeatures(); + assertEquals(1, sfs.size()); - SequenceFeature sf = sfs[0]; + SequenceFeature sf = sfs.get(0); assertEquals("type5", sf.getType()); assertEquals(1, sf.getBegin()); assertEquals(6, sf.getEnd()); @@ -2078,24 +2079,29 @@ public class AlignmentUtilsTests * var6 P -> H COSMIC * var6 P -> R COSMIC */ - SequenceFeature[] sfs = peptide.getSequenceFeatures(); - assertEquals(5, sfs.length); + List sfs = peptide.getSequenceFeatures(); + SequenceFeatures.sortFeatures(sfs, true); + assertEquals(5, sfs.size()); - SequenceFeature sf = sfs[0]; + /* + * features are sorted by start position ascending, but in no + * particular order where start positions match; asserts here + * simply match the data returned (the order is not important) + */ + SequenceFeature sf = sfs.get(0); assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); - assertEquals("p.Lys1Glu", sf.getDescription()); - assertEquals("var1.125A>G", sf.getValue("ID")); - assertNull(sf.getValue("clinical_significance")); - assertEquals("ID=var1.125A>G", sf.getAttributes()); + assertEquals("p.Lys1Asn", sf.getDescription()); + assertEquals("var4", sf.getValue("ID")); + assertEquals("Benign", sf.getValue("clinical_significance")); + assertEquals("ID=var4;clinical_significance=Benign", sf.getAttributes()); assertEquals(1, sf.links.size()); - // link to variation is urlencoded assertEquals( - "p.Lys1Glu var1.125A>G|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var1.125A%3EG", + "p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4", sf.links.get(0)); assertEquals(ensembl, sf.getFeatureGroup()); - sf = sfs[1]; + sf = sfs.get(1); assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); assertEquals("p.Lys1Gln", sf.getDescription()); @@ -2108,43 +2114,44 @@ public class AlignmentUtilsTests sf.links.get(0)); assertEquals(dbSnp, sf.getFeatureGroup()); - sf = sfs[2]; + sf = sfs.get(2); assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); - assertEquals("p.Lys1Asn", sf.getDescription()); - assertEquals("var4", sf.getValue("ID")); - assertEquals("Benign", sf.getValue("clinical_significance")); - assertEquals("ID=var4;clinical_significance=Benign", sf.getAttributes()); + assertEquals("p.Lys1Glu", sf.getDescription()); + assertEquals("var1.125A>G", sf.getValue("ID")); + assertNull(sf.getValue("clinical_significance")); + assertEquals("ID=var1.125A>G", sf.getAttributes()); assertEquals(1, sf.links.size()); + // link to variation is urlencoded assertEquals( - "p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4", + "p.Lys1Glu var1.125A>G|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var1.125A%3EG", sf.links.get(0)); assertEquals(ensembl, sf.getFeatureGroup()); - // var5 generates two distinct protein variant features - sf = sfs[3]; + sf = sfs.get(3); assertEquals(3, sf.getBegin()); assertEquals(3, sf.getEnd()); - assertEquals("p.Pro3His", sf.getDescription()); + assertEquals("p.Pro3Arg", sf.getDescription()); assertEquals("var6", sf.getValue("ID")); assertEquals("Good", sf.getValue("clinical_significance")); assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes()); assertEquals(1, sf.links.size()); assertEquals( - "p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", + "p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", sf.links.get(0)); assertEquals(cosmic, sf.getFeatureGroup()); - sf = sfs[4]; + // var5 generates two distinct protein variant features + sf = sfs.get(4); assertEquals(3, sf.getBegin()); assertEquals(3, sf.getEnd()); - assertEquals("p.Pro3Arg", sf.getDescription()); + assertEquals("p.Pro3His", sf.getDescription()); assertEquals("var6", sf.getValue("ID")); assertEquals("Good", sf.getValue("clinical_significance")); assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes()); assertEquals(1, sf.links.size()); assertEquals( - "p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", + "p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", sf.links.get(0)); assertEquals(cosmic, sf.getFeatureGroup()); } diff --git a/test/jalview/analysis/SeqsetUtilsTest.java b/test/jalview/analysis/SeqsetUtilsTest.java index ee364c9..9839ba0 100644 --- a/test/jalview/analysis/SeqsetUtilsTest.java +++ b/test/jalview/analysis/SeqsetUtilsTest.java @@ -69,18 +69,18 @@ public class SeqsetUtilsTest SequenceI[] sqset2 = new SequenceI[] { new Sequence(sqset[0].getName(), sqset[0].getSequenceAsString()), new Sequence(sqset[1].getName(), sqset[1].getSequenceAsString()) }; - Assert.assertTrue(sqset[0].getSequenceFeatures()[0] == sf1); - Assert.assertEquals(sqset2[0].getSequenceFeatures(), null); + Assert.assertSame(sqset[0].getSequenceFeatures().get(0), sf1); + Assert.assertTrue(sqset2[0].getSequenceFeatures().isEmpty()); ds.getSequenceAt(0).addSequenceFeature(sf2); - Assert.assertEquals(sqset[0].getSequenceFeatures().length, 2); + Assert.assertEquals(sqset[0].getSequenceFeatures().size(), 2); SeqsetUtils.deuniquify(unq, sqset2); // explicitly test that original sequence features still exist because they // are on the shared dataset sequence - Assert.assertEquals(sqset[0].getSequenceFeatures().length, 2); - Assert.assertEquals(sqset2[0].getSequenceFeatures().length, 2); - Assert.assertTrue(sqset[0].getSequenceFeatures()[0] == sqset2[0] - .getSequenceFeatures()[0]); - Assert.assertTrue(sqset[0].getSequenceFeatures()[1] == sqset2[0] - .getSequenceFeatures()[1]); + Assert.assertEquals(sqset[0].getSequenceFeatures().size(), 2); + Assert.assertEquals(sqset2[0].getSequenceFeatures().size(), 2); + Assert.assertSame(sqset[0].getSequenceFeatures().get(0), sqset2[0] + .getSequenceFeatures().get(0)); + Assert.assertSame(sqset[0].getSequenceFeatures().get(1), sqset2[0] + .getSequenceFeatures().get(1)); } } diff --git a/test/jalview/commands/EditCommandTest.java b/test/jalview/commands/EditCommandTest.java index 8781a93..155f00e 100644 --- a/test/jalview/commands/EditCommandTest.java +++ b/test/jalview/commands/EditCommandTest.java @@ -31,10 +31,10 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.SequenceFeatures; import jalview.gui.JvOptionPane; -import java.util.Arrays; -import java.util.Comparator; +import java.util.List; import java.util.Map; import org.testng.Assert; @@ -678,29 +678,23 @@ public class EditCommandTest Edit ec = testee.new Edit(Action.CUT, seqs, 3, 4, al); // cols 3-6 base 0 EditCommand.cut(ec, new AlignmentI[] { al }); - SequenceFeature[] sfs = seq0.getSequenceFeatures(); - Arrays.sort(sfs, new Comparator() - { - @Override - public int compare(SequenceFeature o1, SequenceFeature o2) - { - return Integer.compare(o1.getBegin(), o2.getBegin()); - } - }); - assertEquals(4, sfs.length); // feature internal to cut has been deleted - SequenceFeature sf = sfs[0]; + List sfs = seq0.getSequenceFeatures(); + SequenceFeatures.sortFeatures(sfs, true); + + assertEquals(4, sfs.size()); // feature internal to cut has been deleted + SequenceFeature sf = sfs.get(0); assertEquals("before", sf.getType()); assertEquals(1, sf.getBegin()); assertEquals(3, sf.getEnd()); - sf = sfs[1]; + sf = sfs.get(1); assertEquals("overlap left", sf.getType()); assertEquals(2, sf.getBegin()); assertEquals(3, sf.getEnd()); // truncated by cut - sf = sfs[2]; + sf = sfs.get(2); assertEquals("overlap right", sf.getType()); assertEquals(4, sf.getBegin()); // shifted left by cut assertEquals(5, sf.getEnd()); // truncated by cut - sf = sfs[3]; + sf = sfs.get(3); assertEquals("after", sf.getType()); assertEquals(4, sf.getBegin()); // shifted left by cut assertEquals(6, sf.getEnd()); // shifted left by cut @@ -733,8 +727,8 @@ public class EditCommandTest } } // sanity check - SequenceFeature[] sfs = seq0.getSequenceFeatures(); - assertEquals(func(5), sfs.length); + List sfs = seq0.getSequenceFeatures(); + assertEquals(func(5), sfs.size()); /* * now perform all possible cuts of subranges of 1-5 (followed by Undo) @@ -769,7 +763,7 @@ public class EditCommandTest else { assertEquals(msg + "wrong number of features left", func(5) - - func(to - from + 1), sfs.length); + - func(to - from + 1), sfs.size()); } /* @@ -786,7 +780,7 @@ public class EditCommandTest * undo ready for next cut */ testee.undoCommand(new AlignmentI[] { alignment }); - assertEquals(func(5), seq0.getSequenceFeatures().length); + assertEquals(func(5), seq0.getSequenceFeatures().size()); } } } @@ -868,9 +862,9 @@ public class EditCommandTest /* * feature on CC(3-4) should now be on CC(1-2) */ - SequenceFeature[] sfs = seq0.getSequenceFeatures(); - assertEquals(1, sfs.length); - SequenceFeature sf = sfs[0]; + List sfs = seq0.getSequenceFeatures(); + assertEquals(1, sfs.size()); + SequenceFeature sf = sfs.get(0); assertEquals(1, sf.getBegin()); assertEquals(2, sf.getEnd()); diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index d7e720e..7eeac12 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -27,7 +27,6 @@ import static org.testng.AssertJUnit.assertNotSame; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; -import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; import jalview.datamodel.PDBEntry.Type; import jalview.gui.JvOptionPane; @@ -369,11 +368,10 @@ public class SequenceTest newDs = PA.getValue(sq, "datasetSequence"); assertNotNull(newDs); assertNotSame(ds, newDs); - SequenceFeature[] sfs = sq.getSequenceFeatures(); - assertNotNull(sfs); - assertEquals(1, sfs.length); - assertNotSame(sf1, sfs[0]); - assertEquals(sf1, sfs[0]); + List sfs = sq.getSequenceFeatures(); + assertEquals(1, sfs.size()); + assertNotSame(sf1, sfs.get(0)); + assertEquals(sf1, sfs.get(0)); /* * delete at start - no new dataset sequence created @@ -391,8 +389,8 @@ public class SequenceTest assertSame(ds, PA.getValue(sq, "datasetSequence")); sfs = sq.getSequenceFeatures(); assertNotNull(sfs); - assertEquals(1, sfs.length); - assertSame(sf1, sfs[0]); + assertEquals(1, sfs.size()); + assertSame(sf1, sfs.get(0)); /* * delete at end - no new dataset sequence created @@ -448,16 +446,16 @@ public class SequenceTest SequenceI sq = new Sequence("test", "GATCAT"); sq.createDatasetSequence(); - assertNull(sq.getSequenceFeatures()); + assertTrue(sq.getSequenceFeatures().isEmpty()); /* * SequenceFeature on sequence */ SequenceFeature sf = new SequenceFeature("Cath", "desc", 2, 4, 2f, null); sq.addSequenceFeature(sf); - SequenceFeature[] sfs = sq.getSequenceFeatures(); - assertEquals(1, sfs.length); - assertSame(sf, sfs[0]); + List sfs = sq.getSequenceFeatures(); + assertEquals(1, sfs.size()); + assertSame(sf, sfs.get(0)); /* * SequenceFeature on sequence and dataset sequence; returns that on @@ -470,15 +468,15 @@ public class SequenceTest null); sq.getDatasetSequence().addSequenceFeature(sf2); sfs = sq.getSequenceFeatures(); - assertEquals(1, sfs.length); - assertSame(sf, sfs[0]); + assertEquals(1, sfs.size()); + assertSame(sf, sfs.get(0)); /* * SequenceFeature on dataset sequence only * Note JAL-2046: spurious: we have no use case for setting a non-dataset sequence's feature array to null at the moment. */ sq.setSequenceFeatures(null); - assertNull(sq.getDatasetSequence().getSequenceFeatures()); + assertTrue(sq.getDatasetSequence().getSequenceFeatures().isEmpty()); /* * Corrupt case - no SequenceFeature, dataset's dataset is the original @@ -499,7 +497,7 @@ public class SequenceTest assertTrue(e.getMessage().toLowerCase() .contains("implementation error")); } - assertNull(sq.getSequenceFeatures()); + assertTrue(sq.getSequenceFeatures().isEmpty()); } /** @@ -553,7 +551,6 @@ public class SequenceTest "group")); sq.addDBRef(new DBRefEntry("source", "version", "accession")); assertNull(sq.getDatasetSequence()); - assertNotNull(PA.getValue(sq, "sequenceFeatures")); // to be removed! assertNotNull(PA.getValue(sq, "sequenceFeatureStore")); assertNotNull(PA.getValue(sq, "dbrefs")); @@ -563,10 +560,8 @@ public class SequenceTest assertSame(sq.getDatasetSequence(), rds); // sequence features and dbrefs transferred to dataset sequence - assertNull(PA.getValue(sq, "sequenceFeatures")); assertNull(PA.getValue(sq, "sequenceFeatureStore")); assertNull(PA.getValue(sq, "dbrefs")); - assertNotNull(PA.getValue(rds, "sequenceFeatures")); assertNotNull(PA.getValue(rds, "sequenceFeatureStore")); assertNotNull(PA.getValue(rds, "dbrefs")); } @@ -675,12 +670,9 @@ public class SequenceTest assertEquals("CD", derived.getSequenceAsString()); assertSame(sq.getDatasetSequence(), derived.getDatasetSequence()); - assertNull(sq.sequenceFeatures); - assertNull(derived.sequenceFeatures); // derived sequence should access dataset sequence features assertNotNull(sq.getSequenceFeatures()); - assertArrayEquals(sq.getSequenceFeatures(), - derived.getSequenceFeatures()); + assertEquals(sq.getSequenceFeatures(), derived.getSequenceFeatures()); /* * verify we have primary db refs *just* for PDB IDs with associated @@ -810,18 +802,18 @@ public class SequenceTest assertEquals(anns[0].score, seq1.getAnnotation()[0].score); // copy has a copy of the sequence feature: - SequenceFeature[] sfs = copy.getSequenceFeatures(); - assertEquals(1, sfs.length); + List sfs = copy.getSequenceFeatures(); + assertEquals(1, sfs.size()); if (seq1.getDatasetSequence() != null && copy.getDatasetSequence() == seq1.getDatasetSequence()) { - assertTrue(sfs[0] == seq1.getSequenceFeatures()[0]); + assertSame(sfs.get(0), seq1.getSequenceFeatures().get(0)); } else { - assertFalse(sfs[0] == seq1.getSequenceFeatures()[0]); + assertNotSame(sfs.get(0), seq1.getSequenceFeatures().get(0)); } - assertTrue(sfs[0].equals(seq1.getSequenceFeatures()[0])); + assertEquals(sfs.get(0), seq1.getSequenceFeatures().get(0)); // copy has a copy of the PDB entry Vector pdbs = copy.getAllPDBEntries(); diff --git a/test/jalview/ext/jmol/JmolParserTest.java b/test/jalview/ext/jmol/JmolParserTest.java index 131ef41..4514c60 100644 --- a/test/jalview/ext/jmol/JmolParserTest.java +++ b/test/jalview/ext/jmol/JmolParserTest.java @@ -277,10 +277,10 @@ public class JmolParserTest /* * the ID is also the group for features derived from structure data */ - assertNotNull(structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup); - assertEquals( - structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup, - "localstruct.pdb"); + String featureGroup = structureData.getSeqs().get(0) + .getSequenceFeatures().get(0).featureGroup; + assertNotNull(featureGroup); + assertEquals(featureGroup, "localstruct.pdb"); } } diff --git a/test/jalview/io/AnnotatedPDBFileInputTest.java b/test/jalview/io/AnnotatedPDBFileInputTest.java index d8ae999..e14a478 100644 --- a/test/jalview/io/AnnotatedPDBFileInputTest.java +++ b/test/jalview/io/AnnotatedPDBFileInputTest.java @@ -30,12 +30,14 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.SequenceFeatures; import jalview.gui.AlignFrame; import jalview.gui.JvOptionPane; import jalview.structure.StructureImportSettings; import jalview.structure.StructureImportSettings.StructureParser; import java.io.File; +import java.util.List; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -127,32 +129,35 @@ public class AnnotatedPDBFileInputTest /* * 1GAQ/A */ - SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures(); - assertEquals(296, sf.length); - assertEquals("RESNUM", sf[0].getType()); - assertEquals("GLU: 19 1gaqA", sf[0].getDescription()); - assertEquals("RESNUM", sf[295].getType()); - assertEquals("TYR: 314 1gaqA", sf[295].getDescription()); + List sf = al.getSequenceAt(0).getSequenceFeatures(); + SequenceFeatures.sortFeatures(sf, true); + assertEquals(296, sf.size()); + assertEquals("RESNUM", sf.get(0).getType()); + assertEquals("GLU: 19 1gaqA", sf.get(0).getDescription()); + assertEquals("RESNUM", sf.get(295).getType()); + assertEquals("TYR: 314 1gaqA", sf.get(295).getDescription()); /* * 1GAQ/B */ sf = al.getSequenceAt(1).getSequenceFeatures(); - assertEquals(98, sf.length); - assertEquals("RESNUM", sf[0].getType()); - assertEquals("ALA: 1 1gaqB", sf[0].getDescription()); - assertEquals("RESNUM", sf[97].getType()); - assertEquals("ALA: 98 1gaqB", sf[97].getDescription()); + SequenceFeatures.sortFeatures(sf, true); + assertEquals(98, sf.size()); + assertEquals("RESNUM", sf.get(0).getType()); + assertEquals("ALA: 1 1gaqB", sf.get(0).getDescription()); + assertEquals("RESNUM", sf.get(97).getType()); + assertEquals("ALA: 98 1gaqB", sf.get(97).getDescription()); /* * 1GAQ/C */ sf = al.getSequenceAt(2).getSequenceFeatures(); - assertEquals(296, sf.length); - assertEquals("RESNUM", sf[0].getType()); - assertEquals("GLU: 19 1gaqC", sf[0].getDescription()); - assertEquals("RESNUM", sf[295].getType()); - assertEquals("TYR: 314 1gaqC", sf[295].getDescription()); + SequenceFeatures.sortFeatures(sf, true); + assertEquals(296, sf.size()); + assertEquals("RESNUM", sf.get(0).getType()); + assertEquals("GLU: 19 1gaqC", sf.get(0).getDescription()); + assertEquals("RESNUM", sf.get(295).getType()); + assertEquals("TYR: 314 1gaqC", sf.get(295).getDescription()); } @Test(groups = { "Functional" }) diff --git a/test/jalview/io/FeaturesFileTest.java b/test/jalview/io/FeaturesFileTest.java index b88c2ee..45340d9 100644 --- a/test/jalview/io/FeaturesFileTest.java +++ b/test/jalview/io/FeaturesFileTest.java @@ -23,7 +23,6 @@ package jalview.io; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import jalview.api.FeatureColourI; @@ -33,6 +32,7 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceDummy; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.SequenceFeatures; import jalview.gui.AlignFrame; import jalview.gui.JvOptionPane; @@ -86,10 +86,15 @@ public class FeaturesFileTest /* * verify (some) features on sequences */ - SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence() + List sfs = al.getSequenceAt(0).getDatasetSequence() .getSequenceFeatures(); // FER_CAPAA - assertEquals(8, sfs.length); - SequenceFeature sf = sfs[0]; + SequenceFeatures.sortFeatures(sfs, true); + assertEquals(8, sfs.size()); + + /* + * verify (in ascending start position order) + */ + SequenceFeature sf = sfs.get(0); assertEquals("Pfam family%LINK%", sf.description); assertEquals(0, sf.begin); assertEquals(0, sf.end); @@ -99,46 +104,52 @@ public class FeaturesFileTest assertEquals("Pfam family|http://pfam.xfam.org/family/PF00111", sf.links.get(0)); - sf = sfs[1]; + sf = sfs.get(1); + assertEquals("Ferredoxin_fold Status: True Positive ", sf.description); + assertEquals(3, sf.begin); + assertEquals(93, sf.end); + assertEquals("uniprot", sf.featureGroup); + assertEquals("Cath", sf.type); + + sf = sfs.get(2); + assertEquals("Fer2 Status: True Positive Pfam 8_8%LINK%", + sf.description); + assertEquals("Pfam 8_8|http://pfam.xfam.org/family/PF00111", + sf.links.get(0)); + assertEquals(8, sf.begin); + assertEquals(83, sf.end); + assertEquals("uniprot", sf.featureGroup); + assertEquals("Pfam", sf.type); + + sf = sfs.get(3); assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(39, sf.begin); assertEquals(39, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[2]; + + sf = sfs.get(4); assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(44, sf.begin); assertEquals(44, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[3]; + + sf = sfs.get(5); assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(47, sf.begin); assertEquals(47, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[4]; + + sf = sfs.get(6); assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(77, sf.begin); assertEquals(77, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[5]; - assertEquals("Fer2 Status: True Positive Pfam 8_8%LINK%", - sf.description); - assertEquals("Pfam 8_8|http://pfam.xfam.org/family/PF00111", - sf.links.get(0)); - assertEquals(8, sf.begin); - assertEquals(83, sf.end); - assertEquals("uniprot", sf.featureGroup); - assertEquals("Pfam", sf.type); - sf = sfs[6]; - assertEquals("Ferredoxin_fold Status: True Positive ", sf.description); - assertEquals(3, sf.begin); - assertEquals(93, sf.end); - assertEquals("uniprot", sf.featureGroup); - assertEquals("Cath", sf.type); - sf = sfs[7]; + + sf = sfs.get(7); assertEquals( "High confidence server. Only hits with scores over 0.8 are reported. PHOSPHORYLATION (T) 89_8%LINK%", sf.description); @@ -181,10 +192,10 @@ public class FeaturesFileTest assertEquals(colours.get("METAL").getColour(), new Color(0xcc9900)); // verify feature on FER_CAPAA - SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence() + List sfs = al.getSequenceAt(0).getDatasetSequence() .getSequenceFeatures(); - assertEquals(1, sfs.length); - SequenceFeature sf = sfs[0]; + assertEquals(1, sfs.size()); + SequenceFeature sf = sfs.get(0); assertEquals("Iron-sulfur,2Fe-2S", sf.description); assertEquals(44, sf.begin); assertEquals(45, sf.end); @@ -194,8 +205,8 @@ public class FeaturesFileTest // verify feature on FER1_SOLLC sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures(); - assertEquals(1, sfs.length); - sf = sfs[0]; + assertEquals(1, sfs.size()); + sf = sfs.get(0); assertEquals("uniprot", sf.description); assertEquals(55, sf.begin); assertEquals(130, sf.end); @@ -242,10 +253,10 @@ public class FeaturesFileTest featuresFile.parse(al.getDataset(), colours, true)); // verify feature on FER_CAPAA - SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence() + List sfs = al.getSequenceAt(0).getDatasetSequence() .getSequenceFeatures(); - assertEquals(1, sfs.length); - SequenceFeature sf = sfs[0]; + assertEquals(1, sfs.size()); + SequenceFeature sf = sfs.get(0); // description parsed from Note attribute assertEquals("Iron-sulfur (2Fe-2S),another note", sf.description); assertEquals(39, sf.begin); @@ -258,8 +269,8 @@ public class FeaturesFileTest // verify feature on FER1_SOLLC1 sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures(); - assertEquals(1, sfs.length); - sf = sfs[0]; + assertEquals(1, sfs.size()); + sf = sfs.get(0); // ID used for description if available assertEquals("$23", sf.description); assertEquals(55, sf.begin); @@ -295,10 +306,10 @@ public class FeaturesFileTest featuresFile.parse(al.getDataset(), colours, true)); // verify FER_CAPAA feature - SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence() + List sfs = al.getSequenceAt(0).getDatasetSequence() .getSequenceFeatures(); - assertEquals(1, sfs.length); - SequenceFeature sf = sfs[0]; + assertEquals(1, sfs.size()); + SequenceFeature sf = sfs.get(0); assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(39, sf.begin); assertEquals(39, sf.end); @@ -306,8 +317,8 @@ public class FeaturesFileTest // verify FER1_SOLLC feature sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures(); - assertEquals(1, sfs.length); - sf = sfs[0]; + assertEquals(1, sfs.size()); + sf = sfs.get(0); assertEquals("Iron-phosphorus (2Fe-P)", sf.description); assertEquals(86, sf.begin); assertEquals(87, sf.end); @@ -337,14 +348,14 @@ public class FeaturesFileTest assertFalse("dummy replacement buggy for seq2", placeholderseq.equals(seq2.getSequenceAsString())); assertNotNull("No features added to seq1", seq1.getSequenceFeatures()); - assertEquals("Wrong number of features", 3, - seq1.getSequenceFeatures().length); - assertNull(seq2.getSequenceFeatures()); + assertEquals("Wrong number of features", 3, seq1.getSequenceFeatures() + .size()); + assertTrue(seq2.getSequenceFeatures().isEmpty()); assertEquals( "Wrong number of features", 0, seq2.getSequenceFeatures() == null ? 0 : seq2 - .getSequenceFeatures().length); + .getSequenceFeatures().size()); assertTrue( "Expected at least one CDNA/Protein mapping for seq1", dataset.getCodonFrame(seq1) != null diff --git a/test/jalview/io/StockholmFileTest.java b/test/jalview/io/StockholmFileTest.java index 228c935..4273e6c 100644 --- a/test/jalview/io/StockholmFileTest.java +++ b/test/jalview/io/StockholmFileTest.java @@ -287,7 +287,8 @@ public class StockholmFileTest seq_original = al.getSequencesArray(); SequenceI[] seq_new = new SequenceI[al_input.getSequencesArray().length]; seq_new = al_input.getSequencesArray(); - SequenceFeature[] sequenceFeatures_original, sequenceFeatures_new; + List sequenceFeatures_original; + List sequenceFeatures_new; AlignmentAnnotation annot_original, annot_new; // for (int i = 0; i < al.getSequencesArray().length; i++) @@ -323,23 +324,20 @@ public class StockholmFileTest && seq_new[in].getSequenceFeatures() != null) { System.out.println("There are feature!!!"); - sequenceFeatures_original = new SequenceFeature[seq_original[i] - .getSequenceFeatures().length]; sequenceFeatures_original = seq_original[i] .getSequenceFeatures(); - sequenceFeatures_new = new SequenceFeature[seq_new[in] - .getSequenceFeatures().length]; sequenceFeatures_new = seq_new[in].getSequenceFeatures(); - assertEquals("different number of features", - seq_original[i].getSequenceFeatures().length, - seq_new[in].getSequenceFeatures().length); + assertEquals("different number of features", seq_original[i] + .getSequenceFeatures().size(), seq_new[in] + .getSequenceFeatures().size()); - for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++) + for (int feat = 0; feat < seq_original[i].getSequenceFeatures() + .size(); feat++) { assertEquals("Different features", - sequenceFeatures_original[feat], - sequenceFeatures_new[feat]); + sequenceFeatures_original.get(feat), + sequenceFeatures_new.get(feat)); } } // compare alignment annotation diff --git a/test/jalview/io/gff/InterProScanHelperTest.java b/test/jalview/io/gff/InterProScanHelperTest.java index 59935dd..dde83a3 100644 --- a/test/jalview/io/gff/InterProScanHelperTest.java +++ b/test/jalview/io/gff/InterProScanHelperTest.java @@ -80,8 +80,8 @@ public class InterProScanHelperTest assertEquals("match$17_5_30", newseqs.get(0).getName()); assertNotNull(newseqs.get(0).getSequenceFeatures()); - assertEquals(1, newseqs.get(0).getSequenceFeatures().length); - SequenceFeature sf = newseqs.get(0).getSequenceFeatures()[0]; + assertEquals(1, newseqs.get(0).getSequenceFeatures().size()); + SequenceFeature sf = newseqs.get(0).getSequenceFeatures().get(0); assertEquals(1, sf.getBegin()); assertEquals(26, sf.getEnd()); assertEquals("Pfam", sf.getType()); diff --git a/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java b/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java index 59566ed..7556dff 100644 --- a/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java +++ b/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java @@ -15,6 +15,7 @@ import jalview.io.FileLoader; import jalview.schemes.FeatureColour; import java.awt.Color; +import java.util.List; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; @@ -69,13 +70,10 @@ public class FeatureColourFinderTest @BeforeMethod(alwaysRun = true) public void setUpBeforeTest() { - SequenceFeature[] sfs = seq.getSequenceFeatures(); - if (sfs != null) + List sfs = seq.getSequenceFeatures(); + for (SequenceFeature sf : sfs) { - for (SequenceFeature sf : sfs) - { - seq.deleteFeature(sf); - } + seq.deleteFeature(sf); } fr.findAllFeatures(true); diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java index a7e52ff..a59fbde 100644 --- a/test/jalview/structure/StructureSelectionManagerTest.java +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -145,7 +145,7 @@ public class StructureSelectionManagerTest /* * Verify a RESNUM sequence feature in the PDBfile sequence */ - SequenceFeature sf = pmap.getSeqs().get(0).getSequenceFeatures()[0]; + SequenceFeature sf = pmap.getSeqs().get(0).getSequenceFeatures().get(0); assertEquals("RESNUM", sf.getType()); assertEquals("1gaq", sf.getFeatureGroup()); assertEquals("GLU: 19 1gaqA", sf.getDescription()); @@ -155,7 +155,7 @@ public class StructureSelectionManagerTest * sequence */ StructureMapping map = sm.getMapping("examples/1gaq.txt")[0]; - sf = map.sequence.getSequenceFeatures()[0]; + sf = map.sequence.getSequenceFeatures().get(0); assertEquals("RESNUM", sf.getType()); assertEquals("1gaq", sf.getFeatureGroup()); assertEquals("ALA: 1 1gaqB", sf.getDescription()); diff --git a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java index e35f83e..de91af3 100644 --- a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java +++ b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java @@ -21,6 +21,7 @@ package jalview.ws.seqfetcher; import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; @@ -173,13 +174,13 @@ public class DbRefFetcherTest SequenceI seq = alsq.getSequenceAt(0); assertEquals("Wrong sequence name", embl.getDbSource() + "|" + retrievalId, seq.getName()); - SequenceFeature[] sfs = seq.getSequenceFeatures(); - assertNotNull("Sequence features missing", sfs); + List sfs = seq.getSequenceFeatures(); + assertFalse("Sequence features missing", sfs.isEmpty()); assertTrue( "Feature not CDS", FeatureProperties.isCodingFeature(embl.getDbSource(), - sfs[0].getType())); - assertEquals(embl.getDbSource(), sfs[0].getFeatureGroup()); + sfs.get(0).getType())); + assertEquals(embl.getDbSource(), sfs.get(0).getFeatureGroup()); DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRefs(), new String[] { DBRefSource.UNIPROT }); assertNotNull(dr); -- 1.7.10.2