This builds a jalview.jar file and puts it into dist/
+
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
+
4. Run
mvn install:install-file -Dfile=../dist/jalview.jar -DgroupId=jalview.org -DartifactId=jalview -Dversion=1.0 -Dpackaging=jar -DlocalRepositoryPath=lib
-
to install the jalview.jar file in the local maven repository. The pom.xml in the benchmarking references this installation, so if you change the names the pom.xml file will also need to be updated.
+
5. Build and run jmh benchmarking. In the benchmarking directory:
mvn clean install
java -jar target/benchmarks.jar
To get JSON output instead use:
java -jar target/benchmarks.jar -rf json
- JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
\ No newline at end of file
+ JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
+
+ To get help use the standard -h option:
+ java -jar target/benchmarks.jar -h
+
+ More information here:
+ http://openjdk.java.net/projects/code-tools/jmh/
+ http://java-performance.info/jmh/
+
+
+ 6. If you make changes to the Jalview code everything will need to be refreshed, by performing steps 3-5 again.
<tocitem text="Jalview Documentation" target="home" expand="true">
<tocitem text="What's new" target="new" expand="true">
<tocitem text="Latest Release Notes" target="release"/>
-
</tocitem>
<tocitem text="Editing Alignments" target="edit" />
<li><p>
<strong>Sort by Pairwise Identity</strong>
</p>
- <p>Places pairs of sequences together that align with the
- greatest fraction of conserved residues.</p>
+ <p>Sorts sequences in the selection or alignment according to percent identity with respect to the first sequence in the view.</p>
<p></li>
<li><p>
<strong>Sort by Tree Order</strong>
<li><strong>Viewing Cached Structures</strong><br />If
previously downloaded structures are available for your
sequences, the structure chooser will automatically offer them
- via the <strong>Cached PDB Entries</strong> view. If you wish
+ via the <strong>Cached Structures</strong> view. If you wish
to download new structures, select one of the PDBe selection
criteria from the drop-down menu.</li>
</ul></li>
</td>
</tr>
<tr>
+ <td width=="60" nowrap>
+ <div align="center">
+ <strong><a name="Jalview.2.10.3b1">2.10.3b1</a><br /> <em>5/12/2017</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em></em>
+ </td>
+ <td><div align="left">
+ <ul>
+ <li><!-- JAL-2851-->Alignment doesn't appear to scroll vertically via trackpad and scrollwheel</li>
+ <li><!-- JAL-2842-->Jalview hangs if up/down arrows pressed in cursor mode when cursor lies in hidden region at start of alignment</li>
+ <li><!-- JAL-2827-->Helix annotation has 'notches' when scrolled into view if columns are hidden</li>
+ <li><!-- JAL-2740-->Annotation column filter can be slow to reset (ie after hitting cancel) for large numbers of hidden columns</li>
+ <li><!-- JAL-2849-->User preference for disabling inclusion of sequence limits when exporting as flat file has no effect</li>
+ <ul>
+ </td>
+ </tr>
+ <tr>
<td width="60" nowrap>
<div align="center">
- <strong><a name="Jalview.2.10.3">2.10.3</a><br />
- <em>14/11/2017</em></strong>
+ <strong><a name="Jalview.2.10.3">2.10.3</a><br /> <em>17/11/2017</em></strong>
</div>
</td>
<td><div align="left">
<!-- JAL-2773 -->Structure views don't get updated unless
their colours have changed
</li>
- <li><!-- JAL-2495 -->All linked sequences are highlighted for a structure mousover (Jmol) or selection (Chimera)</li>
- <li><!-- JAL-2790 -->'Cancel' button in progress bar for JABAWS AACon, RNAAliFold and Disorder prediction jobs
+ <li>
+ <!-- JAL-2495 -->All linked sequences are highlighted for
+ a structure mousover (Jmol) or selection (Chimera)
+ </li>
+ <li>
+ <!-- JAL-2790 -->'Cancel' button in progress bar for
+ JABAWS AACon, RNAAliFold and Disorder prediction jobs
+ </li>
+ <li>
+ <!-- JAL-2617 -->Stop codons are excluded in CDS/Protein
+ view from Ensembl locus cross-references
+ </li>
+ <li>
+ <!-- JAL-2685 -->Start/End limits are shown in Pairwise
+ Alignment report
+ </li>
+ <li>
+ <!-- JAL-2810 -->Sequence fetcher's Free text 'autosearch'
+ feature can be disabled
+ </li>
+ <li>
+ <!-- JAL-2810 -->Retrieve IDs tab added for UniProt and
+ PDB easier retrieval of sequences for lists of IDs
+ </li>
+ <li>
+ <!-- JAL-2758 -->Short names for sequences retrieved from
+ Uniprot
</li>
-
- <li><!-- JAL-2617 -->Stop codons are excluded in CDS/Protein view from Ensembl locus cross-references</li>
- <li><!-- JAL-2685 -->Start/End limits are shown in Pairwise Alignment report</li>
- <li><!-- JAL-2810 -->Sequence fetcher's Free text 'autosearch' feature can be disabled</li>
- <li><!-- JAL-2810 -->Retrieve IDs tab added for UniProt and PDB easier retrieval of sequences for lists of IDs</li>
- <li><!-- JAL-2758 -->Short names for sequences retrieved from Uniprot</li>
</ul>
<em>Scripting</em>
<ul>
<li>Groovy interpreter updated to 2.4.12</li>
- <li>Example groovy script for generating a matrix of percent identity scores for current alignment.</li>
+ <li>Example groovy script for generating a matrix of
+ percent identity scores for current alignment.</li>
</ul>
<em>Testing and Deployment</em>
<ul>
- <li><!-- JAL-2727 -->Test to catch memory leaks in Jalview UI</li>
+ <li>
+ <!-- JAL-2727 -->Test to catch memory leaks in Jalview UI
+ </li>
</ul>
- </div>
- </td>
+ </div></td>
<td><div align="left">
<em>General</em>
<ul>
- <li><!-- JAL-2643 -->Pressing tab after updating the colour threshold text field doesn't trigger an update to the alignment view</li>
- <li><!-- JAL-2682 -->Race condition when parsing sequence ID strings in parallel</li>
- <li><!-- JAL-2608 -->Overview windows are also closed when alignment window is closed</li>
- <li><!-- JAL-2548 -->Export of features doesn't always respect group visibility</li>
- <li><!-- JAL-2541,JAL-2829,JAL-2830 -->Cuts and Sequence Edits don't properly relocate sequence features</li>
+ <li>
+ <!-- JAL-2643 -->Pressing tab after updating the colour
+ threshold text field doesn't trigger an update to the
+ alignment view
+ </li>
+ <li>
+ <!-- JAL-2682 -->Race condition when parsing sequence ID
+ strings in parallel
+ </li>
+ <li>
+ <!-- JAL-2608 -->Overview windows are also closed when
+ alignment window is closed
+ </li>
+ <li>
+ <!-- JAL-2548 -->Export of features doesn't always respect
+ group visibility
+ </li>
+ <li>
+ <!-- JAL-2831 -->Jumping from column 1 to column 100,000
+ takes a long time in Cursor mode
+ </li>
</ul>
<em>Desktop</em>
<ul>
- <li><!-- JAL-2777 -->Structures with whitespace chainCode cannot be viewed in Chimera</li>
- <li><!-- JAL-2728 -->Protein annotation panel too high in CDS/Protein view
- </li>
- <li><!-- JAL-2757 -->Can't edit the query after the server error warning icon is shown in Uniprot and PDB Free Text Search Dialogs
- </li>
- <li><!-- JAL-2253 -->Slow EnsemblGenome ID lookup</li>
- <li><!-- JAL-2529 -->Revised Ensembl REST API CDNA query</li>
- <li><!-- JAL-2739 -->Hidden column marker in last column not rendered when switching back from Wrapped to normal view</li>
- <li><!-- JAL-2768 -->Annotation display corrupted when scrolling right in unwapped alignment view</li>
- <li><!-- JAL-2542 -->Existing features on subsequence incorrectly relocated when full sequence retrieved from database</li>
- <li><!-- JAL-2733 -->Last reported memory still shown when Desktop->Show Memory is unticked (OSX only)</li>
- <li><!-- JAL-2658 -->Amend Features dialog doesn't allow features of same type and group to be selected for amending</li>
- <li><!-- JAL-2524 -->Jalview becomes sluggish in wide alignments when hidden columns are present</li>
- <li><!-- JAL-2392 -->Jalview freezes when loading and displaying several structures</li>
- <li><!-- JAL-2732 -->Black outlines left after resizing or moving a window</li>
- <li><!-- JAL-1900,JAL-1625 -->Unable to minimise windows within the Jalview desktop on OSX</li>
- <li><!-- JAL-2667 -->Mouse wheel doesn't scroll vertically when in wrapped alignment mode</li>
- <li><!-- JAL-2636 -->Scale mark not shown when close to right hand end of alignment</li>
- <li><!-- JAL-2684 -->Pairwise alignment only aligns selected regions of each selected sequence</li>
- <li><!-- JAL-2973 -->Alignment ruler height set incorrectly after canceling the Alignment Window's Font dialog</li>
- <li><!-- JAL-2036 -->Show cross-references not enabled after restoring project until a new view is created</li>
- <li><!-- JAL-2756 -->Warning popup about use of SEQUENCE_ID in URL links appears when only default EMBL-EBI link is configured (since 2.10.2b2)</li>
- <li><!-- JAL-2775 -->Overview redraws whole window when box position is adjusted</li>
- <li><!-- JAL-2225 -->Structure viewer doesn't map all chains in a multi-chain structure when viewing alignment involving more than one chain (since 2.10)</li>
- </ul>
- <strong><em>Applet</em></strong><br/>
- <ul>
- <li><!-- JAL-2687 -->Concurrent modification exception when closing alignment panel</li>
+ <li>
+ <!-- JAL-2777 -->Structures with whitespace chainCode
+ cannot be viewed in Chimera
+ </li>
+ <li>
+ <!-- JAL-2728 -->Protein annotation panel too high in
+ CDS/Protein view
+ </li>
+ <li>
+ <!-- JAL-2757 -->Can't edit the query after the server
+ error warning icon is shown in Uniprot and PDB Free Text
+ Search Dialogs
+ </li>
+ <li>
+ <!-- JAL-2253 -->Slow EnsemblGenome ID lookup
+ </li>
+ <li>
+ <!-- JAL-2529 -->Revised Ensembl REST API CDNA query
+ </li>
+ <li>
+ <!-- JAL-2739 -->Hidden column marker in last column not
+ rendered when switching back from Wrapped to normal view
+ </li>
+ <li>
+ <!-- JAL-2768 -->Annotation display corrupted when
+ scrolling right in unwapped alignment view
+ </li>
+ <li>
+ <!-- JAL-2542 -->Existing features on subsequence
+ incorrectly relocated when full sequence retrieved from
+ database
+ </li>
+ <li>
+ <!-- JAL-2733 -->Last reported memory still shown when
+ Desktop->Show Memory is unticked (OSX only)
+ </li>
+ <li>
+ <!-- JAL-2658 -->Amend Features dialog doesn't allow
+ features of same type and group to be selected for
+ amending
+ </li>
+ <li>
+ <!-- JAL-2524 -->Jalview becomes sluggish in wide
+ alignments when hidden columns are present
+ </li>
+ <li>
+ <!-- JAL-2392 -->Jalview freezes when loading and
+ displaying several structures
+ </li>
+ <li>
+ <!-- JAL-2732 -->Black outlines left after resizing or
+ moving a window
+ </li>
+ <li>
+ <!-- JAL-1900,JAL-1625 -->Unable to minimise windows
+ within the Jalview desktop on OSX
+ </li>
+ <li>
+ <!-- JAL-2667 -->Mouse wheel doesn't scroll vertically
+ when in wrapped alignment mode
+ </li>
+ <li>
+ <!-- JAL-2636 -->Scale mark not shown when close to right
+ hand end of alignment
+ </li>
+ <li>
+ <!-- JAL-2684 -->Pairwise alignment of selected regions of
+ each selected sequence do not have correct start/end
+ positions
+ </li>
+ <li>
+ <!-- JAL-2793 -->Alignment ruler height set incorrectly
+ after canceling the Alignment Window's Font dialog
+ </li>
+ <li>
+ <!-- JAL-2036 -->Show cross-references not enabled after
+ restoring project until a new view is created
+ </li>
+ <li>
+ <!-- JAL-2756 -->Warning popup about use of SEQUENCE_ID in
+ URL links appears when only default EMBL-EBI link is
+ configured (since 2.10.2b2)
+ </li>
+ <li>
+ <!-- JAL-2775 -->Overview redraws whole window when box
+ position is adjusted
+ </li>
+ <li>
+ <!-- JAL-2225 -->Structure viewer doesn't map all chains
+ in a multi-chain structure when viewing alignment
+ involving more than one chain (since 2.10)
+ </li>
+ <li>
+ <!-- JAL-2811 -->Double residue highlights in cursor mode
+ if new selection moves alignment window
+ </li>
+ <li>
+ <!-- JAL-2837,JAL-2840 -->Alignment vanishes when using
+ arrow key in cursor mode to pass hidden column marker
+ </li>
+ <li>
+ <!-- JAL-2679 -->Ensembl Genomes example ID changed to one
+ that produces correctly annotated transcripts and products
+ </li>
+ <li>
+ <!-- JAL-2776 -->Toggling a feature group after first time
+ doesn't update associated structure view
+ </li>
+ </ul>
+ <em>Applet</em><br />
+ <ul>
+ <li>
+ <!-- JAL-2687 -->Concurrent modification exception when
+ closing alignment panel
+ </li>
</ul>
- <strong><em>BioJSON</em></strong><br/>
+ <em>BioJSON</em><br />
<ul>
- <li>
- <!-- JAL-2546 -->BioJSON export does not preserve non-positional features
- </li>
+ <li>
+ <!-- JAL-2546 -->BioJSON export does not preserve
+ non-positional features
+ </li>
</ul>
- <strong>Known Java 9 Issues</strong>
+ <em>New Known Issues</em>
<ul>
- <li><!-- JAL-2902 -->Groovy Console very slow to open and is
- not responsive when entering characters (Webstart, Java 9.01,
- OSX 10.10)
+ <li>
+ <!-- JAL-2541 -->Delete/Cut selection doesn't relocate
+ sequence features correctly (for many previous versions of
+ Jalview)
+ </li>
+ <li>
+ <!-- JAL-2841 -->Cursor mode unexpectedly scrolls when
+ using cursor in wrapped panel other than top
+ </li>
+ <li>
+ <!-- JAL-2791 -->Select columns containing feature ignores
+ graduated colour threshold
+ </li>
+ <li>
+ <!-- JAL-2822,JAL-2823 -->Edit sequence operation doesn't
+ always preserve numbering and sequence features
</li>
</ul>
- <strong>New Known Issues</strong>
+ <em>Known Java 9 Issues</em>
<ul>
- <li><!-- JAL- --></li>
+ <li>
+ <!-- JAL-2902 -->Groovy Console very slow to open and is
+ not responsive when entering characters (Webstart, Java
+ 9.01, OSX 10.10)
+ </li>
</ul>
- </div>
- </td>
+ </div></td>
</tr>
<tr>
<td width="60" nowrap>
<strong>What's new in Jalview 2.10.3 ?</strong>
</p>
<p>
- Version 2.10.3 was released in November 2017. The full list of
- bug fixes and new features can be found in the <a
- href="releases.html#Jalview.2.10.3"> 2.10.3 Release Notes</a>, but
- the highlights are below.
+ Version 2.10.3 was released in November 2017. The major focus was to
+ improve Jalview's sequence features datamodel and the scalability of
+ the alignment rendering system. The full list of bug fixes and new
+ features can be found in the <a href="releases.html#Jalview.2.10.3">2.10.3
+ Release Notes</a>. Key improvements include:
</p>
<ul>
- <li>Faster import and more responsive UI when working with wide alignments and handling hundreds and thousands of sequence features</li>
- <li>
- <li>Improved usability with <a href="features/pdbsequencefetcher.html">PDB</a> and
- <a href="features/uniprotsequencefetcher.html">UniProt</a> Free Text Search
- dialog, and new tab for retrieval of sequences for lists of IDs.</li>
- <li>Short names assigned to sequences retrieved from UniProt</li>
+ <li>Faster and more responsive UI when importing and working
+ with wide alignments and handling hundreds and thousands of
+ sequence features</li>
+ <li>Improved usability with <a
+ href="features/pdbsequencefetcher.html">PDB</a> and <a
+ href="features/uniprotsequencefetcher.html">UniProt</a> Free Text
+ Search dialog, and new tab for retrieval of sequences for lists of
+ IDs.
+ </li>
+ <li>Short names assigned to sequences retrieved from UniProt</li>
+ <li>Groovy console upgraded to 2.4.12 (improved support for Java 9)</li>
</ul>
<p>
<strong><a name="experimental">Experimental Features</a></strong>
</p>
<p>
- This release of Jalview introduces an <em>Experimental Features</em>
- option in the Jalview Desktop's <em>Tools</em> menu that allows you
- to try out features that are still in development. To access the
- experimental features below - first enable the <strong>Tools→Enable
- Experimental Features</strong> option, and then restart Jalview.
+ Remember, please enable the <em>Experimental Features</em> option in
+ the Jalview Desktop's <em>Tools</em> menu, and then restart Jalview
+ if you want to try out features below:
</p>
<ul>
<li><em>Annotation transfer between Chimera and Jalview</em><br />Two
the Chimera viewer's Chimera menu</a> allow positional annotation to
be exchanged between Chimera and Jalview.</li>
</ul>
-
+
</body>
</html>
import java.awt.event.MouseListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
-import java.util.ArrayList;
import java.util.Vector;
//import javax.swing.JPanel;
{
HiddenColumns oldHidden = av.getAnnotationColumnSelectionState()
.getOldHiddenColumns();
- if (oldHidden != null)
- {
- ArrayList<int[]> regions = oldHidden.getHiddenColumnsCopy();
- for (int[] positions : regions)
- {
- av.hideColumns(positions[0], positions[1]);
- }
- }
- // TODO not clear why we need to hide all the columns (above) if we are
- // going to copy the hidden columns over wholesale anyway
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0]);
+ }
+ else if (evt.getPropertyName().equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ repaint();
+ }
}
}
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1]);
+ }
+ else if (propertyName.equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ repaint();
+ }
}
}
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES)
+ || evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ)
+ || evt.getPropertyName().equals(ViewportRanges.MOVE_VIEWPORT))
{
// scroll event, repaint panel
repaint();
{
String eventName = evt.getPropertyName();
+ if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ {
+ fastPaint = true;
+ repaint();
+ return;
+ }
+ else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ fastPaint = false;
+ repaint();
+ return;
+ }
+
if (!av.getWrapAlignment())
{
int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (eventName.equals(ViewportRanges.STARTRES)
+ || eventName.equals(ViewportRanges.STARTRESANDSEQ))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ }
+ else
+ {
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ }
ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
int range = vpRanges.getEndRes() - vpRanges.getStartRes();
if (scrollX > range)
{
// scroll
fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(scrollX, 0);
+ }
}
}
import jalview.util.MappingUtils;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
-import jalview.viewmodel.ViewportRanges;
import java.awt.BorderLayout;
import java.awt.Font;
void setCursorRow()
{
seqCanvas.cursorY = getKeyboardNo1() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void setCursorColumn()
{
seqCanvas.cursorX = getKeyboardNo1() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void setCursorRowAndColumn()
{
seqCanvas.cursorX = getKeyboardNo1() - 1;
seqCanvas.cursorY = getKeyboardNo2() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
}
SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void moveCursor(int dx, int dy)
seqCanvas.cursorX = original;
}
}
- scrollToVisible();
+ scrollToVisible(false);
}
- void scrollToVisible()
+ /**
+ * Scroll to make the cursor visible in the viewport.
+ *
+ * @param jump
+ * just jump to the location rather than scrolling
+ */
+ void scrollToVisible(boolean jump)
{
if (seqCanvas.cursorX < 0)
{
}
endEditing();
- if (av.getWrapAlignment())
+
+ boolean repaintNeeded = true;
+ if (jump)
{
- av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX);
+ // only need to repaint if the viewport did not move, as otherwise it will
+ // get a repaint
+ repaintNeeded = !av.getRanges().setViewportLocation(seqCanvas.cursorX,
+ seqCanvas.cursorY);
}
else
{
- ViewportRanges ranges = av.getRanges();
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- while (seqCanvas.cursorY < ranges.getStartSeq())
+ if (av.getWrapAlignment())
{
- ranges.scrollUp(true);
+ av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX);
}
- while (seqCanvas.cursorY > ranges.getEndSeq())
- {
- ranges.scrollUp(false);
- }
- while (seqCanvas.cursorX < hidden
- .adjustForHiddenColumns(ranges.getStartRes()))
- {
-
- if (!ranges.scrollRight(false))
- {
- break;
- }
- }
- while (seqCanvas.cursorX > hidden
- .adjustForHiddenColumns(ranges.getEndRes()))
+ else
{
- if (!ranges.scrollRight(true))
- {
- break;
- }
+ av.getRanges().scrollToVisible(seqCanvas.cursorX,
+ seqCanvas.cursorY);
}
}
setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
seqCanvas.cursorX, seqCanvas.cursorY);
- seqCanvas.repaint();
+ if (repaintNeeded)
+ {
+ seqCanvas.repaint();
+ }
}
void setSelectionAreaAtCursor(boolean topLeft)
import jalview.util.MessageManager;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
@Override
public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
{
- List<AlignmentAnnotation> aa = new ArrayList<>();
AlignmentAnnotation[] alignmentAnnotation = getAlignmentAnnotation();
if (alignmentAnnotation != null)
{
- for (AlignmentAnnotation a : alignmentAnnotation)
- {
- if (a.getCalcId() == calcId || (a.getCalcId() != null
- && calcId != null && a.getCalcId().equals(calcId)))
- {
- aa.add(a);
- }
- }
+ return AlignmentAnnotation.findAnnotation(
+ Arrays.asList(getAlignmentAnnotation()), calcId);
}
- return aa;
+ return Arrays.asList(new AlignmentAnnotation[] {});
}
@Override
public Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
String calcId, String label)
{
- ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
- for (AlignmentAnnotation ann : getAlignmentAnnotation())
- {
- if ((calcId == null || (ann.getCalcId() != null
- && ann.getCalcId().equals(calcId)))
- && (seq == null || (ann.sequenceRef != null
- && ann.sequenceRef == seq))
- && (label == null
- || (ann.label != null && ann.label.equals(label))))
- {
- aa.add(ann);
- }
- }
- return aa;
+ return AlignmentAnnotation.findAnnotations(
+ Arrays.asList(getAlignmentAnnotation()), seq, calcId, label);
}
@Override
import jalview.analysis.SecStrConsensus.SimpleBP;
import jalview.analysis.WUSSParseException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
{
return graphMin < graphMax;
}
+
+ public static Iterable<AlignmentAnnotation> findAnnotations(
+ Iterable<AlignmentAnnotation> list, SequenceI seq, String calcId,
+ String label)
+ {
+
+ ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
+ for (AlignmentAnnotation ann : list)
+ {
+ if ((calcId == null || (ann.getCalcId() != null
+ && ann.getCalcId().equals(calcId)))
+ && (seq == null || (ann.sequenceRef != null
+ && ann.sequenceRef == seq))
+ && (label == null
+ || (ann.label != null && ann.label.equals(label))))
+ {
+ aa.add(ann);
+ }
+ }
+ return aa;
+ }
+
+ /**
+ * Answer true if any annotation matches the calcId passed in (if not null).
+ *
+ * @param list
+ * annotation to search
+ * @param calcId
+ * @return
+ */
+ public static boolean hasAnnotation(List<AlignmentAnnotation> list,
+ String calcId)
+ {
+
+ if (calcId != null && !"".equals(calcId))
+ {
+ for (AlignmentAnnotation a : list)
+ {
+ if (a.getCalcId() == calcId)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static Iterable<AlignmentAnnotation> findAnnotation(
+ List<AlignmentAnnotation> list, String calcId)
+ {
+
+ List<AlignmentAnnotation> aa = new ArrayList<>();
+ if (calcId == null)
+ {
+ return aa;
+ }
+ for (AlignmentAnnotation a : list)
+ {
+
+ if (a.getCalcId() == calcId || (a.getCalcId() != null
+ && calcId != null && a.getCalcId().equals(calcId)))
+ {
+ aa.add(a);
+ }
+ }
+ return aa;
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
public interface ContiguousI
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
/**
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Override
public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
{
- List<AlignmentAnnotation> aa = new ArrayList<>();
- if (calcId == null)
- {
- return aa;
- }
- for (AlignmentAnnotation a : getAlignmentAnnotation())
- {
- if (calcId.equals(a.getCalcId()))
- {
- aa.add(a);
- }
- }
- return aa;
+ return AlignmentAnnotation.findAnnotation(
+ Arrays.asList(getAlignmentAnnotation()), calcId);
}
@Override
public Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
String calcId, String label)
{
- ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
- for (AlignmentAnnotation ann : getAlignmentAnnotation())
- {
- if ((calcId == null || (ann.getCalcId() != null
- && ann.getCalcId().equals(calcId)))
- && (seq == null || (ann.sequenceRef != null
- && ann.sequenceRef == seq))
- && (label == null
- || (ann.label != null && ann.label.equals(label))))
- {
- aa.add(ann);
- }
- }
- return aa;
+ return AlignmentAnnotation.findAnnotations(
+ Arrays.asList(getAlignmentAnnotation()), seq, calcId, label);
}
/**
*/
public boolean hasAnnotation(String calcId)
{
- if (calcId != null && !"".equals(calcId))
- {
- for (AlignmentAnnotation a : getAlignmentAnnotation())
- {
- if (a.getCalcId() == calcId)
- {
- return true;
- }
- }
- }
- return false;
+ return AlignmentAnnotation
+ .hasAnnotation(Arrays.asList(getAlignmentAnnotation()), calcId);
}
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.ContiguousI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.features;
import jalview.datamodel.SequenceFeature;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.xdb.uniprot;
/**
import jalview.io.gff.SequenceOntologyFactory;
import jalview.io.gff.SequenceOntologyI;
-import java.util.HashMap;
-import java.util.Map;
-
import com.stevesoft.pat.Regex;
/**
private static final Regex ACCESSION_REGEX = new Regex(
"(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
- private static Map<String, String> params = new HashMap<String, String>();
-
- static
- {
- params.put("object_type", "transcript");
- }
-
/*
* fetch exon features on genomic sequence (to identify the cdna regions)
* and cds and variation features (to retain)
}
/**
- * Parameter object_type=cdna added to ensure cdna and not peptide is returned
- * (JAL-2529)
+ * Parameter object_type=Transcaript added to ensure cdna and not peptide is
+ * returned (JAL-2529)
*/
@Override
- protected Map<String, String> getAdditionalParameters()
+ protected String getObjectType()
{
- return params;
+ return OBJECT_TYPE_TRANSCRIPT;
}
}
public AlignmentI getSequenceRecords(String query) throws IOException
{
// TODO: use a vararg String... for getSequenceRecords instead?
- List<String> queries = new ArrayList<String>();
+ List<String> queries = new ArrayList<>();
queries.add(query);
FileParse fp = getSequenceReader(queries);
if (fp == null || !fp.isValid())
urlstring.append("?content-type=text/x-gff3");
/*
+ * specify object_type=gene in case is shared by transcript and/or protein;
+ * currently only fetching features for gene sequences;
+ * refactor in future if needed to fetch for transcripts
+ */
+ urlstring.append("&").append(OBJECT_TYPE).append("=")
+ .append(OBJECT_TYPE_GENE);
+
+ /*
* specify features to retrieve
* @see http://rest.ensembl.org/documentation/info/overlap_id
- * could make the list a configurable entry in jalview.properties
+ * could make the list a configurable entry in .jalview_properties
*/
for (EnsemblFeatureType feature : featuresWanted)
{
return EnsemblSeqType.GENOMIC;
}
+ @Override
+ protected String getObjectType()
+ {
+ return OBJECT_TYPE_GENE;
+ }
+
/**
* Returns an alignment containing the gene(s) for the given gene or
* transcript identifier, or external identifier (e.g. Uniprot id). If given a
*/
List<String> getGeneIds(String accessions)
{
- List<String> geneIds = new ArrayList<String>();
+ List<String> geneIds = new ArrayList<>();
for (String acc : accessions.split(getAccessionSeparator()))
{
int transcriptLength = 0;
final char[] geneChars = gene.getSequence();
int offset = gene.getStart(); // to convert to 0-based positions
- List<int[]> mappedFrom = new ArrayList<int[]>();
+ List<int[]> mappedFrom = new ArrayList<>();
for (SequenceFeature sf : splices)
{
* transfer features to the new sequence; we use EnsemblCdna to do this,
* to filter out unwanted features types (see method retainFeature)
*/
- List<int[]> mapTo = new ArrayList<int[]>();
+ List<int[]> mapTo = new ArrayList<>();
mapTo.add(new int[] { 1, transcriptLength });
MapList mapping = new MapList(mappedFrom, mapTo, 1, 1);
EnsemblCdna cdna = new EnsemblCdna(getDomain());
protected List<SequenceFeature> getTranscriptFeatures(String accId,
SequenceI geneSequence)
{
- List<SequenceFeature> transcriptFeatures = new ArrayList<SequenceFeature>();
+ List<SequenceFeature> transcriptFeatures = new ArrayList<>();
String parentIdentifier = GENE_PREFIX + accId;
for (SequenceFeature sf : sfs)
{
String parent = (String) sf.getValue(PARENT);
- if (parentIdentifier.equals(parent))
+ if (parentIdentifier.equalsIgnoreCase(parent))
{
transcriptFeatures.add(sf);
}
if (SequenceOntologyFactory.getInstance().isA(sf.getType(),
SequenceOntologyI.GENE))
{
- String id = (String) sf.getValue(ID);
- if ((GENE_PREFIX + accId).equals(id))
+ // NB features as gff use 'ID'; rest services return as 'id'
+ String id = (String) sf.getValue("ID");
+ if ((GENE_PREFIX + accId).equalsIgnoreCase(id))
{
return true;
}
if (isTranscript(type))
{
String parent = (String) sf.getValue(PARENT);
- if (!(GENE_PREFIX + accessionId).equals(parent))
+ if (!(GENE_PREFIX + accessionId).equalsIgnoreCase(parent))
{
return false;
}
{
if (isTranscript(sf.getType()))
{
- String id = (String) sf.getValue(ID);
+ String id = (String) sf.getValue("ID");
if (("transcript:" + accId).equals(id))
{
return true;
import org.json.simple.parser.ParseException;
/**
- * A client for the Ensembl lookup REST endpoint; used to find the Parent gene
- * identifier given a transcript identifier.
+ * A client for the Ensembl lookup REST endpoint, used to find the gene
+ * identifier given a gene, transcript or protein identifier.
*
* @author gmcarstairs
- *
*/
public class EnsemblLookup extends EnsemblRestClient
{
-
- private static final String OBJECT_TYPE_TRANSLATION = "Translation";
- private static final String PARENT = "Parent";
- private static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
- private static final String ID = "id";
- private static final String OBJECT_TYPE_GENE = "Gene";
- private static final String OBJECT_TYPE = "object_type";
-
/**
* Default constructor (to use rest.ensembl.org)
*/
protected URL getUrl(List<String> ids) throws MalformedURLException
{
String identifier = ids.get(0);
- return getUrl(identifier);
+ return getUrl(identifier, null);
}
/**
+ * Gets the url for lookup of the given identifier, optionally with objectType
+ * also specified in the request
+ *
* @param identifier
+ * @param objectType
* @return
*/
- protected URL getUrl(String identifier)
+ protected URL getUrl(String identifier, String objectType)
{
String url = getDomain() + "/lookup/id/" + identifier
+ CONTENT_TYPE_JSON;
+ if (objectType != null)
+ {
+ url += "&" + OBJECT_TYPE + "=" + objectType;
+ }
+
try
{
return new URL(url);
}
/**
+ * Returns the gene id related to the given identifier, which may be for a
+ * gene, transcript or protein
+ *
+ * @param identifier
+ * @return
+ */
+ public String getGeneId(String identifier)
+ {
+ return getGeneId(identifier, null);
+ }
+
+ /**
* Calls the Ensembl lookup REST endpoint and retrieves the 'Parent' for the
* given identifier, or null if not found
*
* @param identifier
+ * @param objectType
+ * (optional)
* @return
*/
- public String getGeneId(String identifier)
+ public String getGeneId(String identifier, String objectType)
{
List<String> ids = Arrays.asList(new String[] { identifier });
BufferedReader br = null;
try
{
- URL url = getUrl(identifier);
+ URL url = getUrl(identifier, objectType);
if (url != null)
{
br = getHttpResponse(url, ids);
String type = val.get(OBJECT_TYPE).toString();
if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
{
+ // got the gene - just returns its id
geneId = val.get(ID).toString();
}
else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
{
+ // got the transcript - return its (Gene) Parent
geneId = val.get(PARENT).toString();
}
else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
{
+ // got the protein - get its Parent, restricted to type Transcript
String transcriptId = val.get(PARENT).toString();
- try
- {
- geneId = getGeneId(transcriptId);
- } catch (StackOverflowError e)
- {
- /*
- * unlikely data condition error!
- */
- System.err
- .println("** Ensembl lookup "
- + getUrl(transcriptId).toString()
- + " looping on Parent!");
- }
+ geneId = getGeneId(transcriptId, OBJECT_TYPE_TRANSCRIPT);
}
} catch (ParseException e)
{
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
/**
* Base class for Ensembl sequence fetchers
{
private static final String ALLELES = "alleles";
- protected static final String PARENT = "Parent";
-
- protected static final String ID = "ID";
-
protected static final String NAME = "Name";
protected static final String DESCRIPTION = "description";
try
{
/*
- * get 'dummy' genomic sequence with exon, cds and variation features
+ * get 'dummy' genomic sequence with gene, transcript,
+ * exon, cds and variation features
*/
SequenceI genomicSequence = null;
EnsemblFeatures gffFetcher = new EnsemblFeatures(getDomain());
/*
* transfer features to the query sequence
*/
- SequenceI querySeq = alignment.findName(accId);
+ SequenceI querySeq = alignment.findName(accId, true);
if (transferFeatures(accId, genomicSequence, querySeq))
{
urlstring.append("?type=").append(getSourceEnsemblType().getType());
urlstring.append(("&Accept=text/x-fasta"));
- Map<String, String> params = getAdditionalParameters();
- if (params != null)
+ String objectType = getObjectType();
+ if (objectType != null)
{
- for (Entry<String, String> entry : params.entrySet())
- {
- urlstring.append("&").append(entry.getKey()).append("=")
- .append(entry.getValue());
- }
+ urlstring.append("&").append(OBJECT_TYPE).append("=")
+ .append(objectType);
}
URL url = new URL(urlstring.toString());
}
/**
- * Override this method to add any additional x=y URL parameters needed
+ * Override this method to specify object_type request parameter
*
* @return
*/
- protected Map<String, String> getAdditionalParameters()
+ protected String getObjectType()
{
return null;
}
protected MapList getGenomicRangesFromFeatures(SequenceI sourceSequence,
String accId, int start)
{
- // SequenceFeature[] sfs = sourceSequence.getSequenceFeatures();
List<SequenceFeature> sfs = sourceSequence.getFeatures()
.getPositionalFeatures();
if (sfs.isEmpty())
* generously initial size for number of cds regions
* (worst case titin Q8WZ42 has c. 313 exons)
*/
- List<int[]> regions = new ArrayList<int[]>(100);
+ List<int[]> regions = new ArrayList<>(100);
int mappedLength = 0;
int direction = 1; // forward
boolean directionSet = false;
{
String parent = (String) sf.getValue(PARENT);
// using contains to allow for prefix "gene:", "transcript:" etc
- if (parent != null && !parent.contains(identifier))
+ if (parent != null
+ && !parent.toUpperCase().contains(identifier.toUpperCase()))
{
// this genomic feature belongs to a different transcript
return false;
protected List<SequenceFeature> findFeatures(SequenceI sequence,
String term, String parentId)
{
- List<SequenceFeature> result = new ArrayList<SequenceFeature>();
+ List<SequenceFeature> result = new ArrayList<>();
List<SequenceFeature> sfs = sequence.getFeatures()
.getFeaturesByOntology(term);
for (SequenceFeature sf : sfs)
{
String parent = (String) sf.getValue(PARENT);
- if (parent != null && parent.equals(parentId))
+ if (parent != null && parent.equalsIgnoreCase(parentId))
{
result.add(sf);
}
protected static final String ENSEMBL_REST = "http://rest.ensembl.org";
+ protected static final String OBJECT_TYPE_TRANSLATION = "Translation";
+
+ protected static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
+
+ protected static final String OBJECT_TYPE_GENE = "Gene";
+
+ protected static final String PARENT = "Parent";
+
+ protected static final String ID = "id";
+
+ protected static final String OBJECT_TYPE = "object_type";
+
/*
* possible values for the 'feature' parameter of the /overlap REST service
* @see http://rest.ensembl.org/documentation/info/overlap_id
{
private static final String GENE = "gene";
private static final String TYPE = "type";
- private static final String ID = "id";
-
/**
* Constructor given the target domain to fetch data from
*
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
-import java.util.ArrayList;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
{
HiddenColumns oldHidden = av.getAnnotationColumnSelectionState()
.getOldHiddenColumns();
- if (oldHidden != null)
- {
- ArrayList<int[]> regions = oldHidden.getHiddenColumnsCopy();
- for (int[] positions : regions)
- {
- av.hideColumns(positions[0], positions[1]);
- }
- }
- // TODO not clear why we need to hide all the columns (above) if we are
- // going to copy the hidden columns over wholesale anyway
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0]);
+ }
+ else if (evt.getPropertyName().equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ repaint();
+ }
}
}
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1]);
+ }
+ else if (propertyName.equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ repaint();
+ }
}
}
userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
userIdWidth.setText(wi == null ? "" : wi.toString());
+ // TODO: refactor to use common enum via FormatAdapter and allow extension
+ // for new flat file formats
blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES)
+ || evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ)
+ || evt.getPropertyName().equals(ViewportRanges.MOVE_VIEWPORT))
{
// scroll event, repaint panel
repaint();
int transX = 0;
int transY = 0;
- gg.copyArea(horizontal * charWidth, vertical * charHeight,
- img.getWidth(), img.getHeight(), -horizontal * charWidth,
- -vertical * charHeight);
+ gg.copyArea(horizontal * charWidth, vertical * charHeight,
+ img.getWidth(), img.getHeight(), -horizontal * charWidth,
+ -vertical * charHeight);
- if (horizontal > 0) // scrollbar pulled right, image to the left
- {
- transX = (endRes - startRes - horizontal) * charWidth;
- startRes = endRes - horizontal;
- }
- else if (horizontal < 0)
- {
- endRes = startRes - horizontal;
- }
- else if (vertical > 0) // scroll down
- {
- startSeq = endSeq - vertical;
-
- if (startSeq < ranges.getStartSeq())
- { // ie scrolling too fast, more than a page at a time
- startSeq = ranges.getStartSeq();
+ if (horizontal > 0) // scrollbar pulled right, image to the left
+ {
+ transX = (endRes - startRes - horizontal) * charWidth;
+ startRes = endRes - horizontal;
}
- else
+ else if (horizontal < 0)
{
- transY = img.getHeight() - ((vertical + 1) * charHeight);
+ endRes = startRes - horizontal;
}
- }
- else if (vertical < 0)
- {
- endSeq = startSeq - vertical;
- if (endSeq > ranges.getEndSeq())
+ if (vertical > 0) // scroll down
{
- endSeq = ranges.getEndSeq();
+ startSeq = endSeq - vertical;
+
+ if (startSeq < ranges.getStartSeq())
+ { // ie scrolling too fast, more than a page at a time
+ startSeq = ranges.getStartSeq();
+ }
+ else
+ {
+ transY = img.getHeight() - ((vertical + 1) * charHeight);
+ }
}
- }
+ else if (vertical < 0)
+ {
+ endSeq = startSeq - vertical;
- gg.translate(transX, transY);
- drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
- gg.translate(-transX, -transY);
+ if (endSeq > ranges.getEndSeq())
+ {
+ endSeq = ranges.getEndSeq();
+ }
+ }
+
+ gg.translate(transX, transY);
+ drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
+ gg.translate(-transX, -transY);
- repaint();
+ repaint();
} finally
{
fastpainting = false;
// lcimg is a local *copy* of img which we'll draw selectImage on top of
BufferedImage lcimg = buildLocalImage(selectImage);
g.drawImage(lcimg, 0, 0, this);
+
+ }
+
+ if (av.cursorMode)
+ {
+ drawCursor(g, ranges.getStartRes(), ranges.getEndRes(),
+ ranges.getStartSeq(), ranges.getEndSeq());
}
}
AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g2d.drawImage(selectImage, 0, 0, this);
}
+
g2d.dispose();
return lcimg;
* white fill the region to be drawn (so incremental fast paint doesn't
* scribble over an existing image)
*/
- gg.setColor(Color.white);
- gg.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
+ g.setColor(Color.white);
+ g.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
wrappedRepeatHeightPx);
drawPanel(g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
int canvasWidth,
int canvasHeight, int startRes)
{
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
// height gap above each panel
int hgap = charHeight;
if (av.getScaleAboveWrapped())
}
}
}
-
- if (av.cursorMode && cursorY == i && cursorX >= startRes
- && cursorX <= endRes)
- {
- seqRdr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth,
- offset + ((i - startSeq) * charHeight));
- }
}
if (av.getSelectionGroup() != null
return selectionImage;
}
+ /**
+ * Draw the cursor as a separate image and overlay
+ *
+ * @param startRes
+ * start residue of area to draw cursor in
+ * @param endRes
+ * end residue of area to draw cursor in
+ * @param startSeq
+ * start sequence of area to draw cursor in
+ * @param endSeq
+ * end sequence of are to draw cursor in
+ * @return a transparent image of the same size as the sequence canvas, with
+ * the cursor drawn on it, if any
+ */
+ private void drawCursor(Graphics g, int startRes, int endRes,
+ int startSeq,
+ int endSeq)
+ {
+ // convert the cursorY into a position on the visible alignment
+ int cursor_ypos = cursorY;
+
+ // don't do work unless we have to
+ if (cursor_ypos >= startSeq && cursor_ypos <= endSeq)
+ {
+ int yoffset = 0;
+ int xoffset = 0;
+ int startx = startRes;
+ int endx = endRes;
+
+ // convert the cursorX into a position on the visible alignment
+ int cursor_xpos = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(cursorX);
+
+ if (av.getAlignment().getHiddenColumns().isVisible(cursorX))
+ {
+
+ if (av.getWrapAlignment())
+ {
+ // work out the correct offsets for the cursor
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ int canvasWidth = getWidth();
+ int canvasHeight = getHeight();
+
+ // height gap above each panel
+ int hgap = charHeight;
+ if (av.getScaleAboveWrapped())
+ {
+ hgap += charHeight;
+ }
+
+ int cWidth = (canvasWidth - labelWidthEast - labelWidthWest)
+ / charWidth;
+ int cHeight = av.getAlignment().getHeight() * charHeight;
+
+ endx = startx + cWidth - 1;
+ int ypos = hgap; // vertical offset
+
+ // iterate down the wrapped panels
+ while ((ypos <= canvasHeight) && (endx < cursor_xpos))
+ {
+ // update vertical offset
+ ypos += cHeight + getAnnotationHeight() + hgap;
+
+ // update horizontal offset
+ startx += cWidth;
+ endx = startx + cWidth - 1;
+ }
+ yoffset = ypos;
+ xoffset = labelWidthWest;
+ }
+
+ // now check if cursor is within range for x values
+ if (cursor_xpos >= startx && cursor_xpos <= endx)
+ {
+ // get the character the cursor is drawn at
+ SequenceI seq = av.getAlignment().getSequenceAt(cursorY);
+ char s = seq.getCharAt(cursorX);
+
+ seqRdr.drawCursor(g, s,
+ xoffset + (cursor_xpos - startx) * av.getCharWidth(),
+ yoffset + (cursor_ypos - startSeq) * av.getCharHeight());
+ }
+ }
+ }
+ }
+
+
/*
* Set up graphics for selection group
*/
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
- int charWidth = av.getCharWidth();
-
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
int startRes, int endRes, int startSeq, int endSeq,
int verticalOffset)
{
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
int visWidth = (endRes - startRes + 1) * charWidth;
int oldY = -1;
boolean inGroup = false;
int top = -1;
int bottom = -1;
-
- int sx = -1;
int sy = -1;
- int xwidth = -1;
- for (i = startSeq; i <= endSeq; i++)
- {
- // position of start residue of group relative to startRes, in pixels
- sx = (group.getStartRes() - startRes) * charWidth;
+ List<SequenceI> seqs = group.getSequences(null);
- // width of group in pixels
- xwidth = (((group.getEndRes() + 1) - group.getStartRes()) * charWidth)
- - 1;
+ // position of start residue of group relative to startRes, in pixels
+ int sx = (group.getStartRes() - startRes) * charWidth;
- sy = verticalOffset + (i - startSeq) * charHeight;
-
- if (sx + xwidth < 0 || sx > visWidth)
- {
- continue;
- }
+ // width of group in pixels
+ int xwidth = (((group.getEndRes() + 1) - group.getStartRes())
+ * charWidth) - 1;
- if ((sx <= (endRes - startRes) * charWidth)
- && group.getSequences(null)
- .contains(av.getAlignment().getSequenceAt(i)))
+ if (!(sx + xwidth < 0 || sx > visWidth))
+ {
+ for (i = startSeq; i <= endSeq; i++)
{
- if ((bottom == -1) && !group.getSequences(null)
- .contains(av.getAlignment().getSequenceAt(i + 1)))
- {
- bottom = sy + charHeight;
- }
+ sy = verticalOffset + (i - startSeq) * charHeight;
- if (!inGroup)
+ if ((sx <= (endRes - startRes) * charWidth)
+ && seqs.contains(av.getAlignment().getSequenceAt(i)))
{
- if (((top == -1) && (i == 0)) || !group.getSequences(null)
- .contains(av.getAlignment().getSequenceAt(i - 1)))
+ if ((bottom == -1)
+ && !seqs.contains(av.getAlignment().getSequenceAt(i + 1)))
{
- top = sy;
+ bottom = sy + charHeight;
}
- oldY = sy;
- inGroup = true;
- }
- }
- else
- {
- if (inGroup)
- {
- // if start position is visible, draw vertical line to left of
- // group
- if (sx >= 0 && sx < visWidth)
+ if (!inGroup)
{
- g.drawLine(sx, oldY, sx, sy);
- }
-
- // if end position is visible, draw vertical line to right of
- // group
- if (sx + xwidth < visWidth)
- {
- g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
- }
-
- if (sx < 0)
- {
- xwidth += sx;
- sx = 0;
- }
-
- // don't let width extend beyond current block, or group extent
- // fixes JAL-2672
- if (sx + xwidth >= (endRes - startRes + 1) * charWidth)
- {
- xwidth = (endRes - startRes + 1) * charWidth - sx;
- }
-
- // draw horizontal line at top of group
- if (top != -1)
- {
- g.drawLine(sx, top, sx + xwidth, top);
- top = -1;
- }
+ if (((top == -1) && (i == 0)) || !seqs
+ .contains(av.getAlignment().getSequenceAt(i - 1)))
+ {
+ top = sy;
+ }
- // draw horizontal line at bottom of group
- if (bottom != -1)
- {
- g.drawLine(sx, bottom, sx + xwidth, bottom);
- bottom = -1;
+ oldY = sy;
+ inGroup = true;
}
+ }
+ else if (inGroup)
+ {
+ drawVerticals(g, sx, xwidth, visWidth, oldY, sy);
+ drawHorizontals(g, sx, xwidth, visWidth, top, bottom);
+ // reset top and bottom
+ top = -1;
+ bottom = -1;
inGroup = false;
}
}
- }
-
- if (inGroup)
- {
- sy = verticalOffset + ((i - startSeq) * charHeight);
- if (sx >= 0 && sx < visWidth)
+ if (inGroup)
{
- g.drawLine(sx, oldY, sx, sy);
+ sy = verticalOffset + ((i - startSeq) * charHeight);
+ drawVerticals(g, sx, xwidth, visWidth, oldY, sy);
+ drawHorizontals(g, sx, xwidth, visWidth, top, bottom);
}
+ }
+ }
- if (sx + xwidth < visWidth)
- {
- g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
- }
+ /**
+ * Draw horizontal selection group boundaries at top and bottom positions
+ *
+ * @param g
+ * graphics object to draw on
+ * @param sx
+ * start x position
+ * @param xwidth
+ * width of gap
+ * @param visWidth
+ * visWidth maximum available width
+ * @param top
+ * position to draw top of group at
+ * @param bottom
+ * position to draw bottom of group at
+ */
+ private void drawHorizontals(Graphics2D g, int sx, int xwidth,
+ int visWidth, int top, int bottom)
+ {
+ int width = xwidth;
+ int startx = sx;
+ if (startx < 0)
+ {
+ width += startx;
+ startx = 0;
+ }
- if (sx < 0)
- {
- xwidth += sx;
- sx = 0;
- }
+ // don't let width extend beyond current block, or group extent
+ // fixes JAL-2672
+ if (startx + width >= visWidth)
+ {
+ width = visWidth - startx;
+ }
- if (sx + xwidth > visWidth)
- {
- xwidth = visWidth;
- }
- else if (sx + xwidth >= (endRes - startRes + 1) * charWidth)
- {
- xwidth = (endRes - startRes + 1) * charWidth;
- }
+ if (top != -1)
+ {
+ g.drawLine(startx, top, startx + width, top);
+ }
- if (top != -1)
- {
- g.drawLine(sx, top, sx + xwidth, top);
- top = -1;
- }
+ if (bottom != -1)
+ {
+ g.drawLine(startx, bottom - 1, startx + width, bottom - 1);
+ }
+ }
- if (bottom != -1)
- {
- g.drawLine(sx, bottom - 1, sx + xwidth, bottom - 1);
- bottom = -1;
- }
+ /**
+ * Draw vertical lines at sx and sx+xwidth providing they lie within
+ * [0,visWidth)
+ *
+ * @param g
+ * graphics object to draw on
+ * @param sx
+ * start x position
+ * @param xwidth
+ * width of gap
+ * @param visWidth
+ * visWidth maximum available width
+ * @param oldY
+ * top y value
+ * @param sy
+ * bottom y value
+ */
+ private void drawVerticals(Graphics2D g, int sx, int xwidth, int visWidth,
+ int oldY, int sy)
+ {
+ // if start position is visible, draw vertical line to left of
+ // group
+ if (sx >= 0 && sx < visWidth)
+ {
+ g.drawLine(sx, oldY, sx, sy);
+ }
- inGroup = false;
+ // if end position is visible, draw vertical line to right of
+ // group
+ if (sx + xwidth < visWidth)
+ {
+ g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
}
}
*/
protected boolean drawMappedPositions(SearchResultsI results)
{
- if (results == null)
+ if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
{
return false;
}
repaint();
return;
}
+ else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+ {
+ fastPaint = false;
+ repaint();
+ return;
+ }
int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (eventName.equals(ViewportRanges.STARTRES)
+ || eventName.equals(ViewportRanges.STARTRESANDSEQ))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ }
+ else
+ {
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ }
ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- int range = vpRanges.getViewportWidth();
+
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes();
if (scrollX > range)
{
scrollX = range;
scrollX = -range;
}
}
-
// Both scrolling and resizing change viewport ranges: scrolling changes
// both start and end points, but resize only changes end values.
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
-
- // scroll - startres and endres both change
if (eventName.equals(ViewportRanges.STARTRES))
{
if (av.getWrapAlignment())
+ {
+ fastPaintWrapped(scrollX);
+ }
+ else
+ {
+ fastPaint(scrollX, 0);
+ }
+ }
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
+ {
+ // scroll
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ if (av.getWrapAlignment())
{
fastPaintWrapped(scrollX);
}
{
fastPaint(scrollX, 0);
}
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // bizarrely, we only need to scroll on the x value here as fastpaint
+ // copies the full height of the image anyway. Passing in the y value
+ // causes nasty repaint artefacts, which only disappear on a full
+ // repaint.
}
}
*/
protected boolean drawMappedPositionsWrapped(SearchResultsI results)
{
- if (results == null)
+ if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
{
return false;
}
void setCursorRow()
{
seqCanvas.cursorY = getKeyboardNo1() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void setCursorColumn()
{
seqCanvas.cursorX = getKeyboardNo1() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void setCursorRowAndColumn()
{
seqCanvas.cursorX = getKeyboardNo1() - 1;
seqCanvas.cursorY = getKeyboardNo2() - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
}
SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1;
- scrollToVisible();
+ scrollToVisible(true);
}
void moveCursor(int dx, int dy)
int original = seqCanvas.cursorX - dx;
int maxWidth = av.getAlignment().getWidth();
+ // TODO: once JAL-2759 is ready, change this loop to something more
+ // efficient
while (!hidden.isVisible(seqCanvas.cursorX)
- && seqCanvas.cursorX < maxWidth && seqCanvas.cursorX > 0)
+ && seqCanvas.cursorX < maxWidth && seqCanvas.cursorX > 0
+ && dx != 0)
{
seqCanvas.cursorX += dx;
}
}
}
- scrollToVisible();
+ scrollToVisible(false);
}
- void scrollToVisible()
+ /**
+ * Scroll to make the cursor visible in the viewport.
+ *
+ * @param jump
+ * just jump to the location rather than scrolling
+ */
+ void scrollToVisible(boolean jump)
{
if (seqCanvas.cursorX < 0)
{
}
endEditing();
- if (av.getWrapAlignment())
+
+ boolean repaintNeeded = true;
+ if (jump)
{
- av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX);
+ // only need to repaint if the viewport did not move, as otherwise it will
+ // get a repaint
+ repaintNeeded = !av.getRanges().setViewportLocation(seqCanvas.cursorX,
+ seqCanvas.cursorY);
}
else
{
- av.getRanges().scrollToVisible(seqCanvas.cursorX, seqCanvas.cursorY);
+ if (av.getWrapAlignment())
+ {
+ // scrollToWrappedVisible expects x-value to have hidden cols subtracted
+ int x = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(seqCanvas.cursorX);
+ av.getRanges().scrollToWrappedVisible(x);
+ }
+ else
+ {
+ av.getRanges().scrollToVisible(seqCanvas.cursorX,
+ seqCanvas.cursorY);
+ }
}
- setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
+
+ if (av.getAlignment().getHiddenColumns().isVisible(seqCanvas.cursorX))
+ {
+ setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
seqCanvas.cursorX, seqCanvas.cursorY);
+ }
- seqCanvas.repaint();
+ if (repaintNeeded)
+ {
+ seqCanvas.repaint();
+ }
}
+
void setSelectionAreaAtCursor(boolean topLeft)
{
SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
}
}
- public void drawCursor(SequenceI seq, int res, int x1, int y1)
+ /**
+ * Draw a sequence canvas cursor
+ *
+ * @param g
+ * graphics context to draw on
+ * @param s
+ * character to draw at cursor
+ * @param x1
+ * x position of cursor in graphics context
+ * @param y1
+ * y position of cursor in graphics context
+ */
+ public void drawCursor(Graphics g, char s, int x1, int y1)
{
int pady = av.getCharHeight() / 5;
int charOffset = 0;
- graphics.setColor(Color.black);
- graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
+ g.setColor(Color.black);
+ g.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
if (av.isValidCharWidth())
{
- graphics.setColor(Color.white);
-
- char s = seq.getCharAt(res);
-
+ g.setColor(Color.white);
charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
- graphics.drawString(String.valueOf(s), charOffset + x1,
+ g.drawString(String.valueOf(s), charOffset + x1,
(y1 + av.getCharHeight()) - pady);
}
if (cachedPDBExists)
{
- FilterOption cachedOption = new FilterOption("Cached PDB Entries",
+ FilterOption cachedOption = new FilterOption("Cached Structures",
"-", VIEWS_LOCAL_PDB, false);
cmb_filterOption.addItem(cachedOption);
cmb_filterOption.setSelectedItem(cachedOption);
PDBEntry pdb = pdbs[i];
SequenceI seq = seqs[i];
String pdbFile = pdb.getFile();
+ if (pdbFile == null || pdbFile.length() == 0)
+ {
+ pdbFile = pdb.getId();
+ }
if (!pdbsSeen.containsKey(pdbFile))
{
pdbsSeen.put(pdbFile, pdb);
public boolean getCacheSuffixDefault(FileFormatI format)
{
- return Cache.getDefault(format.getName() + "_JVSUFFIX", true);
+ return Cache.getDefault(format.getName().toUpperCase() + "_JVSUFFIX",
+ true);
}
public String formatSequences(FileFormatI format, AlignmentI alignment,
boolean validRes, boolean validEnd)
{
g.setColor(STEM_COLOUR);
- int sCol = (lastSSX / charWidth) + startRes;
+ int sCol = (lastSSX / charWidth)
+ + hiddenColumns.adjustForHiddenColumns(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
// System.out.println(nonCanColor);
g.setColor(nonCanColor);
- int sCol = (lastSSX / charWidth) + startRes;
+ int sCol = (lastSSX / charWidth)
+ + hiddenColumns.adjustForHiddenColumns(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
{
g.setColor(HELIX_COLOUR);
- int sCol = (lastSSX / charWidth) + startRes;
+ int sCol = (lastSSX / charWidth)
+ + hiddenColumns.adjustForHiddenColumns(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.util;
import java.util.Comparator;
}
}
- // update viewport
- ranges.setStartRes(xAsRes);
- ranges.setStartSeq(yAsSeq);
+ ranges.setStartResAndSeq(xAsRes, yAsSeq);
}
@Override
}
// update viewport
- ranges.setStartRes(visXAsRes);
- ranges.setStartSeq(visYAsSeq);
+ ranges.setStartResAndSeq(visXAsRes, visYAsSeq);
}
/**
import jalview.datamodel.HiddenColumns;
/**
- * Slightly less embryonic class which: Supplies and updates viewport properties
- * relating to position such as: start and end residues and sequences; ideally
- * will serve hidden columns/rows too. Intention also to support calculations
- * for positioning, scrolling etc. such as finding the middle of the viewport,
- * checking for scrolls off screen
+ * Supplies and updates viewport properties relating to position such as: start
+ * and end residues and sequences; ideally will serve hidden columns/rows too.
+ * Intention also to support calculations for positioning, scrolling etc. such
+ * as finding the middle of the viewport, checking for scrolls off screen
*/
public class ViewportRanges extends ViewportProperties
{
public static final String ENDSEQ = "endseq";
+ public static final String STARTRESANDSEQ = "startresandseq";
+
+ public static final String MOVE_VIEWPORT = "move_viewport";
+
private boolean wrappedMode = false;
// start residue of viewport
*/
public void setStartEndRes(int start, int end)
{
+ int[] oldvalues = updateStartEndRes(start, end);
+ int oldstartres = oldvalues[0];
+ int oldendres = oldvalues[1];
+
+ changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
+ if (oldstartres == startRes)
+ {
+ // event won't be fired if start positions are same
+ // fire an event for the end positions in case they changed
+ changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
+ }
+ }
+
+ /**
+ * Update start and end residue values, adjusting for width constraints if
+ * necessary
+ *
+ * @param start
+ * start residue
+ * @param end
+ * end residue
+ * @return array containing old start and end residue values
+ */
+ private int[] updateStartEndRes(int start, int end)
+ {
int oldstartres = this.startRes;
/*
{
endRes = end;
}
-
- changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
- if (oldstartres == startRes)
- {
- // event won't be fired if start positions are same
- // fire an event for the end positions in case they changed
- changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
- }
+ return new int[] { oldstartres, oldendres };
}
/**
*/
public void setStartEndSeq(int start, int end)
{
+ int[] oldvalues = updateStartEndSeq(start, end);
+ int oldstartseq = oldvalues[0];
+ int oldendseq = oldvalues[1];
+
+ changeSupport.firePropertyChange(STARTSEQ, oldstartseq, startSeq);
+ if (oldstartseq == startSeq)
+ {
+ // event won't be fired if start positions are the same
+ // fire in case the end positions changed
+ changeSupport.firePropertyChange(ENDSEQ, oldendseq, endSeq);
+ }
+ }
+
+ /**
+ * Update start and end sequence values, adjusting for height constraints if
+ * necessary
+ *
+ * @param start
+ * start sequence
+ * @param end
+ * end sequence
+ * @return array containing old start and end sequence values
+ */
+ private int[] updateStartEndSeq(int start, int end)
+ {
int oldstartseq = this.startSeq;
int visibleHeight = getVisibleAlignmentHeight();
if (start > visibleHeight - 1)
{
endSeq = end;
}
-
- changeSupport.firePropertyChange(STARTSEQ, oldstartseq, startSeq);
- if (oldstartseq == startSeq)
- {
- // event won't be fired if start positions are the same
- // fire in case the end positions changed
- changeSupport.firePropertyChange(ENDSEQ, oldendseq, endSeq);
- }
+ return new int[] { oldstartseq, oldendseq };
}
/**
}
/**
+ * Set start residue and start sequence together (fires single event). The
+ * event supplies a pair of old values and a pair of new values: [old start
+ * residue, old start sequence] and [new start residue, new start sequence]
+ *
+ * @param res
+ * the start residue
+ * @param seq
+ * the start sequence
+ */
+ public void setStartResAndSeq(int res, int seq)
+ {
+ int width = getViewportWidth();
+ int[] oldresvalues = updateStartEndRes(res, res + width - 1);
+
+ int startseq = seq;
+ int height = getViewportHeight();
+ if (startseq + height - 1 > getVisibleAlignmentHeight() - 1)
+ {
+ startseq = getVisibleAlignmentHeight() - height;
+ }
+ int[] oldseqvalues = updateStartEndSeq(startseq, startseq + height - 1);
+
+ int[] old = new int[] { oldresvalues[0], oldseqvalues[0] };
+ int[] newresseq = new int[] { startRes, startSeq };
+ changeSupport.firePropertyChange(STARTRESANDSEQ, old, newresseq);
+ }
+
+ /**
* Get start residue of viewport
*/
public int getStartRes()
* the startRes changed, else false.
*
* @param res
- * residue position to scroll to
+ * residue position to scroll to NB visible position not absolute
+ * alignment position
* @return
*/
public boolean scrollToWrappedVisible(int res)
{
- int oldStartRes = startRes;
- int width = getViewportWidth();
-
- if (res >= oldStartRes && res < oldStartRes + width)
+ int newStartRes = calcWrappedStartResidue(res);
+ if (newStartRes == startRes)
{
return false;
}
+ setStartRes(newStartRes);
+
+ return true;
+ }
+
+ /**
+ * Calculate wrapped start residue from visible start residue
+ *
+ * @param res
+ * visible start residue
+ * @return left column of panel res will be located in
+ */
+ private int calcWrappedStartResidue(int res)
+ {
+ int oldStartRes = startRes;
+ int width = getViewportWidth();
boolean up = res < oldStartRes;
int widthsToScroll = Math.abs((res - oldStartRes) / width);
{
newStartRes = 0;
}
-
- setStartRes(newStartRes);
-
- return true;
+ return newStartRes;
}
/**
* Scroll so that (x,y) is visible. Fires a property change event.
*
* @param x
- * x position in alignment
+ * x position in alignment (absolute position)
* @param y
- * y position in alignment
+ * y position in alignment (absolute position)
*/
public void scrollToVisible(int x, int y)
{
{
scrollUp(false);
}
-
+
HiddenColumns hidden = al.getHiddenColumns();
while (x < hidden.adjustForHiddenColumns(startRes))
{
}
/**
+ * Set the viewport location so that a position is visible
+ *
+ * @param x
+ * column to be visible: absolute position in alignment
+ * @param y
+ * row to be visible: absolute position in alignment
+ */
+ public boolean setViewportLocation(int x, int y)
+ {
+ boolean changedLocation = false;
+
+ // convert the x,y location to visible coordinates
+ int visX = al.getHiddenColumns().findColumnPosition(x);
+ int visY = al.getHiddenSequences().findIndexWithoutHiddenSeqs(y);
+
+ // if (vis_x,vis_y) is already visible don't do anything
+ if (startRes > visX || visX > endRes
+ || startSeq > visY && visY > endSeq)
+ {
+ int[] old = new int[] { startRes, startSeq };
+ int[] newresseq;
+ if (wrappedMode)
+ {
+ int newstartres = calcWrappedStartResidue(visX);
+ setStartRes(newstartres);
+ newresseq = new int[] { startRes, startSeq };
+ }
+ else
+ {
+ // set the viewport x location to contain vis_x
+ int newstartres = visX;
+ int width = getViewportWidth();
+ if (newstartres + width - 1 > getVisibleAlignmentWidth() - 1)
+ {
+ newstartres = getVisibleAlignmentWidth() - width;
+ }
+ updateStartEndRes(newstartres, newstartres + width - 1);
+
+ // set the viewport y location to contain vis_y
+ int newstartseq = visY;
+ int height = getViewportHeight();
+ if (newstartseq + height - 1 > getVisibleAlignmentHeight() - 1)
+ {
+ newstartseq = getVisibleAlignmentHeight() - height;
+ }
+ updateStartEndSeq(newstartseq, newstartseq + height - 1);
+
+ newresseq = new int[] { startRes, startSeq };
+ }
+ changedLocation = true;
+ changeSupport.firePropertyChange(MOVE_VIEWPORT, old, newresseq);
+ }
+ return changedLocation;
+ }
+
+ /**
* Adjust sequence position for page up. Fires a property change event.
*/
public void pageUp()
sf.setValue("Parent", "transcript:" + accId);
assertTrue(testee.retainFeature(sf, accId));
+ // test is not case-sensitive
+ assertTrue(testee.retainFeature(sf, accId.toLowerCase()));
+
// feature with wrong parent is not retained
sf.setValue("Parent", "transcript:XYZ");
assertFalse(testee.retainFeature(sf, accId));
// NMD_transcript_variant treated like transcript in Ensembl
SequenceFeature sf3 = new SequenceFeature("NMD_transcript_variant", "",
22000, 22500, 0f, null);
- sf3.setValue("Parent", "gene:" + geneId);
+ // id matching should not be case-sensitive
+ sf3.setValue("Parent", "gene:" + geneId.toLowerCase());
sf3.setValue("transcript_id", "transcript3");
genomic.addSequenceFeature(sf3);
sf.setValue("ID", "gene:" + accId);
assertTrue(testee.identifiesSequence(sf, accId));
+ // test is not case-sensitive
+ assertTrue(testee.identifiesSequence(sf, accId.toLowerCase()));
+
// transcript not valid:
sf = new SequenceFeature("transcript", "", 1, 2, 0f, null);
sf.setValue("ID", "gene:" + accId);
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.AssertJUnit.assertEquals;
+
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for AnnotationChooser
+ *
+ * @author kmourao
+ *
+ */
+public class AnnotationColumnChooserTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ }
+
+ // 4 sequences x 13 positions
+ final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
+ + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
+ + "TIETHKEEELTA-\n";
+
+ AnnotationChooser testee;
+
+ AlignmentPanel parentPanel;
+
+ AlignFrame af;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws IOException
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ // pin down annotation sort order for test
+ Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS,
+ SequenceAnnotationOrder.NONE.name());
+ final String TRUE = Boolean.TRUE.toString();
+ Cache.applicationProperties.setProperty(Preferences.SHOW_AUTOCALC_ABOVE,
+ TRUE);
+ Cache.applicationProperties.setProperty("SHOW_QUALITY", TRUE);
+ Cache.applicationProperties.setProperty("SHOW_CONSERVATION", TRUE);
+ Cache.applicationProperties.setProperty("SHOW_IDENTITY", TRUE);
+
+ AlignmentI al = new FormatAdapter().readFile(TEST_DATA,
+ DataSourceType.PASTE, FileFormat.Fasta);
+ af = new AlignFrame(al, 700, 500);
+ parentPanel = new AlignmentPanel(af, af.getViewport());
+ addAnnotations();
+ }
+
+ /**
+ * Add 4 annotations, 3 of them sequence-specific.
+ *
+ * <PRE>
+ * ann1 - for sequence 0 - label 'IUPRED' ann2 - not sequence related - label
+ * 'Beauty' ann3 - for sequence 3 - label 'JMol' ann4 - for sequence 2 - label
+ * 'IUPRED' ann5 - for sequence 1 - label 'JMol'
+ */
+ private void addAnnotations()
+ {
+ Annotation an = new Annotation(2f);
+ Annotation[] anns = new Annotation[] { an, an, an };
+ AlignmentAnnotation ann0 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann1 = new AlignmentAnnotation("Beauty", "", anns);
+ AlignmentAnnotation ann2 = new AlignmentAnnotation("JMol", "", anns);
+ AlignmentAnnotation ann3 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann4 = new AlignmentAnnotation("JMol", "", anns);
+ SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
+ ann0.setSequenceRef(seqs[0]);
+ ann2.setSequenceRef(seqs[3]);
+ ann3.setSequenceRef(seqs[2]);
+ ann4.setSequenceRef(seqs[1]);
+ parentPanel.getAlignment().addAnnotation(ann0);
+ parentPanel.getAlignment().addAnnotation(ann1);
+ parentPanel.getAlignment().addAnnotation(ann2);
+ parentPanel.getAlignment().addAnnotation(ann3);
+ parentPanel.getAlignment().addAnnotation(ann4);
+ }
+
+ /**
+ * Test reset
+ */
+ @Test(groups = { "Functional" })
+ public void testReset()
+ {
+ AnnotationColumnChooser acc = new AnnotationColumnChooser(
+ af.getViewport(), af.alignPanel);
+
+ HiddenColumns oldhidden = new HiddenColumns();
+ oldhidden.hideColumns(10, 20);
+ acc.setOldHiddenColumns(oldhidden);
+
+ HiddenColumns newHidden = new HiddenColumns();
+ newHidden.hideColumns(0, 3);
+ newHidden.hideColumns(22, 25);
+ af.getViewport().setHiddenColumns(newHidden);
+
+ HiddenColumns currentHidden = af.getViewport().getAlignment()
+ .getHiddenColumns();
+ List<int[]> regions = currentHidden.getHiddenColumnsCopy();
+ assertEquals(regions.get(0)[0], 0);
+ assertEquals(regions.get(0)[1], 3);
+ assertEquals(regions.get(1)[0], 22);
+ assertEquals(regions.get(1)[1], 25);
+
+ // now reset hidden columns
+ acc.reset();
+ currentHidden = af.getViewport().getAlignment().getHiddenColumns();
+ regions = currentHidden.getHiddenColumnsCopy();
+ assertEquals(regions.get(0)[0], 10);
+ assertEquals(regions.get(0)[1], 20);
+
+ // check works with empty hidden columns as old columns
+ oldhidden = new HiddenColumns();
+ acc.setOldHiddenColumns(oldhidden);
+ acc.reset();
+ currentHidden = af.getViewport().getAlignment().getHiddenColumns();
+ assertFalse(currentHidden.hasHiddenColumns());
+
+ // check works with empty hidden columns as new columns
+ oldhidden.hideColumns(10, 20);
+ acc.setOldHiddenColumns(oldhidden);
+ currentHidden = af.getViewport().getAlignment().getHiddenColumns();
+ assertFalse(currentHidden.hasHiddenColumns());
+
+ acc.reset();
+ currentHidden = af.getViewport().getAlignment().getHiddenColumns();
+ regions = currentHidden.getHiddenColumnsCopy();
+ assertEquals(regions.get(0)[0], 10);
+ assertEquals(regions.get(0)[1], 20);
+ }
+}
PDBEntry dbRef = new PDBEntry();
dbRef.setId("1tim");
- Vector<PDBEntry> pdbIds = new Vector<PDBEntry>();
+ Vector<PDBEntry> pdbIds = new Vector<>();
pdbIds.add(dbRef);
seq.setPDBId(pdbIds);
assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
.getSelectedItem();
- assertEquals("Cached PDB Entries", filterOpt.getName());
+ assertEquals("Cached Structures", filterOpt.getName());
}
@Test(groups = { "Network" })
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 pdbe7 = new PDBEntry("1FOO", "Q", Type.PDB, null);
+
PDBEntry[] pdbs = new PDBEntry[] { pdbe1, pdbe2, pdbe3, pdbe4, pdbe5,
- pdbe6 };
+ pdbe6, pdbe7 };
/*
* seq1 ... seq6 associated with pdbe1 ... pdbe6
assertTrue(uniques.containsKey(pdbe4));
assertFalse(uniques.containsKey(pdbe5));
assertFalse(uniques.containsKey(pdbe6));
+ assertTrue(uniques.containsKey(pdbe7));
// 1A70 associates with seq1 and seq3
SequenceI[] ss = uniques.get(pdbe1);
assertEquals(ss.length, 2);
assertSame(seqs[3], ss[0]);
assertSame(seqs[5], ss[1]);
+
+ // 1FOO has seq7
+ ss = uniques.get(pdbe7);
+ assertEquals(ss.length, 1);
+ assertSame(seqs[6], ss[0]);
}
}
vr.setEndSeq(al.getHeight());
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
- // vr.setEndRes(al.getHeight() - 1);
vr.setEndSeq(al.getHeight() - 1);
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
}
}
@Test(groups = { "Functional" })
+ public void testSetStartResAndSeq()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportHeight(10);
+ vr.setStartResAndSeq(3, 6);
+ assertEquals(vr.getStartRes(), 3);
+ assertEquals(vr.getStartSeq(), 6);
+ assertEquals(vr.getEndRes(), 3 + vr.getViewportWidth() - 1);
+ assertEquals(vr.getEndSeq(), 6 + vr.getViewportHeight() - 1);
+
+ vr.setStartResAndSeq(10, 25);
+ assertEquals(vr.getStartRes(), 10);
+ assertEquals(vr.getStartSeq(), 19);
+ assertEquals(vr.getEndRes(), 10 + vr.getViewportWidth() - 1);
+ assertEquals(vr.getEndSeq(), 19 + vr.getViewportHeight() - 1);
+ }
+
+ @Test(groups = { "Functional" })
public void testSetViewportHeight()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getEndRes(), 52);
}
- // leave until JAL-2388 is merged and we can do without viewport
- /*@Test(groups = { "Functional" })
+ @Test(groups = { "Functional" })
public void testScrollToVisible()
{
ViewportRanges vr = new ViewportRanges(al);
vr.setViewportStartAndWidth(12,5);
vr.setViewportStartAndHeight(10,6);
- vr.scrollToVisible(13,14)
+ vr.scrollToVisible(13, 14);
// no change
assertEquals(vr.getStartRes(), 12);
assertEquals(vr.getStartSeq(), 6);
// test for hidden columns too
- }*/
+ al.getHiddenColumns().hideColumns(1, 3);
+ vr.scrollToVisible(13, 3);
+ assertEquals(vr.getStartRes(), 6);
+ assertEquals(vr.getStartSeq(), 3);
+
+ vr.scrollToVisible(2, 9);
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getStartSeq(), 4);
+ }
@Test(groups = { "Functional" })
public void testEventFiring()
// one event fired when startRes is called with new value
vr.setStartRes(4);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
// no event fired for same value
l.reset();
vr.setStartSeq(4);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setStartSeq(4);
l.reset();
vr.setEndSeq(10);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setEndSeq(10);
l.reset();
vr.setStartEndRes(2, 15);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.setStartEndRes(2, 15);
// check new value fired by event is corrected startres
vr.setStartEndRes(-1, 5);
- assertTrue(l.verify(1, Arrays.asList("startres"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES),
+ Arrays.asList(0)));
l.reset();
// check new value fired by event is corrected endres
vr.setStartEndRes(0, -1);
- assertTrue(l.verify(1, Arrays.asList("endres"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDRES),
+ Arrays.asList(0)));
l.reset();
vr.setStartEndSeq(2, 15);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setStartEndSeq(2, 15);
// check new value fired by event is corrected startseq
vr.setStartEndSeq(-1, 5);
- assertTrue(l.verify(1, Arrays.asList("startseq"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ),
+ Arrays.asList(0)));
l.reset();
// check new value fired by event is corrected endseq
vr.setStartEndSeq(0, -1);
- assertTrue(l.verify(1, Arrays.asList("endseq"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ),
+ Arrays.asList(0)));
l.reset();
// reset for later tests
// test viewport height and width setting triggers event
vr.setViewportHeight(10);
- assertTrue(l.verify(1, Arrays.asList("endseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ)));
l.reset();
vr.setViewportWidth(18);
- assertTrue(l.verify(1, Arrays.asList("endres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDRES)));
l.reset();
// already has seq start set to 2, so triggers endseq
vr.setViewportStartAndHeight(2, 16);
- assertTrue(l.verify(1, Arrays.asList("endseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ)));
l.reset();
vr.setViewportStartAndWidth(1, 14);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
// test page up/down triggers event
vr.pageUp();
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.pageDown();
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
// test scrolling triggers event
vr.scrollUp(true);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.scrollUp(false);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.scrollRight(true);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.scrollRight(false);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.scrollToVisible(10, 10);
assertTrue(l.verify(4,
- Arrays.asList("startseq", "startseq", "startseq", "startseq")));
+ Arrays.asList(ViewportRanges.STARTSEQ, ViewportRanges.STARTSEQ,
+ ViewportRanges.STARTSEQ, ViewportRanges.STARTSEQ)));
l.reset();
/*
l.reset();
vr.scrollToWrappedVisible(25);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
+ l.reset();
+
+ // test setStartResAndSeq triggers one event
+ vr.setStartResAndSeq(5, 7);
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRESANDSEQ),
+ Arrays.asList(5, 7)));
+
+ l.reset();
}
@Test(groups = { "Functional" })
assertEquals(vr.getStartSeq(), 1);
assertEquals(vr.getStartRes(), 43);
}
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportLocation()
+ {
+ AlignmentI al2 = gen.generate(60, 80, 1, 0, 0);
+
+ ViewportRanges vr = new ViewportRanges(al2);
+
+ // start with viewport on 5-14
+ vr.setViewportStartAndWidth(5, 10);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 14);
+
+ vr.setViewportStartAndHeight(3, 13);
+ assertEquals(vr.getStartSeq(), 3);
+ assertEquals(vr.getEndSeq(), 15);
+
+ // set location to (8,5) - no change
+ vr.setViewportLocation(8, 5);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 14);
+ assertEquals(vr.getStartSeq(), 3);
+ assertEquals(vr.getEndSeq(), 15);
+
+ // set location to (40,50) - change to top left (40,50)
+ vr.setViewportLocation(40, 50);
+ assertEquals(vr.getStartRes(), 40);
+ assertEquals(vr.getEndRes(), 49);
+ assertEquals(vr.getStartSeq(), 50);
+ assertEquals(vr.getEndSeq(), 62);
+
+ // set location past end of alignment - resets to leftmost pos
+ vr.setViewportLocation(63, 85);
+ assertEquals(vr.getStartRes(), 50);
+ assertEquals(vr.getEndRes(), 59);
+ assertEquals(vr.getStartSeq(), 67);
+ assertEquals(vr.getEndSeq(), 79);
+
+ // hide some columns
+ al2.getHiddenColumns().hideColumns(20, 50);
+ vr.setViewportLocation(55, 4);
+ assertEquals(vr.getStartRes(), 19);
+ assertEquals(vr.getEndRes(), 28);
+ assertEquals(vr.getStartSeq(), 4);
+ assertEquals(vr.getEndSeq(), 16);
+
+ // hide some sequences
+ al2.getHiddenSequences().hideSequence(al2.getSequenceAt(3));
+ al2.getHiddenSequences().hideSequence(al2.getSequenceAt(4));
+ vr.setViewportLocation(17, 5);
+ assertEquals(vr.getStartRes(), 17);
+ assertEquals(vr.getEndRes(), 26);
+ assertEquals(vr.getStartSeq(), 3);
+ assertEquals(vr.getEndSeq(), 15);
+
+ // set wrapped mode
+ vr.setWrappedMode(true);
+ vr.setViewportLocation(1, 8);
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 9);
+ assertEquals(vr.getStartSeq(), 3);
+ assertEquals(vr.getEndSeq(), 15);
+
+ // try further down the alignment
+ vr.setViewportLocation(57, 5);
+ assertEquals(vr.getStartRes(), 20);
+ assertEquals(vr.getEndRes(), 29);
+ assertEquals(vr.getStartSeq(), 3);
+ assertEquals(vr.getEndSeq(), 15);
+ }
}
// mock listener for property change events
{
firecount++;
events.add(evt.getPropertyName());
- newvalues.add((Integer) evt.getNewValue());
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ newvalues.add(((int[]) evt.getNewValue())[0]);
+ newvalues.add(((int[]) evt.getNewValue())[1]);
+ }
+ else
+ {
+ newvalues.add((Integer) evt.getNewValue());
+ }
}
public boolean verify(int count, List<String> eventslist,
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[groovy-all-2.4.6-indy.jar]]></string>
+ <string><![CDATA[groovy-all-2.4.12-indy.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>
<boolean>true</boolean>
</property>
<property name="destinationName">
- <string><![CDATA[groovy-all-2.4.6-indy.jar]]></string>
+ <string><![CDATA[groovy-all-2.4.12-indy.jar]]></string>
</property>
<property name="fileSize">
<long>6149494</long>
</method>
<method name="put">
<string><![CDATA[com.zerog.ia.installer.options.valid.vm.list]]></string>
- <string><![CDATA[1.8+]]></string>
+ <string><![CDATA[1.8*]]></string>
</method>
<method name="put">
<string><![CDATA[com.zerog.ia.project.build.last.date]]></string>
</method>
<method name="put">
<string><![CDATA[com.zerog.ia.installer.options.platform.macosx.vm.version]]></string>
- <string><![CDATA[1.8+]]></string>
+ <string><![CDATA[1.8*]]></string>
</method>
<method name="put">
<string><![CDATA[com.zerog.ia.build.platform.java.novm]]></string>