From: Ben Soares Date: Thu, 30 Jul 2020 13:08:06 +0000 (+0100) Subject: Merge branch 'releases/Release_2_11_1_Branch' into merge/JAL-3628+JAL-3608+JAL-3609... X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=0c85e43a68ad2de5318b6e3f09bd743b7933a890;hp=57a4549e0f95c10651db22e53dae9411e5e30c46;p=jalview.git Merge branch 'releases/Release_2_11_1_Branch' into merge/JAL-3628+JAL-3608+JAL-3609+JAL-3541+JAL-3633+Release_2_11_1_Branch --- diff --git a/help/help/html/releases.html b/help/help/html/releases.html index 8193433..8c4ba37 100755 --- a/help/help/html/releases.html +++ b/help/help/html/releases.html @@ -74,6 +74,21 @@ li:before { Preferences -> Connections, Proxy server settings now allow selecting "No proxy", "System proxy settings" or custom proxy settings which can be configured for HTTP, HTTPS and allows for an authenticated proxy server. +
  • + Support import of VCF 4.3 by updating + HTSJDK from 2.12 to 2.23 +
  • +
  • + IntervalStore library updated to v.1.1: + optimisations and improvements suggested by Bob Hanson and + improved compatibility with JalviewJS +
  • +
  • + Retrieve GZipped stockholm formatted alignments from Pfam and Rfam +
  • +
  • + Recognise GZipped content for URLs and File import (no longer based on .gz extension) +
  • @@ -102,13 +117,14 @@ li:before { Proxy properties don't set HTTPS proxy for launcher or application.
  • - -
  • -
  • - + Errors encountered when processing variants + from VCF files yield "Error processing VCF: Format specifier + '%s'" on the console
  • - + Count of features not shown can be wrong + when there are both local and complementary features mapped + to the position under the cursor
  • diff --git a/j11lib/htsjdk-2.12.0.jar b/j11lib/htsjdk-2.12.0.jar deleted file mode 100644 index 1df12b2..0000000 Binary files a/j11lib/htsjdk-2.12.0.jar and /dev/null differ diff --git a/j11lib/htsjdk-2.23.0.jar b/j11lib/htsjdk-2.23.0.jar new file mode 100644 index 0000000..bcf201f Binary files /dev/null and b/j11lib/htsjdk-2.23.0.jar differ diff --git a/j11lib/intervalstore-v1.0.jar b/j11lib/intervalstore-v1.0.jar deleted file mode 100644 index 4f6101c..0000000 Binary files a/j11lib/intervalstore-v1.0.jar and /dev/null differ diff --git a/j11lib/intervalstore-v1.1.jar b/j11lib/intervalstore-v1.1.jar new file mode 100644 index 0000000..668b543 Binary files /dev/null and b/j11lib/intervalstore-v1.1.jar differ diff --git a/j8lib/htsjdk-2.12.0.jar b/j8lib/htsjdk-2.12.0.jar deleted file mode 100644 index 1df12b2..0000000 Binary files a/j8lib/htsjdk-2.12.0.jar and /dev/null differ diff --git a/j8lib/htsjdk-2.23.0.jar b/j8lib/htsjdk-2.23.0.jar new file mode 100644 index 0000000..bcf201f Binary files /dev/null and b/j8lib/htsjdk-2.23.0.jar differ diff --git a/j8lib/intervalstore-v1.0.jar b/j8lib/intervalstore-v1.0.jar deleted file mode 100644 index 4f6101c..0000000 Binary files a/j8lib/intervalstore-v1.0.jar and /dev/null differ diff --git a/j8lib/intervalstore-v1.1.jar b/j8lib/intervalstore-v1.1.jar new file mode 100644 index 0000000..668b543 Binary files /dev/null and b/j8lib/intervalstore-v1.1.jar differ diff --git a/src/jalview/datamodel/features/FeatureStore.java b/src/jalview/datamodel/features/FeatureStore.java index 54c0d59..7651016 100644 --- a/src/jalview/datamodel/features/FeatureStore.java +++ b/src/jalview/datamodel/features/FeatureStore.java @@ -20,8 +20,6 @@ */ package jalview.datamodel.features; -import jalview.datamodel.SequenceFeature; - import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -30,7 +28,9 @@ import java.util.Set; import intervalstore.api.IntervalStoreI; import intervalstore.impl.BinarySearcher; +import intervalstore.impl.BinarySearcher.Compare; import intervalstore.impl.IntervalStore; +import jalview.datamodel.SequenceFeature; /** * A data store for a set of sequence features that supports efficient lookup of @@ -277,7 +277,7 @@ public class FeatureStore * binary search the sorted list to find the insertion point */ int insertPosition = BinarySearcher.findFirst(contactFeatureStarts, - f -> f.getBegin() >= feature.getBegin()); + true, Compare.GE, feature.getBegin()); contactFeatureStarts.add(insertPosition, feature); @@ -286,7 +286,7 @@ public class FeatureStore * binary search the sorted list to find the insertion point */ insertPosition = BinarySearcher.findFirst(contactFeatureEnds, - f -> f.getEnd() >= feature.getEnd()); + false, Compare.GE, feature.getEnd()); contactFeatureEnds.add(insertPosition, feature); return true; @@ -314,8 +314,8 @@ public class FeatureStore */ // int pos = binarySearch(features, // SearchCriterion.byFeature(feature, RangeComparator.BY_START_POSITION)); - int pos = BinarySearcher.findFirst(features, - val -> val.getBegin() >= feature.getBegin()); + int pos = BinarySearcher.findFirst(features, true, Compare.GE, + feature.getBegin()); int len = features.size(); while (pos < len) { @@ -396,7 +396,7 @@ public class FeatureStore * whose end point is not before the target range */ int index = BinarySearcher.findFirst(contactFeatureEnds, - f -> f.getEnd() >= from); + false, Compare.GE, (int) from); while (index < contactFeatureEnds.size()) { @@ -449,7 +449,7 @@ public class FeatureStore List result) { int index = BinarySearcher.findFirst(contactFeatureStarts, - f -> f.getBegin() >= from); + true, Compare.GE, (int) from); while (index < contactFeatureStarts.size()) { diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index db2f0e1..8ac4991 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -20,11 +20,8 @@ */ package jalview.datamodel.features; -import jalview.datamodel.SequenceFeature; -import jalview.io.gff.SequenceOntologyFactory; -import jalview.io.gff.SequenceOntologyI; - import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -33,6 +30,9 @@ import java.util.Set; import java.util.TreeMap; import intervalstore.api.IntervalI; +import jalview.datamodel.SequenceFeature; +import jalview.io.gff.SequenceOntologyFactory; +import jalview.io.gff.SequenceOntologyI; /** * A class that stores sequence features in a way that supports efficient @@ -44,7 +44,6 @@ import intervalstore.api.IntervalI; */ public class SequenceFeatures implements SequenceFeaturesI { - /* * map from feature type to structured store of features for that type * null types are permitted (but not a good idea!) @@ -414,7 +413,10 @@ public class SequenceFeatures implements SequenceFeaturesI public static void sortFeatures(List features, final boolean forwardStrand) { - IntervalI.sortIntervals(features, forwardStrand); + Collections.sort(features, + forwardStrand + ? IntervalI.COMPARE_BEGIN_ASC_END_DESC + : IntervalI.COMPARE_END_DESC); } /** diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index 60ad75d..7ed178b 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -53,8 +53,6 @@ import net.miginfocom.swing.MigLayout; @SuppressWarnings("serial") public class AnnotationColourChooser extends AnnotationRowFilter { - private static final int ONETHOUSAND = 1000; - private ColourSchemeI oldcs; private JButton defColours; @@ -147,7 +145,8 @@ public class AnnotationColourChooser extends AnnotationRowFilter "error.implementation_error_dont_know_about_threshold_setting")); } thresholdIsMin.setSelected(acg.isThresholdIsMinMax()); - thresholdValue.setText("" + acg.getAnnotationThreshold()); + thresholdValue + .setText(String.valueOf(acg.getAnnotationThreshold())); } jbInit(); @@ -338,7 +337,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter { updateView(); } - getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + getCurrentAnnotation().threshold.value = getSliderValue(); propagateSeqAssociatedThreshold(updateAllAnnotation, getCurrentAnnotation()); ap.paintAlignment(false, false); @@ -378,6 +377,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter thresholdValue.setEnabled(true); thresholdIsMin.setEnabled(!useOriginalColours.isSelected()); + final AlignmentAnnotation currentAnnotation = getCurrentAnnotation(); if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); @@ -386,33 +386,26 @@ public class AnnotationColourChooser extends AnnotationRowFilter thresholdIsMin.setEnabled(false); } else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD - && getCurrentAnnotation().threshold == null) + && currentAnnotation.threshold == null) { - getCurrentAnnotation().setThreshold(new GraphLine( - (getCurrentAnnotation().graphMax - - getCurrentAnnotation().graphMin) / 2f, + currentAnnotation.setThreshold(new GraphLine( + (currentAnnotation.graphMax - currentAnnotation.graphMin) + / 2f, "Threshold", Color.black)); } if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) { adjusting = true; - float range = getCurrentAnnotation().graphMax * ONETHOUSAND - - getCurrentAnnotation().graphMin * ONETHOUSAND; - - slider.setMinimum( - (int) (getCurrentAnnotation().graphMin * ONETHOUSAND)); - slider.setMaximum( - (int) (getCurrentAnnotation().graphMax * ONETHOUSAND)); - slider.setValue( - (int) (getCurrentAnnotation().threshold.value * ONETHOUSAND)); - thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); - slider.setMajorTickSpacing((int) (range / 10f)); + setSliderModel(currentAnnotation.graphMin, currentAnnotation.graphMax, + currentAnnotation.threshold.value); slider.setEnabled(true); + + setThresholdValueText(); thresholdValue.setEnabled(true); adjusting = false; } - colorAlignmentContaining(getCurrentAnnotation(), selectedThresholdItem); + colorAlignmentContaining(currentAnnotation, selectedThresholdItem); ap.alignmentChanged(); } diff --git a/src/jalview/gui/AnnotationColumnChooser.java b/src/jalview/gui/AnnotationColumnChooser.java index 5adecad..82ec0e7 100644 --- a/src/jalview/gui/AnnotationColumnChooser.java +++ b/src/jalview/gui/AnnotationColumnChooser.java @@ -21,6 +21,7 @@ package jalview.gui; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.HiddenColumns; import jalview.io.cache.JvCacheableInputBox; import jalview.schemes.AnnotationColourGradient; @@ -254,7 +255,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter { if (slider.isEnabled()) { - getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + getCurrentAnnotation().threshold.value = getSliderValue(); updateView(); propagateSeqAssociatedThreshold(updateAllAnnotation, getCurrentAnnotation()); @@ -284,6 +285,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter thresholdValue.setEnabled(true); percentThreshold.setEnabled(true); + final AlignmentAnnotation currentAnnotation = getCurrentAnnotation(); if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); @@ -294,26 +296,22 @@ public class AnnotationColumnChooser extends AnnotationRowFilter } else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) { - if (getCurrentAnnotation().threshold == null) + if (currentAnnotation.threshold == null) { - getCurrentAnnotation().setThreshold(new jalview.datamodel.GraphLine( - (getCurrentAnnotation().graphMax - - getCurrentAnnotation().graphMin) / 2f, + currentAnnotation.setThreshold(new jalview.datamodel.GraphLine( + (currentAnnotation.graphMax + - currentAnnotation.graphMin) / 2f, "Threshold", Color.black)); } adjusting = true; - float range = getCurrentAnnotation().graphMax * 1000 - - getCurrentAnnotation().graphMin * 1000; - slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); - slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); - slider.setValue( - (int) (getCurrentAnnotation().threshold.value * 1000)); + setSliderModel(currentAnnotation.graphMin, + currentAnnotation.graphMax, + currentAnnotation.threshold.value); setThresholdValueText(); - slider.setMajorTickSpacing((int) (range / 10f)); slider.setEnabled(true); thresholdValue.setEnabled(true); adjusting = false; @@ -321,10 +319,10 @@ public class AnnotationColumnChooser extends AnnotationRowFilter // build filter params filterParams.setThresholdType( AnnotationFilterParameter.ThresholdType.NO_THRESHOLD); - if (getCurrentAnnotation().isQuantitative()) + if (currentAnnotation.isQuantitative()) { filterParams - .setThresholdValue(getCurrentAnnotation().threshold.value); + .setThresholdValue(currentAnnotation.threshold.value); if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD) { @@ -380,7 +378,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter // adding them to the selection av.showAllHiddenColumns(); av.getColumnSelection().filterAnnotations( - getCurrentAnnotation().annotations, filterParams); + currentAnnotation.annotations, filterParams); boolean hideCols = getActionOption() == ACTION_OPTION_HIDE; if (hideCols) diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java index f13cb10..6f72e10 100644 --- a/src/jalview/gui/AnnotationRowFilter.java +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -35,6 +35,8 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.math.BigDecimal; +import java.math.MathContext; import java.util.HashMap; import java.util.Map; import java.util.Vector; @@ -44,7 +46,6 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JInternalFrame; import javax.swing.JPanel; -import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -52,6 +53,10 @@ import javax.swing.event.ChangeListener; @SuppressWarnings("serial") public abstract class AnnotationRowFilter extends JPanel { + private static final String TWO_DP = "%.2f"; + + private final static MathContext FOUR_SIG_FIG = new MathContext(4); + protected AlignViewport av; protected AlignmentPanel ap; @@ -64,7 +69,7 @@ public abstract class AnnotationRowFilter extends JPanel protected JCheckBox percentThreshold = new JCheckBox(); - protected JSlider slider = new JSlider(); + protected Slider slider; protected JTextField thresholdValue = new JTextField(20); @@ -103,6 +108,8 @@ public abstract class AnnotationRowFilter extends JPanel { this.av = viewport; this.ap = alignPanel; + this.slider = new Slider(0f, 100f, 50f); + thresholdValue.addFocusListener(new FocusAdapter() { @Override @@ -140,16 +147,62 @@ public abstract class AnnotationRowFilter extends JPanel adjusting = true; if (percentThreshold.isSelected()) { - thresholdValue.setText("" + (slider.getValue() - slider.getMinimum()) - * 100f / (slider.getMaximum() - slider.getMinimum())); + thresholdValue + .setText(String.format(TWO_DP, getSliderPercentageValue())); } else { - thresholdValue.setText((slider.getValue() / 1000f) + ""); + /* + * round to 4 significant digits without trailing zeroes + */ + float f = getSliderValue(); + BigDecimal formatted = new BigDecimal(f).round(FOUR_SIG_FIG) + .stripTrailingZeros(); + thresholdValue.setText(formatted.toPlainString()); } adjusting = oldadj; } + /** + * Answers the value of the slider position (descaled to 'true' value) + * + * @return + */ + protected float getSliderValue() + { + return slider.getSliderValue(); + } + + /** + * Sets the slider value (scaled from the true value to the slider range) + * + * @param value + */ + protected void setSliderValue(float value) + { + slider.setSliderValue(value); + } + /** + * Answers the value of the slider position as a percentage between minimum and + * maximum of its range + * + * @return + */ + protected float getSliderPercentageValue() + { + return slider.getSliderPercentageValue(); + } + + /** + * Sets the slider position for a given percentage value of its min-max range + * + * @param pct + */ + protected void setSliderPercentageValue(float pct) + { + slider.setSliderPercentageValue(pct); + } + protected void addSliderMouseListeners() { @@ -290,6 +343,10 @@ public abstract class AnnotationRowFilter extends JPanel updateView(); } + /** + * Updates the slider position, and the display, for an update in the slider's + * text input field + */ protected void thresholdValue_actionPerformed() { try @@ -297,12 +354,11 @@ public abstract class AnnotationRowFilter extends JPanel float f = Float.parseFloat(thresholdValue.getText()); if (percentThreshold.isSelected()) { - slider.setValue(slider.getMinimum() + ((int) ((f / 100f) - * (slider.getMaximum() - slider.getMinimum())))); + setSliderPercentageValue(f); } else { - slider.setValue((int) (f * 1000)); + setSliderValue(f); } updateView(); } catch (NumberFormatException ex) @@ -528,4 +584,23 @@ public abstract class AnnotationRowFilter extends JPanel valueChanged(true); } } + + /** + * Sets the min-max range and current value of the slider, with rescaling from + * true values to slider range as required + * + * @param min + * @param max + * @param value + */ + protected void setSliderModel(float min, float max, float value) + { + slider.setSliderModel(min, max, value); + + /* + * tick mark every 10th position + */ + slider.setMajorTickSpacing( + (slider.getMaximum() - slider.getMinimum()) / 10); + } } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index b87e4bf..aeac959 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -162,7 +162,7 @@ public class FeatureSettings extends JPanel JPanel groupPanel; - JSlider transparency = new JSlider(); + JSlider transparency= new JSlider(); private JCheckBox showComplementOnTop; diff --git a/src/jalview/gui/FeatureTypeSettings.java b/src/jalview/gui/FeatureTypeSettings.java index 5b77dfc..512cf06 100644 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@ -49,6 +49,8 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.math.BigDecimal; +import java.math.MathContext; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -63,7 +65,6 @@ import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; -import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; @@ -79,6 +80,8 @@ import javax.swing.event.ChangeListener; */ public class FeatureTypeSettings extends JalviewDialog { + private final static MathContext FOUR_SIG_FIG = new MathContext(4); + private final static String LABEL_18N = MessageManager .getString("label.label"); @@ -142,11 +145,6 @@ public class FeatureTypeSettings extends JalviewDialog private float max; /* - * scale factor for conversion between absolute min-max and slider - */ - private float scaleFactor; - - /* * radio button group, to select what to colour by: * simple colour, by category (text), or graduated */ @@ -169,7 +167,7 @@ public class FeatureTypeSettings extends JalviewDialog private JComboBox threshold = new JComboBox<>(); - private JSlider slider = new JSlider(); + private Slider slider; private JTextField thresholdValue = new JTextField(20); @@ -348,12 +346,11 @@ public class FeatureTypeSettings extends JalviewDialog * update min-max scaling if there is a range to work with, * else disable the widgets (this shouldn't happen if only * valid options are offered in the combo box) + * offset slider to have only non-negative values if necessary (JAL-2983) */ - scaleFactor = (max == min) ? 1f : 100f / (max - min); - float range = (max - min) * scaleFactor; - slider.setMinimum((int) (min * scaleFactor)); - slider.setMaximum((int) (max * scaleFactor)); - slider.setMajorTickSpacing((int) (range / 10f)); + slider.setSliderModel(min, max, min); + slider.setMajorTickSpacing( + (int) ((slider.getMaximum() - slider.getMinimum()) / 10f)); threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black); @@ -365,8 +362,8 @@ public class FeatureTypeSettings extends JalviewDialog fc.isAboveThreshold() ? ABOVE_THRESHOLD_OPTION : BELOW_THRESHOLD_OPTION); slider.setEnabled(true); - slider.setValue((int) (fc.getThreshold() * scaleFactor)); - thresholdValue.setText(String.valueOf(fc.getThreshold())); + slider.setSliderValue(fc.getThreshold()); + setThresholdValueText(fc.getThreshold()); thresholdValue.setEnabled(true); thresholdIsMin.setEnabled(true); } @@ -641,6 +638,7 @@ public class FeatureTypeSettings extends JalviewDialog thresholdValue_actionPerformed(); } }); + slider = new Slider(0f, 100f, 50f); slider.setPaintLabels(false); slider.setPaintTicks(true); slider.setBackground(Color.white); @@ -657,8 +655,7 @@ public class FeatureTypeSettings extends JalviewDialog { if (!adjusting) { - thresholdValue - .setText(String.valueOf(slider.getValue() / scaleFactor)); + setThresholdValueText(slider.getSliderValue()); thresholdValue.setBackground(Color.white); // to reset red for invalid sliderValueChanged(); } @@ -1033,8 +1030,8 @@ public class FeatureTypeSettings extends JalviewDialog float f = Float.parseFloat(thresholdValue.getText()); f = Float.max(f, this.min); f = Float.min(f, this.max); - thresholdValue.setText(String.valueOf(f)); - slider.setValue((int) (f * scaleFactor)); + setThresholdValueText(f); + slider.setSliderValue(f); threshline.value = f; thresholdValue.setBackground(Color.white); // ok adjusting = false; @@ -1047,13 +1044,25 @@ public class FeatureTypeSettings extends JalviewDialog } /** + * Sets the text field for threshold value, rounded to four significant figures + * + * @param f + */ + void setThresholdValueText(float f) + { + BigDecimal formatted = new BigDecimal(f).round(FOUR_SIG_FIG) + .stripTrailingZeros(); + thresholdValue.setText(formatted.toPlainString()); + } + + /** * Action on change of threshold slider value. This may be done interactively * (by moving the slider), or programmatically (to update the slider after * manual input of a threshold value). */ protected void sliderValueChanged() { - threshline.value = getRoundedSliderValue(); + threshline.value = slider.getSliderValue(); /* * repaint alignment, but not Overview or structure, @@ -1062,21 +1071,6 @@ public class FeatureTypeSettings extends JalviewDialog colourChanged(false); } - /** - * Converts the slider value to its absolute value by dividing by the - * scaleFactor. Rounding errors are squashed by forcing min/max of slider - * range to the actual min/max of feature score range - * - * @return - */ - private float getRoundedSliderValue() - { - int value = slider.getValue(); - float f = value == slider.getMaximum() ? max - : (value == slider.getMinimum() ? min : value / scaleFactor); - return f; - } - void addActionListener(ActionListener listener) { if (featureSettings != null) diff --git a/src/jalview/gui/OptsAndParamsPage.java b/src/jalview/gui/OptsAndParamsPage.java index 5342c90..0f4d0e7 100644 --- a/src/jalview/gui/OptsAndParamsPage.java +++ b/src/jalview/gui/OptsAndParamsPage.java @@ -53,7 +53,6 @@ import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; -import javax.swing.JSlider; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.border.TitledBorder; @@ -277,7 +276,7 @@ public class OptsAndParamsPage boolean choice = false; - JComboBox choicebox; + JComboBox choicebox; JPanel controlPanel = new JPanel(); @@ -289,7 +288,7 @@ public class OptsAndParamsPage boolean integ = false; - Object lastVal; + String lastVal; ParameterI parameter; @@ -299,7 +298,7 @@ public class OptsAndParamsPage JButton showDesc = new JButton(); - JSlider slider = null; + Slider slider = null; JTextArea string = new JTextArea(); @@ -363,7 +362,7 @@ public class OptsAndParamsPage validate(); } - private void makeExpanderParam(ParameterI parm) + private void makeExpanderParam(final ParameterI parm) { setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT)); setBorder(new TitledBorder(parm.getName())); @@ -451,6 +450,9 @@ public class OptsAndParamsPage validate(); } + /** + * Action on input in text field + */ @Override public void actionPerformed(ActionEvent e) { @@ -467,24 +469,20 @@ public class OptsAndParamsPage private void checkIfModified() { - Object cstate = updateSliderFromValueField(); - boolean notmod = false; - if (cstate.getClass() == lastVal.getClass()) - { - if (cstate instanceof int[]) - { - notmod = (((int[]) cstate)[0] == ((int[]) lastVal)[0]); - } - else if (cstate instanceof float[]) - { - notmod = (((float[]) cstate)[0] == ((float[]) lastVal)[0]); - } - else if (cstate instanceof String[]) - { - notmod = (((String[]) cstate)[0].equals(((String[]) lastVal)[0])); - } - } - pmdialogbox.argSetModified(this, !notmod); + Object cstate = getCurrentValue(); + boolean modified = !cstate.equals(lastVal); + pmdialogbox.argSetModified(this, modified); + } + + /** + * Answers the current value of the parameter, as text + * + * @return + */ + private String getCurrentValue() + { + return choice ? (String) choicebox.getSelectedItem() + : valueField.getText(); } @Override @@ -566,16 +564,20 @@ public class OptsAndParamsPage } + /** + * Action on change of slider value + */ @Override public void stateChanged(ChangeEvent e) { if (!adjusting) { - valueField.setText("" + ((integ) ? ("" + slider.getValue()) - : ("" + slider.getValue() / 1000f))); + float value = slider.getSliderValue(); + valueField.setText( + integ ? Integer.toString((int) value) + : Float.toString(value)); checkIfModified(); } - } public void updateControls(ParameterI parm) @@ -592,8 +594,6 @@ public class OptsAndParamsPage } else { - slider = new JSlider(); - slider.addChangeListener(this); valueField = new JTextField(); valueField.addActionListener(this); valueField.addKeyListener(new KeyListener() @@ -622,9 +622,11 @@ public class OptsAndParamsPage } }); valueField.setPreferredSize(new Dimension(60, 25)); + slider = makeSlider(parm.getValidValue()); + slider.addChangeListener(this); + controlPanel.add(slider, BorderLayout.WEST); controlPanel.add(valueField, BorderLayout.EAST); - } } @@ -634,8 +636,8 @@ public class OptsAndParamsPage { if (init) { - List vals = parm.getPossibleValues(); - for (Object val : vals) + List vals = parm.getPossibleValues(); + for (String val : vals) { choicebox.addItem(val); } @@ -651,96 +653,105 @@ public class OptsAndParamsPage valueField.setText(parm.getValue()); } } - lastVal = updateSliderFromValueField(); + lastVal = getCurrentValue(); adjusting = false; } - public Object updateSliderFromValueField() + private Slider makeSlider(ValueConstrainI validValue) + { + if (validValue != null) + { + final Number minValue = validValue.getMin(); + final Number maxValue = validValue.getMax(); + if (minValue != null && maxValue != null) + { + return new Slider(minValue.floatValue(), maxValue.floatValue(), + minValue.floatValue()); + } + } + + /* + * otherwise, a nominal slider which will not be visible + */ + return new Slider(0, 100, 50); + } + + public void updateSliderFromValueField() { - int iVal; - float fVal; if (validator != null) { + final Number minValue = validator.getMin(); + final Number maxValue = validator.getMax(); if (integ) { - iVal = 0; + int iVal = 0; try { valueField.setText(valueField.getText().trim()); iVal = Integer.valueOf(valueField.getText()); - if (validator.getMin() != null - && validator.getMin().intValue() > iVal) + if (minValue != null + && minValue.intValue() > iVal) { - iVal = validator.getMin().intValue(); + iVal = minValue.intValue(); // TODO: provide visual indication that hard limit was reached for // this parameter } - if (validator.getMax() != null - && validator.getMax().intValue() < iVal) + if (maxValue != null && maxValue.intValue() < iVal) { - iVal = validator.getMax().intValue(); - // TODO: provide visual indication that hard limit was reached for - // this parameter + iVal = maxValue.intValue(); } - } catch (Exception e) + } catch (NumberFormatException e) { + System.err.println(e.toString()); } - ; - // update value field to reflect any bound checking we performed. - valueField.setText("" + iVal); - if (validator.getMin() != null && validator.getMax() != null) + if (minValue != null || maxValue != null) { - slider.getModel().setRangeProperties(iVal, 1, - validator.getMin().intValue(), - validator.getMax().intValue() + 1, true); + valueField.setText(String.valueOf(iVal)); + slider.setSliderValue(iVal); } else { slider.setVisible(false); } - return new int[] { iVal }; } else { - fVal = 0f; + float fVal = 0f; try { valueField.setText(valueField.getText().trim()); fVal = Float.valueOf(valueField.getText()); - if (validator.getMin() != null - && validator.getMin().floatValue() > fVal) + if (minValue != null + && minValue.floatValue() > fVal) { - fVal = validator.getMin().floatValue(); + fVal = minValue.floatValue(); // TODO: provide visual indication that hard limit was reached for // this parameter // update value field to reflect any bound checking we performed. valueField.setText("" + fVal); } - if (validator.getMax() != null - && validator.getMax().floatValue() < fVal) + if (maxValue != null + && maxValue.floatValue() < fVal) { - fVal = validator.getMax().floatValue(); + fVal = maxValue.floatValue(); // TODO: provide visual indication that hard limit was reached for // this parameter // update value field to reflect any bound checking we performed. valueField.setText("" + fVal); } - } catch (Exception e) + } catch (NumberFormatException e) { + System.err.println(e.toString()); } - ; - if (validator.getMin() != null && validator.getMax() != null) + if (minValue != null && maxValue != null) { - slider.getModel().setRangeProperties((int) (fVal * 1000f), 1, - (int) (validator.getMin().floatValue() * 1000f), - 1 + (int) (validator.getMax().floatValue() * 1000f), - true); + slider.setSliderModel(minValue.floatValue(), + maxValue.floatValue(), fVal); } else { slider.setVisible(false); } - return new float[] { fVal }; } } else @@ -748,14 +759,8 @@ public class OptsAndParamsPage if (!choice) { slider.setVisible(false); - return new String[] { valueField.getText().trim() }; - } - else - { - return new String[] { (String) choicebox.getSelectedItem() }; } } - } } @@ -801,9 +806,9 @@ public class OptsAndParamsPage URL linkImageURL = getClass().getResource("/images/link.gif"); - Map optSet = new java.util.LinkedHashMap(); + Map optSet = new java.util.LinkedHashMap<>(); - Map paramSet = new java.util.LinkedHashMap(); + Map paramSet = new java.util.LinkedHashMap<>(); public Map getOptSet() { @@ -904,7 +909,7 @@ public class OptsAndParamsPage */ public List getCurrentSettings() { - List argSet = new ArrayList(); + List argSet = new ArrayList<>(); for (OptionBox opts : getOptSet().values()) { OptionI opt = opts.getOptionIfEnabled(); diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 407acd6..92f221c 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -1098,7 +1098,7 @@ public class SeqPanel extends JPanel pos); if (mf != null) { - unshownFeatures = seqARep.appendFeatures(tooltipText, + unshownFeatures += seqARep.appendFeatures(tooltipText, pos, mf, fr2, MAX_TOOLTIP_LENGTH); } } diff --git a/src/jalview/gui/Slider.java b/src/jalview/gui/Slider.java new file mode 100644 index 0000000..c8f673d --- /dev/null +++ b/src/jalview/gui/Slider.java @@ -0,0 +1,115 @@ +package jalview.gui; + +import javax.swing.JSlider; + +/** + * A modified {@code javax.swing.JSlider} that + *
      + *
    • supports float valued numbers (by scaling up integer values)
    • + *
    • rescales 'true' value range to avoid negative values, as these are not + * rendered correctly by some look and feel libraries
    • + *
    + * + * @author gmcarstairs + */ +@SuppressWarnings("serial") +public class Slider extends JSlider +{ + /* + * 'true' value corresponding to zero on the slider + */ + private float trueMin; + + /* + * 'true' value corresponding to slider maximum + */ + private float trueMax; + + /* + * scaleFactor applied to true value range to give a + * slider range of 0 - 100 + */ + private float sliderScaleFactor; + + /** + * Constructor that rescales min - max to 0 - 100 for the slider + * + * @param min + * @param max + * @param value + */ + public Slider(float min, float max, float value) + { + super(); + setSliderModel(min, max, value); + } + + /** + * Sets the min-max range and current value of the slider, with rescaling from + * true values to slider range as required + * + * @param min + * @param max + * @param value + */ + public void setSliderModel(float min, float max, float value) + { + trueMin = min; + trueMax = max; + setMinimum(0); + sliderScaleFactor = 100f / (max - min); + int sliderMax = (int) ((max - min) * sliderScaleFactor); + int extent = 1; + setExtent(extent); + setMaximum(sliderMax + extent); + setSliderValue(value); + } + + /** + * Answers the value of the slider position (descaled to 'true' value) + * + * @return + */ + public float getSliderValue() + { + /* + * convert slider max to 'true max' in case of rounding errors + */ + int value = getValue(); + return value == getMaximum() ? trueMax + : value / sliderScaleFactor + trueMin; + } + + /** + * Sets the slider value (scaled from the true value to the slider range) + * + * @param value + */ + public void setSliderValue(float value) + { + setValue(Math.round((value - trueMin) * sliderScaleFactor)); + } + + /** + * Answers the value of the slider position as a percentage between minimum and + * maximum of its range + * + * @return + */ + public float getSliderPercentageValue() + { + return (getValue() - getMinimum()) * 100f + / (getMaximum() - getMinimum()); + } + + /** + * Sets the slider position for a given percentage value of its min-max range + * + * @param pct + */ + public void setSliderPercentageValue(float pct) + { + float pc = pct / 100f * getMaximum(); + setValue((int) pc); + } +} diff --git a/src/jalview/io/FileParse.java b/src/jalview/io/FileParse.java index 7117d0f..f1d79fe 100755 --- a/src/jalview/io/FileParse.java +++ b/src/jalview/io/FileParse.java @@ -26,19 +26,22 @@ import jalview.api.AlignmentViewPanel; import jalview.api.FeatureSettingsModelI; import jalview.util.MessageManager; +import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLConnection; import java.util.zip.GZIPInputStream; + /** * implements a random access wrapper around a particular datasource, for * passing to identifyFile and AlignFile objects. @@ -56,6 +59,7 @@ public class FileParse public File inFile = null; + /** * a viewport associated with the current file operation. May be null. May * move to different object. @@ -182,29 +186,73 @@ public class FileParse } if (!error) { - if (fileStr.toLowerCase().endsWith(".gz")) + try { - try - { - dataIn = tryAsGzipSource(new FileInputStream(fileStr)); - dataName = fileStr; - return error; - } catch (Exception x) - { - warningMessage = "Failed to resolve as a GZ stream (" - + x.getMessage() + ")"; - // x.printStackTrace(); - } - ; + dataIn = checkForGzipStream(new FileInputStream(fileStr)); + dataName = fileStr; + } catch (Exception x) + { + warningMessage = "Failed to resolve " + fileStr + + " as a data source. (" + x.getMessage() + ")"; + // x.printStackTrace(); + error = true; } - - dataIn = new BufferedReader(new FileReader(fileStr)); - dataName = fileStr; + ; } return error; } + + /** + * Recognise the 2-byte magic header for gzip streams + * + * https://recalll.co/ask/v/topic/java-How-to-check-if-InputStream-is-Gzipped/555aadd62bd27354438b90f6 + * + * @param bytes - at least two bytes + * @return + */ + private static boolean isGzipStream(byte[] bytes) { + int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); + return (GZIPInputStream.GZIP_MAGIC == head); + } - private BufferedReader tryAsGzipSource(InputStream inputStream) + /** + * Returns a Reader for the given input after wrapping it in a buffered input + * stream, and then checking if it needs to be wrapped by a GZipInputStream + * + * @param input + * @return + */ + private BufferedReader checkForGzipStream(InputStream input) throws Exception { + + // NB: stackoverflow https://stackoverflow.com/questions/4818468/how-to-check-if-inputstream-is-gzipped + // could use a PushBackInputStream rather than a BufferedInputStream + + BufferedInputStream bufinput; + if (!input.markSupported()) { + bufinput= new BufferedInputStream(input,16); + input = bufinput; + } + input.mark(4); + byte[] bytes=input.readNBytes(2); + input.reset(); + if (bytes.length==2 && isGzipStream(bytes)) { + return getGzipReader(input); + } + // return a buffered reader for the stream. + InputStreamReader isReader= new InputStreamReader(input); + BufferedReader toReadFrom=new BufferedReader(isReader); + return toReadFrom; + } + /** + * Returns a {@code BufferedReader} which wraps the input stream with a + * GZIPInputStream. Throws a {@code ZipException} if a GZIP format error + * occurs or the compression method used is unsupported. + * + * @param inputStream + * @return + * @throws Exception + */ + private BufferedReader getGzipReader(InputStream inputStream) throws Exception { BufferedReader inData = new BufferedReader( @@ -215,44 +263,74 @@ public class FileParse return inData; } - private boolean checkURLSource(String fileStr) + /** + * Tries to read from the given URL. If successful, saves a reader to the + * response in field {@code dataIn}, otherwise (on exception, or HTTP response + * status not 200), throws an exception. + *

    + * If the response status includes + * + *

    +   * Content-Type : application/x-gzip
    +   * 
    + * + * then tries to read as gzipped content. + * + * @param urlStr + * @throws IOException + * @throws MalformedURLException + */ + private void checkURLSource(String urlStr) throws IOException, MalformedURLException { errormessage = "URL NOT FOUND"; - URL url = new URL(fileStr); - // - // GZIPInputStream code borrowed from Aquaria (soon to be open sourced) via - // Kenny Sabir - Exception e = null; - if (fileStr.toLowerCase().endsWith(".gz")) + URL url = new URL(urlStr); + URLConnection _conn = url.openConnection(); + if (_conn instanceof HttpURLConnection) { - try + HttpURLConnection conn = (HttpURLConnection) _conn; + int rc = conn.getResponseCode(); + if (rc != HttpURLConnection.HTTP_OK) { - InputStream inputStream = url.openStream(); - dataIn = tryAsGzipSource(inputStream); - dataName = fileStr; - return false; + throw new IOException( + "Response status from " + urlStr + " was " + rc); + } + } else { + try { + dataIn = checkForGzipStream(_conn.getInputStream()); + dataName=urlStr; + } catch (IOException ex) + { + throw new IOException("Failed to handle non-HTTP URI stream",ex); } catch (Exception ex) { - e = ex; + throw new IOException("Failed to determine type of input stream for given URI",ex); } + return; } - - try - { - dataIn = new BufferedReader(new InputStreamReader(url.openStream())); - } catch (IOException q) + String encoding = _conn.getContentEncoding(); + String contentType = _conn.getContentType(); + boolean isgzipped = "application/x-gzip".equalsIgnoreCase(contentType) + || "gzip".equals(encoding); + Exception e = null; + InputStream inputStream = _conn.getInputStream(); + if (isgzipped) { - if (e != null) + try + { + dataIn = getGzipReader(inputStream); + dataName = urlStr; + } catch (Exception e1) { throw new IOException(MessageManager .getString("exception.failed_to_resolve_gzip_stream"), e); } - throw q; + return; } - // record URL as name of datasource. - dataName = fileStr; - return false; + + dataIn = new BufferedReader(new InputStreamReader(inputStream)); + dataName = urlStr; + return; } /** diff --git a/src/jalview/io/vcf/VCFLoader.java b/src/jalview/io/vcf/VCFLoader.java index a44ee26..13d7ae8 100644 --- a/src/jalview/io/vcf/VCFLoader.java +++ b/src/jalview/io/vcf/VCFLoader.java @@ -912,7 +912,7 @@ public class VCFLoader * RuntimeException throwable by htsjdk */ String msg = String.format("Error reading VCF for %s:%d-%d: %s ", - map.chromosome, vcfStart, vcfEnd); + map.chromosome, vcfStart, vcfEnd,e.getLocalizedMessage()); Cache.log.error(msg); } } diff --git a/src/jalview/ws/dbsources/Pfam.java b/src/jalview/ws/dbsources/Pfam.java index 8877c34..47e66ac 100644 --- a/src/jalview/ws/dbsources/Pfam.java +++ b/src/jalview/ws/dbsources/Pfam.java @@ -35,6 +35,11 @@ import com.stevesoft.pat.Regex; */ abstract public class Pfam extends Xfam { + /* + * append to URLs to retrieve as a gzipped file + */ + protected static final String GZIPPED = "/gzipped"; + static final String PFAM_BASEURL_KEY = "PFAM_BASEURL"; private static final String DEFAULT_PFAM_BASEURL = "https://pfam.xfam.org"; diff --git a/src/jalview/ws/dbsources/PfamFull.java b/src/jalview/ws/dbsources/PfamFull.java index 0600427..d71892b 100644 --- a/src/jalview/ws/dbsources/PfamFull.java +++ b/src/jalview/ws/dbsources/PfamFull.java @@ -34,7 +34,7 @@ public class PfamFull extends Pfam @Override public String getURLSuffix() { - return "/alignment/full"; + return "/alignment/full" + GZIPPED; } /* diff --git a/src/jalview/ws/dbsources/PfamSeed.java b/src/jalview/ws/dbsources/PfamSeed.java index dff8a17..f64d07f 100644 --- a/src/jalview/ws/dbsources/PfamSeed.java +++ b/src/jalview/ws/dbsources/PfamSeed.java @@ -36,7 +36,7 @@ public class PfamSeed extends Pfam @Override public String getURLSuffix() { - return "/alignment/seed"; + return "/alignment/seed" + GZIPPED; } /* diff --git a/src/jalview/ws/dbsources/Rfam.java b/src/jalview/ws/dbsources/Rfam.java index 1d9d99a..c9ee7fc 100644 --- a/src/jalview/ws/dbsources/Rfam.java +++ b/src/jalview/ws/dbsources/Rfam.java @@ -36,6 +36,11 @@ abstract public class Rfam extends Xfam private static final String DEFAULT_RFAM_BASEURL = "https://rfam.xfam.org"; + /* + * append to URLs to retrieve as a gzipped file + */ + protected static final String GZIPPED = "?gzip=1&download=1"; + @Override protected String getURLPrefix() { diff --git a/src/jalview/ws/dbsources/RfamFull.java b/src/jalview/ws/dbsources/RfamFull.java index d815336..396511c 100644 --- a/src/jalview/ws/dbsources/RfamFull.java +++ b/src/jalview/ws/dbsources/RfamFull.java @@ -36,7 +36,7 @@ public class RfamFull extends Rfam @Override public String getURLSuffix() { - return "/alignment/full"; + return "/alignment/full" + GZIPPED; } /* diff --git a/src/jalview/ws/dbsources/RfamSeed.java b/src/jalview/ws/dbsources/RfamSeed.java index a74e829..eaa574b 100644 --- a/src/jalview/ws/dbsources/RfamSeed.java +++ b/src/jalview/ws/dbsources/RfamSeed.java @@ -36,8 +36,7 @@ public class RfamSeed extends Rfam @Override public String getURLSuffix() { - // to download gzipped file add '?gzip=1' - return "/alignment/stockholm"; + return "/alignment/stockholm" + GZIPPED; } /* diff --git a/src/jalview/ws/dbsources/Xfam.java b/src/jalview/ws/dbsources/Xfam.java index b83f558..f0cb14b 100644 --- a/src/jalview/ws/dbsources/Xfam.java +++ b/src/jalview/ws/dbsources/Xfam.java @@ -36,7 +36,6 @@ import jalview.ws.seqfetcher.DbSourceProxyImpl; */ public abstract class Xfam extends DbSourceProxyImpl { - public Xfam() { super(); diff --git a/test/jalview/datamodel/features/SequenceFeaturesTest.java b/test/jalview/datamodel/features/SequenceFeaturesTest.java index 4198a37..56512cd 100644 --- a/test/jalview/datamodel/features/SequenceFeaturesTest.java +++ b/test/jalview/datamodel/features/SequenceFeaturesTest.java @@ -5,8 +5,6 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import jalview.datamodel.SequenceFeature; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -15,6 +13,7 @@ import java.util.Set; import org.testng.annotations.Test; +import jalview.datamodel.SequenceFeature; import junit.extensions.PA; public class SequenceFeaturesTest @@ -1052,7 +1051,8 @@ public class SequenceFeaturesTest public void testSortFeatures() { List sfs = new ArrayList<>(); - SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, 80, + SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, + 60, Float.NaN, null); sfs.add(sf1); SequenceFeature sf2 = new SequenceFeature("Rfam", "desc", 40, 50, @@ -1061,18 +1061,34 @@ public class SequenceFeaturesTest SequenceFeature sf3 = new SequenceFeature("Rfam", "desc", 50, 60, Float.NaN, null); sfs.add(sf3); + SequenceFeature sf4 = new SequenceFeature("Xfam", "desc", 30, + 80, + Float.NaN, null); + sfs.add(sf4); + SequenceFeature sf5 = new SequenceFeature("Xfam", "desc", 30, + 90, + Float.NaN, null); + sfs.add(sf5); - // sort by end position descending + /* + * sort by end position descending, order unchanged if matched + */ SequenceFeatures.sortFeatures(sfs, false); - assertSame(sfs.get(0), sf1); - assertSame(sfs.get(1), sf3); - assertSame(sfs.get(2), sf2); + assertSame(sfs.get(0), sf5); // end 90 + assertSame(sfs.get(1), sf4); // end 80 + assertSame(sfs.get(2), sf1); // end 60, start 50 + assertSame(sfs.get(3), sf3); // end 60, start 30 + assertSame(sfs.get(4), sf2); // end 50 - // sort by start position ascending + /* + * resort {5, 4, 1, 3, 2} by start position ascending, end descending + */ SequenceFeatures.sortFeatures(sfs, true); - assertSame(sfs.get(0), sf1); - assertSame(sfs.get(1), sf2); - assertSame(sfs.get(2), sf3); + assertSame(sfs.get(0), sf5); // start 30, end 90 + assertSame(sfs.get(1), sf4); // start 30, end 80 + assertSame(sfs.get(2), sf1); // start 30, end 60 + assertSame(sfs.get(3), sf2); // start 40 + assertSame(sfs.get(4), sf3); // start 50 } @Test(groups = "Functional") diff --git a/test/jalview/ws/dbsources/PfamFullTest.java b/test/jalview/ws/dbsources/PfamFullTest.java index f5cc640..23cceb2 100644 --- a/test/jalview/ws/dbsources/PfamFullTest.java +++ b/test/jalview/ws/dbsources/PfamFullTest.java @@ -38,7 +38,7 @@ public class PfamFullTest @Test(groups = "Functional") public void testGetURL() { - String path = "pfam.xfam.org/family/ABC/alignment/full"; + String path = "pfam.xfam.org/family/ABC/alignment/full/gzipped"; // with default value for domain String url = new PfamFull().getURL(" abc "); diff --git a/test/jalview/ws/dbsources/PfamSeedTest.java b/test/jalview/ws/dbsources/PfamSeedTest.java index 355ef0c..451810b 100644 --- a/test/jalview/ws/dbsources/PfamSeedTest.java +++ b/test/jalview/ws/dbsources/PfamSeedTest.java @@ -38,7 +38,7 @@ public class PfamSeedTest @Test(groups = "Functional") public void testGetURL() { - String path = "pfam.xfam.org/family/ABC/alignment/seed"; + String path = "pfam.xfam.org/family/ABC/alignment/seed/gzipped"; // with default value for domain String url = new PfamSeed().getURL(" abc "); diff --git a/test/jalview/ws/dbsources/RfamFullTest.java b/test/jalview/ws/dbsources/RfamFullTest.java index 2d1497f..87b963f 100644 --- a/test/jalview/ws/dbsources/RfamFullTest.java +++ b/test/jalview/ws/dbsources/RfamFullTest.java @@ -38,7 +38,7 @@ public class RfamFullTest @Test(groups = "Functional") public void testGetURL() { - String path = "rfam.xfam.org/family/ABC/alignment/full"; + String path = "rfam.xfam.org/family/ABC/alignment/full?gzip=1&download=1"; // with default value for domain String url = new RfamFull().getURL(" abc "); diff --git a/test/jalview/ws/dbsources/RfamSeedTest.java b/test/jalview/ws/dbsources/RfamSeedTest.java index 745ba2e..1165d1f 100644 --- a/test/jalview/ws/dbsources/RfamSeedTest.java +++ b/test/jalview/ws/dbsources/RfamSeedTest.java @@ -38,7 +38,7 @@ public class RfamSeedTest @Test(groups = "Functional") public void testGetURL() { - String path = "rfam.xfam.org/family/ABC/alignment/stockholm"; + String path = "rfam.xfam.org/family/ABC/alignment/stockholm?gzip=1&download=1"; // with default value for domain String url = new RfamSeed().getURL(" abc ");