Datatype type;
/**
- * Note one instance of this attribute, recording unique, non-null names,
- * and the min/max of any numerical values
+ * Note one instance of this attribute, recording unique, non-null
+ * descriptions, and the min/max of any numerical values
*
* @param desc
* @param value
if (value != null)
{
- try
- {
- float f = Float.valueOf(value);
- min = hasValue ? Float.min(min, f) : f;
- max = hasValue ? Float.max(max, f) : f;
- hasValue = true;
- type = (type == null || type == Datatype.Number) ? Datatype.Number
- : Datatype.Mixed;
- } catch (NumberFormatException e)
+ value = value.trim();
+
+ /*
+ * Parse numeric value unless we have previously
+ * seen text data for this attribute type
+ */
+ if (type == null || type == Datatype.Number)
{
- // not a number, ignore for min-max purposes
- type = (type == null || type == Datatype.Character)
- ? Datatype.Character
- : Datatype.Mixed;
+ try
+ {
+ float f = Float.valueOf(value);
+ min = hasValue ? Float.min(min, f) : f;
+ max = hasValue ? Float.max(max, f) : f;
+ hasValue = true;
+ type = (type == null || type == Datatype.Number)
+ ? Datatype.Number
+ : Datatype.Mixed;
+ } catch (NumberFormatException e)
+ {
+ /*
+ * non-numeric data: treat attribute as Character (or Mixed)
+ */
+ type = (type == null || type == Datatype.Character)
+ ? Datatype.Character
+ : Datatype.Mixed;
+ min = 0f;
+ max = 0f;
+ hasValue = false;
+ }
}
}
}
/**
* Answers the [min, max] value range of the given attribute for the given
- * feature type, if known, else null. Attributes which only have text values
- * would normally return null, however text values which happen to be numeric
- * could result in a 'min-max' range.
+ * feature type, if known, else null. Attributes with a mixture of text and
+ * numeric values are considered text (do not return a min-max range).
*
* @param featureType
* @param attName
* @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
* @see http://rest.ensembl.org/info/rest?content-type=application/json
*/
- private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "6.0";
+ private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "6.3";
- private static final String LATEST_ENSEMBL_REST_VERSION = "6.1";
+ private static final String LATEST_ENSEMBL_REST_VERSION = "6.3";
private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
private static Map<String, EnsemblData> domainData;
- // @see https://github.com/Ensembl/ensembl-rest/wiki/Output-formats
- private static final String PING_URL = "http://rest.ensembl.org/info/ping.json";
-
private final static long AVAILABILITY_RETEST_INTERVAL = 10000L; // 10 seconds
private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
* if a numeric condition is selected, show the value range
* as a tooltip on the value input field
*/
- setPatternTooltip(filterBy, selectedCondition, patternField);
+ setNumericHints(filterBy, selectedCondition, patternField);
/*
* add remove button if filter is populated (non-empty pattern)
}
/**
- * If a numeric comparison condition is selected, retrieve the min-max range for
- * the value (score or attribute), and set it as a tooltip on the value file
+ * If a numeric comparison condition is selected, retrieves the min-max range
+ * for the value (score or attribute), and sets it as a tooltip on the value
+ * field. If the field is currently empty, then pre-populates it with
+ * <ul>
+ * <li>the minimum value, if condition is > or >=</li>
+ * <li>the maximum value, if condition is < or <=</li>
+ * </ul>
*
* @param attName
* @param selectedCondition
* @param patternField
*/
- private void setPatternTooltip(String attName,
+ private void setNumericHints(String attName,
Condition selectedCondition, JTextField patternField)
{
patternField.setToolTipText("");
float[] minMax = getMinMax(attName);
if (minMax != null)
{
- String tip = String.format("(%s - %s)",
- DECFMT_2_2.format(minMax[0]), DECFMT_2_2.format(minMax[1]));
+ String minFormatted = DECFMT_2_2.format(minMax[0]);
+ String maxFormatted = DECFMT_2_2.format(minMax[1]);
+ String tip = String.format("(%s - %s)", minFormatted, maxFormatted);
patternField.setToolTipText(tip);
+ if (patternField.getText().isEmpty())
+ {
+ if (selectedCondition == Condition.GE
+ || selectedCondition == Condition.GT)
+ {
+ patternField.setText(minFormatted);
+ }
+ else
+ {
+ if (selectedCondition == Condition.LE
+ || selectedCondition == Condition.LT)
+ {
+ patternField.setText(maxFormatted);
+ }
+ }
+ }
}
}
}
ItemListener listener = condCombo.getItemListeners()[0];
condCombo.removeItemListener(listener);
boolean condIsValid = false;
+
condCombo.removeAllItems();
for (Condition c : Condition.values())
{
- if ((c.isNumeric() && type != Datatype.Character)
+ if ((c.isNumeric() && type == Datatype.Number)
|| (!c.isNumeric() && type != Datatype.Number))
{
condCombo.addItem(c);
condCombo.setSelectedIndex(0);
}
- condCombo.addItemListener(listener);
-
/*
* clear pattern if it is now invalid for condition
*/
patternField.setText("");
}
}
+
+ /*
+ * restore the listener
+ */
+ condCombo.addItemListener(listener);
}
/**
Condition cond = (Condition) condCombo.getSelectedItem();
String pattern = valueField.getText().trim();
- setPatternTooltip(attName, cond, valueField);
+ setNumericHints(attName, cond, valueField);
if (pattern.length() == 0 && cond.needsAPattern())
{
fromHighest = Integer.MIN_VALUE;
for (int[] range : fromRange)
{
+ if (range.length != 2)
+ {
+ // throw new IllegalArgumentException(range);
+ System.err.println(
+ "Invalid format for fromRange " + Arrays.toString(range)
+ + " may cause errors");
+ }
fromLowest = Math.min(fromLowest, Math.min(range[0], range[1]));
fromHighest = Math.max(fromHighest, Math.max(range[0], range[1]));
}
toHighest = Integer.MIN_VALUE;
for (int[] range : toRange)
{
+ if (range.length != 2)
+ {
+ // throw new IllegalArgumentException(range);
+ System.err.println("Invalid format for toRange "
+ + Arrays.toString(range)
+ + " may cause errors");
+ }
toLowest = Math.min(toLowest, Math.min(range[0], range[1]));
toHighest = Math.max(toHighest, Math.max(range[0], range[1]));
}
for (int[] range : getToRanges())
{
int[] transferred = map.locateInTo(range[0], range[1]);
- if (transferred == null)
+ if (transferred == null || transferred.length % 2 != 0)
{
return null;
}
- toRanges.add(transferred);
+
+ /*
+ * convert [start1, end1, start2, end2, ...]
+ * to [[start1, end1], [start2, end2], ...]
+ */
+ for (int i = 0; i < transferred.length;)
+ {
+ toRanges.add(new int[] { transferred[i], transferred[i + 1] });
+ i += 2;
+ }
}
return new MapList(getFromRanges(), toRanges, outFromRatio, outToRatio);
assertEquals(2, toMap.getFromRanges().get(0).length);
assertEquals(1, toMap.getFromRanges().get(0)[0]);
assertEquals(12, toMap.getFromRanges().get(0)[1]);
- assertEquals(1, toMap.getToRanges().size());
- assertEquals(4, toMap.getToRanges().get(0).length);
+ assertEquals(2, toMap.getToRanges().size());
+ assertEquals(2, toMap.getToRanges().get(0).length);
assertEquals(158, toMap.getToRanges().get(0)[0]);
assertEquals(164, toMap.getToRanges().get(0)[1]);
- assertEquals(210, toMap.getToRanges().get(0)[2]);
- assertEquals(214, toMap.getToRanges().get(0)[3]);
+ assertEquals(210, toMap.getToRanges().get(1)[0]);
+ assertEquals(214, toMap.getToRanges().get(1)[1]);
// or summarised as (but toString might change in future):
- assertEquals("[ [1, 12] ] 1:1 to [ [158, 164, 210, 214] ]",
+ assertEquals("[ [1, 12] ] 1:1 to [ [158, 164] [210, 214] ]",
toMap.toString());
/*
assertEquals("GRCh38", toLoci.getAssemblyId());
assertEquals("7", toLoci.getChromosomeId());
toMap = toLoci.getMap();
- assertEquals("[ [1, 12] ] 1:1 to [ [158, 164, 210, 214] ]",
+ assertEquals("[ [1, 12] ] 1:1 to [ [158, 164] [210, 214] ]",
toMap.toString());
}
assertNull(fa.getMinMax("Pfam", "kd"));
sf.setValue("domain", "xyz");
assertNull(fa.getMinMax("Pfam", "kd"));
- sf.setValue("kd", "some text");
- assertNull(fa.getMinMax("Pfam", "kd"));
sf.setValue("kd", "1.3");
assertEquals(fa.getMinMax("Pfam", "kd"), new float[] { 1.3f, 1.3f });
sf.setValue("kd", "-2.6");
assertEquals(fa.getMinMax("Pfam", "kd"), new float[] { -2.6f, 1.3f });
+ // setting 'mixed' character and numeric values wipes the min/max value
+ sf.setValue("kd", "some text");
+ assertNull(fa.getMinMax("Pfam", "kd"));
+
Map<String, String> csq = new HashMap<>();
csq.put("AF", "-3");
sf.setValue("CSQ", csq);
*/
MapList ml1 = new MapList(new int[] { 3, 4, 8, 12 }, new int[] { 5, 8,
11, 13 }, 1, 1);
+ assertEquals("{[3, 4], [8, 12]}", prettyPrint(ml1.getFromRanges()));
+ assertEquals("{[5, 8], [11, 13]}", prettyPrint(ml1.getToRanges()));
+
MapList ml2 = new MapList(new int[] { 1, 50 }, new int[] { 40, 45, 70,
75, 90, 127 }, 1, 1);
+ assertEquals("{[1, 50]}", prettyPrint(ml2.getFromRanges()));
+ assertEquals("{[40, 45], [70, 75], [90, 127]}",
+ prettyPrint(ml2.getToRanges()));
+
MapList compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 1);
- assertEquals(compound.getToRatio(), 1);
+ assertEquals(1, compound.getFromRatio());
+ assertEquals(1, compound.getToRatio());
List<int[]> fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 2);
+ assertEquals(2, fromRanges.size());
assertArrayEquals(new int[] { 3, 4 }, fromRanges.get(0));
assertArrayEquals(new int[] { 8, 12 }, fromRanges.get(1));
List<int[]> toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 2);
+ assertEquals(4, toRanges.size());
// 5-8 maps to 44-45,70-71
// 11-13 maps to 74-75,90
- assertArrayEquals(new int[] { 44, 45, 70, 71 }, toRanges.get(0));
- assertArrayEquals(new int[] { 74, 75, 90, 90 }, toRanges.get(1));
+ assertArrayEquals(new int[] { 44, 45 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 70, 71 }, toRanges.get(1));
+ assertArrayEquals(new int[] { 74, 75 }, toRanges.get(2));
+ assertArrayEquals(new int[] { 90, 90 }, toRanges.get(3));
/*
* 1:1 over 1:1 backwards ('reverse strand')
new int[] { 1000, 901, 600, 201 }, 1, 1);
compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 1);
- assertEquals(compound.getToRatio(), 1);
+ assertEquals(1, compound.getFromRatio());
+ assertEquals(1, compound.getToRatio());
fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 1);
+ assertEquals(1, fromRanges.size());
assertArrayEquals(new int[] { 1, 50 }, fromRanges.get(0));
toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 1);
- assertArrayEquals(new int[] { 931, 901, 600, 582 }, toRanges.get(0));
+ assertEquals(2, toRanges.size());
+ assertArrayEquals(new int[] { 931, 901 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 600, 582 }, toRanges.get(1));
/*
* 1:1 plus 1:3 should result in 1:3
1, 3);
compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 1);
- assertEquals(compound.getToRatio(), 3);
+ assertEquals(1, compound.getFromRatio());
+ assertEquals(3, compound.getToRatio());
fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 1);
+ assertEquals(1, fromRanges.size());
assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0));
// 11-40 maps to 31-50,91-160
toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 1);
- assertArrayEquals(new int[] { 31, 50, 91, 160 }, toRanges.get(0));
+ assertEquals(2, toRanges.size());
+ assertArrayEquals(new int[] { 31, 50 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 91, 160 }, toRanges.get(1));
/*
* 3:1 plus 1:1 should result in 3:1
1, 1);
compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 3);
- assertEquals(compound.getToRatio(), 1);
+ assertEquals(3, compound.getFromRatio());
+ assertEquals(1, compound.getToRatio());
fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 1);
+ assertEquals(1, fromRanges.size());
assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0));
// 11-20 maps to 11-15, 91-95
toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 1);
- assertArrayEquals(new int[] { 11, 15, 91, 95 }, toRanges.get(0));
+ assertEquals(2, toRanges.size());
+ assertArrayEquals(new int[] { 11, 15 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 91, 95 }, toRanges.get(1));
/*
* 1:3 plus 3:1 should result in 1:1
3, 1);
compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 1);
- assertEquals(compound.getToRatio(), 1);
+ assertEquals(1, compound.getFromRatio());
+ assertEquals(1, compound.getToRatio());
fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 1);
+ assertEquals(1, fromRanges.size());
assertArrayEquals(new int[] { 21, 40 }, fromRanges.get(0));
// 13-72 maps 3:1 to 55-70, 121-124
toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 1);
- assertArrayEquals(new int[] { 55, 70, 121, 124 }, toRanges.get(0));
+ assertEquals(2, toRanges.size());
+ assertArrayEquals(new int[] { 55, 70 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 121, 124 }, toRanges.get(1));
/*
* 3:1 plus 1:3 should result in 1:1
1, 3);
compound = ml1.traverse(ml2);
- assertEquals(compound.getFromRatio(), 1);
- assertEquals(compound.getToRatio(), 1);
+ assertEquals(1, compound.getFromRatio());
+ assertEquals(1, compound.getToRatio());
fromRanges = compound.getFromRanges();
- assertEquals(fromRanges.size(), 1);
+ assertEquals(1, fromRanges.size());
assertArrayEquals(new int[] { 31, 90 }, fromRanges.get(0));
// 13-32 maps to 47-50,71-126
toRanges = compound.getToRanges();
- assertEquals(toRanges.size(), 1);
- assertArrayEquals(new int[] { 47, 50, 71, 126 }, toRanges.get(0));
+ assertEquals(2, toRanges.size());
+ assertArrayEquals(new int[] { 47, 50 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 71, 126 }, toRanges.get(1));
/*
* method returns null if not all regions are mapped through