From: gmungoc Date: Mon, 13 Nov 2017 16:39:02 +0000 (+0000) Subject: Merge branch 'develop' into features/JAL-1793VCF X-Git-Tag: Release_2_11_0~137 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=c68e41c5f6d66c05ded22a514e5b0fa5775627b6;hp=9f58b747475c9aae8d5acfb52b5c25c778662e4e;p=jalview.git Merge branch 'develop' into features/JAL-1793VCF Conflicts: .classpath build.xml resources/lang/Messages.properties --- diff --git a/.classpath b/.classpath index 441ba60..c85feaf 100644 --- a/.classpath +++ b/.classpath @@ -66,8 +66,8 @@ - + diff --git a/benchmarking/README b/benchmarking/README index 60b94a9..fac0bf6 100644 --- a/benchmarking/README +++ b/benchmarking/README @@ -1,11 +1,13 @@ To set up benchmarking: -1. In the jalview directory run +You will need to install Maven: https://maven.apache.org/install.html + +1. Run the makedist target of build.xml in Eclipse, or in the jalview directory run ant makedist This builds a jalview.jar file and puts it into dist/ -2. Make a lib directory in benchmarking/ if not already present. +2. Make a lib directory in benchmarking/ if not already present and cd into this directory. 3. Purge any previous maven dependencies: mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false diff --git a/benchmarking/src/main/java/org/jalview/HiddenColumnsBenchmark.java b/benchmarking/src/main/java/org/jalview/HiddenColumnsBenchmark.java index eb35e3b..d3c67d7 100644 --- a/benchmarking/src/main/java/org/jalview/HiddenColumnsBenchmark.java +++ b/benchmarking/src/main/java/org/jalview/HiddenColumnsBenchmark.java @@ -47,126 +47,128 @@ import jalview.datamodel.HiddenColumns; @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Fork(1) public class HiddenColumnsBenchmark -{ - /* - * State with multiple hidden columns and a start position set - */ - @State(Scope.Thread) - public static class HiddenColsAndStartState - { - @Param({"300", "10000", "100000"}) - public int maxcols; - - @Param({"1", "50", "90"}) - public int startpcnt; // position as percentage of maxcols - - @Param({"1","15","100"}) - public int hide; - - HiddenColumns h = new HiddenColumns(); - Random rand = new Random(); - - public int hiddenColumn; - public int visibleColumn; - - @Setup - public void setup() - { - rand.setSeed(1234); - int lastcol = 0; - while (lastcol < maxcols) - { - int count = rand.nextInt(100); - lastcol += count; - h.hideColumns(lastcol, lastcol+hide); - lastcol+=hide; - } - - // make sure column at start is hidden - hiddenColumn = (int)(maxcols * startpcnt/100.0); - h.hideColumns(hiddenColumn, hiddenColumn); - - // and column after start is visible - ColumnSelection sel = new ColumnSelection(); - h.revealHiddenColumns(hiddenColumn+hide, sel); - visibleColumn = hiddenColumn+hide; - - System.out.println("Maxcols: " + maxcols + " HiddenCol: " + hiddenColumn + " Hide: " + hide); - System.out.println("Number of hidden columns: " + h.getSize()); - } - } - - /* Convention: functions in alphabetical order */ - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public int benchAdjustForHiddenColumns(HiddenColsAndStartState tstate) - { - return tstate.h.adjustForHiddenColumns(tstate.visibleColumn); - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public int benchFindColumnPosition(HiddenColsAndStartState tstate) - { - return tstate.h.findColumnPosition(tstate.visibleColumn); - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public List benchFindHiddenRegionPositions(HiddenColsAndStartState tstate) - { - return tstate.h.findHiddenRegionPositions(); - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public ArrayList benchGetHiddenColumnsCopy(HiddenColsAndStartState tstate) - { - return tstate.h.getHiddenColumnsCopy(); - } - - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public int benchGetSize(HiddenColsAndStartState tstate) - { - return tstate.h.getSize(); - } +{ + /* + * State with multiple hidden columns and a start position set + */ + @State(Scope.Thread) + public static class HiddenColsAndStartState + { + @Param({ "300", "10000", "100000" }) + public int maxcols; - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public HiddenColumns benchHideCols(HiddenColsAndStartState tstate) - { - tstate.h.hideColumns(tstate.visibleColumn, - tstate.visibleColumn+2000); - return tstate.h; - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public boolean benchIsVisible(HiddenColsAndStartState tstate) - { - return tstate.h.isVisible(tstate.hiddenColumn); - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public HiddenColumns benchReveal(HiddenColsAndStartState tstate) - { - ColumnSelection sel = new ColumnSelection(); - tstate.h.revealHiddenColumns(tstate.hiddenColumn, sel); - return tstate.h; - } - - @Benchmark - @BenchmarkMode({Mode.Throughput}) - public HiddenColumns benchRevealAll(HiddenColsAndStartState tstate) + @Param({ "1", "50", "90" }) + public int startpcnt; // position as percentage of maxcols + + @Param({ "1", "15", "100" }) + public int hide; + + HiddenColumns h = new HiddenColumns(); + + Random rand = new Random(); + + public int hiddenColumn; + + public int visibleColumn; + + @Setup + public void setup() { - ColumnSelection sel = new ColumnSelection(); - tstate.h.revealAllHiddenColumns(sel); - return tstate.h; + rand.setSeed(1234); + int lastcol = 0; + while (lastcol < maxcols) + { + int count = rand.nextInt(100); + lastcol += count; + h.hideColumns(lastcol, lastcol + hide); + lastcol += hide; + } + + // make sure column at start is hidden + hiddenColumn = (int) (maxcols * startpcnt / 100.0); + h.hideColumns(hiddenColumn, hiddenColumn); + + // and column after start is visible + ColumnSelection sel = new ColumnSelection(); + h.revealHiddenColumns(hiddenColumn + hide, sel); + visibleColumn = hiddenColumn + hide; + + System.out.println("Maxcols: " + maxcols + " HiddenCol: " + + hiddenColumn + " Hide: " + hide); + System.out.println("Number of hidden columns: " + h.getSize()); } - - + } + + /* Convention: functions in alphabetical order */ + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public int benchAdjustForHiddenColumns(HiddenColsAndStartState tstate) + { + return tstate.h.adjustForHiddenColumns(tstate.visibleColumn); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public int benchFindColumnPosition(HiddenColsAndStartState tstate) + { + return tstate.h.findColumnPosition(tstate.visibleColumn); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public List benchFindHiddenRegionPositions( + HiddenColsAndStartState tstate) + { + return tstate.h.findHiddenRegionPositions(); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public ArrayList benchGetHiddenColumnsCopy( + HiddenColsAndStartState tstate) + { + return tstate.h.getHiddenColumnsCopy(); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public int benchGetSize(HiddenColsAndStartState tstate) + { + return tstate.h.getSize(); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public HiddenColumns benchHideCols(HiddenColsAndStartState tstate) + { + tstate.h.hideColumns(tstate.visibleColumn, tstate.visibleColumn + 2000); + return tstate.h; + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public boolean benchIsVisible(HiddenColsAndStartState tstate) + { + return tstate.h.isVisible(tstate.hiddenColumn); + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public HiddenColumns benchReveal(HiddenColsAndStartState tstate) + { + ColumnSelection sel = new ColumnSelection(); + tstate.h.revealHiddenColumns(tstate.hiddenColumn, sel); + return tstate.h; + } + + @Benchmark + @BenchmarkMode({ Mode.Throughput }) + public HiddenColumns benchRevealAll(HiddenColsAndStartState tstate) + { + ColumnSelection sel = new ColumnSelection(); + tstate.h.revealAllHiddenColumns(sel); + return tstate.h; + } + } \ No newline at end of file diff --git a/build.xml b/build.xml index 436148a..43d6a0c 100755 --- a/build.xml +++ b/build.xml @@ -451,10 +451,9 @@ - + j2se version="1.8+" - - + diff --git a/help/helpTOC.xml b/help/helpTOC.xml index 4636ea3..7ba4ee5 100755 --- a/help/helpTOC.xml +++ b/help/helpTOC.xml @@ -24,13 +24,7 @@ - - - - - - - + diff --git a/help/html/features/pdbseqfetcher.png b/help/html/features/pdbseqfetcher.png index 97a779a..2081a3d 100644 Binary files a/help/html/features/pdbseqfetcher.png and b/help/html/features/pdbseqfetcher.png differ diff --git a/help/html/features/pdbsequencefetcher.html b/help/html/features/pdbsequencefetcher.html index 2962ba6..bb63bed 100644 --- a/help/html/features/pdbsequencefetcher.html +++ b/help/html/features/pdbsequencefetcher.html @@ -37,7 +37,7 @@

