X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FSequence.java;h=32d295a7132a56058faa8adc46fa58de76a18edc;hb=19c22459dca6c69d6f1fd0eed029c01e21c99854;hp=7549ef500bcc2e44611ed56cb8d7317e434838e5;hpb=beff7ac7ab7be2c24ccb179be16b8816d2c18610;p=jalview.git diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 7549ef5..32d295a 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -20,17 +20,10 @@ */ 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; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; @@ -39,6 +32,16 @@ import java.util.ListIterator; import java.util.Vector; import fr.orsay.lri.varna.models.rna.RNA; +import jalview.analysis.AlignSeq; +import jalview.analysis.AlignmentUtils; +import jalview.analysis.SeqsetUtils; +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 jalview.ws.datamodel.alphafold.MappableContactMatrix; /** * @@ -47,23 +50,26 @@ import fr.orsay.lri.varna.models.rna.RNA; public class Sequence extends ASequence implements SequenceI { - /** - * A subclass that gives us access to modCount, which tracks - * whether there have been any changes. We use this to update - * @author hansonr - * - * @param - */ + /** + * A subclass that gives us access to modCount, which tracks whether there + * have been any changes. We use this to update + * + * @author hansonr + * + * @param + */ @SuppressWarnings("serial") - public class DBModList extends ArrayList { + public class DBModList extends ArrayList + { + + protected int getModCount() + { + return modCount; + } - protected int getModCount() { - return modCount; - } - } -SequenceI datasetSequence; + SequenceI datasetSequence; private String name; @@ -89,7 +95,7 @@ SequenceI datasetSequence; private int refModCount = 0; private RNA rna; - + /** * This annotation is displayed below the alignment but the positions are tied * to the residues of this sequence @@ -301,7 +307,7 @@ SequenceI datasetSequence; { setDatasetSequence(seq.getDatasetSequence()); } - + /* * only copy DBRefs and seqfeatures if we really are a dataset sequence */ @@ -346,6 +352,11 @@ SequenceI datasetSequence; { // only copy the given annotation AlignmentAnnotation newann = new AlignmentAnnotation(sqann[i]); + ContactMatrixI cm = seq.getContactMatrixFor(sqann[i]); + if (cm!=null) + { + addContactListFor(newann, cm); + } addAlignmentAnnotation(newann); } } @@ -376,8 +387,8 @@ SequenceI datasetSequence; { if (sf.getType() == null) { - System.err.println("SequenceFeature type may not be null: " - + sf.toString()); + System.err.println( + "SequenceFeature type may not be null: " + sf.toString()); return false; } @@ -469,18 +480,19 @@ SequenceI datasetSequence; } /** - * DOCUMENT ME! + * Answers the sequence name, with '/start-end' appended if jvsuffix is true * - * @return DOCUMENT ME! + * @return */ @Override public String getDisplayId(boolean jvsuffix) { - StringBuffer result = new StringBuffer(name); - if (jvsuffix) + if (!jvsuffix) { - result.append("/" + start + "-" + end); + return name; } + StringBuilder result = new StringBuilder(name); + result.append("/").append(start).append("-").append(end); return result.toString(); } @@ -519,6 +531,7 @@ SequenceI datasetSequence; public void setStart(int start) { this.start = start; + sequenceChanged(); } /** @@ -596,8 +609,8 @@ SequenceI datasetSequence; public char[] getSequence() { // return sequence; - return sequence == null ? null : Arrays.copyOf(sequence, - sequence.length); + return sequence == null ? null + : Arrays.copyOf(sequence, sequence.length); } /* @@ -693,8 +706,8 @@ SequenceI datasetSequence; public void setGeneLoci(String speciesId, String assemblyId, String chromosomeId, MapList map) { - addDBRef(new DBRefEntry(speciesId, assemblyId, DBRefEntry.CHROMOSOME - + ":" + chromosomeId, new Mapping(map))); + addDBRef(new GeneLocus(speciesId, assemblyId, chromosomeId, + new Mapping(map))); } /** @@ -710,39 +723,9 @@ SequenceI datasetSequence; { for (final DBRefEntry ref : refs) { - if (ref.isChromosome()) + if (ref instanceof GeneLociI) { - return new GeneLociI() - { - @Override - public String getSpeciesId() - { - return ref.getSource(); - } - - @Override - public String getAssemblyId() - { - // DEV NOTE: DBRefEntry is reused here to hold chromosomal locus of a gene sequence. - // source=species, version=assemblyId, accession=chromosome, map = positions. - - return ref.getVersion(); - } - - @Override - public String getChromosomeId() - { - // strip off "chromosome:" prefix to chrId - return ref.getAccessionId().substring( - DBRefEntry.CHROMOSOME.length() + 1); - } - - @Override - public MapList getMap() - { - return ref.getMap().getMap(); - } - }; + return (GeneLociI) ref; } } } @@ -905,7 +888,7 @@ SequenceI datasetSequence; { return findPosition(column + 1, cursor); } - + // TODO recode this more naturally i.e. count residues only // as they are found, not 'in anticipation' @@ -1092,7 +1075,7 @@ SequenceI datasetSequence; * {@inheritDoc} */ @Override - public Range findPositions(int fromColumn, int toColumn) + public ContiguousI findPositions(int fromColumn, int toColumn) { if (toColumn < fromColumn || fromColumn < 1) { @@ -1210,7 +1193,7 @@ SequenceI datasetSequence; { ArrayList map = new ArrayList<>(); int lastj = -1, j = 0; - int pos = start; + // int pos = start; int seqlen = sequence.length; while ((j < seqlen)) { @@ -1244,7 +1227,7 @@ SequenceI datasetSequence; { BitSet map = new BitSet(); int lastj = -1, j = 0; - int pos = start; + // int pos = start; int seqlen = sequence.length; while ((j < seqlen)) { @@ -1437,10 +1420,10 @@ SequenceI datasetSequence; return dbrefs; } - @Override public void addDBRef(DBRefEntry entry) { + // TODO JAL-3980 maintain as sorted list if (datasetSequence != null) { datasetSequence.addDBRef(entry); @@ -1449,10 +1432,11 @@ SequenceI datasetSequence; if (dbrefs == null) { - dbrefs = new DBModList(); + dbrefs = new DBModList<>(); } + // TODO JAL-3979 LOOK UP RATHER THAN SWEEP FOR EFFICIENCY - for (int ib = 0, nb= dbrefs.size(); ib < nb; ib++) + for (int ib = 0, nb = dbrefs.size(); ib < nb; ib++) { if (dbrefs.get(ib).updateFrom(entry)) { @@ -1464,19 +1448,18 @@ SequenceI datasetSequence; } } + // /// BH OUCH! + // /* + // * extend the array to make room for one more + // */ + // // TODO use an ArrayList instead + // int j = dbrefs.length; + // List temp = new DBRefEntry[j + 1]; + // System.arraycopy(dbrefs, 0, temp, 0, j); + // temp[temp.length - 1] = entry; + // + // dbrefs = temp; -// /// BH OUCH! -// /* -// * extend the array to make room for one more -// */ -// // TODO use an ArrayList instead -// int j = dbrefs.length; -// List temp = new DBRefEntry[j + 1]; -// System.arraycopy(dbrefs, 0, temp, 0, j); -// temp[temp.length - 1] = entry; -// -// dbrefs = temp; - dbrefs.add(entry); } @@ -1590,7 +1573,7 @@ SequenceI datasetSequence; private int _seqhash = 0; -private List primaryRefs; + private List primaryRefs; /** * Answers false if the sequence is more than 85% nucleotide (ACGTU), else @@ -1609,7 +1592,7 @@ private List primaryRefs; _isNa = Comparison.isNucleotide(this); } return !_isNa; - }; + } /* * (non-Javadoc) @@ -1650,8 +1633,20 @@ private List primaryRefs; _aa.adjustForAlignment(); // uses annotation's own record of // sequence-column mapping datasetSequence.addAlignmentAnnotation(_aa); + + if (_cmholder != null) + { // transfer contact matrices + ContactMatrixI cm = _cmholder.getContactMatrixFor(aa); + if (cm != null) + { + datasetSequence.addContactListFor(_aa, cm); + datasetSequence.addContactListFor(aa, cm); + } + } } } + // all matrices should have been transferred. so we clear the local holder + _cmholder=null; } return datasetSequence; } @@ -1766,8 +1761,9 @@ private List primaryRefs; List sfs = entry.getSequenceFeatures(); for (SequenceFeature feature : sfs) { - SequenceFeature sf[] = (mp != null) ? mp.locateFeature(feature) - : new SequenceFeature[] { new SequenceFeature(feature) }; + SequenceFeature sf[] = (mp != null) ? mp.locateFeature(feature) + : new SequenceFeature[] + { new SequenceFeature(feature) }; if (sf != null) { for (int sfi = 0; sfi < sf.length; sfi++) @@ -1825,13 +1821,30 @@ private List primaryRefs; public List getAlignmentAnnotations(String calcId, String label) { + return getAlignmentAnnotations(calcId, label, null, true); + } + + @Override + public List getAlignmentAnnotations(String calcId, + String label, String description) + { + return getAlignmentAnnotations(calcId, label, description, false); + } + + private List getAlignmentAnnotations(String calcId, + String label, String description, boolean ignoreDescription) + { List result = new ArrayList<>(); if (this.annotation != null) { for (AlignmentAnnotation ann : annotation) { - if (ann.calcId != null && ann.calcId.equals(calcId) - && ann.label != null && ann.label.equals(label)) + if ((ann.calcId != null && ann.calcId.equals(calcId)) + && (ann.label != null && ann.label.equals(label)) + && ((ignoreDescription && description == null) + || (ann.description != null + && ann.description.equals(description)))) + { result.add(ann); } @@ -1869,7 +1882,7 @@ private List primaryRefs; } private List tmpList; - + @Override public List getPrimaryDBRefs() { @@ -1884,17 +1897,22 @@ private List primaryRefs; synchronized (dbrefs) { if (refModCount == dbrefs.getModCount() && primaryRefs != null) - return primaryRefs; // no changes - refModCount = dbrefs.getModCount(); - List primaries = (primaryRefs == null ? (primaryRefs = new ArrayList<>()) : primaryRefs); + { + return primaryRefs; // no changes + } + refModCount = dbrefs.getModCount(); + List primaries = (primaryRefs == null + ? (primaryRefs = new ArrayList<>()) + : primaryRefs); primaries.clear(); - if (tmpList == null) { - tmpList = new ArrayList<>(); - tmpList.add(null); // for replacement + if (tmpList == null) + { + tmpList = new ArrayList<>(); + tmpList.add(null); // for replacement } for (int i = 0, n = dbrefs.size(); i < n; i++) { - DBRefEntry ref = dbrefs.get(i); + DBRefEntry ref = dbrefs.get(i); if (!ref.isPrimaryCandidate()) { continue; @@ -1909,7 +1927,8 @@ private List primaryRefs; } } // whilst it looks like it is a primary ref, we also sanity check type - if (DBRefSource.PDB_CANONICAL_NAME.equals(ref.getCanonicalSourceName())) + if (DBRefSource.PDB_CANONICAL_NAME + .equals(ref.getCanonicalSourceName())) { // PDB dbrefs imply there should be a PDBEntry associated // TODO: tighten PDB dbrefs @@ -1922,19 +1941,23 @@ private List primaryRefs; { continue; } - } else { - // check standard protein or dna sources - tmpList.set(0, ref); - List res = DBRefUtils.selectDbRefs(!isProtein(), tmpList); - if (res == null || res.get(0) != tmpList.get(0)) - { - continue; - } - } + } + else + { + // check standard protein or dna sources + tmpList.set(0, ref); + List res = DBRefUtils.selectDbRefs(!isProtein(), + tmpList); + if (res == null || res.get(0) != tmpList.get(0)) + { + continue; + } + } primaries.add(ref); } - - // version must be not null, as otherwise it will not be a candidate, above + + // version must be not null, as otherwise it will not be a candidate, + // above DBRefUtils.ensurePrimaries(this, primaries); return primaries; } @@ -1953,15 +1976,6 @@ private List primaryRefs; List result = getFeatures().findFeatures(startPos, endPos, types); - if (datasetSequence != null) - { - result = datasetSequence.getFeatures().findFeatures(startPos, endPos, - types); - } - else - { - result = sequenceFeatureStore.findFeatures(startPos, endPos, types); - } /* * if end column is gapped, endPos may be to the right, @@ -2113,4 +2127,83 @@ private List primaryRefs; // otherwise, sequence was completely hidden return 0; } + + //// + //// Contact Matrix Holder Boilerplate + //// + ContactMapHolderI _cmholder = null; + + private ContactMapHolderI getContactMapHolder() + { + if (datasetSequence!=null) { + return ((Sequence)datasetSequence).getContactMapHolder(); + } + if (_cmholder==null) + { + _cmholder=new ContactMapHolder(); + } + return _cmholder; + } + @Override + public Collection getContactMaps() + { + return getContactMapHolder().getContactMaps(); + } + + @Override + public ContactMatrixI getContactMatrixFor(AlignmentAnnotation ann) + { + return getContactMapHolder().getContactMatrixFor(ann); + } + + @Override + public ContactListI getContactListFor(AlignmentAnnotation _aa, int column) + { + return getContactMapHolder().getContactListFor(_aa, column); + } + + @Override + public AlignmentAnnotation addContactList(ContactMatrixI cm) + { + AlignmentAnnotation aa; + + if (datasetSequence != null) + { + aa = datasetSequence.addContactList(cm); + // clone the annotation for the local sequence + aa = new AlignmentAnnotation(aa); + aa.restrict(start, end); + aa.adjustForAlignment(); + getContactMapHolder().addContactListFor(aa,cm); + addAlignmentAnnotation(aa); + return aa; + } + + // construct new annotation for matrix on dataset sequence + aa = getContactMapHolder().addContactList(cm); + + Annotation _aa[] = new Annotation[getLength()]; + + for (int i = 0; i < _aa.length; _aa[i++] = new Annotation(0.0f)) + { + ; + } + aa.annotations = _aa; + aa.setSequenceRef(this); + if (cm instanceof MappableContactMatrix + && !((MappableContactMatrix) cm).hasReferenceSeq()) + { + ((MappableContactMatrix) cm).setRefSeq(this); + } + aa.createSequenceMapping(this, getStart(), false); + addAlignmentAnnotation(aa); + return aa; + } + + @Override + public void addContactListFor(AlignmentAnnotation annotation, + ContactMatrixI cm) + { + getContactMapHolder().addContactListFor(annotation, cm); + } }