From: gmungoc Date: Thu, 26 Jan 2017 11:34:46 +0000 (+0000) Subject: Merge branch 'features/JAL-2360colourSchemeApplicability' into features/JAL-2371colle... X-Git-Tag: Release_2_10_3b1~357^2~10 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=400b50efffaa43ae2c3b4d3f653bf8215c5d1edc;hp=89911f9bb8cd7c981cbeefb0445af265fc2b0d0b;p=jalview.git Merge branch 'features/JAL-2360colourSchemeApplicability' into features/JAL-2371collectionColourScheme --- diff --git a/examples/groovy/colourSchemes.groovy b/examples/groovy/colourSchemes.groovy index 84eabbf..d5ca973 100644 --- a/examples/groovy/colourSchemes.groovy +++ b/examples/groovy/colourSchemes.groovy @@ -1,64 +1,93 @@ import java.awt.Color; -import jalview.schemes.ResidueColourScheme; +import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; import jalview.datamodel.AnnotatedCollectionI; -import java.util.Map; import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceCollectionI; /* * Example script that registers two new alignment colour schemes */ /* - * Class that defines a colour scheme where odd columns are red, - * even numbered columns are blue, and gaps are yellow + * Closure that defines a colour scheme where consensus residues are pink, + * other residues are red in odd columns and blue in even columns, and + * gaps are yellow */ -class Stripy extends ResidueColourScheme { - Stripy() { } - String getSchemeName() { "stripy" } - Stripy getInstance(AnnotatedCollectionI coll, Map map) { new Stripy() } - Color findColour(char res, int col, SequenceI seq) { - // determine the colour - Color colour = findColour(res, col) - // let Jalview apply conservation or consensus shading - adjustColour(res, col, colour); - } - Color findColour(char res, int col) { +def candy +candy = { -> + [ + /* + * name shown in the colour menu + */ + getSchemeName: { -> 'candy' }, + + /* + * to make a new instance for each alignment view + */ + getInstance: { AnnotatedCollectionI coll, Map map -> candy() }, + + /* + * method only needed if colour scheme has to recalculate + * values when an alignment is modified + */ + alignmentChanged: { AnnotatedCollectionI coll, Map map -> }, + + /* + * determine colour for a residue at an aligned position of a + * sequence, given consensus residue(s) for the column and the + * consensus percentage identity score for the column + */ + findColour: { char res, int col, SequenceI seq, String consensus, float pid -> if (res == ' ' || res == '-' || res == '.') { Color.yellow - } else if (col % 2 == 0) - { + } else if (consensus.contains(String.valueOf(res))) + { + Color.pink + } else if (col % 2 == 0) + { Color.blue - } else - { + } else + { Color.red - } - } + } + }, + + /* + * true means applicable to nucleotide or peptide data + */ + isApplicableTo: {AnnotatedCollectionI coll -> true}, + + /* + * simple colour schemes are those that depend on the residue + * only (these are also available to colour structure viewers) + */ + isSimple: { false } + ] as ColourSchemeI } /* - * Class that defines a colour scheme graduated - * (approximately) by amino acid weight + * A closure that defines a colour scheme graduated + * (approximately) by amino acid weight + * here from lightest (G) Blue, to heaviest (W) Red */ -class ByWeight extends ResidueColourScheme { - int min = 75 - int max = 204 - ByWeight() { } - boolean isPeptideSpecific() {true} - String getSchemeName() { "By Weight" } - ByWeight getInstance(AnnotatedCollectionI coll, Map map) { new ByWeight() } - Color makeColour(int weight) { - int i = 255 * (weight - min) / (max - min); - new Color(i, 0, i); - } - Color findColour(char res, int col, SequenceI seq) { - // determine the colour - Color colour = findColour(res, col) - // let Jalview apply any conservation or consensus shading - adjustColour(res, col, colour); - } - Color findColour(char res, int col) { +def makeColour = { weight -> + minWeight = 75 // Glycine + maxWeight = 204 // Tryptophan + int i = 255 * (weight - minWeight) / (maxWeight - minWeight); + new Color(i, 0, 255-i); +} +def byWeight +byWeight = { -> + [ + getSchemeName: { 'By Weight' }, + // this colour scheme is peptide-specific: + isApplicableTo: { coll -> !coll.isNucleotide() }, + alignmentChanged: { coll, map -> }, + getInstance: { coll, map -> byWeight() }, + isSimple: { true }, + findColour: {res, col, seq, consensus, pid -> switch (res) { case ' ': case '-': @@ -119,7 +148,8 @@ class ByWeight extends ResidueColourScheme { makeColour(150) } } + ] as ColourSchemeI } -ColourSchemes.instance.registerColourScheme(new Stripy()) -ColourSchemes.instance.registerColourScheme(new ByWeight()) +ColourSchemes.instance.registerColourScheme(candy()) +ColourSchemes.instance.registerColourScheme(byWeight()) diff --git a/src/MCview/PDBChain.java b/src/MCview/PDBChain.java index 783a4e2..c40cdda 100755 --- a/src/MCview/PDBChain.java +++ b/src/MCview/PDBChain.java @@ -516,10 +516,12 @@ public class PDBChain try { index = ResidueProperties.aa3Hash.get(b.at1.resName).intValue(); - b.startCol = cs.findColour(ResidueProperties.aa[index].charAt(0)); + b.startCol = cs.findColour(ResidueProperties.aa[index].charAt(0), + 0, null, null, 0f); index = ResidueProperties.aa3Hash.get(b.at2.resName).intValue(); - b.endCol = cs.findColour(ResidueProperties.aa[index].charAt(0)); + b.endCol = cs.findColour(ResidueProperties.aa[index].charAt(0), 0, + null, null, 0f); } catch (Exception e) { diff --git a/src/jalview/analysis/Conservation.java b/src/jalview/analysis/Conservation.java index 5e5f716..565924b 100755 --- a/src/jalview/analysis/Conservation.java +++ b/src/jalview/analysis/Conservation.java @@ -519,7 +519,7 @@ public class Conservation * * @return Conservation sequence */ - public Sequence getConsSequence() + public SequenceI getConsSequence() { return consSequence; } diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 72542b3..ee03852 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -31,6 +31,7 @@ import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; import java.awt.Color; @@ -79,6 +80,8 @@ public interface AlignViewportI extends ViewStyleI ColourSchemeI getGlobalColourScheme(); + CollectionColourSchemeI getViewportColourScheme(); + AlignmentI getAlignment(); ColumnSelection getColumnSelection(); diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index 897c78c..018b227 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -42,7 +42,8 @@ import jalview.io.SequenceAnnotationReport; import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.BuriedColourScheme; import jalview.schemes.ClustalxColourScheme; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.HelixColourScheme; import jalview.schemes.HydrophobicColourScheme; import jalview.schemes.JalviewColourScheme; @@ -329,20 +330,21 @@ public class APopupMenu extends java.awt.PopupMenu implements * * @param cs */ - protected void setSelectedColour(ColourSchemeI cs) + protected void setSelectedColour(CollectionColourSchemeI cs) { - if (cs == null) + if (cs == null || cs.getColourScheme() == null) { noColour.setState(true); } else { + String name = cs.getColourScheme().getSchemeName(); for (int i = 0; i < colourMenu.getItemCount(); i++) { MenuItem item = colourMenu.getItem(i); if (item instanceof CheckboxMenuItem) { - if (cs.getSchemeName().equals(item.getName())) + if (name.equals(item.getName())) { ((CheckboxMenuItem) item).setState(true); } @@ -565,7 +567,7 @@ public class APopupMenu extends java.awt.PopupMenu implements { BLOSUM62Colour_actionPerformed(); } - else if (source == PIDColour) + else if (evt.getSource() == PIDColour) { PIDColour_actionPerformed(); } @@ -1145,61 +1147,63 @@ public class APopupMenu extends java.awt.PopupMenu implements protected void clustalColour_actionPerformed() { SequenceGroup sg = getGroup(); - sg.cs = new ClustalxColourScheme(sg, ap.av.getHiddenRepSequences()); + sg.cs = new CollectionColourScheme(new ClustalxColourScheme(sg, + ap.av.getHiddenRepSequences())); refresh(); } protected void zappoColour_actionPerformed() { - getGroup().cs = new ZappoColourScheme(); + getGroup().cs = new CollectionColourScheme(new ZappoColourScheme()); refresh(); } protected void taylorColour_actionPerformed() { - getGroup().cs = new TaylorColourScheme(); + getGroup().cs = new CollectionColourScheme(new TaylorColourScheme()); refresh(); } protected void hydrophobicityColour_actionPerformed() { - getGroup().cs = new HydrophobicColourScheme(); + getGroup().cs = new CollectionColourScheme(new HydrophobicColourScheme()); refresh(); } protected void helixColour_actionPerformed() { - getGroup().cs = new HelixColourScheme(); + getGroup().cs = new CollectionColourScheme(new HelixColourScheme()); refresh(); } protected void strandColour_actionPerformed() { - getGroup().cs = new StrandColourScheme(); + getGroup().cs = new CollectionColourScheme(new StrandColourScheme()); refresh(); } protected void turnColour_actionPerformed() { - getGroup().cs = new TurnColourScheme(); + getGroup().cs = new CollectionColourScheme(new TurnColourScheme()); refresh(); } protected void buriedColour_actionPerformed() { - getGroup().cs = new BuriedColourScheme(); + getGroup().cs = new CollectionColourScheme(new BuriedColourScheme()); refresh(); } public void nucleotideMenuItem_actionPerformed() { - getGroup().cs = new NucleotideColourScheme(); + getGroup().cs = new CollectionColourScheme(new NucleotideColourScheme()); refresh(); } public void purinePyrimidineColour_actionPerformed() { - getGroup().cs = new PurinePyrimidineColourScheme(); + getGroup().cs = new CollectionColourScheme( + new PurinePyrimidineColourScheme()); refresh(); } @@ -1241,7 +1245,7 @@ public class APopupMenu extends java.awt.PopupMenu implements protected void PIDColour_actionPerformed() { SequenceGroup sg = getGroup(); - sg.cs = new PIDColourScheme(); + sg.cs = new CollectionColourScheme(new PIDColourScheme()); sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av .getHiddenRepSequences()), 0, ap.av.getAlignment().getWidth())); refresh(); @@ -1251,7 +1255,7 @@ public class APopupMenu extends java.awt.PopupMenu implements { SequenceGroup sg = getGroup(); - sg.cs = new Blosum62ColourScheme(); + sg.cs = new CollectionColourScheme(new Blosum62ColourScheme()); sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av .getHiddenRepSequences()), 0, ap.av.getAlignment().getWidth())); @@ -1275,10 +1279,12 @@ public class APopupMenu extends java.awt.PopupMenu implements if (conservationColour.getState()) { - sg.cs.setConservation(Conservation.calculateConservation("Group", sg + Conservation conservation = Conservation.calculateConservation( + "Group", sg .getSequences(ap.av.getHiddenRepSequences()), 0, ap.av .getAlignment().getWidth(), false, ap.av.getConsPercGaps(), - false)); + false); + sg.getGroupColourScheme().setConservation(conservation); SliderPanel.setConservationSlider(ap, sg.cs, sg.getName()); SliderPanel.showConservationSlider(); } diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index cfd3d00..4c4c84f 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -65,7 +65,6 @@ import jalview.schemes.NucleotideColourScheme; import jalview.schemes.PIDColourScheme; import jalview.schemes.PurinePyrimidineColourScheme; import jalview.schemes.RNAHelicesColour; -import jalview.schemes.RNAHelicesColourChooser; import jalview.schemes.StrandColourScheme; import jalview.schemes.TCoffeeColourScheme; import jalview.schemes.TaylorColourScheme; @@ -2632,26 +2631,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, @Override public void changeColour(ColourSchemeI cs) { - - if (cs != null) - { - if (viewport.getAbovePIDThreshold()) - { - viewport.setThreshold(SliderPanel.setPIDSliderSource(alignPanel, - cs, "Background")); - } - - if (viewport.getConservationSelected()) - { - cs.setConservationApplied(true); - viewport.setIncrement(SliderPanel.setConservationSlider(alignPanel, - cs, "Background")); - } - else - { - cs.setConservationApplied(false); - } - } viewport.setGlobalColourScheme(cs); alignPanel.paintAlignment(true); @@ -2663,7 +2642,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, && viewport.getGlobalColourScheme() != null) { SliderPanel.setPIDSliderSource(alignPanel, - viewport.getGlobalColourScheme(), "Background"); + viewport.getViewportColourScheme(), "Background"); SliderPanel.showPIDSlider(); } } @@ -2674,7 +2653,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, && viewport.getGlobalColourScheme() != null) { SliderPanel.setConservationSlider(alignPanel, - viewport.getGlobalColourScheme(), "Background"); + viewport.getViewportColourScheme(), "Background"); SliderPanel.showConservationSlider(); } } diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index 9e82ae5..2e76e1a 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -32,6 +32,7 @@ import jalview.datamodel.SearchResultsI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.schemes.CollectionColourScheme; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; import jalview.structure.CommandListener; @@ -208,8 +209,8 @@ public class AlignViewport extends AlignmentViewport implements if (colour != null) { - globalColourScheme = ColourSchemeProperty.getColourScheme( - alignment, colour); + globalColourScheme = new CollectionColourScheme( + ColourSchemeProperty.getColourScheme(alignment, colour)); if (globalColourScheme != null) { globalColourScheme.setConsensus(hconsensus); @@ -218,8 +219,9 @@ public class AlignViewport extends AlignmentViewport implements if (applet.getParameter("userDefinedColour") != null) { - globalColourScheme = new UserColourScheme( - applet.getParameter("userDefinedColour")); + globalColourScheme = new CollectionColourScheme( + new UserColourScheme( + applet.getParameter("userDefinedColour"))); } } initAutoAnnotation(); diff --git a/src/jalview/appletgui/AnnotationColourChooser.java b/src/jalview/appletgui/AnnotationColourChooser.java index 79d2f1f..487b75c 100644 --- a/src/jalview/appletgui/AnnotationColourChooser.java +++ b/src/jalview/appletgui/AnnotationColourChooser.java @@ -81,9 +81,9 @@ public class AnnotationColourChooser extends Panel implements oldgroupColours = new Hashtable(); for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - if (sg.cs != null) + if (sg.getColourScheme() != null) { - oldgroupColours.put(sg, sg.cs); + oldgroupColours.put(sg, sg.getColourScheme()); } else { @@ -487,8 +487,6 @@ public class AnnotationColourChooser extends Panel implements AnnotationColourGradient acg = null; if (currentColours.getState()) { - acg = new AnnotationColourGradient(currentAnnotation, - av.getGlobalColourScheme(), aboveThreshold); } else { @@ -513,21 +511,21 @@ public class AnnotationColourChooser extends Panel implements for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - if (sg.cs == null) + if (sg.getColourScheme() == null) { continue; } if (currentColours.getState()) { - sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs, - aboveThreshold); + sg.setColourScheme(new AnnotationColourGradient( + currentAnnotation, sg.getColourScheme(), aboveThreshold)); } else { - sg.cs = new AnnotationColourGradient(currentAnnotation, - minColour.getBackground(), maxColour.getBackground(), - aboveThreshold); + sg.setColourScheme(new AnnotationColourGradient( + currentAnnotation, minColour.getBackground(), maxColour + .getBackground(), aboveThreshold)); } } @@ -548,12 +546,12 @@ public class AnnotationColourChooser extends Panel implements Object cs = oldgroupColours.get(sg); if (cs instanceof ColourSchemeI) { - sg.cs = (ColourSchemeI) cs; + sg.setColourScheme((ColourSchemeI) cs); } else { // probably the "null" string we set it to if it was null originally. - sg.cs = null; + sg.setColourScheme(null); } } } diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java index 1debda8..c1cddaa 100644 --- a/src/jalview/appletgui/SeqPanel.java +++ b/src/jalview/appletgui/SeqPanel.java @@ -1505,12 +1505,12 @@ public class SeqPanel extends Panel implements MouseMotionListener, if (av.getConservationSelected()) { - SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(), + SliderPanel.setConservationSlider(ap, av.getViewportColourScheme(), "Background"); } if (av.getAbovePIDThreshold()) { - SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(), + SliderPanel.setPIDSliderSource(ap, av.getViewportColourScheme(), "Background"); } diff --git a/src/jalview/appletgui/SequenceRenderer.java b/src/jalview/appletgui/SequenceRenderer.java index 970d20e..4d9d37c 100755 --- a/src/jalview/appletgui/SequenceRenderer.java +++ b/src/jalview/appletgui/SequenceRenderer.java @@ -23,7 +23,7 @@ package jalview.appletgui; import jalview.api.FeatureRenderer; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourSchemeI; import java.awt.Color; import java.awt.Font; @@ -78,12 +78,12 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (currentSequenceGroup.getDisplayBoxes()) { - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i); } } else if (av.getShowBoxes()) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); } return resBoxColour; @@ -114,11 +114,13 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer return col; } - void getBoxColour(ColourSchemeI cs, SequenceI seq, int i) + void getBoxColour(CollectionColourSchemeI collectionColourSchemeI, + SequenceI seq, int i) { - if (cs != null) + if (collectionColourSchemeI != null) { - resBoxColour = cs.findColour(seq.getCharAt(i), i, seq); + resBoxColour = collectionColourSchemeI.findColour(seq.getCharAt(i), + i, seq); } else if (forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i))) @@ -176,12 +178,13 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (currentSequenceGroup.getDisplayBoxes()) { - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, + i); } } else if (av.getShowBoxes()) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); } } @@ -254,7 +257,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer if (currentSequenceGroup.getColourText()) { - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i); graphics.setColor(resBoxColour.darker()); } if (currentSequenceGroup.getShowNonconserved()) @@ -271,7 +274,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer if (av.getColourText()) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); if (av.getShowBoxes()) { graphics.setColor(resBoxColour.darker()); diff --git a/src/jalview/appletgui/SliderPanel.java b/src/jalview/appletgui/SliderPanel.java index b52fae9..1beb82b 100644 --- a/src/jalview/appletgui/SliderPanel.java +++ b/src/jalview/appletgui/SliderPanel.java @@ -21,7 +21,7 @@ package jalview.appletgui; import jalview.datamodel.SequenceGroup; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourSchemeI; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -53,28 +53,28 @@ public class SliderPanel extends Panel implements ActionListener, boolean forConservation = true; - ColourSchemeI cs; + CollectionColourSchemeI cs; static Frame conservationSlider; static Frame PIDSlider; public static int setConservationSlider(AlignmentPanel ap, - ColourSchemeI cs, String source) + CollectionColourSchemeI ccs, String source) { SliderPanel sp = null; if (conservationSlider == null) { - sp = new SliderPanel(ap, cs.getConservationInc(), true, cs); + sp = new SliderPanel(ap, ccs.getConservationInc(), true, ccs); conservationSlider = new Frame(); conservationSlider.add(sp); } else { sp = (SliderPanel) conservationSlider.getComponent(0); - sp.valueField.setText(String.valueOf(cs.getConservationInc())); - sp.cs = cs; + sp.cs = ccs; + sp.valueField.setText(String.valueOf(ccs.getConservationInc())); } conservationSlider @@ -120,21 +120,21 @@ public class SliderPanel extends Panel implements ActionListener, } - public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs, - String source) + public static int setPIDSliderSource(AlignmentPanel ap, + CollectionColourSchemeI ccs, String source) { SliderPanel pid = null; if (PIDSlider == null) { - pid = new SliderPanel(ap, cs.getThreshold(), false, cs); + pid = new SliderPanel(ap, ccs.getThreshold(), false, ccs); PIDSlider = new Frame(); PIDSlider.add(pid); } else { pid = (SliderPanel) PIDSlider.getComponent(0); - pid.valueField.setText(String.valueOf(cs.getThreshold())); - pid.cs = cs; + pid.cs = ccs; + pid.valueField.setText(String.valueOf(ccs.getThreshold())); } PIDSlider .setTitle(MessageManager.formatMessage( @@ -204,7 +204,7 @@ public class SliderPanel extends Panel implements ActionListener, } } public SliderPanel(AlignmentPanel ap, int value, boolean forConserve, - ColourSchemeI cs) + CollectionColourSchemeI collectionColourSchemeI) { try { @@ -214,7 +214,7 @@ public class SliderPanel extends Panel implements ActionListener, e.printStackTrace(); } this.ap = ap; - this.cs = cs; + this.cs = collectionColourSchemeI; forConservation = forConserve; undoButton.setVisible(false); applyButton.setVisible(false); @@ -249,7 +249,7 @@ public class SliderPanel extends Panel implements ActionListener, return; } - ColourSchemeI toChange = cs; + CollectionColourSchemeI toChange = cs; Iterator allGroups = null; if (allGroupsCheck.getState()) diff --git a/src/jalview/appletgui/TreeCanvas.java b/src/jalview/appletgui/TreeCanvas.java index ca9f2d8..510df94 100755 --- a/src/jalview/appletgui/TreeCanvas.java +++ b/src/jalview/appletgui/TreeCanvas.java @@ -661,31 +661,33 @@ public class TreeCanvas extends Panel implements MouseListener, .getGlobalColourScheme())); } // cs is null if shading is an annotationColourGradient - if (cs != null) - { - cs.setThreshold(av.getGlobalColourScheme().getThreshold(), - av.isIgnoreGapsConsensus()); - } + // if (cs != null) + // { + // cs.setThreshold(av.getViewportColourScheme().getThreshold(), + // av.isIgnoreGapsConsensus()); + // } } // TODO: cs used to be initialized with a sequence collection and // recalcConservation called automatically // instead we set it manually - recalc called after updateAnnotation - sg.cs = cs; + sg.setColourScheme(cs); + sg.getGroupColourScheme().setThreshold( + av.getViewportColourScheme().getThreshold(), + av.isIgnoreGapsConsensus()); sg.setName("JTreeGroup:" + sg.hashCode()); sg.setIdColour(col); if (av.getGlobalColourScheme() != null - && av.getGlobalColourScheme().conservationApplied()) + && av.getViewportColourScheme().conservationApplied()) { Conservation c = new Conservation("Group", sg.getSequences(null), sg.getStartRes(), sg.getEndRes()); c.calculate(); c.verdict(false, av.getConsPercGaps()); - cs.setConservation(c); - - sg.cs = cs; + sg.setColourScheme(cs); + sg.getGroupColourScheme().setConservation(c); } av.getAlignment().addGroup(sg); diff --git a/src/jalview/appletgui/UserDefinedColours.java b/src/jalview/appletgui/UserDefinedColours.java index 88098a9..aecc0c9 100644 --- a/src/jalview/appletgui/UserDefinedColours.java +++ b/src/jalview/appletgui/UserDefinedColours.java @@ -22,6 +22,7 @@ package jalview.appletgui; import jalview.api.FeatureColourI; import jalview.datamodel.SequenceGroup; +import jalview.schemes.CollectionColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.FeatureColour; import jalview.schemes.ResidueProperties; @@ -93,7 +94,7 @@ public class UserDefinedColours extends Panel implements ActionListener, if (seqGroup != null) { - oldColourScheme = seqGroup.cs; + oldColourScheme = seqGroup.getColourScheme(); } else { @@ -407,14 +408,9 @@ public class UserDefinedColours extends Panel implements ActionListener, { final Button button = new Button(); Color col = Color.white; - if (oldColourScheme != null) + if (oldColourScheme != null && oldColourScheme.isSimple()) { - try - { - col = oldColourScheme.findColour(aa.charAt(0), -1, null); - } catch (Exception ex) - { - } + col = oldColourScheme.findColour(aa.charAt(0), 0, null, null, 0f); } button.setBackground(col); oldColours.addElement(col); @@ -501,20 +497,24 @@ public class UserDefinedColours extends Panel implements ActionListener, } UserColourScheme ucs = new UserColourScheme(newColours); - if (ap != null) - { - ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); - } + // if (ap != null) + // { + // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); + // } if (ap != null) { if (seqGroup != null) { - seqGroup.cs = ucs; + seqGroup.cs = new CollectionColourScheme(ucs); + seqGroup.getGroupColourScheme().setThreshold(0, + ap.av.isIgnoreGapsConsensus()); } else { ap.av.setGlobalColourScheme(ucs); + ap.av.getViewportColourScheme().setThreshold(0, + ap.av.isIgnoreGapsConsensus()); } ap.seqPanel.seqCanvas.img = null; ap.paintAlignment(true); @@ -592,7 +592,7 @@ public class UserDefinedColours extends Panel implements ActionListener, { if (seqGroup != null) { - seqGroup.cs = ucs; + seqGroup.cs = new CollectionColourScheme(ucs); } else { diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index a0b3ff1..752235b 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -285,13 +285,6 @@ public interface AlignmentI extends AnnotatedCollectionI 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 diff --git a/src/jalview/datamodel/SequenceCollectionI.java b/src/jalview/datamodel/SequenceCollectionI.java index aca79c8..f681f11 100644 --- a/src/jalview/datamodel/SequenceCollectionI.java +++ b/src/jalview/datamodel/SequenceCollectionI.java @@ -64,4 +64,10 @@ public interface SequenceCollectionI */ int getEndRes(); + /** + * Answers true if sequence data is nucleotide (according to some heuristic) + * + * @return + */ + boolean isNucleotide(); } diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index da47a89..8218ba7 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -22,6 +22,8 @@ package jalview.datamodel; import jalview.analysis.AAFrequency; import jalview.analysis.Conservation; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; import java.awt.Color; @@ -69,7 +71,7 @@ public class SequenceGroup implements AnnotatedCollectionI /** * Colourscheme applied to group if any */ - public ColourSchemeI cs; + public CollectionColourSchemeI cs; // start column (base 0) int startRes = 0; @@ -116,6 +118,7 @@ public class SequenceGroup implements AnnotatedCollectionI public SequenceGroup() { groupName = "JGroup:" + this.hashCode(); + cs = new CollectionColourScheme(); } /** @@ -136,12 +139,13 @@ public class SequenceGroup implements AnnotatedCollectionI ColourSchemeI scheme, boolean displayBoxes, boolean displayText, boolean colourText, int start, int end) { + this(); this.sequences = sequences; this.groupName = groupName; this.displayBoxes = displayBoxes; this.displayText = displayText; this.colourText = colourText; - this.cs = scheme; + this.cs = new CollectionColourScheme(scheme); startRes = start; endRes = end; recalcConservation(); @@ -154,6 +158,7 @@ public class SequenceGroup implements AnnotatedCollectionI */ public SequenceGroup(SequenceGroup seqsel) { + this(); if (seqsel != null) { sequences = new ArrayList(); @@ -1361,4 +1366,38 @@ public class SequenceGroup implements AnnotatedCollectionI { return context; } + + public void setColourScheme(ColourSchemeI scheme) + { + if (cs == null) + { + cs = new CollectionColourScheme(); + } + cs.setColourScheme(scheme); + } + + public void setGroupColourScheme(CollectionColourSchemeI scheme) + { + cs = scheme; + } + + public ColourSchemeI getColourScheme() + { + return cs == null ? null : cs.getColourScheme(); + } + + public CollectionColourSchemeI getGroupColourScheme() + { + return cs; + } + + @Override + public boolean isNucleotide() + { + if (context != null && context instanceof AlignmentI) + { + return ((AlignmentI) context).isNucleotide(); + } + return false; + } } diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index b4586ca..bf80831 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -168,6 +168,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel releaseUIResources(); } + @Override public void colourByChain() { colourBySequence = false; @@ -177,6 +178,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel evalStateCommand("select *;color chain"); } + @Override public void colourByCharge() { colourBySequence = false; @@ -1264,7 +1266,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel { char res = resName.length() == 3 ? ResidueProperties .getSingleCharacterCode(resName) : resName.charAt(0); - Color col = cs.findColour(res); + Color col = cs.findColour(res, 0, null, null, 0f); command.append("select " + resName + ";color[" + col.getRed() + "," + col.getGreen() + "," + col.getBlue() + "];"); } diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 2171815..b05c168 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -929,7 +929,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel { char res = resName.length() == 3 ? ResidueProperties .getSingleCharacterCode(resName) : resName.charAt(0); - Color col = cs.findColour(res); + Color col = cs.findColour(res, 0, null, null, 0f); command.append("color " + col.getRed() / normalise + "," + col.getGreen() / normalise + "," + col.getBlue() / normalise + " ::" + resName + ";"); diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 40ab6bb..266cbcb 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -1254,8 +1254,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { FileFormatI format = fileFormat; cap.setText(new FormatAdapter(alignPanel, exportData.getSettings()) - .formatSequences(format, - exportData.getAlignment(), + .formatSequences(format, exportData.getAlignment(), exportData.getOmitHidden(), exportData.getStartEndPostions(), viewport.getColumnSelection())); @@ -1846,8 +1845,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } String output = new FormatAdapter().formatSequences(FileFormat.Fasta, - seqs, - omitHidden, null); + seqs, omitHidden, null); StringSelection ss = new StringSelection(output); @@ -3300,11 +3298,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * colour scheme to all groups. If unchecked, groups may have their own * independent colour schemes. * + * @param selected */ @Override - protected void applyToAllGroups_actionPerformed() + protected void applyToAllGroups_actionPerformed(boolean selected) { - viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected()); + viewport.setColourAppliesToAllGroups(selected); } /** @@ -3346,19 +3345,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, if (cs != null) { ColourMenuHelper.setColourSelected(colourMenu, cs.getSchemeName()); - // Make sure viewport is up to date w.r.t. any sliders - if (viewport.getAbovePIDThreshold()) - { - int threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, - "Background"); - viewport.setThreshold(threshold); - } - - if (viewport.getConservationSelected()) - { - cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, - cs, "Background")); - } } viewport.setGlobalColourScheme(cs); @@ -3367,50 +3353,36 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } /** - * DOCUMENT ME! - * - * @param e - * DOCUMENT ME! + * Show the PID threshold slider panel */ @Override protected void modifyPID_actionPerformed() { - if (viewport.getAbovePIDThreshold() - && viewport.getGlobalColourScheme() != null) - { - SliderPanel.setPIDSliderSource(alignPanel, - viewport.getGlobalColourScheme(), "Background"); - SliderPanel.showPIDSlider(); - } + SliderPanel.setPIDSliderSource(alignPanel, + viewport.getViewportColourScheme(), "Background"); + SliderPanel.showPIDSlider(); } /** - * DOCUMENT ME! - * - * @param e - * DOCUMENT ME! + * Show the Conservation slider panel */ @Override protected void modifyConservation_actionPerformed() { - if (viewport.getConservationSelected() - && viewport.getGlobalColourScheme() != null) - { - SliderPanel.setConservationSlider(alignPanel, - viewport.getGlobalColourScheme(), "Background"); - SliderPanel.showConservationSlider(); - } + SliderPanel.setConservationSlider(alignPanel, + viewport.getViewportColourScheme(), "Background"); + SliderPanel.showConservationSlider(); } /** * Action on selecting or deselecting (Colour) By Conservation */ @Override - protected void conservationMenuItem_actionPerformed() + protected void conservationMenuItem_actionPerformed(boolean selected) { - boolean selected = conservationMenuItem.isSelected(); modifyConservation.setEnabled(selected); viewport.setConservationSelected(selected); + viewport.getViewportColourScheme().setConservationApplied(selected); changeColour(viewport.getGlobalColourScheme()); if (selected) @@ -3427,9 +3399,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * Action on selecting or deselecting (Colour) Above PID Threshold */ @Override - public void abovePIDThreshold_actionPerformed() + public void abovePIDThreshold_actionPerformed(boolean selected) { - boolean selected = abovePIDThreshold.isSelected(); modifyPID.setEnabled(selected); viewport.setAbovePIDThreshold(selected); @@ -4787,8 +4758,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } if (FileFormat.Jnet.equals(format)) { - JPredFile predictions = new JPredFile( - file, sourceType); + JPredFile predictions = new JPredFile(file, sourceType); new JnetAnnotationMaker(); JnetAnnotationMaker.add_annotation(predictions, viewport.getAlignment(), 0, false); @@ -5696,17 +5666,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, colourMenu.add(modifyPID); colourMenu.add(annotationColour); - /* - * select the default colour for the alignment (this may be - * overridden later) - */ - boolean nucleotide = viewport.getAlignment().isNucleotide(); - String defaultColourScheme = Cache.getDefault( - nucleotide ? Preferences.DEFAULT_COLOUR_NUC - : Preferences.DEFAULT_COLOUR_PROT, - ResidueColourScheme.NONE); + ColourSchemeI colourScheme = viewport.getGlobalColourScheme(); + String schemeName = colourScheme == null ? null : colourScheme + .getSchemeName(); - ColourMenuHelper.setColourSelected(colourMenu, defaultColourScheme); + ColourMenuHelper.setColourSelected(colourMenu, schemeName); } } diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 2115617..35a87d4 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -41,6 +41,8 @@ import jalview.datamodel.SearchResultsI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; import jalview.structure.CommandListener; @@ -61,7 +63,6 @@ import java.util.List; import java.util.Vector; import javax.swing.JInternalFrame; -import javax.swing.JOptionPane; /** * DOCUMENT ME! @@ -292,14 +293,15 @@ public class AlignViewport extends AlignmentViewport implements } if (propertyValue != null) { - globalColourScheme = ColourSchemeProperty.getColourScheme(alignment, - propertyValue); + ColourSchemeI colourScheme = ColourSchemeProperty.getColourScheme( + alignment, propertyValue); + globalColourScheme = new CollectionColourScheme(colourScheme); - if (globalColourScheme instanceof UserColourScheme) + if (colourScheme instanceof UserColourScheme) { - globalColourScheme = UserDefinedColours.loadDefaultColours(); - ((UserColourScheme) globalColourScheme).setThreshold(0, - isIgnoreGapsConsensus()); + globalColourScheme = new CollectionColourScheme( + UserDefinedColours.loadDefaultColours()); + globalColourScheme.setThreshold(0, isIgnoreGapsConsensus()); } if (globalColourScheme != null) diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index 39cde03..f6352d7 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -80,9 +80,9 @@ public class AnnotationColourChooser extends AnnotationRowFilter oldgroupColours = new Hashtable(); for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - if (sg.cs != null) + if (sg.getColourScheme() != null) { - oldgroupColours.put(sg, sg.cs); + oldgroupColours.put(sg, sg.getColourScheme()); } } } @@ -381,7 +381,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - sg.cs = oldgroupColours.get(sg); + sg.setColourScheme(oldgroupColours.get(sg)); } } } diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java index c8bd69c..166e1ad 100644 --- a/src/jalview/gui/AnnotationRowFilter.java +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -366,23 +366,20 @@ public abstract class AnnotationRowFilter extends JPanel continue; } + AnnotationColourGradient scheme = null; if (currentColours.isSelected()) { - sg.cs = new AnnotationColourGradient(currentAnn, sg.cs, - selectedThresholdOption); - ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated - .isSelected()); - + scheme = new AnnotationColourGradient(currentAnn, + sg.getColourScheme(), selectedThresholdOption); } else { - sg.cs = new AnnotationColourGradient(currentAnn, + scheme = new AnnotationColourGradient(currentAnn, minColour.getBackground(), maxColour.getBackground(), selectedThresholdOption); - ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated - .isSelected()); } - + scheme.setSeqAssociated(seqAssociated.isSelected()); + sg.setColourScheme(scheme); } } return false; diff --git a/src/jalview/gui/ColourMenuHelper.java b/src/jalview/gui/ColourMenuHelper.java index 52abfe1..31780d6 100644 --- a/src/jalview/gui/ColourMenuHelper.java +++ b/src/jalview/gui/ColourMenuHelper.java @@ -77,7 +77,7 @@ public class ColourMenuHelper /* * scan registered colour schemes (built-in or user-defined - * and add them to the menu (in the order they were added) + * and add them to the menu (in the order they were registered) */ Iterable colourSchemes = ColourSchemes.getInstance() .getColourSchemes(); diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index b6587fb..8393693 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -73,6 +73,7 @@ import jalview.schemabinding.version2.Tree; import jalview.schemabinding.version2.UserColours; import jalview.schemabinding.version2.Viewport; import jalview.schemes.AnnotationColourGradient; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.FeatureColour; @@ -1174,38 +1175,43 @@ public class Jalview2XML // group has references so set its ID field jGroup.setId(groupRefs.get(sg)); } - if (sg.cs != null) + ColourSchemeI colourScheme = sg.getColourScheme(); + if (colourScheme != null) { - if (sg.cs.conservationApplied()) + CollectionColourSchemeI groupColourScheme = sg + .getGroupColourScheme(); + if (groupColourScheme.conservationApplied()) { - jGroup.setConsThreshold(sg.cs.getConservationInc()); + jGroup.setConsThreshold(groupColourScheme.getConservationInc()); - if (sg.cs instanceof jalview.schemes.UserColourScheme) + if (colourScheme instanceof jalview.schemes.UserColourScheme) { - jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms)); + jGroup.setColour(setUserColourScheme(colourScheme, + userColours, jms)); } else { - jGroup.setColour(sg.cs.getSchemeName()); + jGroup.setColour(colourScheme.getSchemeName()); } } - else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient) + else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient) { jGroup.setColour("AnnotationColourGradient"); jGroup.setAnnotationColours(constructAnnotationColours( - (jalview.schemes.AnnotationColourGradient) sg.cs, + (jalview.schemes.AnnotationColourGradient) colourScheme, userColours, jms)); } - else if (sg.cs instanceof jalview.schemes.UserColourScheme) + else if (colourScheme instanceof jalview.schemes.UserColourScheme) { - jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms)); + jGroup.setColour(setUserColourScheme(colourScheme, + userColours, jms)); } else { - jGroup.setColour(sg.cs.getSchemeName()); + jGroup.setColour(colourScheme.getSchemeName()); } - jGroup.setPidThreshold(sg.cs.getThreshold()); + jGroup.setPidThreshold(groupColourScheme.getThreshold()); } jGroup.setOutlineColour(sg.getOutlineColour().getRGB()); @@ -1288,23 +1294,20 @@ public class Jalview2XML .getGlobalColourScheme())); } + CollectionColourSchemeI vcs = av.getViewportColourScheme(); ColourSchemeI cs = av.getGlobalColourScheme(); if (cs != null) { - if (cs.conservationApplied()) + if (vcs.conservationApplied()) { - view.setConsThreshold(cs.getConservationInc()); + view.setConsThreshold(vcs.getConservationInc()); if (cs instanceof jalview.schemes.UserColourScheme) { view.setBgColour(setUserColourScheme(cs, userColours, jms)); } } - - if (cs instanceof ResidueColourScheme) - { - view.setPidThreshold(cs.getThreshold()); - } + view.setPidThreshold(vcs.getThreshold()); } view.setConservationSelected(av.getConservationSelected()); @@ -3340,19 +3343,13 @@ public class Jalview2XML && jGroup.getAnnotationColours() != null) { addAnnotSchemeGroup = true; - cs = null; } else { cs = ColourSchemeProperty.getColourScheme(al, jGroup.getColour()); } - - if (cs != null) - { - cs.setThreshold(jGroup.getPidThreshold(), true); - cs.setConservationInc(jGroup.getConsThreshold()); - } } + int pidThreshold = jGroup.getPidThreshold(); Vector seqs = new Vector(); @@ -3375,7 +3372,8 @@ public class Jalview2XML SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs, jGroup.getDisplayBoxes(), jGroup.getDisplayText(), jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd()); - + sg.getGroupColourScheme().setThreshold(pidThreshold, true); + sg.getGroupColourScheme().setConservationInc(jGroup.getConsThreshold()); sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour())); sg.textColour = new java.awt.Color(jGroup.getTextCol1()); @@ -3441,8 +3439,8 @@ public class Jalview2XML if (addAnnotSchemeGroup) { // reconstruct the annotation colourscheme - sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(), - null, al, jms, false); + sg.setColourScheme(constructAnnotationColour( + jGroup.getAnnotationColours(), null, al, jms, false)); } } } @@ -4473,19 +4471,19 @@ public class Jalview2XML { cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour()); } - - if (cs != null) - { - cs.setConsensus(af.viewport.getSequenceConsensusHash()); - } } af.viewport.setGlobalColourScheme(cs); + af.viewport.getViewportColourScheme().setThreshold( + view.getPidThreshold(), true); + af.viewport.getViewportColourScheme().setConsensus( + af.viewport.getSequenceConsensusHash()); af.viewport.setColourAppliesToAllGroups(false); if (view.getConservationSelected() && cs != null) { - cs.setConservationInc(view.getConsThreshold()); + af.viewport.getViewportColourScheme().setConservationInc( + view.getConsThreshold()); } af.changeColour(cs); @@ -4706,7 +4704,7 @@ public class Jalview2XML propagateAnnColour = true; for (jalview.datamodel.SequenceGroup sg : al.getGroups()) { - if (sg.cs instanceof AnnotationColourGradient) + if (sg.getColourScheme() instanceof AnnotationColourGradient) { propagateAnnColour = false; } @@ -4787,9 +4785,10 @@ public class Jalview2XML * viewAnnColour.getAboveThreshold()); } else */ { - sg.cs = new AnnotationColourGradient( - annAlignment.getAlignmentAnnotation()[i], sg.cs, - viewAnnColour.getAboveThreshold()); + sg.setColourScheme(new AnnotationColourGradient( + annAlignment.getAlignmentAnnotation()[i], sg + .getColourScheme(), viewAnnColour + .getAboveThreshold())); if (cs instanceof AnnotationColourGradient) { if (viewAnnColour.hasPerSequence()) diff --git a/src/jalview/gui/Jalview2XML_V1.java b/src/jalview/gui/Jalview2XML_V1.java index aefc233..7472877 100755 --- a/src/jalview/gui/Jalview2XML_V1.java +++ b/src/jalview/gui/Jalview2XML_V1.java @@ -52,8 +52,6 @@ import java.util.Vector; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; -import javax.swing.JOptionPane; - /** * DOCUMENT ME! * @@ -335,13 +333,8 @@ public class Jalview2XML_V1 { cs = ColourSchemeProperty.getColourScheme(al, groups[i].getColour()); } - - if (cs != null) - { - cs.setThreshold(groups[i].getPidThreshold(), true); - } - } + int pidThreshold = groups[i].getPidThreshold(); Vector seqs = new Vector(); int[] ids = groups[i].getSeq(); @@ -355,6 +348,7 @@ public class Jalview2XML_V1 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(), groups[i].getDisplayText(), groups[i].getColourText(), groups[i].getStart(), groups[i].getEnd()); + sg.getGroupColourScheme().setThreshold(pidThreshold, true); sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour())); @@ -404,20 +398,24 @@ public class Jalview2XML_V1 cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour()); } - if (cs != null) - { - cs.setThreshold(view.getPidThreshold(), true); - cs.setConsensus(af.viewport.getSequenceConsensusHash()); - } + // if (cs != null) + // { + // cs.setThreshold(view.getPidThreshold(), true); + // cs.setConsensus(af.viewport.getSequenceConsensusHash()); + // } } - af.viewport.setGlobalColourScheme(cs); + af.viewport.getViewportColourScheme().setThreshold( + view.getPidThreshold(), true); + af.viewport.getViewportColourScheme().setConsensus( + af.viewport.getSequenceConsensusHash()); af.viewport.setColourAppliesToAllGroups(false); af.alignPanel.updateLayout(); af.changeColour(cs); if (view.getConservationSelected() && cs != null) { - cs.setConservationInc(view.getConsThreshold()); + af.viewport.getViewportColourScheme().setConservationInc( + view.getConsThreshold()); } af.viewport.setColourAppliesToAllGroups(true); diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 310266e..37cd8b3 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -45,6 +45,7 @@ import jalview.io.FormatAdapter; import jalview.io.SequenceAnnotationReport; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueColourScheme; @@ -425,7 +426,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener groupName.setText(MessageManager .getString("label.edit_name_and_description_current_group")); - ColourMenuHelper.setColourSelected(colourMenu, sg.cs); + ColourMenuHelper.setColourSelected(colourMenu, sg.getColourScheme()); if (sg.cs != null) { @@ -1260,7 +1261,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener @Override public void actionPerformed(ActionEvent e) { - abovePIDColour_actionPerformed(); + abovePIDColour_actionPerformed(abovePIDColour.isSelected()); } }); @@ -1282,7 +1283,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener @Override public void actionPerformed(ActionEvent e) { - conservationMenuItem_actionPerformed(); + conservationMenuItem_actionPerformed(conservationMenuItem + .isSelected()); } }); @@ -1527,10 +1529,12 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener /** * DOCUMENT ME! * + * @param selected + * * @param e * DOCUMENT ME! */ - protected void abovePIDColour_actionPerformed() + protected void abovePIDColour_actionPerformed(boolean selected) { SequenceGroup sg = getGroup(); if (sg.cs == null) @@ -1538,14 +1542,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener return; } - boolean selected = abovePIDColour.isSelected(); if (selected) { sg.cs.setConsensus(AAFrequency.calculate( sg.getSequences(ap.av.getHiddenRepSequences()), sg.getStartRes(), sg.getEndRes() + 1)); - int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup() + int threshold = SliderPanel.setPIDSliderSource(ap, + sg.getGroupColourScheme(), getGroup() .getName()); sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus()); @@ -1581,7 +1585,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener * @param e * DOCUMENT ME! */ - protected void conservationMenuItem_actionPerformed() + protected void conservationMenuItem_actionPerformed(boolean selected) { SequenceGroup sg = getGroup(); if (sg.cs == null) @@ -1589,7 +1593,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener return; } - boolean selected = conservationMenuItem.isSelected(); if (selected) { // JBPNote: Conservation name shouldn't be i18n translated @@ -1599,10 +1602,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener c.calculate(); c.verdict(false, ap.av.getConsPercGaps()); - sg.cs.setConservation(c); - SliderPanel.setConservationSlider(ap, sg.cs, sg.getName()); + SliderPanel.setConservationSlider(ap, sg.getGroupColourScheme(), + sg.getName()); SliderPanel.showConservationSlider(); } else @@ -1629,7 +1632,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener AnnotationColourGradient.NO_THRESHOLD); acg.setPredefinedColours(true); - sg.cs = acg; + sg.setColourScheme(acg); refresh(); } @@ -1997,6 +2000,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener /** * Action on user selecting an item from the colour menu (that does not have * its bespoke action handler) + * + * @return */ @Override public void changeColour_actionPerformed(String colourSchemeName) @@ -2014,10 +2019,11 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener /* * switch to the chosen colour scheme (or null for None) */ - sg.cs = ColourSchemes.getInstance().getColourScheme(colourSchemeName, - sg, ap.av.getHiddenRepSequences()); - if (sg.cs instanceof Blosum62ColourScheme - || sg.cs instanceof PIDColourScheme) + ColourSchemeI colourScheme = ColourSchemes.getInstance().getColourScheme( + colourSchemeName, sg, ap.av.getHiddenRepSequences()); + sg.setColourScheme(colourScheme); + if (colourScheme instanceof Blosum62ColourScheme + || colourScheme instanceof PIDColourScheme) { sg.cs.setConsensus(AAFrequency.calculate( sg.getSequences(ap.av.getHiddenRepSequences()), diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 4fdb25a..47b0694 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -35,6 +35,7 @@ import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.io.SequenceAnnotationReport; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ResidueProperties; import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; @@ -1654,13 +1655,13 @@ public class SeqPanel extends JPanel implements MouseListener, if (av.getConservationSelected()) { - SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(), + SliderPanel.setConservationSlider(ap, av.getViewportColourScheme(), "Background"); } if (av.getAbovePIDThreshold()) { - SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(), + SliderPanel.setPIDSliderSource(ap, av.getViewportColourScheme(), "Background"); } if ((stretchGroup != null) && (stretchGroup.getEndRes() == res)) @@ -1732,15 +1733,15 @@ public class SeqPanel extends JPanel implements MouseListener, stretchGroup.cs.alignmentChanged(stretchGroup, av.getHiddenRepSequences()); + CollectionColourSchemeI groupColourScheme = stretchGroup.getGroupColourScheme(); + String name = stretchGroup.getName(); if (stretchGroup.cs.conservationApplied()) { - SliderPanel.setConservationSlider(ap, stretchGroup.cs, - stretchGroup.getName()); + SliderPanel.setConservationSlider(ap, groupColourScheme, name); } if (stretchGroup.cs.getThreshold() > 0) { - SliderPanel.setPIDSliderSource(ap, stretchGroup.cs, - stretchGroup.getName()); + SliderPanel.setPIDSliderSource(ap, groupColourScheme, name); } } PaintRefresher.Refresh(this, av.getSequenceSetId()); diff --git a/src/jalview/gui/SequenceRenderer.java b/src/jalview/gui/SequenceRenderer.java index 64fe053..311439a 100755 --- a/src/jalview/gui/SequenceRenderer.java +++ b/src/jalview/gui/SequenceRenderer.java @@ -23,7 +23,8 @@ package jalview.gui; import jalview.api.FeatureRenderer; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourSchemeI; +import jalview.util.Comparison; import java.awt.Color; import java.awt.FontMetrics; @@ -92,12 +93,12 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (currentSequenceGroup.getDisplayBoxes()) { - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i); } } else if (av.getShowBoxes()) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); } return resBoxColour; @@ -131,21 +132,22 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer /** * DOCUMENT ME! * - * @param cs + * @param collectionColourSchemeI * DOCUMENT ME! * @param seq * DOCUMENT ME! * @param i * DOCUMENT ME! */ - void getBoxColour(ColourSchemeI cs, SequenceI seq, int i) + void getBoxColour(CollectionColourSchemeI collectionColourSchemeI, + SequenceI seq, int i) { - if (cs != null) + if (collectionColourSchemeI != null) { - resBoxColour = cs.findColour(seq.getCharAt(i), i, seq); + resBoxColour = collectionColourSchemeI.findColour(seq.getCharAt(i), + i, seq); } - else if (forOverview - && !jalview.util.Comparison.isGap(seq.getCharAt(i))) + else if (forOverview && !Comparison.isGap(seq.getCharAt(i))) { resBoxColour = Color.lightGray; } @@ -234,14 +236,14 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (currentSequenceGroup.getDisplayBoxes()) { - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, + i); } } else if (av.getShowBoxes()) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); } - } if (resBoxColour != tempColour) @@ -345,7 +347,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer || currentSequenceGroup.getColourText()) { getboxColour = true; - getBoxColour(currentSequenceGroup.cs, seq, i); + getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, + i); if (currentSequenceGroup.getColourText()) { @@ -385,7 +388,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer if (av.getColourText()) { getboxColour = true; - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); if (av.getShowBoxes()) { @@ -401,7 +404,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (!getboxColour) { - getBoxColour(av.getGlobalColourScheme(), seq, i); + getBoxColour(av.getViewportColourScheme(), seq, i); } if (resBoxColour.getRed() + resBoxColour.getBlue() diff --git a/src/jalview/gui/SliderPanel.java b/src/jalview/gui/SliderPanel.java index 62ee954..40f86b8 100755 --- a/src/jalview/gui/SliderPanel.java +++ b/src/jalview/gui/SliderPanel.java @@ -22,13 +22,12 @@ package jalview.gui; import jalview.datamodel.SequenceGroup; import jalview.jbgui.GSliderPanel; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourSchemeI; import jalview.util.MessageManager; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyVetoException; -import java.util.Iterator; import javax.swing.JInternalFrame; import javax.swing.JLayeredPane; @@ -53,7 +52,19 @@ public class SliderPanel extends GSliderPanel boolean forConservation = true; - ColourSchemeI cs; + CollectionColourSchemeI cs; + + private static SliderPanel sliderPanel; + + /** + * Returns the currently active slider panel (or null if none). + * + * @return + */ + public static SliderPanel getSliderPanel() + { + return sliderPanel; + } /** * Creates a new SliderPanel object. @@ -64,14 +75,14 @@ public class SliderPanel extends GSliderPanel * DOCUMENT ME! * @param forConserve * DOCUMENT ME! - * @param cs + * @param scheme * DOCUMENT ME! */ public SliderPanel(final AlignmentPanel ap, int value, - boolean forConserve, ColourSchemeI cs) + boolean forConserve, CollectionColourSchemeI scheme) { this.ap = ap; - this.cs = cs; + this.cs = scheme; forConservation = forConserve; undoButton.setVisible(false); applyButton.setVisible(false); @@ -119,7 +130,7 @@ public class SliderPanel extends GSliderPanel * * @param ap * DOCUMENT ME! - * @param cs + * @param ccs * DOCUMENT ME! * @param source * DOCUMENT ME! @@ -127,22 +138,22 @@ public class SliderPanel extends GSliderPanel * @return DOCUMENT ME! */ public static int setConservationSlider(AlignmentPanel ap, - ColourSchemeI cs, String source) + CollectionColourSchemeI ccs, String source) { - SliderPanel sp = null; + sliderPanel = null; if (conservationSlider == null) { - sp = new SliderPanel(ap, cs.getConservationInc(), true, cs); + sliderPanel = new SliderPanel(ap, ccs.getConservationInc(), true, ccs); conservationSlider = new JInternalFrame(); - conservationSlider.setContentPane(sp); + conservationSlider.setContentPane(sliderPanel); conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER); } else { - sp = (SliderPanel) conservationSlider.getContentPane(); - sp.valueField.setText(String.valueOf(cs.getConservationInc())); - sp.cs = cs; + sliderPanel = (SliderPanel) conservationSlider.getContentPane(); + sliderPanel.valueField.setText(String.valueOf(ccs.getConservationInc())); + sliderPanel.cs = ccs; } conservationSlider @@ -152,14 +163,14 @@ public class SliderPanel extends GSliderPanel if (ap.av.getAlignment().getGroups() != null) { - sp.setAllGroupsCheckEnabled(true); + sliderPanel.setAllGroupsCheckEnabled(true); } else { - sp.setAllGroupsCheckEnabled(false); + sliderPanel.setAllGroupsCheckEnabled(false); } - return sp.getValue(); + return sliderPanel.getValue(); } /** @@ -225,32 +236,30 @@ public class SliderPanel extends GSliderPanel * * @param ap * DOCUMENT ME! - * @param cs + * @param ccs * DOCUMENT ME! * @param source * DOCUMENT ME! * * @return DOCUMENT ME! */ - public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs, - String source) + public static int setPIDSliderSource(AlignmentPanel ap, + CollectionColourSchemeI ccs, String source) { - SliderPanel pid = null; - - int threshold = cs.getThreshold(); + int threshold = ccs.getThreshold(); if (PIDSlider == null) { - pid = new SliderPanel(ap, threshold, false, cs); + sliderPanel = new SliderPanel(ap, threshold, false, ccs); PIDSlider = new JInternalFrame(); - PIDSlider.setContentPane(pid); + PIDSlider.setContentPane(sliderPanel); PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER); } else { - pid = (SliderPanel) PIDSlider.getContentPane(); - pid.valueField.setText(String.valueOf(cs.getThreshold())); - pid.cs = cs; + sliderPanel = (SliderPanel) PIDSlider.getContentPane(); + sliderPanel.cs = ccs; + sliderPanel.valueField.setText(String.valueOf(ccs.getThreshold())); } PIDSlider @@ -260,20 +269,22 @@ public class SliderPanel extends GSliderPanel if (ap.av.getAlignment().getGroups() != null) { - pid.setAllGroupsCheckEnabled(true); + sliderPanel.setAllGroupsCheckEnabled(true); } else { - pid.setAllGroupsCheckEnabled(false); + sliderPanel.setAllGroupsCheckEnabled(false); } - return pid.getValue(); + return sliderPanel.getValue(); } /** * DOCUMENT ME! + * + * @return */ - public static void showPIDSlider() + public static JInternalFrame showPIDSlider() { hideConservationSlider(); @@ -292,50 +303,29 @@ public class SliderPanel extends GSliderPanel }); PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER); } + return PIDSlider; } /** - * DOCUMENT ME! + * Updates the colour scheme with the current (identity threshold or + * conservation) percentage value. Also updates all groups if 'apply to all + * groups' is selected. * - * @param i - * DOCUMENT ME! + * @param percent */ - public void valueChanged(int i) + public void valueChanged(int percent) { - if (cs == null) + if (!forConservation) { - return; + ap.av.setThreshold(percent); } - - ColourSchemeI toChange = cs; - Iterator allGroups = null; + updateColourScheme(percent, cs); if (allGroupsCheck.isSelected()) { - allGroups = ap.av.getAlignment().getGroups().listIterator(); - } - - while (toChange != null) - { - if (forConservation) - { - toChange.setConservationInc(i); - } - else + for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus()); - } - if (allGroups != null && allGroups.hasNext()) - { - while ((toChange = allGroups.next().cs) == null - && allGroups.hasNext()) - { - ; - } - } - else - { - toChange = null; + updateColourScheme(percent, sg.getGroupColourScheme()); } } @@ -343,6 +333,29 @@ public class SliderPanel extends GSliderPanel } /** + * Updates the colour scheme (if not null) with the current (identity + * threshold or conservation) percentage value + * + * @param percent + * @param scheme + */ + protected void updateColourScheme(int percent, CollectionColourSchemeI scheme) + { + if (scheme == null) + { + return; + } + if (forConservation) + { + scheme.setConservationInc(percent); + } + else + { + scheme.setThreshold(percent, ap.av.isIgnoreGapsConsensus()); + } + } + + /** * DOCUMENT ME! * * @param b @@ -356,6 +369,25 @@ public class SliderPanel extends GSliderPanel /** * DOCUMENT ME! * + * @param e + * DOCUMENT ME! + */ + @Override + public void valueField_actionPerformed() + { + try + { + int i = Integer.parseInt(valueField.getText()); + slider.setValue(i); + } catch (NumberFormatException ex) + { + valueField.setText(slider.getValue() + ""); + } + } + + /** + * DOCUMENT ME! + * * @param value * DOCUMENT ME! */ @@ -383,4 +415,53 @@ public class SliderPanel extends GSliderPanel } } + public static int getConservationValue() + { + return getValue(conservationSlider); + } + + static int getValue(JInternalFrame slider) + { + return slider == null ? 0 : ((SliderPanel) slider.getContentPane()) + .getValue(); + } + + public static int getPIDValue() + { + return getValue(PIDSlider); + } + + /** + * Answers true if the SliderPanel is for Conservation, false if it is for PID + * threshold + * + * @return + */ + public boolean isForConservation() + { + return forConservation; + } + + /** + * Answers the title for the slider panel; this may include 'Background' if + * for the alignment, or the group id if for a group + * + * @return + */ + public String getTitle() + { + String title = null; + if (isForConservation()) + { + if (conservationSlider != null) + { + title = conservationSlider.getTitle(); + } + } + else if (PIDSlider != null) + { + title = PIDSlider.getTitle(); + } + return title; + } } diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index 8ad5699..9fa98ee 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -1002,13 +1002,16 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, .getGlobalColourScheme())); } // cs is null if shading is an annotationColourGradient - if (cs != null) - { - cs.setThreshold(av.getGlobalColourScheme().getThreshold(), - av.isIgnoreGapsConsensus()); - } + // if (cs != null) + // { + // cs.setThreshold(av.getViewportColourScheme().getThreshold(), + // av.isIgnoreGapsConsensus()); + // } } - sg.cs = cs; + sg.setColourScheme(cs); + sg.getGroupColourScheme().setThreshold( + av.getViewportColourScheme().getThreshold(), + av.isIgnoreGapsConsensus()); // sg.recalcConservation(); sg.setName("JTreeGroup:" + sg.hashCode()); sg.setIdColour(col); @@ -1016,7 +1019,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, for (int a = 0; a < aps.length; a++) { if (aps[a].av.getGlobalColourScheme() != null - && aps[a].av.getGlobalColourScheme().conservationApplied()) + && aps[a].av.getViewportColourScheme() + .conservationApplied()) { Conservation c = new Conservation("Group", sg.getSequences(null), sg.getStartRes(), sg.getEndRes()); diff --git a/src/jalview/gui/UserDefinedColours.java b/src/jalview/gui/UserDefinedColours.java index 5314c5c..7a5c1f1 100755 --- a/src/jalview/gui/UserDefinedColours.java +++ b/src/jalview/gui/UserDefinedColours.java @@ -110,7 +110,7 @@ public class UserDefinedColours extends GUserDefinedColours implements if (seqGroup != null) { - oldColourScheme = seqGroup.cs; + oldColourScheme = seqGroup.getColourScheme(); } else { @@ -437,7 +437,8 @@ public class UserDefinedColours extends GUserDefinedColours implements col = Color.white; if (oldColourScheme != null && oldColourScheme.isSimple()) { - col = oldColourScheme.findColour(residue.charAt(0)); + col = oldColourScheme.findColour(residue.charAt(0), 0, null, null, + 0f); } } @@ -523,7 +524,7 @@ public class UserDefinedColours extends GUserDefinedColours implements if (seqGroup != null) { - seqGroup.cs = ucs; + seqGroup.setColourScheme(ucs); ap.paintAlignment(true); } else if (ap != null) @@ -587,10 +588,10 @@ public class UserDefinedColours extends GUserDefinedColours implements ucs.setLowerCaseColours(newColours); } - if (ap != null) - { - ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); - } + // if (ap != null) + // { + // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); + // } return ucs; } @@ -822,7 +823,7 @@ public class UserDefinedColours extends GUserDefinedColours implements { if (seqGroup != null) { - seqGroup.cs = oldColourScheme; + seqGroup.setColourScheme(oldColourScheme); } else { diff --git a/src/jalview/io/AnnotationFile.java b/src/jalview/io/AnnotationFile.java index ae34f6b..9a4071d 100755 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@ -1609,8 +1609,7 @@ public class AnnotationFile if (sg != null) { String keyValue, key, value; - ColourSchemeI def = sg.cs; - sg.cs = null; + ColourSchemeI def = sg.getColourScheme(); while (st.hasMoreTokens()) { keyValue = st.nextToken(); @@ -1623,7 +1622,8 @@ public class AnnotationFile } else if (key.equalsIgnoreCase("colour")) { - sg.cs = ColourSchemeProperty.getColourScheme(al, value); + sg.cs.setColourScheme(ColourSchemeProperty + .getColourScheme(al, value)); } else if (key.equalsIgnoreCase("pidThreshold")) { @@ -1691,9 +1691,9 @@ public class AnnotationFile } sg.recalcConservation(); } - if (sg.cs == null) + if (sg.getColourScheme() == null) { - sg.cs = def; + sg.setColourScheme(def); } } } diff --git a/src/jalview/io/JSONFile.java b/src/jalview/io/JSONFile.java index bdd2dcb..27ebe5a 100644 --- a/src/jalview/io/JSONFile.java +++ b/src/jalview/io/JSONFile.java @@ -239,7 +239,8 @@ public class JSONFile extends AlignFile implements ComplexAlignFile { SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo(); seqGrpPojo.setGroupName(seqGrp.getName()); - seqGrpPojo.setColourScheme(seqGrp.cs.getSchemeName()); + seqGrpPojo.setColourScheme(seqGrp.getColourScheme() + .getSchemeName()); seqGrpPojo.setColourText(seqGrp.getColourText()); seqGrpPojo.setDescription(seqGrp.getDescription()); seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes()); @@ -527,8 +528,8 @@ public class JSONFile extends AlignFile implements ComplexAlignFile } SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName, null, displayBoxes, displayText, colourText, startRes, endRes); - seqGrp.cs = ColourSchemeMapper.getJalviewColourScheme(colourScheme, - seqGrp); + seqGrp.setColourScheme(ColourSchemeMapper.getJalviewColourScheme( + colourScheme, seqGrp)); seqGrp.setShowNonconserved(showNonconserved); seqGrp.setDescription(description); this.seqGroups.add(seqGrp); diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index c8aa94f..b39f4a8 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -752,17 +752,6 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, redoMenuItem, al); - conservationMenuItem.setText(MessageManager - .getString("action.by_conservation")); - conservationMenuItem.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - conservationMenuItem_actionPerformed(); - } - }); - wrapMenuItem.setText(MessageManager.getString("label.wrap")); wrapMenuItem.addActionListener(new ActionListener() { @@ -815,17 +804,6 @@ public class GAlignFrame extends JInternalFrame }; addMenuActionAndAccelerator(keyStroke, findMenuItem, al); - abovePIDThreshold.setText(MessageManager - .getString("label.above_identity_threshold")); - abovePIDThreshold.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - abovePIDThreshold_actionPerformed(); - } - }); - showSeqFeatures.setText(MessageManager .getString("label.show_sequence_features")); showSeqFeatures.addActionListener(new ActionListener() @@ -1217,27 +1195,6 @@ public class GAlignFrame extends JInternalFrame }); - modifyPID = new JMenuItem( - MessageManager.getString("label.modify_identity_threshold")); - modifyPID.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyPID_actionPerformed(); - } - }); - modifyConservation.setText(MessageManager - .getString("label.modify_conservation_threshold")); - modifyConservation.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyConservation_actionPerformed(); - } - }); - sortByTreeMenu .setText(MessageManager.getString("action.by_tree_order")); sort.setText(MessageManager.getString("action.sort")); @@ -1960,7 +1917,7 @@ public class GAlignFrame extends JInternalFrame @Override public void actionPerformed(ActionEvent e) { - applyToAllGroups_actionPerformed(); + applyToAllGroups_actionPerformed(applyToAllGroups.isSelected()); } }); @@ -1982,7 +1939,8 @@ public class GAlignFrame extends JInternalFrame @Override public void actionPerformed(ActionEvent e) { - conservationMenuItem_actionPerformed(); + conservationMenuItem_actionPerformed(conservationMenuItem + .isSelected()); } }); @@ -1993,7 +1951,7 @@ public class GAlignFrame extends JInternalFrame @Override public void actionPerformed(ActionEvent e) { - abovePIDThreshold_actionPerformed(); + abovePIDThreshold_actionPerformed(abovePIDThreshold.isSelected()); } }); modifyPID = new JMenuItem( @@ -2385,7 +2343,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void conservationMenuItem_actionPerformed() + protected void conservationMenuItem_actionPerformed(boolean selected) { } @@ -2401,7 +2359,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void abovePIDThreshold_actionPerformed() + protected void abovePIDThreshold_actionPerformed(boolean selected) { } @@ -2441,7 +2399,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void applyToAllGroups_actionPerformed() + protected void applyToAllGroups_actionPerformed(boolean selected) { } diff --git a/src/jalview/renderer/AnnotationRenderer.java b/src/jalview/renderer/AnnotationRenderer.java index a0e530c..5973710 100644 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@ -29,8 +29,12 @@ import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; import jalview.datamodel.ColumnSelection; import jalview.datamodel.ProfilesI; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; +import jalview.schemes.NucleotideColourScheme; import jalview.schemes.ResidueProperties; +import jalview.schemes.ZappoColourScheme; import jalview.util.Platform; import java.awt.BasicStroke; @@ -70,7 +74,7 @@ public class AnnotationRenderer boolean av_renderHistogram = true, av_renderProfile = true, av_normaliseProfile = false; - ColourSchemeI profcolour = null; + CollectionColourSchemeI profcolour = null; private ColumnSelection columnSelection; @@ -312,13 +316,17 @@ public class AnnotationRenderer av_renderHistogram = av.isShowConsensusHistogram(); av_renderProfile = av.isShowSequenceLogo(); av_normaliseProfile = av.isNormaliseSequenceLogo(); - profcolour = av.getGlobalColourScheme(); - if (profcolour == null) + profcolour = av.getViewportColourScheme(); + 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 CollectionColourScheme(col); } columnSelection = av.getColumnSelection(); hconsensus = av.getSequenceConsensusHash(); diff --git a/src/jalview/schemes/AnnotationColourGradient.java b/src/jalview/schemes/AnnotationColourGradient.java index fb1443d..1a3e9ef 100755 --- a/src/jalview/schemes/AnnotationColourGradient.java +++ b/src/jalview/schemes/AnnotationColourGradient.java @@ -68,7 +68,7 @@ public class AnnotationColourGradient extends FollowerColourScheme Map hiddenRepSequences) { AnnotationColourGradient acg = new AnnotationColourGradient(annotation, - colourScheme, aboveAnnotationThreshold); + getColourScheme(), aboveAnnotationThreshold); acg.thresholdIsMinMax = thresholdIsMinMax; acg.annotationThreshold = (annotationThreshold == null) ? null : new GraphLine(annotationThreshold); @@ -92,11 +92,12 @@ public class AnnotationColourGradient extends FollowerColourScheme { if (originalColour instanceof AnnotationColourGradient) { - colourScheme = ((AnnotationColourGradient) originalColour).colourScheme; + setColourScheme(((AnnotationColourGradient) originalColour) + .getColourScheme()); } else { - colourScheme = originalColour; + setColourScheme(originalColour); } this.annotation = annotation; @@ -276,88 +277,89 @@ public class AnnotationColourGradient extends FollowerColourScheme { return currentColour; } - if ((threshold == 0) || aboveThreshold(c, j)) + // if ((threshold == 0) || aboveThreshold(c, j)) + // { + if (annotation.annotations != null && j < annotation.annotations.length + && annotation.annotations[j] != null + && !jalview.util.Comparison.isGap(c)) { - if (annotation.annotations != null - && j < annotation.annotations.length - && annotation.annotations[j] != null - && !jalview.util.Comparison.isGap(c)) + Annotation aj = annotation.annotations[j]; + // 'use original colours' => colourScheme != null + // -> look up colour to be used + // predefined colours => preconfigured shading + // -> only use original colours reference if thresholding enabled & + // minmax exists + // annotation.hasIcons => null or black colours replaced with glyph + // colours + // -> reuse original colours if present + // -> if thresholding enabled then return colour on non-whitespace glyph + + if (aboveAnnotationThreshold == NO_THRESHOLD + || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value + : aj.value <= annotationThreshold.value))) { - Annotation aj = annotation.annotations[j]; - // 'use original colours' => colourScheme != null - // -> look up colour to be used - // predefined colours => preconfigured shading - // -> only use original colours reference if thresholding enabled & - // minmax exists - // annotation.hasIcons => null or black colours replaced with glyph - // colours - // -> reuse original colours if present - // -> if thresholding enabled then return colour on non-whitespace glyph - - if (aboveAnnotationThreshold == NO_THRESHOLD - || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value - : aj.value <= annotationThreshold.value))) + if (predefinedColours && aj.colour != null + && !aj.colour.equals(Color.black)) { - if (predefinedColours && aj.colour != null - && !aj.colour.equals(Color.black)) - { - currentColour = aj.colour; - } - else if (annotation.hasIcons - && annotation.graph == AlignmentAnnotation.NO_GRAPH) + currentColour = aj.colour; + } + else if (annotation.hasIcons + && annotation.graph == AlignmentAnnotation.NO_GRAPH) + { + if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.' + && aj.secondaryStructure != '-') { - if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.' - && aj.secondaryStructure != '-') + if (getColourScheme() != null) + { + currentColour = getColourScheme().findColour(c, j, seq, null, + 0f); + } + else { - if (colourScheme != null) + if (annotation.isRNA()) { - currentColour = colourScheme.findColour(c, j, seq); + currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value]; } else { - if (annotation.isRNA()) - { - currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value]; - } - else - { - currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR - : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR - : jalview.renderer.AnnotationRenderer.STEM_COLOUR; - } + currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR + : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR + : jalview.renderer.AnnotationRenderer.STEM_COLOUR; } } - else - { - // - return Color.white; - } } - else if (noGradient) + else { - if (colourScheme != null) - { - currentColour = colourScheme.findColour(c, j, seq); - } - else - { - if (aj.colour != null) - { - currentColour = aj.colour; - } - } + // + return Color.white; + } + } + else if (noGradient) + { + if (getColourScheme() != null) + { + currentColour = getColourScheme().findColour(c, j, seq, null, + 0f); } else { - currentColour = shadeCalculation(annotation, j); + if (aj.colour != null) + { + currentColour = aj.colour; + } } } - if (conservationColouring) + else { - currentColour = applyConservation(currentColour, j); + currentColour = shadeCalculation(annotation, j); } } + // if (conservationColouring) + // { + // currentColour = applyConservation(currentColour, j); + // } } + // } return currentColour; } diff --git a/src/jalview/schemes/Blosum62ColourScheme.java b/src/jalview/schemes/Blosum62ColourScheme.java index be77e00..53670e3 100755 --- a/src/jalview/schemes/Blosum62ColourScheme.java +++ b/src/jalview/schemes/Blosum62ColourScheme.java @@ -50,65 +50,49 @@ public class Blosum62ColourScheme extends ResidueColourScheme } @Override - public Color findColour(char res, int j, SequenceI seq) + public Color findColour(char res, int j, SequenceI seq, + String consensusResidue, float pid) { + /* + * compare as upper case; note toUpperCase does nothing + * if the string is already uppercase + */ + consensusResidue = consensusResidue.toUpperCase(); if ('a' <= res && res <= 'z') { - // TO UPPERCASE !!! res -= ('a' - 'A'); } - if (consensus == null || consensus.get(j) == null - || (threshold != 0 && !aboveThreshold(res, j))) + if (Comparison.isGap(res) || consensusResidue == null) { return Color.white; } - Color currentColour; + Color colour; - if (!Comparison.isGap(res)) + if (consensusResidue.indexOf(res) > -1) { - /* - * test if this is the consensus (or joint consensus) residue - */ - String max = consensus.get(j).getModalResidue(); + colour = DARK_BLUE; + } + else + { + int c = 0; - if (max.indexOf(res) > -1) + for (char consensus : consensusResidue.toCharArray()) { - currentColour = DARK_BLUE; + c += ResidueProperties.getBLOSUM62(consensus, res); } - else - { - int c = 0; - int max_aa = 0; - int n = max.length(); - - do - { - c += ResidueProperties.getBLOSUM62(max.charAt(max_aa), res); - } while (++max_aa < n); - if (c > 0) - { - currentColour = LIGHT_BLUE; - } - else - { - currentColour = Color.white; - } + if (c > 0) + { + colour = LIGHT_BLUE; } - - if (conservationColouring) + else { - currentColour = applyConservation(currentColour, j); + colour = Color.white; } } - else - { - return Color.white; - } - - return currentColour; + return colour; } @Override diff --git a/src/jalview/schemes/ClustalxColourScheme.java b/src/jalview/schemes/ClustalxColourScheme.java index 9c0b953..3c9f095 100755 --- a/src/jalview/schemes/ClustalxColourScheme.java +++ b/src/jalview/schemes/ClustalxColourScheme.java @@ -23,6 +23,7 @@ package jalview.schemes; import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; +import jalview.util.Comparison; import java.awt.Color; import java.util.List; @@ -276,23 +277,22 @@ public class ClustalxColourScheme extends ResidueColourScheme } @Override - public Color findColour(char c, int j, SequenceI seq) + protected Color findColour(char c, int j, SequenceI seq) { - Color currentColour; - - if (cons2.length <= j - || (includeGaps && threshold != 0 && !aboveThreshold(c, j))) + // TODO why the test for includeGaps here? + if (cons2.length <= j || Comparison.isGap(c) + /*|| (includeGaps && threshold != 0 && !aboveThreshold(c, j))*/) { return Color.white; } int i = ResidueProperties.aaIndex[c]; - currentColour = Color.white; + Color colour = Color.white; if (i > 19) { - return currentColour; + return colour; } for (int k = 0; k < residueColour[i].cons.length; k++) @@ -300,7 +300,7 @@ public class ClustalxColourScheme extends ResidueColourScheme if (residueColour[i].cons[k].isConserved(cons2, j, size, includeGaps)) { - currentColour = residueColour[i].c; + colour = residueColour[i].c; } } @@ -311,16 +311,11 @@ public class ClustalxColourScheme extends ResidueColourScheme */ if (conses[27].isConserved(cons2, j, size, includeGaps)) { - currentColour = ClustalColour.PINK.colour; + colour = ClustalColour.PINK.colour; } } - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; + return colour; } /** diff --git a/src/jalview/schemes/CollectionColourScheme.java b/src/jalview/schemes/CollectionColourScheme.java new file mode 100644 index 0000000..a212795 --- /dev/null +++ b/src/jalview/schemes/CollectionColourScheme.java @@ -0,0 +1,333 @@ +package jalview.schemes; + +import jalview.analysis.Conservation; +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.ProfileI; +import jalview.datamodel.ProfilesI; +import jalview.datamodel.SequenceCollectionI; +import jalview.datamodel.SequenceI; +import jalview.util.ColorUtils; +import jalview.util.Comparison; + +import java.awt.Color; +import java.util.Map; + +/** + * A data bean that holds the information to determine the colour scheme of an + * alignment (or subgroup), consisting of + *
    + *
  • the colour scheme that determines the colour of a residue
  • + *
  • any threshold for colour, based on percentage identity with consensus
  • + *
  • any graduation based on consensus
  • + *
  • the consensus data
  • + *
+ * + * @author gmcarstairs + * + */ +public class CollectionColourScheme implements CollectionColourSchemeI +{ + private ColourSchemeI colourScheme; + + private ProfilesI consensus; + + private boolean conservationColouring; + + private char[] conservation; + + private int threshold; + + private boolean ignoreGaps; + + private int inc; + + public CollectionColourScheme(ColourSchemeI cs) + { + colourScheme = cs; + } + + /** + * Default constructor + */ + public CollectionColourScheme() + { + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setConsensus(jalview.datamodel.ProfilesI) + */ + @Override + public void setConsensus(ProfilesI cons) + { + consensus = cons; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#conservationApplied() + */ + @Override + public boolean conservationApplied() + { + return conservationColouring; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setConservationApplied(boolean) + */ + @Override + public void setConservationApplied(boolean conservationApplied) + { + conservationColouring = conservationApplied; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setConservation(jalview.analysis.Conservation) + */ + @Override + public void setConservation(Conservation cons) + { + if (cons == null) + { + conservationColouring = false; + conservation = null; + } + else + { + conservationColouring = true; + conservation = cons.getConsSequence().getSequenceAsString() + .toCharArray(); + } + + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#alignmentChanged(jalview.datamodel.AnnotatedCollectionI, + * java.util.Map) + */ + @Override + public void alignmentChanged(AnnotatedCollectionI alignment, + Map hiddenReps) + { + if (colourScheme != null) + { + colourScheme.alignmentChanged(alignment, hiddenReps); + } + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setThreshold(int, boolean) + */ + @Override + public void setThreshold(int consensusThreshold, boolean ignoreGaps) + { + threshold = consensusThreshold; + this.ignoreGaps = ignoreGaps; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setConservationInc(int) + */ + @Override + public void setConservationInc(int i) + { + inc = i; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#getConservationInc() + */ + @Override + public int getConservationInc() + { + return inc; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#getThreshold() + */ + @Override + public int getThreshold() + { + return threshold; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#findColour(char, int, + * jalview.datamodel.SequenceI) + */ + @Override + public Color findColour(char symbol, int position, SequenceI seq) + { + /* + * get 'base' colour + */ + ProfileI profile = consensus == null ? null : consensus.get(position); + String modalResidue = profile == null ? null : profile + .getModalResidue(); + float pid = profile == null ? 0f : profile + .getPercentageIdentity(ignoreGaps); + Color colour = colourScheme == null ? Color.white : colourScheme + .findColour(symbol, position, seq, modalResidue, pid); + + /* + * apply PID threshold and consensus fading if in force + */ + colour = adjustColour(symbol, position, colour); + + return colour; + } + + /** + * Adjusts colour by applying thresholding or conservation shading, if in + * force. That is + *
    + *
  • if there is a threshold set for colouring, and the residue doesn't + * match the consensus (or a joint consensus) residue, or the consensus score + * is not above the threshold, then the colour is set to white
  • + *
  • if conservation colouring is selected, the colour is faded by an amount + * depending on the conservation score for the column, and the conservation + * colour threshold
  • + *
+ * + * @param symbol + * @param column + * @param colour + * @return + */ + protected Color adjustColour(char symbol, int column, Color colour) + { + if (!aboveThreshold(symbol, column)) + { + colour = Color.white; + } + + if (conservationColouring) + { + colour = applyConservation(colour, column); + } + return colour; + } + + /** + * Answers true if there is a consensus profile for the specified column, and + * the given residue matches the consensus (or joint consensus) residue for + * the column, and the percentage identity for the profile is equal to or + * greater than the current threshold; else answers false. The percentage + * calculation depends on whether or not we are ignoring gapped sequences. + * + * @param residue + * @param column + * (index into consensus profiles) + * + * @return + * @see #setThreshold(int, boolean) + */ + protected boolean aboveThreshold(char residue, int column) + { + if (threshold == 0) + { + return true; + } + if ('a' <= residue && residue <= 'z') + { + // TO UPPERCASE !!! + // Faster than toUpperCase + residue -= ('a' - 'A'); + } + + if (consensus == null) + { + return false; + } + + ProfileI profile = consensus.get(column); + + /* + * test whether this is the consensus (or joint consensus) residue + */ + if (profile != null + && profile.getModalResidue().contains(String.valueOf(residue))) + { + if (profile.getPercentageIdentity(ignoreGaps) >= threshold) + { + return true; + } + } + + return false; + } + + /** + * Applies a combination of column conservation score, and conservation + * percentage slider, to 'bleach' out the residue colours towards white. + *

+ * If a column is fully conserved (identical residues, conservation score 11, + * shown as *), or all 10 physico-chemical properties are conserved + * (conservation score 10, shown as +), then the colour is left unchanged. + *

+ * Otherwise a 'bleaching' factor is computed and applied to the colour. This + * is designed to fade colours for scores of 0-9 completely to white at slider + * positions ranging from 18% - 100% respectively. + * + * @param currentColour + * @param column + * + * @return bleached (or unmodified) colour + */ + protected Color applyConservation(Color currentColour, int column) + { + if (conservation == null || conservation.length <= column) + { + return currentColour; + } + char conservationScore = conservation[column]; + + /* + * if residues are fully conserved (* or 11), or all properties + * are conserved (+ or 10), leave colour unchanged + */ + if (conservationScore == '*' || conservationScore == '+' + || conservationScore == (char) 10 + || conservationScore == (char) 11) + { + return currentColour; + } + + if (Comparison.isGap(conservationScore)) + { + return Color.white; + } + + /* + * convert score 0-9 to a bleaching factor 1.1 - 0.2 + */ + float bleachFactor = (11 - (conservationScore - '0')) / 10f; + + /* + * scale this up by 0-5 (percentage slider / 20) + * as a result, scores of: 0 1 2 3 4 5 6 7 8 9 + * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100% + */ + bleachFactor *= (inc / 20f); + + return ColorUtils.bleachColour(currentColour, bleachFactor); + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#getColourScheme() + */ + @Override + public ColourSchemeI getColourScheme() + { + return this.colourScheme; + } + + /** + * @see jalview.schemes.CollectionColourSchemeI#setColourScheme(jalview.schemes.ColourSchemeI) + */ + @Override + public void setColourScheme(ColourSchemeI cs) + { + colourScheme = cs; + } +} diff --git a/src/jalview/schemes/CollectionColourSchemeI.java b/src/jalview/schemes/CollectionColourSchemeI.java new file mode 100644 index 0000000..152b02a --- /dev/null +++ b/src/jalview/schemes/CollectionColourSchemeI.java @@ -0,0 +1,63 @@ +package jalview.schemes; + +import jalview.analysis.Conservation; +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.ProfilesI; +import jalview.datamodel.SequenceCollectionI; +import jalview.datamodel.SequenceI; + +import java.awt.Color; +import java.util.Map; + +public interface CollectionColourSchemeI +{ + + public abstract void setConsensus(ProfilesI cons); + + public abstract boolean conservationApplied(); + + public abstract void setConservationApplied(boolean conservationApplied); + + public abstract void setConservation(Conservation cons); + + public abstract void alignmentChanged(AnnotatedCollectionI alignment, + Map hiddenReps); + + /** + * Sets the percentage consensus threshold value, and whether gaps are ignored + * in percentage identity calculation + * + * @param consensusThreshold + * @param ignoreGaps + */ + public abstract void setThreshold(int consensusThreshold, + boolean ignoreGaps); + + public abstract void setConservationInc(int i); + + public abstract int getConservationInc(); + + /** + * Get the percentage threshold for this colour scheme + * + * @return Returns the percentage threshold + */ + public abstract int getThreshold(); + + /** + * Returns the possibly context dependent colour for the given symbol at the + * aligned position in the given sequence. For example, the colour may depend + * on the symbol's relationship to the consensus residue for the column. + * + * @param symbol + * @param position + * @param seq + * @return + */ + public abstract Color findColour(char symbol, int position, SequenceI seq); + + public abstract ColourSchemeI getColourScheme(); + + public abstract void setColourScheme(ColourSchemeI cs); + +} \ No newline at end of file diff --git a/src/jalview/schemes/ColourSchemeI.java b/src/jalview/schemes/ColourSchemeI.java index 64248c5..f16ca21 100755 --- a/src/jalview/schemes/ColourSchemeI.java +++ b/src/jalview/schemes/ColourSchemeI.java @@ -20,9 +20,7 @@ */ package jalview.schemes; -import jalview.analysis.Conservation; import jalview.datamodel.AnnotatedCollectionI; -import jalview.datamodel.ProfilesI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; @@ -32,15 +30,6 @@ import java.util.Map; public interface ColourSchemeI { /** - * Returns the colour for the given character. For use when the colour depends - * only on the symbol. - * - * @param c - * @return - */ - Color findColour(char c); - - /** * Returns the possibly context dependent colour for the given symbol at the * aligned position in the given sequence. For example, the colour may depend * on the symbol's relationship to the consensus residue for the column. @@ -48,67 +37,14 @@ public interface ColourSchemeI * @param symbol * @param position * @param seq + * @param consensusResidue + * the modal symbol (e.g. K) or symbols (e.g. KF) for the column + * @param pid + * the percentage identity of the column's consensus (if known) * @return */ - Color findColour(char symbol, int position, SequenceI seq); - - /** - * Assigns the given consensus profile for the colourscheme - */ - void setConsensus(ProfilesI hconsensus); - - /** - * Assigns the given conservation to the colourscheme - * - * @param c - */ - void setConservation(Conservation c); - - /** - * Enable or disable conservation shading for this colourscheme - * - * @param conservationApplied - */ - void setConservationApplied(boolean conservationApplied); - - /** - * Answers true if conservation shading is enabled for this colourscheme - * - * @return - */ - boolean conservationApplied(); - - /** - * Sets the scale factor for bleaching of colour in unconserved regions - * - * @param i - */ - void setConservationInc(int i); - - /** - * Returns the scale factor for bleaching colour in unconserved regions - * - * @return - */ - int getConservationInc(); - - /** - * Returns the percentage identity threshold for applying colourscheme - * - * @return - */ - int getThreshold(); - - /** - * Sets the percentage identity threshold and type of %age identity - * calculation for shading - * - * @param pct - * 0..100 percentage identity for applying this colourscheme - * @param ignoreGaps - * when true, calculate PID without including gapped positions - */ - void setThreshold(int pct, boolean ignoreGaps); + Color findColour(char symbol, int position, SequenceI seq, + String consensusResidue, float pid); /** * Recalculate dependent data using the given sequence collection, taking diff --git a/src/jalview/schemes/FollowerColourScheme.java b/src/jalview/schemes/FollowerColourScheme.java index 94f92b7..57c19e5 100644 --- a/src/jalview/schemes/FollowerColourScheme.java +++ b/src/jalview/schemes/FollowerColourScheme.java @@ -20,9 +20,7 @@ */ package jalview.schemes; -import jalview.analysis.Conservation; import jalview.datamodel.AnnotatedCollectionI; -import jalview.datamodel.ProfilesI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; @@ -37,7 +35,7 @@ import java.util.Map; public class FollowerColourScheme extends ResidueColourScheme { - protected ColourSchemeI colourScheme; + private ColourSchemeI colourScheme; public ColourSchemeI getBaseColour() { @@ -45,33 +43,6 @@ public class FollowerColourScheme extends ResidueColourScheme } @Override - public void setConsensus(ProfilesI consensus) - { - if (colourScheme != null) - { - colourScheme.setConsensus(consensus); - } - } - - @Override - public void setConservation(Conservation cons) - { - if (colourScheme != null) - { - colourScheme.setConservation(cons); - } - } - - @Override - public void setConservationInc(int i) - { - if (colourScheme != null) - { - colourScheme.setConservationInc(i); - } - } - - @Override public String getSchemeName() { return "Follower"; @@ -88,4 +59,14 @@ public class FollowerColourScheme extends ResidueColourScheme return new FollowerColourScheme(); } + protected ColourSchemeI getColourScheme() + { + return colourScheme; + } + + protected void setColourScheme(ColourSchemeI colourScheme) + { + this.colourScheme = colourScheme; + } + } diff --git a/src/jalview/schemes/NucleotideColourScheme.java b/src/jalview/schemes/NucleotideColourScheme.java index 3a71732..abae733 100755 --- a/src/jalview/schemes/NucleotideColourScheme.java +++ b/src/jalview/schemes/NucleotideColourScheme.java @@ -24,7 +24,6 @@ import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; -import java.awt.Color; import java.util.Map; /** @@ -40,60 +39,7 @@ public class NucleotideColourScheme extends ResidueColourScheme */ public NucleotideColourScheme() { - super(ResidueProperties.nucleotideIndex, ResidueProperties.nucleotide, - 0); - } - - /** - * DOCUMENT ME! - * - * @param n - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - @Override - public Color findColour(char c) - { - // System.out.println("called"); log.debug - return colors[ResidueProperties.nucleotideIndex[c]]; - } - - /** - * DOCUMENT ME! - * - * @param n - * DOCUMENT ME! - * @param j - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - @Override - public Color findColour(char c, int j, SequenceI seq) - { - Color currentColour; - if ((threshold == 0) || aboveThreshold(c, j)) - { - try - { - currentColour = colors[ResidueProperties.nucleotideIndex[c]]; - } catch (Exception ex) - { - return Color.white; - } - } - else - { - return Color.white; - } - - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; + super(ResidueProperties.nucleotideIndex, ResidueProperties.nucleotide); } @Override diff --git a/src/jalview/schemes/PIDColourScheme.java b/src/jalview/schemes/PIDColourScheme.java index 389655c..6ca1393 100755 --- a/src/jalview/schemes/PIDColourScheme.java +++ b/src/jalview/schemes/PIDColourScheme.java @@ -21,7 +21,6 @@ package jalview.schemes; import jalview.datamodel.AnnotatedCollectionI; -import jalview.datamodel.ProfileI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -45,57 +44,44 @@ public class PIDColourScheme extends ResidueColourScheme } @Override - public Color findColour(char c, int j, SequenceI seq) + public Color findColour(char c, int j, SequenceI seq, + String consensusResidue, float pid) { + /* + * make everything uppercase; note this does nothing (fast) + * if consensusResidue is already uppercase + */ + consensusResidue = consensusResidue.toUpperCase(); if ('a' <= c && c <= 'z') { c -= ('a' - 'A'); } - if (consensus == null || consensus.get(j) == null) - { - return Color.white; - } - - if ((threshold != 0) && !aboveThreshold(c, j)) + if (consensusResidue == null || Comparison.isGap(c)) { return Color.white; } - Color currentColour = Color.white; - - double sc = 0; - + Color colour = Color.white; /* * test whether this is the consensus (or joint consensus) residue */ - ProfileI profile = consensus.get(j); - boolean matchesConsensus = profile.getModalResidue().contains( + boolean matchesConsensus = consensusResidue.contains( String.valueOf(c)); if (matchesConsensus) { - sc = profile.getPercentageIdentity(ignoreGaps); - - if (!Comparison.isGap(c)) + for (int i = 0; i < thresholds.length; i++) { - for (int i = 0; i < thresholds.length; i++) + if (pid > thresholds[i]) { - if (sc > thresholds[i]) - { - currentColour = pidColours[i]; - break; - } + colour = pidColours[i]; + break; } } } - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; + return colour; } @Override diff --git a/src/jalview/schemes/PurinePyrimidineColourScheme.java b/src/jalview/schemes/PurinePyrimidineColourScheme.java index e451135..1b36f30 100644 --- a/src/jalview/schemes/PurinePyrimidineColourScheme.java +++ b/src/jalview/schemes/PurinePyrimidineColourScheme.java @@ -24,7 +24,6 @@ import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; -import java.awt.Color; import java.util.Map; /** @@ -40,58 +39,7 @@ public class PurinePyrimidineColourScheme extends ResidueColourScheme public PurinePyrimidineColourScheme() { super(ResidueProperties.purinepyrimidineIndex, - ResidueProperties.purinepyrimidine, 0); - } - - /** - * Finds the corresponding color for the type of character inputed - * - * @param c - * Character in sequence - * - * @return Color from purinepyrimidineIndex in - * jalview.schemes.ResidueProperties - */ - @Override - public Color findColour(char c) - { - return colors[ResidueProperties.purinepyrimidineIndex[c]]; - } - - /** - * Returns color based on conservation - * - * @param c - * Character in sequence - * @param j - * Threshold - * - * @return Color in RGB - */ - public Color findColour(char c, int j) - { - Color currentColour; - if ((threshold == 0) || aboveThreshold(c, j)) - { - try - { - currentColour = colors[ResidueProperties.purinepyrimidineIndex[c]]; - } catch (Exception ex) - { - return Color.white; - } - } - else - { - return Color.white; - } - - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; + ResidueProperties.purinepyrimidine); } @Override diff --git a/src/jalview/schemes/RNAHelicesColourChooser.java b/src/jalview/schemes/RNAHelicesColourChooser.java index 90cc14f..15cb157 100644 --- a/src/jalview/schemes/RNAHelicesColourChooser.java +++ b/src/jalview/schemes/RNAHelicesColourChooser.java @@ -61,9 +61,9 @@ public class RNAHelicesColourChooser oldgroupColours = new Hashtable(); for (SequenceGroup sg : ap.getAlignment().getGroups()) { - if (sg.cs != null) + if (sg.getColourScheme() != null) { - oldgroupColours.put(sg, sg.cs); + oldgroupColours.put(sg, sg.getColourScheme()); } } } diff --git a/src/jalview/schemes/RNAInteractionColourScheme.java b/src/jalview/schemes/RNAInteractionColourScheme.java index f4c831a..d236803 100644 --- a/src/jalview/schemes/RNAInteractionColourScheme.java +++ b/src/jalview/schemes/RNAInteractionColourScheme.java @@ -45,25 +45,12 @@ public class RNAInteractionColourScheme extends ResidueColourScheme public Color findColour(char c, int j, SequenceI seq) { // FIXME this is just a copy of NucleotideColourScheme - Color currentColour; - if ((threshold == 0) || aboveThreshold(c, j)) + Color currentColour = Color.white; + try { - try - { - currentColour = colors[ResidueProperties.nucleotideIndex[c]]; - } catch (Exception ex) - { - return Color.white; - } - } - else - { - return Color.white; - } - - if (conservationColouring) + currentColour = colors[ResidueProperties.nucleotideIndex[c]]; + } catch (Exception ex) { - currentColour = applyConservation(currentColour, j); } return currentColour; diff --git a/src/jalview/schemes/ResidueColourScheme.java b/src/jalview/schemes/ResidueColourScheme.java index 217786a..358417b 100755 --- a/src/jalview/schemes/ResidueColourScheme.java +++ b/src/jalview/schemes/ResidueColourScheme.java @@ -20,14 +20,10 @@ */ package jalview.schemes; -import jalview.analysis.Conservation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AnnotatedCollectionI; -import jalview.datamodel.ProfileI; -import jalview.datamodel.ProfilesI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; -import jalview.util.ColorUtils; import jalview.util.Comparison; import java.awt.Color; @@ -48,33 +44,14 @@ public abstract class ResidueColourScheme implements ColourSchemeI */ final int[] symbolIndex; - boolean conservationColouring = false; - /* * colour for residue characters as indexed by symbolIndex */ Color[] colors = null; - int threshold = 0; - /* Set when threshold colouring to either pid_gaps or pid_nogaps */ protected boolean ignoreGaps = false; - /* - * Consensus data indexed by column - */ - ProfilesI consensus; - - /* - * Conservation string as a char array - */ - char[] conservation; - - /* - * The conservation slider percentage setting - */ - int inc = 30; - /** * Creates a new ResidueColourScheme object. * @@ -82,15 +59,11 @@ public abstract class ResidueColourScheme implements ColourSchemeI * ResidueProperties.aaIndex) * @param colors * colours for symbols in sequences - * @param threshold - * threshold for conservation shading */ - public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours, - int threshold) + public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours) { symbolIndex = aaOrnaIndex; this.colors = colours; - this.threshold = threshold; } /** @@ -114,247 +87,45 @@ public abstract class ResidueColourScheme implements ColourSchemeI /** * Find a colour without an index in a sequence */ - @Override public Color findColour(char c) { - return colors == null ? Color.white : colors[symbolIndex[c]]; - } - - @Override - public Color findColour(char c, int j, SequenceI seq) - { Color colour = Color.white; - if (colors != null && symbolIndex != null) + if (!Comparison.isGap(c) && colors != null && symbolIndex != null + && c < symbolIndex.length + && symbolIndex[c] < colors.length) { colour = colors[symbolIndex[c]]; } - colour = adjustColour(c, j, colour); return colour; } /** - * Adjusts colour by applying thresholding or conservation shading, if in - * force. That is - *

    - *
  • if there is a threshold set for colouring, and the residue doesn't - * match the consensus (or a joint consensus) residue, or the consensus score - * is not above the threshold, then the colour is set to white
  • - *
  • if conservation colouring is selected, the colour is faded by an amount - * depending on the conservation score for the column, and the conservation - * colour threshold
  • - *
- * - * @param symbol - * @param column - * @param colour - * @return - */ - protected Color adjustColour(char symbol, int column, Color colour) - { - if (!aboveThreshold(symbol, column)) - { - colour = Color.white; - } - - if (conservationColouring) - { - colour = applyConservation(colour, column); - } - return colour; - } - - /** - * Get the percentage threshold for this colour scheme - * - * @return Returns the percentage threshold - */ - @Override - public int getThreshold() - { - return threshold; - } - - /** - * Sets the percentage consensus threshold value, and whether gaps are ignored - * in percentage identity calculation - * - * @param consensusThreshold - * @param ignoreGaps + * Default is to call the overloaded method that ignores consensus. A colour + * scheme that depends on consensus (for example, Blosum62), should override + * this method instead. */ @Override - public void setThreshold(int consensusThreshold, boolean ignoreGaps) + public Color findColour(char c, int j, SequenceI seq, + String consensusResidue, float pid) { - threshold = consensusThreshold; - this.ignoreGaps = ignoreGaps; + return findColour(c, j, seq); } /** - * Answers true if there is a consensus profile for the specified column, and - * the given residue matches the consensus (or joint consensus) residue for - * the column, and the percentage identity for the profile is equal to or - * greater than the current threshold; else answers false. The percentage - * calculation depends on whether or not we are ignoring gapped sequences. - * - * @param residue - * @param column - * (index into consensus profiles) + * Default implementation looks up the residue colour in a fixed scheme, or + * returns White if not found. Override this method for a colour scheme that + * depends on the column position or sequence. * + * @param c + * @param j + * @param seq * @return - * @see #setThreshold(int, boolean) */ - public boolean aboveThreshold(char residue, int column) + protected Color findColour(char c, int j, SequenceI seq) { - if (threshold == 0) - { - return true; - } - if ('a' <= residue && residue <= 'z') - { - // TO UPPERCASE !!! - // Faster than toUpperCase - residue -= ('a' - 'A'); - } - - if (consensus == null) - { - return false; - } - - ProfileI profile = consensus.get(column); - - /* - * test whether this is the consensus (or joint consensus) residue - */ - if (profile != null - && profile.getModalResidue().contains(String.valueOf(residue))) - { - if (profile.getPercentageIdentity(ignoreGaps) >= threshold) - { - return true; - } - } - - return false; - } - - @Override - public boolean conservationApplied() - { - return conservationColouring; - } - - @Override - public void setConservationApplied(boolean conservationApplied) - { - conservationColouring = conservationApplied; - } - - @Override - public void setConservationInc(int i) - { - inc = i; - } - - @Override - public int getConservationInc() - { - return inc; - } - - /** - * DOCUMENT ME! - * - * @param consensus - * DOCUMENT ME! - */ - @Override - public void setConsensus(ProfilesI consensus) - { - if (consensus == null) - { - return; - } - - this.consensus = consensus; - } - - @Override - public void setConservation(Conservation cons) - { - if (cons == null) - { - conservationColouring = false; - conservation = null; - } - else - { - conservationColouring = true; - int iSize = cons.getConsSequence().getLength(); - conservation = new char[iSize]; - for (int i = 0; i < iSize; i++) - { - conservation[i] = cons.getConsSequence().getCharAt(i); - } - } - - } - - /** - * Applies a combination of column conservation score, and conservation - * percentage slider, to 'bleach' out the residue colours towards white. - *

- * If a column is fully conserved (identical residues, conservation score 11, - * shown as *), or all 10 physico-chemical properties are conserved - * (conservation score 10, shown as +), then the colour is left unchanged. - *

- * Otherwise a 'bleaching' factor is computed and applied to the colour. This - * is designed to fade colours for scores of 0-9 completely to white at slider - * positions ranging from 18% - 100% respectively. - * - * @param currentColour - * @param column - * - * @return bleached (or unmodified) colour - */ - Color applyConservation(Color currentColour, int column) - { - if (conservation == null || conservation.length <= column) - { - return currentColour; - } - char conservationScore = conservation[column]; - - /* - * if residues are fully conserved (* or 11), or all properties - * are conserved (+ or 10), leave colour unchanged - */ - if (conservationScore == '*' || conservationScore == '+' - || conservationScore == (char) 10 - || conservationScore == (char) 11) - { - return currentColour; - } - - if (Comparison.isGap(conservationScore)) - { - return Color.white; - } - - /* - * convert score 0-9 to a bleaching factor 1.1 - 0.2 - */ - float bleachFactor = (11 - (conservationScore - '0')) / 10f; - - /* - * scale this up by 0-5 (percentage slider / 20) - * as a result, scores of: 0 1 2 3 4 5 6 7 8 9 - * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100% - */ - bleachFactor *= (inc / 20f); - - return ColorUtils.bleachColour(currentColour, bleachFactor); + return findColour(c); } @Override diff --git a/src/jalview/schemes/ScoreColourScheme.java b/src/jalview/schemes/ScoreColourScheme.java index ec06e06..aa20121 100755 --- a/src/jalview/schemes/ScoreColourScheme.java +++ b/src/jalview/schemes/ScoreColourScheme.java @@ -87,42 +87,6 @@ public class ScoreColourScheme extends ResidueColourScheme /** * DOCUMENT ME! * - * @param s - * DOCUMENT ME! - * @param j - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - @Override - public Color findColour(char c, int j, SequenceI seq) - { - if (threshold > 0) - { - if (!aboveThreshold(c, j)) - { - return Color.white; - } - } - - if (jalview.util.Comparison.isGap(c)) - { - return Color.white; - } - - Color currentColour = colors[ResidueProperties.aaIndex[c]]; - - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; - } - - /** - * DOCUMENT ME! - * * @param c * DOCUMENT ME! * diff --git a/src/jalview/schemes/TaylorColourScheme.java b/src/jalview/schemes/TaylorColourScheme.java index cae3e15..ac8abbc 100755 --- a/src/jalview/schemes/TaylorColourScheme.java +++ b/src/jalview/schemes/TaylorColourScheme.java @@ -30,7 +30,7 @@ public class TaylorColourScheme extends ResidueColourScheme { public TaylorColourScheme() { - super(ResidueProperties.aaIndex, ResidueProperties.taylor, 0); + super(ResidueProperties.aaIndex, ResidueProperties.taylor); } @Override diff --git a/src/jalview/schemes/UserColourScheme.java b/src/jalview/schemes/UserColourScheme.java index 969e6b3..85bf54e 100755 --- a/src/jalview/schemes/UserColourScheme.java +++ b/src/jalview/schemes/UserColourScheme.java @@ -238,36 +238,6 @@ public class UserColourScheme extends ResidueColourScheme } - @Override - public Color findColour(char c, int j, SequenceI seq) - { - Color currentColour; - int index = ResidueProperties.aaIndex[c]; - - if ((threshold == 0) || aboveThreshold(c, j)) - { - if (lowerCaseColours != null && 'a' <= c && c <= 'z') - { - currentColour = lowerCaseColours[index]; - } - else - { - currentColour = colors[index]; - } - } - else - { - currentColour = Color.white; - } - - if (conservationColouring) - { - currentColour = applyConservation(currentColour, j); - } - - return currentColour; - } - public void setLowerCaseColours(Color[] lcolours) { lowerCaseColours = lcolours; diff --git a/src/jalview/schemes/ZappoColourScheme.java b/src/jalview/schemes/ZappoColourScheme.java index d193714..c32a39c 100755 --- a/src/jalview/schemes/ZappoColourScheme.java +++ b/src/jalview/schemes/ZappoColourScheme.java @@ -39,7 +39,7 @@ public class ZappoColourScheme extends ResidueColourScheme */ public ZappoColourScheme() { - super(ResidueProperties.aaIndex, ResidueProperties.zappo, 0); + super(ResidueProperties.aaIndex, ResidueProperties.zappo); } @Override diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java index f35339c..2e30132 100644 --- a/src/jalview/util/MappingUtils.java +++ b/src/jalview/util/MappingUtils.java @@ -320,7 +320,7 @@ public final class MappingUtils * Copy group name, colours etc, but not sequences or sequence colour scheme */ SequenceGroup mappedGroup = new SequenceGroup(sg); - mappedGroup.cs = mapTo.getGlobalColourScheme(); + mappedGroup.setColourScheme(mapTo.getGlobalColourScheme()); mappedGroup.clear(); int minStartCol = -1; diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 0171fd1..a9d3b77 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -43,6 +43,8 @@ import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.structure.CommandListener; @@ -597,7 +599,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean ignoreGapsInConsensusCalculation = false; - protected ColourSchemeI globalColourScheme = null; + protected CollectionColourSchemeI globalColourScheme; @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -609,70 +611,52 @@ public abstract class AlignmentViewport implements AlignViewportI, // - 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 colour scheme once, thereafter update it + * this means that any conservation or PID threshold settings + * persist when the alignment colour scheme is changed + */ + if (globalColourScheme == null) + { + globalColourScheme = new CollectionColourScheme(); + } + globalColourScheme.setColourScheme(cs); + + // boolean recalc = false; + // TODO: do threshold and increment belong in ViewStyle or colour scheme? + // problem: groups need this but do not currently have a ViewStyle + if (cs != null) { - recalc = getConservationSelected(); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme + if (getConservationSelected() || getAbovePIDThreshold() + || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - recalc = true; - cs.setThreshold(viewStyle.getThreshold(), - ignoreGapsInConsensusCalculation); - } - else - { - cs.setThreshold(0, ignoreGapsInConsensusCalculation); - } - if (recalc) - { - cs.setConsensus(hconsensus); - cs.setConservation(hconservation); + globalColourScheme.setConservation(hconservation); + globalColourScheme + .setConservationApplied(getConservationSelected()); } - cs.setConservationApplied(getConservationSelected()); - cs.alignmentChanged(alignment, hiddenRepSequences); + globalColourScheme.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.getInstance(sg, getHiddenRepSequences()); - sg.setConsPercGaps(ConsPercGaps); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme - || cs instanceof Blosum62ColourScheme) + /* + * retain any colour thresholds per group while + * changing choice of colour scheme (JAL-2386) + */ + sg.setColourScheme(cs); + if (cs != null) { - sg.cs.setThreshold(viewStyle.getThreshold(), - isIgnoreGapsConsensus()); - recalc = true; - } - else - { - 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); } } } @@ -681,6 +665,13 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public ColourSchemeI getGlobalColourScheme() { + return globalColourScheme == null ? null : globalColourScheme + .getColourScheme(); + } + + @Override + public CollectionColourSchemeI getViewportColourScheme() + { return globalColourScheme; } @@ -1859,7 +1850,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ void resetAllColourSchemes() { - ColourSchemeI cs = globalColourScheme; + CollectionColourSchemeI cs = globalColourScheme; if (cs != null) { cs.alignmentChanged(alignment, hiddenRepSequences); diff --git a/src/jalview/workers/ConsensusThread.java b/src/jalview/workers/ConsensusThread.java index debe45d..0278a3b 100644 --- a/src/jalview/workers/ConsensusThread.java +++ b/src/jalview/workers/ConsensusThread.java @@ -28,7 +28,7 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.ProfilesI; import jalview.datamodel.SequenceI; -import jalview.schemes.ColourSchemeI; +import jalview.schemes.CollectionColourSchemeI; public class ConsensusThread extends AlignCalcWorker { @@ -147,11 +147,10 @@ public class ConsensusThread extends AlignCalcWorker */ protected void setColourSchemeConsensus(ProfilesI hconsensus) { - ColourSchemeI globalColourScheme = alignViewport - .getGlobalColourScheme(); - if (globalColourScheme != null) + CollectionColourSchemeI cs = alignViewport.getViewportColourScheme(); + if (cs != null) { - globalColourScheme.setConsensus(hconsensus); + cs.setConsensus(hconsensus); } } diff --git a/test/jalview/datamodel/SequenceGroupTest.java b/test/jalview/datamodel/SequenceGroupTest.java new file mode 100644 index 0000000..53ac181 --- /dev/null +++ b/test/jalview/datamodel/SequenceGroupTest.java @@ -0,0 +1,82 @@ +package jalview.datamodel; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; + +import jalview.schemes.NucleotideColourScheme; + +import org.testng.annotations.Test; + +public class SequenceGroupTest +{ + @Test + public void testAddSequence() + { + SequenceGroup sg = new SequenceGroup(); + assertTrue(sg.getSequences().isEmpty()); + + SequenceI seq1 = new Sequence("seq1", "abc"); + SequenceI seq2 = new Sequence("seq2", "abc"); + SequenceI seq3 = new Sequence(seq1); + + sg.addSequence(null, false); + assertTrue(sg.getSequences().isEmpty()); + sg.addSequence(seq1, false); + assertEquals(sg.getSequences().size(), 1); + assertTrue(sg.getSequences().contains(seq1)); + // adding the same sequence again does nothing + sg.addSequence(seq1, false); + assertEquals(sg.getSequences().size(), 1); + assertTrue(sg.getSequences().contains(seq1)); + sg.addSequence(seq2, false); + sg.addSequence(seq2, false); + sg.addSequence(seq3, false); + assertEquals(sg.getSequences().size(), 3); + assertTrue(sg.getSequences().contains(seq1)); + assertTrue(sg.getSequences().contains(seq2)); + assertTrue(sg.getSequences().contains(seq3)); + } + + @Test + public void testAddOrRemove() + { + SequenceGroup sg = new SequenceGroup(); + assertTrue(sg.getSequences().isEmpty()); + + SequenceI seq1 = new Sequence("seq1", "abc"); + SequenceI seq2 = new Sequence("seq2", "abc"); + SequenceI seq3 = new Sequence(seq1); + + sg.addOrRemove(seq1, false); + assertEquals(sg.getSequences().size(), 1); + sg.addOrRemove(seq2, false); + assertEquals(sg.getSequences().size(), 2); + sg.addOrRemove(seq3, false); + assertEquals(sg.getSequences().size(), 3); + assertTrue(sg.getSequences().contains(seq1)); + assertTrue(sg.getSequences().contains(seq2)); + assertTrue(sg.getSequences().contains(seq3)); + sg.addOrRemove(seq1, false); + assertEquals(sg.getSequences().size(), 2); + assertFalse(sg.getSequences().contains(seq1)); + } + + @Test + public void testGetColourScheme() + { + SequenceGroup sg = new SequenceGroup(); + assertNotNull(sg.getGroupColourScheme()); + assertNull(sg.getColourScheme()); + + sg.setGroupColourScheme(null); + assertNull(sg.getColourScheme()); + + NucleotideColourScheme scheme = new NucleotideColourScheme(); + sg.setColourScheme(scheme); + assertSame(scheme, sg.getColourScheme()); + } +} diff --git a/test/jalview/gui/AlignFrameTest.java b/test/jalview/gui/AlignFrameTest.java index 60db9dd..d71fe63 100644 --- a/test/jalview/gui/AlignFrameTest.java +++ b/test/jalview/gui/AlignFrameTest.java @@ -22,21 +22,33 @@ package jalview.gui; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.io.DataSourceType; +import jalview.io.FileLoader; +import jalview.schemes.BuriedColourScheme; +import jalview.schemes.HelixColourScheme; +import jalview.schemes.JalviewColourScheme; +import jalview.schemes.StrandColourScheme; +import jalview.schemes.TurnColourScheme; +import jalview.util.MessageManager; import java.util.List; import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class AlignFrameTest { + AlignFrame af; @BeforeClass(alwaysRun = true) public void setUpJvOptionPane() @@ -95,4 +107,137 @@ public class AlignFrameTest assertEquals(6, hidden.get(1)[0]); assertEquals(8, hidden.get(1)[1]); } + + @BeforeMethod + public void setUp() + { + af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa", + DataSourceType.FILE); + } + + /** + * Test that changing background (alignment) colour scheme + *

    + *
  • with Apply Colour to All Groups not selected, does not change group + * colours
  • + *
  • with Apply Colour to All Groups selected, does change group colours
  • + *
  • in neither case, changes alignment or group colour thresholds (PID or + * Conservation)
  • + *
+ */ + @Test + public void testChangeColour_background_groupsAndThresholds() + { + AlignViewport av = af.getViewport(); + AlignmentI al = av.getAlignment(); + + /* + * Colour alignment by Buried Index + */ + af.applyToAllGroups_actionPerformed(false); + af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString()); + assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme); + assertFalse(av.getViewportColourScheme().conservationApplied()); + assertEquals(av.getViewportColourScheme().getThreshold(), 0); + + /* + * Apply Conservation 20% + */ + af.conservationMenuItem_actionPerformed(true); + SliderPanel sp = SliderPanel.getSliderPanel(); + assertEquals(sp.getTitle(), MessageManager.formatMessage( + "label.conservation_colour_increment", + new String[] { "Background" })); + assertTrue(sp.isForConservation()); + sp.valueChanged(20); + assertTrue(av.getViewportColourScheme().conservationApplied()); + assertEquals(av.getViewportColourScheme().getConservationInc(), 20); + + /* + * Apply PID threshold 10% (conservation still applies as well) + */ + af.abovePIDThreshold_actionPerformed(true); + sp = SliderPanel.getSliderPanel(); + assertFalse(sp.isForConservation()); + assertEquals(sp.getTitle(), MessageManager.formatMessage( + "label.percentage_identity_threshold", + new String[] { "Background" })); + sp.valueChanged(10); + assertEquals(av.getViewportColourScheme().getThreshold(), 10); + assertTrue(av.getViewportColourScheme().conservationApplied()); + assertEquals(av.getViewportColourScheme().getConservationInc(), 20); + + /* + * create a group with Strand colouring, 30% Conservation + * and 40% PID threshold + */ + SequenceGroup sg = new SequenceGroup(); + sg.addSequence(al.getSequenceAt(0), false); + sg.setStartRes(15); + sg.setEndRes(25); + av.setSelectionGroup(sg); + + /* + * apply 30% Conservation to group + */ + PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null); + popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand + .toString()); + assertTrue(sg.getColourScheme() instanceof StrandColourScheme); + assertEquals(al.getGroups().size(), 1); + assertSame(al.getGroups().get(0), sg); + popupMenu.conservationMenuItem_actionPerformed(true); + sp = SliderPanel.getSliderPanel(); + assertTrue(sp.isForConservation()); + assertEquals(sp.getTitle(), MessageManager.formatMessage( + "label.conservation_colour_increment", + new String[] { sg.getName() })); + sp.valueChanged(30); + assertTrue(sg.getGroupColourScheme().conservationApplied()); + assertEquals(sg.getGroupColourScheme().getConservationInc(), 30); + + /* + * apply 40% PID threshold to group + */ + popupMenu.abovePIDColour_actionPerformed(true); + sp = SliderPanel.getSliderPanel(); + assertFalse(sp.isForConservation()); + assertEquals(sp.getTitle(), MessageManager.formatMessage( + "label.percentage_identity_threshold", + new String[] { sg.getName() })); + sp.valueChanged(40); + assertEquals(sg.getGroupColourScheme().getThreshold(), 40); + // conservation threshold is unchanged: + assertTrue(sg.getGroupColourScheme().conservationApplied()); + assertEquals(sg.getGroupColourScheme().getConservationInc(), 30); + + /* + * change alignment colour - group colour, and all thresholds, + * should be unaffected + */ + af.changeColour_actionPerformed(JalviewColourScheme.Turn.toString()); + assertTrue(av.getGlobalColourScheme() instanceof TurnColourScheme); + assertTrue(av.getViewportColourScheme().conservationApplied()); + assertEquals(av.getViewportColourScheme().getConservationInc(), 20); + assertEquals(av.getViewportColourScheme().getThreshold(), 10); + assertTrue(sg.getColourScheme() instanceof StrandColourScheme); + assertTrue(sg.getGroupColourScheme().conservationApplied()); + assertEquals(sg.getGroupColourScheme().getConservationInc(), 30); + assertEquals(sg.getGroupColourScheme().getThreshold(), 40); + + /* + * Now change alignment colour with Apply Colour To All Groups + * - group colour should change, but not colour thresholds + */ + af.applyToAllGroups_actionPerformed(true); + af.changeColour_actionPerformed(JalviewColourScheme.Helix.toString()); + assertTrue(av.getGlobalColourScheme() instanceof HelixColourScheme); + assertTrue(av.getViewportColourScheme().conservationApplied()); + assertEquals(av.getViewportColourScheme().getConservationInc(), 20); + assertEquals(av.getViewportColourScheme().getThreshold(), 10); + assertTrue(sg.getColourScheme() instanceof HelixColourScheme); + assertTrue(sg.getGroupColourScheme().conservationApplied()); + assertEquals(sg.getGroupColourScheme().getConservationInc(), 30); + assertEquals(sg.getGroupColourScheme().getThreshold(), 40); + } } diff --git a/test/jalview/gui/AlignViewportTest.java b/test/jalview/gui/AlignViewportTest.java index 213f769..fa71b2e 100644 --- a/test/jalview/gui/AlignViewportTest.java +++ b/test/jalview/gui/AlignViewportTest.java @@ -354,7 +354,8 @@ public class AlignViewportTest "examples/uniref50.fa", DataSourceType.FILE); ColourSchemeI cs = new PIDColourScheme(); af.getViewport().setGlobalColourScheme(cs); - assertFalse(cs.conservationApplied()); + assertFalse(af.getViewport().getViewportColourScheme() + .conservationApplied()); } @Test(groups = { "Functional" }) diff --git a/test/jalview/io/JSONFileTest.java b/test/jalview/io/JSONFileTest.java index a705a78..a8611cc 100644 --- a/test/jalview/io/JSONFileTest.java +++ b/test/jalview/io/JSONFileTest.java @@ -137,7 +137,7 @@ public class JSONFileTest null, true, true, false, 21, 29); ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme( "zappo", seqGrp); - seqGrp.cs = scheme; + seqGrp.cs.setColourScheme(scheme); seqGrp.setShowNonconserved(false); seqGrp.setDescription(null); diff --git a/test/jalview/io/Jalview2xmlTests.java b/test/jalview/io/Jalview2xmlTests.java index 734bfe0..5b99fa1 100644 --- a/test/jalview/io/Jalview2xmlTests.java +++ b/test/jalview/io/Jalview2xmlTests.java @@ -163,7 +163,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase SequenceGroup sg = new SequenceGroup(); sg.setStartRes(57); sg.setEndRes(92); - sg.cs = gcs; + sg.cs.setColourScheme(gcs); af.getViewport().getAlignment().addGroup(sg); sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false); sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true); @@ -179,7 +179,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme(); ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups() - .get(0).cs; + .get(0).getColourScheme(); assertNotNull("Didn't recover global colourscheme", _rcs); assertTrue("Didn't recover annotation colour global scheme", _rcs instanceof AnnotationColourGradient); @@ -192,8 +192,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++) { - if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0]) != _rcs - .findColour(sqs[5].getCharAt(p), p, sqs[5])) + if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs + .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f)) { diffseqcols = true; } @@ -212,8 +212,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++) { - if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1]) != _rgcs - .findColour(sqs[2].getCharAt(p), p, sqs[2])) + if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null, 0f) != _rgcs + .findColour(sqs[2].getCharAt(p), p, sqs[2], null, 0f)) { diffgseqcols = true; } @@ -381,8 +381,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase Desktop.getAlignFrames().length, Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length); Assert.assertEquals( - oldviews, - Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length); + Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length, + oldviews); } /** diff --git a/test/jalview/schemes/Blosum62ColourSchemeTest.java b/test/jalview/schemes/Blosum62ColourSchemeTest.java new file mode 100644 index 0000000..b3dd165 --- /dev/null +++ b/test/jalview/schemes/Blosum62ColourSchemeTest.java @@ -0,0 +1,57 @@ +package jalview.schemes; + +import static org.testng.Assert.assertEquals; + +import java.awt.Color; + +import org.testng.annotations.Test; + +public class Blosum62ColourSchemeTest +{ + /** + * Test the method that determines colour as: + *
    + *
  • white if there is no consensus
  • + *
  • white if 'residue' is a gap
  • + *
  • dark blue if residue matches consensus (or joint consensus)
  • + *
  • else, total the residue's Blosum score with the consensus residue(s)
  • + *
      + *
    • if positive, light blue, else white
    • + *
    + *
      + */ + @Test + public void testFindColour() + { + ColourSchemeI blosum = new Blosum62ColourScheme(); + Color lightBlue = new Color(204, 204, 255); + Color darkBlue = new Color(154, 154, 255); + + /* + * findColour does not use column, sequence or pid score + */ + assertEquals(blosum.findColour('A', 0, null, "A", 0f), darkBlue); + assertEquals(blosum.findColour('a', 0, null, "A", 0f), darkBlue); + assertEquals(blosum.findColour('A', 0, null, "a", 0f), darkBlue); + assertEquals(blosum.findColour('a', 0, null, "a", 0f), darkBlue); + + /* + * L has a Blosum score of + * -1 with A + * -4 with B + * 0 with F + * 2 with I + * -1 with T + * 1 with V + * etc + */ + assertEquals(blosum.findColour('L', 0, null, "A", 0f), Color.white); // -1 + assertEquals(blosum.findColour('L', 0, null, "B", 0f), Color.white); // -4 + assertEquals(blosum.findColour('L', 0, null, "F", 0f), Color.white); // 0 + assertEquals(blosum.findColour('L', 0, null, "I", 0f), lightBlue); // 2 + assertEquals(blosum.findColour('L', 0, null, "TV", 0f), Color.white); // 0 + assertEquals(blosum.findColour('L', 0, null, "IV", 0f), lightBlue); // 3 + assertEquals(blosum.findColour('L', 0, null, "IT", 0f), lightBlue); // 1 + assertEquals(blosum.findColour('L', 0, null, "IAT", 0f), Color.white); // 0 + } +} diff --git a/test/jalview/schemes/ClustalxColourSchemeTest.java b/test/jalview/schemes/ClustalxColourSchemeTest.java index acd2e8d..d35ca76 100644 --- a/test/jalview/schemes/ClustalxColourSchemeTest.java +++ b/test/jalview/schemes/ClustalxColourSchemeTest.java @@ -33,7 +33,7 @@ public class ClustalxColourSchemeTest AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(FASTA, DataSourceType.PASTE); AlignmentI al = af.getViewport().getAlignment(); - ColourSchemeI cs = new ClustalxColourScheme(al, null); + ClustalxColourScheme cs = new ClustalxColourScheme(al, null); /* * column 1 is 70% A which is above Clustalx threshold of 60% diff --git a/test/jalview/schemes/CollectionColourSchemeTest.java b/test/jalview/schemes/CollectionColourSchemeTest.java new file mode 100644 index 0000000..9dffdb4 --- /dev/null +++ b/test/jalview/schemes/CollectionColourSchemeTest.java @@ -0,0 +1,166 @@ +package jalview.schemes; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + +import jalview.analysis.Conservation; +import jalview.datamodel.Profile; +import jalview.datamodel.ProfileI; +import jalview.datamodel.Profiles; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import java.awt.Color; +import java.util.Collections; + +import org.testng.annotations.Test; + +public class CollectionColourSchemeTest +{ + + @Test(groups = "Functional") + public void testAboveThreshold() + { + /* + * make up profiles for this alignment: + * AR-Q + * AR-- + * SR-T + * SR-T + */ + ProfileI[] profiles = new ProfileI[4]; + profiles[0] = new Profile(4, 0, 2, "AS"); + profiles[1] = new Profile(4, 0, 4, "R"); + profiles[2] = new Profile(4, 4, 0, ""); + profiles[3] = new Profile(4, 1, 2, "T"); + CollectionColourScheme ccs = new CollectionColourScheme( + new PIDColourScheme()); + ccs.setConsensus(new Profiles(profiles)); + + /* + * no threshold + */ + ccs.setThreshold(0, true); + assertTrue(ccs.aboveThreshold('a', 0)); + assertTrue(ccs.aboveThreshold('S', 0)); + assertTrue(ccs.aboveThreshold('W', 0)); + assertTrue(ccs.aboveThreshold('R', 1)); + assertTrue(ccs.aboveThreshold('W', 2)); + assertTrue(ccs.aboveThreshold('t', 3)); + assertTrue(ccs.aboveThreshold('Q', 3)); + + /* + * with threshold, include gaps + */ + ccs.setThreshold(60, false); + assertFalse(ccs.aboveThreshold('a', 0)); + assertFalse(ccs.aboveThreshold('S', 0)); + assertTrue(ccs.aboveThreshold('R', 1)); + assertFalse(ccs.aboveThreshold('W', 2)); + assertFalse(ccs.aboveThreshold('t', 3)); // 50% < 60% + + /* + * with threshold, ignore gaps + */ + ccs.setThreshold(60, true); + assertFalse(ccs.aboveThreshold('a', 0)); + assertFalse(ccs.aboveThreshold('S', 0)); + assertTrue(ccs.aboveThreshold('R', 1)); + assertFalse(ccs.aboveThreshold('W', 2)); + assertTrue(ccs.aboveThreshold('t', 3)); // 67% > 60% + } + + /** + * Test colour bleaching based on conservation score and conservation slider. + * Scores of 10 or 11 should leave colours unchanged. Gap is always white. + */ + @Test(groups = "Functional") + public void testApplyConservation() + { + CollectionColourScheme ccs = new CollectionColourScheme( + new PIDColourScheme()); + + // no conservation present - no fading + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 12)); + + /* + * stub Conservation to return a given consensus string + */ + final String consSequence = "0123456789+*-"; + Conservation cons = new Conservation(null, + Collections. emptyList(), 0, 0) + { + @Override + public SequenceI getConsSequence() { + return new Sequence("seq", consSequence); + } + }; + ccs.setConservation(cons); + + // column out of range: + assertEquals(Color.RED, + ccs.applyConservation(Color.RED, consSequence.length())); + + /* + * with 100% threshold, 'fade factor' is + * (11-score)/10 * 100/20 = (11-score)/2 + * which is >= 1 for all scores i.e. all fade to white except +, * + */ + ccs.setConservationInc(100); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 0)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 1)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 2)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 3)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 4)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 5)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 6)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 7)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 8)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 9)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 10)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 11)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 12)); + + /* + * with 0% threshold, there should be no fading + */ + ccs.setConservationInc(0); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 0)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 1)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 2)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 3)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 4)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 5)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 6)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 7)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 8)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 9)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 10)); + assertEquals(Color.RED, ccs.applyConservation(Color.RED, 11)); + assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 12)); // gap + + /* + * with 40% threshold, 'fade factor' is + * (11-score)/10 * 40/20 = (11-score)/5 + * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9 + * e.g. score 7 colour fades 80% of the way to white (255, 255, 255) + */ + ccs.setConservationInc(40); + Color colour = new Color(155, 105, 55); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 0)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 1)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 2)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 3)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 4)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 5)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 6)); + assertEquals(new Color(235, 225, 215), ccs.applyConservation(colour, 7)); + assertEquals(new Color(215, 195, 175), ccs.applyConservation(colour, 8)); + assertEquals(new Color(195, 165, 135), ccs.applyConservation(colour, 9)); + assertEquals(colour, ccs.applyConservation(colour, 10)); + assertEquals(colour, ccs.applyConservation(colour, 11)); + assertEquals(Color.WHITE, ccs.applyConservation(colour, 12)); + } + +} diff --git a/test/jalview/schemes/ColourSchemePropertyTest.java b/test/jalview/schemes/ColourSchemePropertyTest.java index 2854784..c1c6846 100644 --- a/test/jalview/schemes/ColourSchemePropertyTest.java +++ b/test/jalview/schemes/ColourSchemePropertyTest.java @@ -105,7 +105,8 @@ public class ColourSchemePropertyTest /* * explicit aa colours */ - ColourSchemeI cs = ColourSchemeProperty.getColourScheme(al, + UserColourScheme cs = (UserColourScheme) ColourSchemeProperty + .getColourScheme(al, "R,G=red;C=blue;c=green;Q=10,20,30;S,T=11ffdd"); assertEquals(cs.findColour('H'), Color.white); assertEquals(cs.findColour('R'), Color.red); diff --git a/test/jalview/schemes/ColourSchemesTest.java b/test/jalview/schemes/ColourSchemesTest.java index 6527756..39d58f8 100644 --- a/test/jalview/schemes/ColourSchemesTest.java +++ b/test/jalview/schemes/ColourSchemesTest.java @@ -34,9 +34,9 @@ public class ColourSchemesTest */ class Stripy extends ResidueColourScheme { - private ColourSchemeI odd; + private ResidueColourScheme odd; - private ColourSchemeI even; + private ResidueColourScheme even; private Stripy() { @@ -50,8 +50,8 @@ public class ColourSchemesTest */ private Stripy(ColourSchemeI cs1, ColourSchemeI cs2) { - odd = cs1; - even = cs2; + odd = (ResidueColourScheme) cs1; + even = (ResidueColourScheme) cs2; } @Override @@ -92,15 +92,16 @@ public class ColourSchemesTest */ class MyClustal extends ResidueColourScheme { - ColourSchemeI delegate; + ClustalxColourScheme delegate; private MyClustal() { } - private MyClustal(ColourSchemeI scheme) + private MyClustal(AnnotatedCollectionI sg, + Map hiddenRepSequences) { - delegate = scheme; + delegate = new ClustalxColourScheme(sg, hiddenRepSequences); } @Override @@ -147,8 +148,7 @@ public class ColourSchemesTest public ColourSchemeI getInstance(AnnotatedCollectionI sg, Map hiddenRepSequences) { - return new MyClustal(new ClustalxColourScheme().getInstance(sg, - hiddenRepSequences)); + return new MyClustal(sg, hiddenRepSequences); } @Override diff --git a/test/jalview/schemes/PIDColourSchemeTest.java b/test/jalview/schemes/PIDColourSchemeTest.java new file mode 100644 index 0000000..6f60e50 --- /dev/null +++ b/test/jalview/schemes/PIDColourSchemeTest.java @@ -0,0 +1,104 @@ +package jalview.schemes; + +import static org.testng.Assert.assertEquals; + +import jalview.datamodel.SequenceI; +import jalview.gui.AlignFrame; +import jalview.gui.AlignViewport; +import jalview.io.DataSourceType; +import jalview.io.FileLoader; + +import java.awt.Color; + +import org.testng.annotations.Test; + +public class PIDColourSchemeTest +{ + static final Color white = Color.white; + + static final Color over40 = new Color(204, 204, 255); + + static final Color over60 = new Color(153, 153, 255); + + static final Color over80 = new Color(100, 100, 255); + + /** + * Test findColour for cases: + *
        + *
      • gap: white
      • + *
      • no match to consensus: white
      • + *
      • match consensus with pid > 80%: 100,100,255
      • + *
      • match consensus with pid > 60%: 153, 153, 255
      • + *
      • match consensus with pid > 40%: 204, 204, 255
      • + *
      • match consensus with pid <= 40%: white
      • + *
      • joint consensus matching
      • + *
      • case insensitive matching
      • + *
          + */ + @Test + public void testFindColour() + { + ColourSchemeI scheme = new PIDColourScheme(); + + /* + * doesn't use column or sequence + */ + assertEquals(scheme.findColour('A', 0, null, "A", 0f), white); + assertEquals(scheme.findColour('A', 0, null, "A", 40f), white); + assertEquals(scheme.findColour('A', 0, null, "A", 40.1f), over40); + assertEquals(scheme.findColour('A', 0, null, "A", 60f), over40); + assertEquals(scheme.findColour('A', 0, null, "A", 60.1f), over60); + assertEquals(scheme.findColour('A', 0, null, "A", 80f), over60); + assertEquals(scheme.findColour('A', 0, null, "A", 80.1f), over80); + assertEquals(scheme.findColour('A', 0, null, "A", 100f), over80); + assertEquals(scheme.findColour('A', 0, null, "KFV", 100f), white); + + assertEquals(scheme.findColour('a', 0, null, "A", 80f), over60); + assertEquals(scheme.findColour('A', 0, null, "a", 80f), over60); + assertEquals(scheme.findColour('a', 0, null, "a", 80f), over60); + assertEquals(scheme.findColour('A', 0, null, "AC", 80f), over60); + assertEquals(scheme.findColour('A', 0, null, "KCA", 80f), over60); + } + + /** + * Test that changing the 'ignore gaps in consensus' in the viewport (an + * option on the annotation label popup menu) results in a change to the + * colouring + */ + @Test + public void testFindColour_ignoreGaps() + { + /* + * AAAAA + * AAAAA + * -CCCC + * FFFFF + * + * first column consensus is A + * first column PID is 50%, or 67% ignoring gaps + */ + String seqs = ">seq1\nAAAAA\n>seq2\nAAAAA\n>seq3\n-CCCC\n>seq4\nFFFFF\n"; + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqs, + DataSourceType.PASTE); + AlignViewport viewport = af.getViewport(); + viewport.setIgnoreGapsConsensus(false, af.alignPanel); + af.changeColour_actionPerformed(JalviewColourScheme.PID.toString()); + + SequenceI seq = viewport.getAlignment().getSequenceAt(0); + + /* + * including gaps, A should be coloured for 50% consensus + */ + Color c = viewport + .getViewportColourScheme().findColour('A', 0, seq); + assertEquals(c, over40); + + /* + * now choose to ignore gaps; colour should be for 67% + */ + viewport.setIgnoreGapsConsensus(true, af.alignPanel); + c = viewport + .getViewportColourScheme().findColour('A', 0, seq); + assertEquals(c, over60); + } +} diff --git a/test/jalview/schemes/ResidueColourSchemeTest.java b/test/jalview/schemes/ResidueColourSchemeTest.java index c3ea385..b45e0d3 100644 --- a/test/jalview/schemes/ResidueColourSchemeTest.java +++ b/test/jalview/schemes/ResidueColourSchemeTest.java @@ -29,16 +29,11 @@ import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.Annotation; -import jalview.datamodel.Profile; -import jalview.datamodel.ProfileI; -import jalview.datamodel.Profiles; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.gui.JvOptionPane; import jalview.io.TCoffeeScoreFile; -import java.awt.Color; - import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -58,139 +53,6 @@ public class ResidueColourSchemeTest } @Test(groups = "Functional") - public void testAboveThreshold() - { - /* - * make up profiles for this alignment: - * AR-Q - * AR-- - * SR-T - * SR-T - */ - ProfileI[] profiles = new ProfileI[4]; - profiles[0] = new Profile(4, 0, 2, "AS"); - profiles[1] = new Profile(4, 0, 4, "R"); - profiles[2] = new Profile(4, 4, 0, ""); - profiles[3] = new Profile(4, 1, 2, "T"); - ResidueColourScheme rcs = new PIDColourScheme(); - rcs.setConsensus(new Profiles(profiles)); - - /* - * no threshold - */ - rcs.setThreshold(0, true); - assertTrue(rcs.aboveThreshold('a', 0)); - assertTrue(rcs.aboveThreshold('S', 0)); - assertTrue(rcs.aboveThreshold('W', 0)); - assertTrue(rcs.aboveThreshold('R', 1)); - assertTrue(rcs.aboveThreshold('W', 2)); - assertTrue(rcs.aboveThreshold('t', 3)); - assertTrue(rcs.aboveThreshold('Q', 3)); - - /* - * with threshold, include gaps - */ - rcs.setThreshold(60, false); - assertFalse(rcs.aboveThreshold('a', 0)); - assertFalse(rcs.aboveThreshold('S', 0)); - assertTrue(rcs.aboveThreshold('R', 1)); - assertFalse(rcs.aboveThreshold('W', 2)); - assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60% - - /* - * with threshold, ignore gaps - */ - rcs.setThreshold(60, true); - assertFalse(rcs.aboveThreshold('a', 0)); - assertFalse(rcs.aboveThreshold('S', 0)); - assertTrue(rcs.aboveThreshold('R', 1)); - assertFalse(rcs.aboveThreshold('W', 2)); - assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60% - } - - /** - * Test colour bleaching based on conservation score and conservation slider. - * Scores of 10 or 11 should leave colours unchanged. Gap is always white. - */ - @Test(groups = "Functional") - public void testApplyConservation() - { - ResidueColourScheme rcs = new PIDColourScheme(); - - // no conservation present - no fading - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12)); - - // cheat by setting conservation sequence directly - // rather than calculating it - good enough for this test - String consensus = "0123456789+*-"; - rcs.conservation = consensus.toCharArray(); - - // column out of range: - assertEquals(Color.RED, - rcs.applyConservation(Color.RED, consensus.length())); - - /* - * with 100% threshold, 'fade factor' is - * (11-score)/10 * 100/20 = (11-score)/2 - * which is >= 1 for all scores i.e. all fade to white except +, * - */ - rcs.setConservationInc(100); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); - - /* - * with 0% threshold, there should be no fading - */ - rcs.setConservationInc(0); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10)); - assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11)); - assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap - - /* - * with 40% threshold, 'fade factor' is - * (11-score)/10 * 40/20 = (11-score)/5 - * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9 - * e.g. score 7 colour fades 80% of the way to white (255, 255, 255) - */ - rcs.setConservationInc(40); - Color colour = new Color(155, 105, 55); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 0)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 1)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 2)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 3)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 4)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 5)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 6)); - assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7)); - assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8)); - assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9)); - assertEquals(colour, rcs.applyConservation(colour, 10)); - assertEquals(colour, rcs.applyConservation(colour, 11)); - assertEquals(Color.WHITE, rcs.applyConservation(colour, 12)); - } - - @Test(groups = "Functional") public void testIsApplicableTo() { SequenceI pep1 = new Sequence("pep1", "APQTWLS");