To open the PDB Sequence Fetcher, select PDB as the database from any Sequence Fetcher dialog (opened via - "File →Fetch Sequences"). + "File →Fetch Sequences").

PDB sequence fetcher (introduced in Jalview 2.9) @@ -45,13 +45,18 @@

Searching the PDB Database

+

To search the PDB, begin typing in the text box. If the + 'autosearch' checkbox is enabled, then the results of your query + will be automatically updated and shown in the search results tab; + otherwise, press return to update the results. To access previous + searches, press the down-arrow or click the drop down menu icon at + the side of the search box. If you just want to paste in a list of + IDs, the 'Retrieve IDs' tab provides a batch-retrieval interface.

- To search the PDB, begin typing in the text box. The results of your - query are shown in the search results tab, which updates every time - you type in the search text box. You can sort results according to - the displayed columns, and select entries with the mouse and - keyboard. Once you have selected one or more entries, hit the OK - button to retrieve and view them in Jalview. + You can sort results according to the displayed columns, and select + entries with the mouse and keyboard. Once you have selected one or + more entries, hit the OK button to retrieve and + view them in Jalview.

    @@ -64,9 +69,8 @@ 1xyz:A
  • Bulk PDB retrieval
    Multiple PDB - IDs can be specified by separating them with a semi-colon.
    - e.g. 1xyz;2xyz;3xyz
    Hitting Return or OK will automatically - fetch those IDs, like the default Sequence Fetcher interface.
  • + IDs can be specified for retrieval via the + Retrieve IDs tab.
  • Wild card searching
    The following wild cards are supported by the EMBL-EBI PDBe query service: diff --git a/help/html/features/uniprotseqfetcher.png b/help/html/features/uniprotseqfetcher.png index a592e8e..23b55fa 100644 Binary files a/help/html/features/uniprotseqfetcher.png and b/help/html/features/uniprotseqfetcher.png differ diff --git a/help/html/features/uniprotsequencefetcher.html b/help/html/features/uniprotsequencefetcher.html index edd8995..4a64f52 100644 --- a/help/html/features/uniprotsequencefetcher.html +++ b/help/html/features/uniprotsequencefetcher.html @@ -46,10 +46,13 @@

    Searching the UniProt Database

    -

    - To search UniProt, simply begin typing in the text box. After a - short delay (about 1.5 seconds), results will be shown in the table - below. You can sort results by clicking on the displayed columns, +

    To search UniProt, simply begin typing in the text box. If the + 'autosearch' check box is enabled, then after a short delay (about + 1.5 seconds), results will be shown in the table below. Results are + also updated whenever you press Enter, and you can access previous + searches by pressing the 'Down' arrow or clicking the drop-down menu + icon at the side of the search box.

    +

    You can sort results by clicking on the displayed columns, and select entries with the mouse or keyboard. Once you have selected one or more entries, hit the OK button to retrieve the sequences. @@ -61,11 +64,8 @@

  • Bulk UniProt record retrieval
    To - retrieve several uniprot accessions at once, first select UniProt - ID from the dropdown menu, then paste in the accession IDs as a - semi-colon separated list. (e.g. fila_human; mnt_human; - mnt_mouse).
    Hitting Return or OK will automatically fetch - those IDs, like the default Sequence Fetcher interface.
  • + retrieve sequences for a list of Uniprot accessions, please enter + them via the 'Retrieve IDs' tab.
  • Complex queries with the UniProt query Syntax The text box also allows complex diff --git a/help/html/releases.html b/help/html/releases.html index 859b081..6396313 100755 --- a/help/html/releases.html +++ b/help/html/releases.html @@ -95,8 +95,15 @@ li:before {
  • Stop codons are excluded in CDS/Protein view from Ensembl locus cross-references
  • Start/End limits are shown in Pairwise Alignment report
  • +
  • Sequence fetcher's Free text 'autosearch' feature can be disabled
  • +
  • Retrieve IDs tab added for UniProt and PDB easier retrieval of sequences for lists of IDs
  • + +
+ Scripting +
    +
  • Groovy interpreter updated to 2.4.12
  • +
  • Example groovy script for generating a matrix of percent identity scores for current alignment.
-
  • Example groovy script for generating a matrix of percent identity scores for current alignment.
Testing and Deployment
  • Test to catch memory leaks in Jalview UI
@@ -133,7 +140,8 @@ li:before {
  • Alignment ruler height set incorrectly after canceling the Alignment Window's Font dialog
  • Show cross-references not enabled after restoring project until a new view is created
  • Warning popup about use of SEQUENCE_ID in URL links appears when only default EMBL-EBI link is configured (since 2.10.2b2)
  • -
  • Overview redraws whole window when box position is adjusted
  • +
  • Overview redraws whole window when box position is adjusted
  • +
  • Structure viewer doesn't map all chains in a multi-chain structure when viewing alignment involving more than one chain (since 2.10)
  • Applet
      @@ -145,6 +153,17 @@ li:before { BioJSON export does not preserve non-positional features
    + Known Java 9 Issues +
      +
    • Groovy Console very slow to open and is + not responsive when entering characters (Webstart, Java 9.01, + OSX 10.10) +
    • +
    + New Known Issues +
      +
    • +
    diff --git a/help/html/whatsNew.html b/help/html/whatsNew.html index 3475012..9cf1044 100755 --- a/help/html/whatsNew.html +++ b/help/html/whatsNew.html @@ -27,11 +27,18 @@ What's new in Jalview 2.10.3 ?

    - Version 2.10.3 is due for release in October 2017. The full list of + Version 2.10.3 was released in November 2017. The full list of bug fixes and new features can be found in the 2.10.3 Release Notes, but the highlights are below.

    +
      +
    • Faster import and more responsive UI when working with wide alignments and handling hundreds and thousands of sequence features
    • +
    • +
    • Improved usability with PDB and + UniProt Free Text Search + dialog, and new tab for retrieval of sequences for lists of IDs.
    • +

    Experimental Features

    diff --git a/lib/groovy-all-2.4.6-indy.jar b/lib/groovy-all-2.4.12-indy.jar similarity index 62% rename from lib/groovy-all-2.4.6-indy.jar rename to lib/groovy-all-2.4.12-indy.jar index 5f3d51c..bb246a3 100644 Binary files a/lib/groovy-all-2.4.6-indy.jar and b/lib/groovy-all-2.4.12-indy.jar differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 75c002a..39ec4f1 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1350,3 +1350,6 @@ label.colour_by_label = Colour by label label.variable_colour = Variable colour label.select_new_colour = Select new colour label.no_feature_attributes = No feature attributes found +option.enable_disable_autosearch = When ticked, search is performed automatically. +option.autosearch = Autosearch +label.retrieve_ids = Retrieve IDs diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 1905f42..9e81d81 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -77,11 +77,6 @@ public class Sequence extends ASequence implements SequenceI */ Vector annotation; - /** - * The index of the sequence in a MSA - */ - int index = -1; - private SequenceFeaturesI sequenceFeatureStore; /* @@ -1739,30 +1734,6 @@ public class Sequence extends ASequence implements SequenceI } } - /** - * @return The index (zero-based) on this sequence in the MSA. It returns - * {@code -1} if this information is not available. - */ - @Override - public int getIndex() - { - return index; - } - - /** - * Defines the position of this sequence in the MSA. Use the value {@code -1} - * if this information is undefined. - * - * @param The - * position for this sequence. This value is zero-based (zero for - * this first sequence) - */ - @Override - public void setIndex(int value) - { - index = value; - } - @Override public void setRNA(RNA r) { diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 28be85f..c064373 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -450,17 +450,6 @@ public interface SequenceI extends ASequenceI public void transferAnnotation(SequenceI entry, Mapping mp); /** - * @param index - * The sequence index in the MSA - */ - public void setIndex(int index); - - /** - * @return The index of the sequence in the alignment - */ - public int getIndex(); - - /** * @return The RNA of the sequence in the alignment */ diff --git a/src/jalview/ext/ensembl/EnsemblGenomes.java b/src/jalview/ext/ensembl/EnsemblGenomes.java index b40df50..bbd1f26 100644 --- a/src/jalview/ext/ensembl/EnsemblGenomes.java +++ b/src/jalview/ext/ensembl/EnsemblGenomes.java @@ -44,11 +44,13 @@ public class EnsemblGenomes extends EnsemblGene return "EnsemblGenomes"; } - private String Wrong[]; @Override public String getTestQuery() { - return "DDB_G0283883"; + /* + * Salmonella gene, Uniprot Q8Z9G6, EMBLCDS CAD01290 + */ + return "CAD01290"; } @Override diff --git a/src/jalview/fts/api/GFTSPanelI.java b/src/jalview/fts/api/GFTSPanelI.java index 99c0c51..974cc88 100644 --- a/src/jalview/fts/api/GFTSPanelI.java +++ b/src/jalview/fts/api/GFTSPanelI.java @@ -145,4 +145,11 @@ public interface GFTSPanelI * @return */ public String getCacheKey(); + + /** + * + * @return user preference name for configuring this FTS search's autosearch + * checkbox + */ + public String getAutosearchPreference(); } diff --git a/src/jalview/fts/core/GFTSPanel.java b/src/jalview/fts/core/GFTSPanel.java index c0d005f..9802d4b 100644 --- a/src/jalview/fts/core/GFTSPanel.java +++ b/src/jalview/fts/core/GFTSPanel.java @@ -56,6 +56,7 @@ import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JInternalFrame; @@ -88,6 +89,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI protected JInternalFrame mainFrame = new JInternalFrame( getFTSFrameTitle()); + protected JTabbedPane tabs = new JTabbedPane(); protected IProgressIndicator progressIndicator; protected JComboBox cmb_searchTarget = new JComboBox(); @@ -98,6 +100,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI protected JButton btn_cancel = new JButton(); + protected JCheckBox btn_autosearch = new JCheckBox(); + protected JvCacheableInputBox txt_search; protected SequenceFetcher seqFetcher; @@ -239,16 +243,38 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI public GFTSPanel() { + this(null); + } + + public GFTSPanel(SequenceFetcher fetcher) + { try { + if (fetcher == null) + { + tabs = null; + } jbInit(); + if (fetcher != null) + { + tabs.addTab(MessageManager.getString("label.retrieve_ids"), + fetcher); + fetcher.setDatabaseChooserVisible(false); + fetcher.embedWithFTSPanel(this); + } mainFrame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT)); + final JPanel ftsPanel = this; mainFrame.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { - txt_search.requestFocusInWindow(); + // TODO: make selected tab gain focus in correct widget + if (tabs != null + && tabs.getSelectedComponent() == ftsPanel) + { + txt_search.requestFocusInWindow(); + } } }); mainFrame.invalidate(); @@ -331,6 +357,20 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI } }); + btn_autosearch.setText(MessageManager.getString("option.autosearch")); + btn_autosearch.setToolTipText( + MessageManager.getString("option.enable_disable_autosearch")); + btn_autosearch.setSelected( + jalview.bin.Cache.getDefault(getAutosearchPreference(), true)); + btn_autosearch.addActionListener(new java.awt.event.ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + jalview.bin.Cache.setProperty(getAutosearchPreference(), + Boolean.toString(btn_autosearch.isSelected())); + } + }); btn_back.setFont(new java.awt.Font("Verdana", 0, 12)); btn_back.setText(MessageManager.getString("action.back")); btn_back.addActionListener(new java.awt.event.ActionListener() @@ -511,8 +551,14 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI if (primaryKeyName.equalsIgnoreCase(getCmbSearchTarget() .getSelectedItem().toString())) { + // TODO: nicer to show the list in the result set before + // viewing in Jalview perhaps ? transferToSequenceFetcher(getTypedText()); } + else + { + performSearchAction(); + } } } }); @@ -522,12 +568,10 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI @Override public void actionPerformed(ActionEvent e) { - String typed = getTypedText(); - if (!typed.equalsIgnoreCase(lastSearchTerm)) + if (btn_autosearch.isSelected() + || txt_search.wasEnterPressed()) { - searchAction(true); - paginatorCart.clear(); - lastSearchTerm = typed; + performSearchAction(); } } }, false); @@ -549,6 +593,15 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI } }); + txt_search.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + performSearchAction(); + } + }); final String searchTabTitle = MessageManager .getString("label.search_result"); final String configureCols = MessageManager @@ -613,6 +666,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI pnl_results.add(tabbedPane); pnl_inputs.add(cmb_searchTarget); pnl_inputs.add(txt_search); + pnl_inputs.add(btn_autosearch); pnl_inputs.add(lbl_loading); pnl_inputs.add(lbl_warning); pnl_inputs.add(lbl_blank); @@ -624,7 +678,17 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI this.add(pnl_results, java.awt.BorderLayout.CENTER); this.add(pnl_actions, java.awt.BorderLayout.SOUTH); mainFrame.setVisible(true); - mainFrame.setContentPane(this); + if (tabs != null) + { + tabs.setOpaque(true); + tabs.insertTab("Free Text Search", null, this, "", 0); + mainFrame.setContentPane(tabs); + tabs.setVisible(true); + } + else + { + mainFrame.setContentPane(this); + } mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); mainFrame.addInternalFrameListener( new javax.swing.event.InternalFrameAdapter() @@ -635,8 +699,6 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI closeAction(); } }); - mainFrame.setVisible(true); - mainFrame.setContentPane(this); mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); Integer x = getTempUserPrefs().get("FTSPanel.x"); Integer y = getTempUserPrefs().get("FTSPanel.y"); @@ -698,6 +760,18 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI } + void performSearchAction() + { + String typed = getTypedText(); + if (typed != null && typed.length() > 0 + && !typed.equalsIgnoreCase(lastSearchTerm)) + { + searchAction(true); + paginatorCart.clear(); + lastSearchTerm = typed; + } + } + public boolean wantedFieldsUpdated() { if (previousWantedFields == null) @@ -774,7 +848,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI } } - protected void btn_back_ActionPerformed() + public void btn_back_ActionPerformed() { closeAction(); new SequenceFetcher(progressIndicator); @@ -787,7 +861,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI btn_cancel.setEnabled(false); } - protected void btn_cancel_ActionPerformed() + public void btn_cancel_ActionPerformed() { closeAction(); } diff --git a/src/jalview/fts/service/pdb/PDBFTSPanel.java b/src/jalview/fts/service/pdb/PDBFTSPanel.java index 19f7db4..053d91b 100644 --- a/src/jalview/fts/service/pdb/PDBFTSPanel.java +++ b/src/jalview/fts/service/pdb/PDBFTSPanel.java @@ -43,9 +43,11 @@ public class PDBFTSPanel extends GFTSPanel private static final String PDB_FTS_CACHE_KEY = "CACHE.PDB_FTS"; + private static final String PDB_AUTOSEARCH = "FTS.PDB.AUTOSEARCH"; + public PDBFTSPanel(SequenceFetcher fetcher) { - super(); + super(fetcher); pageLimit = PDBFTSRestClient.getInstance().getDefaultResponsePageSize(); this.seqFetcher = fetcher; this.progressIndicator = (fetcher == null) ? null @@ -281,4 +283,9 @@ public class PDBFTSPanel extends GFTSPanel return PDB_FTS_CACHE_KEY; } -} + @Override + public String getAutosearchPreference() + { + return PDB_AUTOSEARCH; + } +} \ No newline at end of file diff --git a/src/jalview/fts/service/uniprot/UniprotFTSPanel.java b/src/jalview/fts/service/uniprot/UniprotFTSPanel.java index 020331a..df54dea 100644 --- a/src/jalview/fts/service/uniprot/UniprotFTSPanel.java +++ b/src/jalview/fts/service/uniprot/UniprotFTSPanel.java @@ -44,9 +44,11 @@ public class UniprotFTSPanel extends GFTSPanel private static final String UNIPROT_FTS_CACHE_KEY = "CACHE.UNIPROT_FTS"; + private static final String UNIPROT_AUTOSEARCH = "FTS.UNIPROT.AUTOSEARCH"; + public UniprotFTSPanel(SequenceFetcher fetcher) { - super(); + super(fetcher); pageLimit = UniProtFTSRestClient.getInstance() .getDefaultResponsePageSize(); this.seqFetcher = fetcher; @@ -237,4 +239,10 @@ public class UniprotFTSPanel extends GFTSPanel { return UNIPROT_FTS_CACHE_KEY; } + + @Override + public String getAutosearchPreference() + { + return UNIPROT_AUTOSEARCH; + } } diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 90271c8..4d09084 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -583,58 +583,6 @@ public class AlignViewport extends AlignmentViewport .getStructureSelectionManager(Desktop.instance); } - /** - * - * @param pdbEntries - * @return an array of SequenceI arrays, one for each PDBEntry, listing which - * sequences in the alignment hold a reference to it - */ - public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries) - { - List seqvectors = new ArrayList(); - for (PDBEntry pdb : pdbEntries) - { - List choosenSeqs = new ArrayList(); - for (SequenceI sq : alignment.getSequences()) - { - Vector pdbRefEntries = sq.getDatasetSequence() - .getAllPDBEntries(); - if (pdbRefEntries == null) - { - continue; - } - for (PDBEntry pdbRefEntry : pdbRefEntries) - { - if (pdbRefEntry.getId().equals(pdb.getId())) - { - if (pdbRefEntry.getChainCode() != null - && pdb.getChainCode() != null) - { - if (pdbRefEntry.getChainCode().equalsIgnoreCase( - pdb.getChainCode()) && !choosenSeqs.contains(sq)) - { - choosenSeqs.add(sq); - continue; - } - } - else - { - if (!choosenSeqs.contains(sq)) - { - choosenSeqs.add(sq); - continue; - } - } - - } - } - } - seqvectors - .add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()])); - } - return seqvectors.toArray(new SequenceI[seqvectors.size()][]); - } - @Override public boolean isNormaliseSequenceLogo() { diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index e05230b..8d46792 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -26,6 +26,7 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.fts.core.GFTSPanel; import jalview.fts.service.pdb.PDBFTSPanel; import jalview.fts.service.uniprot.UniprotFTSPanel; import jalview.io.FileFormatI; @@ -78,6 +79,8 @@ public class SequenceFetcher extends JPanel implements Runnable JButton close = new JButton(); + JButton back = new JButton(); + JPanel jPanel1 = new JPanel(); JTextArea textArea = new JTextArea(); @@ -383,6 +386,15 @@ public class SequenceFetcher extends JPanel implements Runnable .getString("label.additional_sequence_fetcher")); } + GFTSPanel parentFTSframe = null; + /** + * change the buttons so they fit with the FTS panel. + */ + public void embedWithFTSPanel(GFTSPanel toClose) + { + back.setVisible(true); + parentFTSframe = toClose; + } private void jbInit() throws Exception { this.setLayout(borderLayout2); @@ -427,7 +439,7 @@ public class SequenceFetcher extends JPanel implements Runnable example_actionPerformed(); } }); - close.setText(MessageManager.getString("action.close")); + close.setText(MessageManager.getString("action.cancel")); close.addActionListener(new ActionListener() { @Override @@ -436,6 +448,17 @@ public class SequenceFetcher extends JPanel implements Runnable close_actionPerformed(e); } }); + back.setText(MessageManager.getString("action.back")); + back.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + parentFTSframe.btn_back_ActionPerformed(); + } + }); + // back not visible unless embedded + back.setVisible(false); textArea.setFont(JvSwingUtils.getLabelFont()); textArea.setLineWrap(true); textArea.addKeyListener(new KeyAdapter() @@ -451,9 +474,10 @@ public class SequenceFetcher extends JPanel implements Runnable }); jPanel3.setLayout(borderLayout1); borderLayout1.setVgap(5); - jPanel1.add(ok); + jPanel1.add(back); jPanel1.add(example); jPanel1.add(clear); + jPanel1.add(ok); jPanel1.add(close); jPanel2.setLayout(borderLayout3); databaseButt = /*database.getDatabaseSelectorButton(); @@ -582,6 +606,10 @@ public class SequenceFetcher extends JPanel implements Runnable try { frame.setClosed(true); + if (parentFTSframe!=null) + { + parentFTSframe.btn_cancel_ActionPerformed(); + } } catch (Exception ex) { } @@ -594,7 +622,7 @@ public class SequenceFetcher extends JPanel implements Runnable textArea.setEnabled(false); ok.setEnabled(false); close.setEnabled(false); - + back.setEnabled(false); Thread worker = new Thread(this); worker.start(); } @@ -606,6 +634,7 @@ public class SequenceFetcher extends JPanel implements Runnable textArea.setEnabled(true); ok.setEnabled(true); close.setEnabled(true); + back.setEnabled(parentFTSframe != null); } @Override @@ -1087,4 +1116,9 @@ public class SequenceFetcher extends JPanel implements Runnable { frame.setVisible(false); } + + public void setDatabaseChooserVisible(boolean b) + { + databaseButt.setVisible(b); + } } diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 20f4a49..37632ef 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -927,16 +927,10 @@ public class StructureChooser extends GStructureChooser } if (pdbEntriesToView.length > 1) { - ArrayList seqsMap = new ArrayList<>(); - for (SequenceI seq : sequences) - { - seqsMap.add(new SequenceI[] { seq }); - } - SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]); - - setProgressBar(MessageManager - .getString("status.fetching_3d_structures_for_selected_entries"), progressId); - sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel); + setProgressBar(MessageManager.getString( + "status.fetching_3d_structures_for_selected_entries"), + progressId); + sViewer.viewStructures(pdbEntriesToView, sequences, alignPanel); } else { diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java index e58b378..b142613 100644 --- a/src/jalview/gui/StructureViewer.java +++ b/src/jalview/gui/StructureViewer.java @@ -29,19 +29,24 @@ import jalview.structure.StructureSelectionManager; import java.awt.Rectangle; import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** - * proxy for handling structure viewers. - * - * this allows new views to be created with the currently configured viewer, the - * preferred viewer to be set/read and existing views created previously with a - * particular viewer to be recovered + * A proxy for handling structure viewers, that orchestrates adding selected + * structures, associated with sequences in Jalview, to an existing viewer, or + * opening a new one. Currently supports either Jmol or Chimera as the structure + * viewer. * * @author jprocter */ public class StructureViewer { + private static final String UNKNOWN_VIEWER_TYPE = "Unknown structure viewer type "; + StructureSelectionManager ssm; public enum ViewerType @@ -49,6 +54,16 @@ public class StructureViewer JMOL, CHIMERA }; + /** + * Constructor + * + * @param structureSelectionManager + */ + public StructureViewer(StructureSelectionManager structureSelectionManager) + { + ssm = structureSelectionManager; + } + public ViewerType getViewerType() { String viewType = Cache.getDefault(Preferences.STRUCTURE_DISPLAY, @@ -61,135 +76,157 @@ public class StructureViewer Cache.setProperty(Preferences.STRUCTURE_DISPLAY, type.name()); } - public StructureViewer( - StructureSelectionManager structureSelectionManager) - { - ssm = structureSelectionManager; - } - /** * View multiple PDB entries, each with associated sequences * * @param pdbs - * @param seqsForPdbs + * @param seqs * @param ap * @return */ public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs, - SequenceI[][] seqsForPdbs, AlignmentPanel ap) + SequenceI[] seqs, AlignmentPanel ap) { - JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqsForPdbs, ap); + JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqs, ap); if (viewer != null) { + /* + * user added structure to an existing viewer - all done + */ return viewer; } - return viewStructures(getViewerType(), pdbs, seqsForPdbs, ap); + + ViewerType viewerType = getViewerType(); + + Map seqsForPdbs = getSequencesForPdbs(pdbs, + seqs); + PDBEntry[] pdbsForFile = seqsForPdbs.keySet().toArray( + new PDBEntry[seqsForPdbs.size()]); + SequenceI[][] theSeqs = seqsForPdbs.values().toArray( + new SequenceI[seqsForPdbs.size()][]); + JalviewStructureDisplayI sview = null; + if (viewerType.equals(ViewerType.JMOL)) + { + sview = new AppJmol(ap, pdbsForFile, theSeqs); + } + else if (viewerType.equals(ViewerType.CHIMERA)) + { + sview = new ChimeraViewFrame(pdbsForFile, theSeqs, ap); + } + else + { + Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString()); + } + return sview; } /** - * A strictly temporary method pending JAL-1761 refactoring. Determines if all - * the passed PDB entries are the same (this is the case if selected sequences - * to view structure for are chains of the same structure). If so, calls the - * single-pdb version of viewStructures and returns the viewer, else returns - * null. + * Converts the list of selected PDB entries (possibly including duplicates + * for multiple chains), and corresponding sequences, into a map of sequences + * for each distinct PDB file. Returns null if either argument is null, or + * their lengths do not match. * * @param pdbs - * @param seqsForPdbs - * @param ap + * @param seqs * @return */ - private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs, - SequenceI[][] seqsForPdbs, AlignmentPanel ap) + Map getSequencesForPdbs(PDBEntry[] pdbs, + SequenceI[] seqs) { - List seqs = new ArrayList(); - if (pdbs == null || pdbs.length == 0) + if (pdbs == null || seqs == null || pdbs.length != seqs.length) { return null; } - int i = 0; - String firstFile = pdbs[0].getFile(); - for (PDBEntry pdb : pdbs) + + /* + * we want only one 'representative' PDBEntry per distinct file name + * (there may be entries for distinct chains) + */ + Map pdbsSeen = new HashMap<>(); + + /* + * LinkedHashMap preserves order of PDB entries (significant if they + * will get superimposed to the first structure) + */ + Map> pdbSeqs = new LinkedHashMap<>(); + for (int i = 0; i < pdbs.length; i++) { + PDBEntry pdb = pdbs[i]; + SequenceI seq = seqs[i]; String pdbFile = pdb.getFile(); - if (pdbFile == null || !pdbFile.equals(firstFile)) + if (!pdbsSeen.containsKey(pdbFile)) { - return null; + pdbsSeen.put(pdbFile, pdb); + pdbSeqs.put(pdb, new ArrayList()); + } + else + { + pdb = pdbsSeen.get(pdbFile); } - SequenceI[] pdbseqs = seqsForPdbs[i++]; - if (pdbseqs != null) + List seqsForPdb = pdbSeqs.get(pdb); + if (!seqsForPdb.contains(seq)) { - for (SequenceI sq : pdbseqs) - { - seqs.add(sq); - } + seqsForPdb.add(seq); } } - return viewStructures(pdbs[0], seqs.toArray(new SequenceI[seqs.size()]), - ap); - } - - public JalviewStructureDisplayI viewStructures(PDBEntry pdb, - SequenceI[] seqsForPdb, AlignmentPanel ap) - { - return viewStructures(getViewerType(), pdb, seqsForPdb, ap); - } - protected JalviewStructureDisplayI viewStructures(ViewerType viewerType, - PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap) - { - PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs); - JalviewStructureDisplayI sview = null; - if (viewerType.equals(ViewerType.JMOL)) - { - sview = new AppJmol(ap, pdbsForFile, - ap.av.collateForPDB(pdbsForFile)); - } - else if (viewerType.equals(ViewerType.CHIMERA)) + /* + * convert to Map + */ + Map result = new LinkedHashMap<>(); + for (Entry> entry : pdbSeqs.entrySet()) { - sview = new ChimeraViewFrame(pdbsForFile, - ap.av.collateForPDB(pdbsForFile), ap); + List theSeqs = entry.getValue(); + result.put(entry.getKey(), + theSeqs.toArray(new SequenceI[theSeqs.size()])); } - else - { - Cache.log.error("Unknown structure viewer type " - + getViewerType().toString()); - } - return sview; + + return result; } /** - * Convert the array of PDBEntry into an array with no filename repeated + * A strictly temporary method pending JAL-1761 refactoring. Determines if all + * the passed PDB entries are the same (this is the case if selected sequences + * to view structure for are chains of the same structure). If so, calls the + * single-pdb version of viewStructures and returns the viewer, else returns + * null. * * @param pdbs + * @param seqsForPdbs + * @param ap * @return */ - static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs) + private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs, + SequenceI[] seqsForPdbs, AlignmentPanel ap) { - if (pdbs == null) + List seqs = new ArrayList(); + if (pdbs == null || pdbs.length == 0) { return null; } - List uniques = new ArrayList(); - List filesSeen = new ArrayList(); - for (PDBEntry entry : pdbs) + int i = 0; + String firstFile = pdbs[0].getFile(); + for (PDBEntry pdb : pdbs) { - String file = entry.getFile(); - if (file == null) + String pdbFile = pdb.getFile(); + if (pdbFile == null || !pdbFile.equals(firstFile)) { - uniques.add(entry); + return null; } - else if (!filesSeen.contains(file)) + SequenceI pdbseq = seqsForPdbs[i++]; + if (pdbseq != null) { - uniques.add(entry); - filesSeen.add(file); + seqs.add(pdbseq); } } - return uniques.toArray(new PDBEntry[uniques.size()]); + return viewStructures(pdbs[0], seqs.toArray(new SequenceI[seqs.size()]), + ap); } - protected JalviewStructureDisplayI viewStructures(ViewerType viewerType, - PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap) + public JalviewStructureDisplayI viewStructures(PDBEntry pdb, + SequenceI[] seqsForPdb, AlignmentPanel ap) { + ViewerType viewerType = getViewerType(); JalviewStructureDisplayI sview = null; if (viewerType.equals(ViewerType.JMOL)) { @@ -201,8 +238,7 @@ public class StructureViewer } else { - Cache.log.error("Unknown structure viewer type " - + getViewerType().toString()); + Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString()); } return sview; } @@ -242,7 +278,7 @@ public class StructureViewer "Unsupported structure viewer type " + type.toString()); break; default: - Cache.log.error("Unknown structure viewer type " + type.toString()); + Cache.log.error(UNKNOWN_VIEWER_TYPE + type.toString()); } return sview; } diff --git a/src/jalview/io/AlignFile.java b/src/jalview/io/AlignFile.java index a603cca..2340283 100755 --- a/src/jalview/io/AlignFile.java +++ b/src/jalview/io/AlignFile.java @@ -174,11 +174,6 @@ public abstract class AlignFile extends FileParse } parseCalled = true; parse(); - // sets the index of each sequence in the alignment - for (int i = 0, c = seqs.size(); i < c; i++) - { - seqs.get(i).setIndex(i); - } } /** diff --git a/src/jalview/io/cache/JvCacheableInputBox.java b/src/jalview/io/cache/JvCacheableInputBox.java index 3d0daed..a837512 100644 --- a/src/jalview/io/cache/JvCacheableInputBox.java +++ b/src/jalview/io/cache/JvCacheableInputBox.java @@ -28,6 +28,7 @@ import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -70,11 +71,49 @@ public class JvCacheableInputBox extends JComboBox private JMenuItem menuItemClearCache = new JMenuItem(); + volatile boolean enterWasPressed = false; + + /** + * @return flag indicating if the most recent keypress was enter + */ + public boolean wasEnterPressed() + { + return enterWasPressed; + } + public JvCacheableInputBox(String newCacheKey) { super(); this.cacheKey = newCacheKey; setEditable(true); + addKeyListener(new KeyListener() + { + + @Override + public void keyTyped(KeyEvent e) + { + enterWasPressed = false; + if (e.getKeyCode() == KeyEvent.VK_ENTER) + { + enterWasPressed = true; + } + // let event bubble up + } + + @Override + public void keyReleased(KeyEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) + { + // TODO Auto-generated method stub + + } + }); setPrototypeDisplayValue( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); appCache = AppCache.getInstance(); diff --git a/test/jalview/gui/AlignViewportTest.java b/test/jalview/gui/AlignViewportTest.java index 812fd8f..5ed0cac 100644 --- a/test/jalview/gui/AlignViewportTest.java +++ b/test/jalview/gui/AlignViewportTest.java @@ -96,57 +96,6 @@ public class AlignViewportTest testee = new AlignViewport(al); } - @Test(groups = { "Functional" }) - public void testCollateForPdb() - { - // JBP: What behaviour is this supposed to test ? - /* - * Set up sequence pdb ids - */ - PDBEntry pdb1 = new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb"); - PDBEntry pdb2 = new PDBEntry("2ABC", "C", Type.PDB, "2ABC.pdb"); - PDBEntry pdb3 = new PDBEntry("3ABC", "D", Type.PDB, "3ABC.pdb"); - - /* - * seq1 and seq3 refer to 1abcB, seq2 to 2abcC, none to 3abcD - */ - al.getSequenceAt(0).getDatasetSequence() - .addPDBId(new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb")); - al.getSequenceAt(2).getDatasetSequence() - .addPDBId(new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb")); - al.getSequenceAt(1).getDatasetSequence() - .addPDBId(new PDBEntry("2ABC", "C", Type.PDB, "2ABC.pdb")); - /* - * Add a second chain PDB xref to Seq2 - should not result in a duplicate in - * the results - */ - al.getSequenceAt(1).getDatasetSequence() - .addPDBId(new PDBEntry("2ABC", "D", Type.PDB, "2ABC.pdb")); - /* - * Seq3 refers to 3abc - this does not match 3ABC (as the code stands) - */ - al.getSequenceAt(2).getDatasetSequence() - .addPDBId(new PDBEntry("3abc", "D", Type.PDB, "3ABC.pdb")); - - /* - * run method under test - */ - SequenceI[][] seqs = testee.collateForPDB(new PDBEntry[] { pdb1, pdb2, - pdb3 }); - - // seq1 and seq3 refer to PDBEntry[0] - assertEquals(2, seqs[0].length); - assertSame(al.getSequenceAt(0), seqs[0][0]); - assertSame(al.getSequenceAt(2), seqs[0][1]); - - // seq2 refers to PDBEntry[1] - assertEquals(1, seqs[1].length); - assertSame(al.getSequenceAt(1), seqs[1][0]); - - // no sequence refers to PDBEntry[2] - assertEquals(0, seqs[2].length); - } - /** * Test that a mapping is not deregistered when a second view is closed but * the first still holds a reference to the mapping diff --git a/test/jalview/gui/StructureViewerTest.java b/test/jalview/gui/StructureViewerTest.java index c1c1d5c..4d5b114 100644 --- a/test/jalview/gui/StructureViewerTest.java +++ b/test/jalview/gui/StructureViewerTest.java @@ -1,10 +1,17 @@ package jalview.gui; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; import jalview.datamodel.PDBEntry; import jalview.datamodel.PDBEntry.Type; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import java.util.Map; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -20,9 +27,11 @@ public class StructureViewerTest } @Test(groups = "Functional") - public void testGetUniquePdbFiles() + public void testGetSequencesForPdbs() { - assertNull(StructureViewer.getUniquePdbFiles(null)); + StructureViewer sv = new StructureViewer(null); + + assertNull(sv.getSequencesForPdbs(null, null)); PDBEntry pdbe1 = new PDBEntry("1A70", "A", Type.PDB, "path1"); PDBEntry pdbe2 = new PDBEntry("3A6S", "A", Type.PDB, "path2"); @@ -30,13 +39,45 @@ public class StructureViewerTest PDBEntry pdbe4 = new PDBEntry("1GAQ", "A", Type.PDB, null); PDBEntry pdbe5 = new PDBEntry("3A6S", "B", Type.PDB, "path2"); PDBEntry pdbe6 = new PDBEntry("1GAQ", "B", Type.PDB, null); + PDBEntry[] pdbs = new PDBEntry[] { pdbe1, pdbe2, pdbe3, pdbe4, pdbe5, + pdbe6 }; + + /* + * seq1 ... seq6 associated with pdbe1 ... pdbe6 + */ + SequenceI[] seqs = new SequenceI[pdbs.length]; + for (int i = 0; i < seqs.length; i++) + { + seqs[i] = new Sequence("Seq" + i, "abc"); + } /* - * pdbe2 and pdbe5 get removed as having a duplicate file path + * pdbe3/5/6 should get removed as having a duplicate file path */ - PDBEntry[] uniques = StructureViewer.getUniquePdbFiles(new PDBEntry[] { - pdbe1, pdbe2, pdbe3, pdbe4, pdbe5, pdbe6 }); - assertEquals(uniques, - new PDBEntry[] { pdbe1, pdbe2, pdbe4, pdbe6 }); + Map uniques = sv.getSequencesForPdbs(pdbs, seqs); + assertTrue(uniques.containsKey(pdbe1)); + assertTrue(uniques.containsKey(pdbe2)); + assertFalse(uniques.containsKey(pdbe3)); + assertTrue(uniques.containsKey(pdbe4)); + assertFalse(uniques.containsKey(pdbe5)); + assertFalse(uniques.containsKey(pdbe6)); + + // 1A70 associates with seq1 and seq3 + SequenceI[] ss = uniques.get(pdbe1); + assertEquals(ss.length, 2); + assertSame(seqs[0], ss[0]); + assertSame(seqs[2], ss[1]); + + // 3A6S has seq2 and seq5 + ss = uniques.get(pdbe2); + assertEquals(ss.length, 2); + assertSame(seqs[1], ss[0]); + assertSame(seqs[4], ss[1]); + + // 1GAQ has seq4 and seq6 + ss = uniques.get(pdbe4); + assertEquals(ss.length, 2); + assertSame(seqs[3], ss[0]); + assertSame(seqs[5], ss[1]); } }