From: Jim Procter Date: Fri, 10 Feb 2017 18:46:15 +0000 (+0000) Subject: Merge branch 'develop' into spike/matrix_annot X-Git-Tag: Release_2_11_3_0~23^2~60^2~9^2~6 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=c007d50b16da69f9a0bab23f8a1afd7347fc7e87;hp=-c;p=jalview.git Merge branch 'develop' into spike/matrix_annot --- c007d50b16da69f9a0bab23f8a1afd7347fc7e87 diff --combined src/jalview/api/AlignViewportI.java index cb11886,2802684..06fa179 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@@ -26,12 -26,12 +26,13 @@@ import jalview.datamodel.AlignmentI import jalview.datamodel.AlignmentView; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.ContactListI; import jalview.datamodel.ProfilesI; import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; + import jalview.renderer.ResidueShaderI; import jalview.schemes.ColourSchemeI; import java.awt.Color; @@@ -80,6 -80,14 +81,14 @@@ public interface AlignViewportI extend ColourSchemeI getGlobalColourScheme(); + /** + * Returns an object that describes colouring (including any thresholding or + * fading) of the alignment + * + * @return + */ + ResidueShaderI getResidueShading(); + AlignmentI getAlignment(); ColumnSelection getColumnSelection(); @@@ -158,7 -166,7 +167,7 @@@ /** * - * @return the alignment annotatino row for the structure consensus + * @return the alignment annotation row for the structure consensus * calculation */ AlignmentAnnotation getAlignmentStrucConsensusAnnotation(); @@@ -171,11 -179,13 +180,13 @@@ void setRnaStructureConsensusHash(Hashtable[] hStrucConsensus); /** - * set global colourscheme + * Sets the colour scheme for the background alignment (as distinct from + * sub-groups, which may have their own colour schemes). A null value is used + * for no residue colour (white). * - * @param rhc + * @param cs */ - void setGlobalColourScheme(ColourSchemeI rhc); + void setGlobalColourScheme(ColourSchemeI cs); Map getHiddenRepSequences(); @@@ -446,6 -456,4 +457,6 @@@ * @return search results or null */ SearchResultsI getSearchResults(); + + ContactListI getContactList(AlignmentAnnotation _aa, int column); } diff --combined src/jalview/datamodel/Alignment.java index d65f5b3,a6f2bf4..e0326c0 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@@ -30,7 -30,6 +30,7 @@@ import jalview.util.MessageManager import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.List; @@@ -55,11 -54,7 +55,7 @@@ public class Alignment implements Align protected char gapCharacter = '-'; - protected int type = NUCLEOTIDE; - - public static final int PROTEIN = 0; - - public static final int NUCLEOTIDE = 1; + private boolean nucleotide = true; public boolean hasRNAStructure = false; @@@ -77,14 -72,7 +73,7 @@@ hiddenSequences = new HiddenSequences(this); codonFrameList = new ArrayList(); - if (Comparison.isNucleotide(seqs)) - { - type = NUCLEOTIDE; - } - else - { - type = PROTEIN; - } + nucleotide = Comparison.isNucleotide(seqs); sequences = Collections.synchronizedList(new ArrayList()); @@@ -219,7 -207,9 +208,9 @@@ } /** - * Adds a sequence to the alignment. Recalculates maxLength and size. + * Adds a sequence to the alignment. Recalculates maxLength and size. Note + * this currently does not recalculate whether or not the alignment is + * nucleotide, so mixed alignments may have undefined behaviour. * * @param snew */ @@@ -367,17 -357,18 +358,18 @@@ * @see jalview.datamodel.AlignmentI#findGroup(jalview.datamodel.SequenceI) */ @Override - public SequenceGroup findGroup(SequenceI s) + public SequenceGroup findGroup(SequenceI seq, int position) { synchronized (groups) { - for (int i = 0; i < this.groups.size(); i++) + for (SequenceGroup sg : groups) { - SequenceGroup sg = groups.get(i); - - if (sg.getSequences(null).contains(s)) + if (sg.getSequences(null).contains(seq)) { - return sg; + if (position >= sg.getStartRes() && position <= sg.getEndRes()) + { + return sg; + } } } } @@@ -978,29 -969,9 +970,9 @@@ } @Override - public void setNucleotide(boolean b) - { - if (b) - { - type = NUCLEOTIDE; - } - else - { - type = PROTEIN; - } - } - - @Override public boolean isNucleotide() { - if (type == NUCLEOTIDE) - { - return true; - } - else - { - return false; - } + return nucleotide; } @Override @@@ -1591,7 -1562,6 +1563,6 @@@ String calcId, boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef) { - assert (name != null); if (annotations != null) { for (AlignmentAnnotation annot : getAlignmentAnnotation()) @@@ -1623,14 -1593,18 +1594,18 @@@ @Override public Iterable findAnnotation(String calcId) { - ArrayList aa = new ArrayList(); - for (AlignmentAnnotation a : getAlignmentAnnotation()) + List aa = new ArrayList(); + AlignmentAnnotation[] alignmentAnnotation = getAlignmentAnnotation(); + if (alignmentAnnotation != null) { - if (a.getCalcId() == calcId - || (a.getCalcId() != null && calcId != null && a.getCalcId() - .equals(calcId))) + for (AlignmentAnnotation a : alignmentAnnotation) { - aa.add(a); + if (a.getCalcId() == calcId + || (a.getCalcId() != null && calcId != null && a + .getCalcId().equals(calcId))) + { + aa.add(a); + } } } return aa; @@@ -1947,38 -1921,4 +1922,38 @@@ } return new int[] { startPos, endPos }; } + + Map contactmaps = new HashMap(); + @Override + public + ContactListI getContactListFor(AlignmentAnnotation _aa, int column) + { + ContactMatrixI cm = contactmaps.get(_aa.annotationId); + if (cm == null) + { + return null; + } + return cm.getContactList(column); + } + + @Override + public AlignmentAnnotation addContactList(ContactMatrixI cm) + { + Annotation _aa[] = new Annotation[getWidth()]; + Annotation dummy = new Annotation(0.0f); + for (int i = 0; i < _aa.length; _aa[i++] = dummy) + { + ; + } + AlignmentAnnotation aa = new AlignmentAnnotation("Contact Matrix", + "Contact Matrix", _aa); + aa.graph = AlignmentAnnotation.CUSTOMRENDERER; + aa.graphMin = cm.getMin(); + aa.graphMax = cm.getMax(); + aa.editable = false; + // aa.autoCalculated = true; + contactmaps.put(aa.annotationId, cm); + addAnnotation(aa); + return aa; + } } diff --combined src/jalview/datamodel/AlignmentI.java index 8ddba6c,752235b..d7391cd --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@@ -156,15 -156,16 +156,16 @@@ public interface AlignmentI extends Ann int findIndex(SequenceI s); /** - * Finds group that given sequence is part of. + * Returns the first group (in the order in which groups were added) that + * includes the given sequence and aligned position (base 0), or null if none + * found * - * @param s - * Sequence in alignment. + * @param seq + * @param position * - * @return First group found for sequence. WARNING : Sequences may be members - * of several groups. This method is incomplete. + * @return */ - SequenceGroup findGroup(SequenceI s); + SequenceGroup findGroup(SequenceI seq, int position); /** * Finds all groups that a given sequence is part of. @@@ -284,13 -285,6 +285,6 @@@ char getGapCharacter(); /** - * Test for all nucleotide alignment - * - * @return true if alignment is nucleotide sequence - */ - boolean isNucleotide(); - - /** * Test if alignment contains RNA structure * * @return true if RNA structure AligmnentAnnotation was added to alignment @@@ -298,12 -292,6 +292,6 @@@ boolean hasRNAStructure(); /** - * Set alignment to be a nucleotide sequence - * - */ - void setNucleotide(boolean b); - - /** * Get the associated dataset for the alignment. * * @return Alignment containing dataset sequences or null of this is a @@@ -556,16 -544,4 +544,16 @@@ * @return */ public int[] getVisibleStartAndEndIndex(List hiddenCols); + + /** + * resolve a contact list instance (if any) associated with the annotation row + * and column position + * + * @param _aa + * @param column + * @return + */ + ContactListI getContactListFor(AlignmentAnnotation _aa, int column); + + AlignmentAnnotation addContactList(ContactMatrixI cm); } diff --combined src/jalview/io/AppletFormatAdapter.java index 4c9324c,c5a80e3..1c97900 --- a/src/jalview/io/AppletFormatAdapter.java +++ b/src/jalview/io/AppletFormatAdapter.java @@@ -26,7 -26,6 +26,7 @@@ import jalview.datamodel.Alignment import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; +import jalview.datamodel.SeqDistanceContactMatrix; import jalview.datamodel.PDBEntry.Type; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolParser; @@@ -65,7 -64,7 +65,7 @@@ public class AppletFormatAdapte */ boolean serviceSecondaryStruct = false; - private AlignmentFileI alignFile = null; + private AlignmentFileReaderI alignFile = null; String inFile; @@@ -78,9 -77,16 +78,16 @@@ public static String INVALID_CHARACTERS = "Contains invalid characters"; - public static String SUPPORTED_FORMATS = "Formats currently supported are\n" - + prettyPrint(FileFormat.getReadableFormats()); - + /** + * Returns an error message with a list of supported readable file formats + * + * @return + */ + public static String getSupportedFormats() + { + return "Formats currently supported are\n" + + prettyPrint(FileFormats.getInstance().getReadableFormats()); + } public AppletFormatAdapter() { } @@@ -158,7 -164,7 +165,7 @@@ } else { - // todo is MCview parsing obsolete yet? + // todo is MCview parsing obsolete yet? JAL-2120 StructureImportSettings.setShowSeqFeatures(true); alignFile = new MCview.PDBfile(annotFromStructure, localSecondaryStruct, serviceSecondaryStruct, inFile, @@@ -169,7 -175,9 +176,9 @@@ } else { - alignFile = fileFormat.getAlignmentFile(inFile, sourceType); + // alignFile = fileFormat.getAlignmentFile(inFile, sourceType); + alignFile = fileFormat.getReader(new FileParse(inFile, + sourceType)); } return buildAlignmentFromFile(); } catch (Exception e) @@@ -209,7 -217,7 +218,7 @@@ throw new IOException(e.getMessage()); } } - throw new FileFormatException(SUPPORTED_FORMATS); + throw new FileFormatException(getSupportedFormats()); } /** @@@ -249,7 -257,7 +258,7 @@@ } else { - alignFile = format.getAlignmentFile(source); + alignFile = format.getReader(source); } return buildAlignmentFromFile(); @@@ -288,7 -296,7 +297,7 @@@ } // If we get to this stage, the format was not supported - throw new FileFormatException(SUPPORTED_FORMATS); + throw new FileFormatException(getSupportedFormats()); } } @@@ -309,8 -317,6 +318,8 @@@ alignFile.addGroups(al); + al.addContactList(new SeqDistanceContactMatrix(al.getWidth())); + return al; } @@@ -364,7 -370,7 +373,7 @@@ { try { - AlignmentFileI afile = format.getAlignmentFile(alignment); + AlignmentFileWriterI afile = format.getWriter(alignment); afile.setNewlineString(newline); afile.setExportSettings(exportSettings); @@@ -392,7 -398,8 +401,8 @@@ return afileresp; } catch (Exception e) { - System.err.println("Failed to write alignment as a '" + format + System.err.println("Failed to write alignment as a '" + + format.getName() + "' file\n"); e.printStackTrace(); } @@@ -641,7 -648,7 +651,7 @@@ return null; } - public AlignmentFileI getAlignFile() + public AlignmentFileReaderI getAlignFile() { return alignFile; } diff --combined src/jalview/renderer/AnnotationRenderer.java index 1928ba3,6f84a2e..f5562d7 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@@ -29,10 -29,10 +29,12 @@@ import jalview.datamodel.AlignmentAnnot import jalview.datamodel.Annotation; import jalview.datamodel.ColumnSelection; import jalview.datamodel.ProfilesI; +import jalview.renderer.api.AnnotationRendererFactoryI; +import jalview.renderer.api.AnnotationRowRendererI; import jalview.schemes.ColourSchemeI; + import jalview.schemes.NucleotideColourScheme; import jalview.schemes.ResidueProperties; + import jalview.schemes.ZappoColourScheme; import jalview.util.Platform; import java.awt.BasicStroke; @@@ -72,7 -72,7 +74,7 @@@ public class AnnotationRendere boolean av_renderHistogram = true, av_renderProfile = true, av_normaliseProfile = false; - ColourSchemeI profcolour = null; + ResidueShaderI profcolour = null; private ColumnSelection columnSelection; @@@ -152,7 -152,6 +154,7 @@@ hStrucConsensus = null; fadedImage = null; annotationPanel = null; + rendererFactoryI = null; } void drawStemAnnot(Graphics g, Annotation[] row_annotations, int lastSSX, @@@ -302,7 -301,6 +304,7 @@@ useClip = false; } + rendererFactoryI = AnnotationRendererFactory.getRendererFactory(); updateFromAlignViewport(av); } @@@ -316,13 -314,17 +318,17 @@@ av_renderHistogram = av.isShowConsensusHistogram(); av_renderProfile = av.isShowSequenceLogo(); av_normaliseProfile = av.isNormaliseSequenceLogo(); - profcolour = av.getGlobalColourScheme(); - if (profcolour == null) + profcolour = av.getResidueShading(); + if (profcolour == null || profcolour.getColourScheme() == null) { - // Set the default colour for sequence logo if the alignnent has no - // colourscheme set - profcolour = av.getAlignment().isNucleotide() ? new jalview.schemes.NucleotideColourScheme() - : new jalview.schemes.ZappoColourScheme(); + /* + * Use default colour for sequence logo if + * the alignment has no colourscheme set + * (would like to use user preference but n/a for applet) + */ + ColourSchemeI col = av.getAlignment().isNucleotide() ? new NucleotideColourScheme() + : new ZappoColourScheme(); + profcolour = new ResidueShader(col); } columnSelection = av.getColumnSelection(); hconsensus = av.getSequenceConsensusHash(); @@@ -370,7 -372,8 +376,7 @@@ } else { - return AAFrequency.extractProfile( -hconsensus.get(column), + return AAFrequency.extractProfile(hconsensus.get(column), av_ignoreGapsConsensus); } } @@@ -404,8 -407,6 +410,8 @@@ boolean rna = false; + private AnnotationRendererFactoryI rendererFactoryI; + /** * Render the annotation rows associated with an alignment. * @@@ -1039,32 -1040,6 +1045,32 @@@ row.graphMin, row.graphMax, y, renderHistogram, renderProfile, normaliseProfile); } + else + { + AnnotationRowRendererI renderer = rendererFactoryI + .getRendererFor(row); + if (renderer != null) + { + renderer.renderRow(g, charWidth, charHeight, + hasHiddenColumns, av, columnSelection, row, + row_annotations, startRes, endRes, row.graphMin, + row.graphMax, y); + } + if (debugRedraw) + { + if (renderer == null) + { + System.err.println("No renderer found for " + + row.toString()); + } + else + { + System.err.println("rendered with " + + renderer.getClass().toString()); + } + } + + } } } else diff --combined src/jalview/viewmodel/AlignmentViewport.java index cb9dd67,0c470fe..cb15a77 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@@ -35,7 -35,6 +35,7 @@@ import jalview.datamodel.AlignmentView import jalview.datamodel.Annotation; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.ContactListI; import jalview.datamodel.HiddenSequences; import jalview.datamodel.ProfilesI; import jalview.datamodel.SearchResultsI; @@@ -43,9 -42,9 +43,9 @@@ import jalview.datamodel.Sequence import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; - import jalview.schemes.Blosum62ColourScheme; + import jalview.renderer.ResidueShader; + import jalview.renderer.ResidueShaderI; import jalview.schemes.ColourSchemeI; - import jalview.schemes.PIDColourScheme; import jalview.structure.CommandListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; @@@ -598,7 -597,7 +598,7 @@@ public abstract class AlignmentViewpor protected boolean ignoreGapsInConsensusCalculation = false; - protected ColourSchemeI globalColourScheme = null; + protected ResidueShaderI residueShading; @Override public void setGlobalColourScheme(ColourSchemeI cs) @@@ -606,74 -605,51 +606,51 @@@ // TODO: logic refactored from AlignFrame changeColour - // TODO: autorecalc stuff should be changed to rely on the worker system // check to see if we should implement a changeColour(cs) method rather than - // put th logic in here + // put the logic in here // - means that caller decides if they want to just modify state and defer // calculation till later or to do all calculations in thread. // via changecolour - globalColourScheme = cs; - boolean recalc = false; + + /* + * only instantiate alignment colouring once, thereafter update it; + * this means that any conservation or PID threshold settings + * persist when the alignment colour scheme is changed + */ + if (residueShading == null) + { + residueShading = new ResidueShader(viewStyle); + } + residueShading.setColourScheme(cs); + + // TODO: do threshold and increment belong in ViewStyle or ResidueShader? + // ...problem: groups need these, but do not currently have a ViewStyle + if (cs != null) { - recalc = getConservationSelected(); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme - || cs instanceof Blosum62ColourScheme) - { - recalc = true; - cs.setThreshold(viewStyle.getThreshold(), - ignoreGapsInConsensusCalculation); - } - else + if (getConservationSelected()) { - cs.setThreshold(0, ignoreGapsInConsensusCalculation); + residueShading.setConservation(hconservation); } - if (recalc) - { - cs.setConsensus(hconsensus); - cs.setConservation(hconservation); - } - cs.setConservationApplied(getConservationSelected()); - cs.alignmentChanged(alignment, hiddenRepSequences); + residueShading.alignmentChanged(alignment, hiddenRepSequences); } + + /* + * if 'apply colour to all groups' is selected... do so + * (but don't transfer any colour threshold settings to groups) + */ if (getColourAppliesToAllGroups()) { for (SequenceGroup sg : getAlignment().getGroups()) { - if (cs == null) - { - sg.cs = null; - continue; - } - sg.cs = cs.applyTo(sg, getHiddenRepSequences()); - sg.setConsPercGaps(ConsPercGaps); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme - || cs instanceof Blosum62ColourScheme) - { - sg.cs.setThreshold(viewStyle.getThreshold(), - isIgnoreGapsConsensus()); - recalc = true; - } - else + /* + * retain any colour thresholds per group while + * changing choice of colour scheme (JAL-2386) + */ + sg.setColourScheme(cs); + if (cs != null) { - sg.cs.setThreshold(0, isIgnoreGapsConsensus()); - } - - if (getConservationSelected()) - { - sg.cs.setConservationApplied(true); - recalc = true; - } - else - { - sg.cs.setConservation(null); - // sg.cs.setThreshold(0, getIgnoreGapsConsensus()); - } - if (recalc) - { - sg.recalcConservation(); - } - else - { - sg.cs.alignmentChanged(sg, hiddenRepSequences); + sg.getGroupColourScheme() + .alignmentChanged(sg, hiddenRepSequences); } } } @@@ -682,7 -658,14 +659,14 @@@ @Override public ColourSchemeI getGlobalColourScheme() { - return globalColourScheme; + return residueShading == null ? null : residueShading + .getColourScheme(); + } + + @Override + public ResidueShaderI getResidueShading() + { + return residueShading; } protected AlignmentAnnotation consensus; @@@ -942,7 -925,7 +926,7 @@@ hconsensus = null; hcomplementConsensus = null; // colour scheme may hold reference to consensus - globalColourScheme = null; + residueShading = null; // TODO remove listeners from changeSupport? changeSupport = null; setAlignment(null); @@@ -1090,7 -1073,8 +1074,8 @@@ } /** - * Set the selection group for this window. + * Set the selection group for this window. Also sets the current alignment as + * the context for the group, if it does not already have one. * * @param sg * - group holding references to sequences in this alignment view @@@ -1100,6 -1084,10 +1085,10 @@@ public void setSelectionGroup(SequenceGroup sg) { selectionGroup = sg; + if (sg != null && sg.getContext() == null) + { + sg.setContext(alignment); + } } public void setHiddenColumns(ColumnSelection colsel) @@@ -1212,9 -1200,9 +1201,9 @@@ if (ap != null) { updateConsensus(ap); - if (globalColourScheme != null) + if (residueShading != null) { - globalColourScheme.setThreshold(globalColourScheme.getThreshold(), + residueShading.setThreshold(residueShading.getThreshold(), ignoreGapsInConsensusCalculation); } } @@@ -1850,7 -1838,7 +1839,7 @@@ selectionGroup.setEndRes(alWidth - 1); } - resetAllColourSchemes(); + updateAllColourSchemes(); calculator.restartWorkers(); // alignment.adjustSequenceAnnotations(); } @@@ -1858,17 -1846,17 +1847,17 @@@ /** * reset scope and do calculations for all applied colourschemes on alignment */ - void resetAllColourSchemes() + void updateAllColourSchemes() { - ColourSchemeI cs = globalColourScheme; - if (cs != null) + ResidueShaderI rs = residueShading; + if (rs != null) { - cs.alignmentChanged(alignment, hiddenRepSequences); + rs.alignmentChanged(alignment, hiddenRepSequences); - cs.setConsensus(hconsensus); - if (cs.conservationApplied()) + rs.setConsensus(hconsensus); + if (rs.conservationApplied()) { - cs.setConservation(Conservation.calculateConservation("All", + rs.setConservation(Conservation.calculateConservation("All", alignment.getSequences(), 0, alignment.getWidth(), false, getConsPercGaps(), false)); } @@@ -2442,6 -2430,11 +2431,11 @@@ public void setViewStyle(ViewStyleI settingsForView) { viewStyle = new ViewStyle(settingsForView); + if (residueShading != null) + { + residueShading.setConservationApplied(settingsForView + .isConservationColourSelected()); + } } @Override @@@ -2873,10 -2866,4 +2867,10 @@@ { return searchResults; } + + @Override + public ContactListI getContactList(AlignmentAnnotation _aa, int column) + { + return alignment.getContactListFor(_aa, column); + } }