*/
public class FeatureAttributes
{
+ public enum Datatype
+ {
+ Character, Number, Mixed
+ }
+
private static FeatureAttributes instance = new FeatureAttributes();
/*
*/
boolean hasValue = false;
+ Datatype type;
+
/**
* Note one instance of this attribute, recording unique, non-null names,
* and the min/max of any numerical values
try
{
float f = Float.valueOf(value);
- min = Float.min(min, f);
- max = Float.max(max, f);
+ 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)
{
- // ok, wasn't a number, ignore for min-max purposes
+ // not a number, ignore for min-max purposes
+ type = (type == null || type == Datatype.Character)
+ ? Datatype.Character
+ : Datatype.Mixed;
}
}
}
return null;
}
+ public Datatype getType()
+ {
+ return type;
+ }
+
/**
* Adds the given description to the list of known descriptions (without
* duplication)
}
attData.addDescription(description);
}
+
+ /**
+ * Answers the datatype of the feature, which is one of Character, Number or
+ * Mixed (or null if not known), as discovered from values recorded.
+ *
+ * @param featureType
+ * @param attName
+ * @return
+ */
+ public Datatype getDatatype(String featureType, String... attName)
+ {
+ Map<String[], AttributeData> atts = attributes.get(featureType);
+ if (atts != null)
+ {
+ AttributeData attData = atts.get(attName);
+ if (attData != null)
+ {
+ return attData.getType();
+ }
+ }
+ return null;
+ }
}
package jalview.datamodel.features;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-import java.util.Comparator;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.features.FeatureAttributes.Datatype;
-import junit.extensions.PA;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
+import junit.extensions.PA;
+
public class FeatureAttributesTest
{
/**
+ * clear down attributes map after tests
+ */
+ @AfterMethod
+ public void tearDown()
+ {
+ FeatureAttributes fa = FeatureAttributes.getInstance();
+ ((Map<?, ?>) PA.getValue(fa, "attributes")).clear();
+ }
+
+ /**
* Test the method that keeps attribute names in non-case-sensitive order,
* including handling of 'compound' names
*/
assertTrue(comp.compare(new String[] { "CSQ", "ac" }, new String[] {
"csq", "AF" }) < 0);
}
+
+ @Test
+ public void testGetMinMax()
+ {
+ SequenceFeature sf = new SequenceFeature("Pfam", "desc", 10, 20,
+ "group");
+ FeatureAttributes fa = FeatureAttributes.getInstance();
+ 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 });
+ Map<String, String> csq = new HashMap<>();
+ csq.put("AF", "-3");
+ sf.setValue("CSQ", csq);
+ assertEquals(fa.getMinMax("Pfam", "CSQ", "AF"),
+ new float[]
+ { -3f, -3f });
+ csq.put("AF", "4");
+ sf.setValue("CSQ", csq);
+ assertEquals(fa.getMinMax("Pfam", "CSQ", "AF"),
+ new float[]
+ { -3f, 4f });
+ }
+
+ /**
+ * Test the method that returns an attribute description, provided it is
+ * recorded and unique
+ */
+ @Test
+ public void testGetDescription()
+ {
+ FeatureAttributes fa = FeatureAttributes.getInstance();
+ // with no description returns null
+ assertNull(fa.getDescription("Pfam", "kd"));
+ // with a unique description, returns that value
+ fa.addDescription("Pfam", "desc1", "kd");
+ assertEquals(fa.getDescription("Pfam", "kd"), "desc1");
+ // with ambiguous description, returns null
+ fa.addDescription("Pfam", "desc2", "kd");
+ assertNull(fa.getDescription("Pfam", "kd"));
+ }
+
+ @Test
+ public void testDatatype()
+ {
+ FeatureAttributes fa = FeatureAttributes.getInstance();
+ assertNull(fa.getDatatype("Pfam", "kd"));
+ SequenceFeature sf = new SequenceFeature("Pfam", "desc", 10, 20,
+ "group");
+ sf.setValue("kd", "-1");
+ sf.setValue("domain", "Metal");
+ sf.setValue("phase", "1");
+ sf.setValue("phase", "reverse");
+ assertEquals(fa.getDatatype("Pfam", "kd"), Datatype.Number);
+ assertEquals(fa.getDatatype("Pfam", "domain"), Datatype.Character);
+ assertEquals(fa.getDatatype("Pfam", "phase"), Datatype.Mixed);
+ }
}