Skip to content

Commit

Permalink
Add scripts and basic tests for unit conversion #19
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-austin committed Apr 30, 2022
1 parent 61230e1 commit fec327e
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/main/java/org/icatproject/utils/IcatUnits.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.icatproject.utils;

import javax.measure.IncommensurableException;
import javax.measure.UnconvertibleException;
import javax.measure.Unit;
import javax.measure.UnitConverter;
import javax.measure.format.MeasurementParseException;

import tech.units.indriya.format.SimpleUnitFormat;

/**
* Utility to perform conversions to SI (System) units.
*/
public class IcatUnits {

/**
* Holds the SI units and value for a quantity. If the units provided at construction could not be parsed, then these will be null.
*/
public class SystemValue {
public String units = null;
public Double value = null;

/**
* Converts value units into an SI quantity.
*
* @param value Quantity in (potentially) non-SI units.
* @param units Units of the provided value.
*/
public SystemValue(Double value, String units) {
try {
Unit<?> unit = unitFormat.parse(units);
Unit<?> systemUnit = unit.getSystemUnit();
this.units = systemUnit.getName();
if (value == null) {
return;
}
UnitConverter converter = unit.getConverterToAny(systemUnit);
this.value = converter.convert(value.doubleValue());
} catch (MeasurementParseException | UnconvertibleException | IncommensurableException e) {
// If the units can't be parsed, or the value converted, then just return
return;
}
}
}

private static final SimpleUnitFormat unitFormat = SimpleUnitFormat.getInstance();

/**
* Creates instance with any aliasing.
*/
public IcatUnits() {
}

/**
* In addition to the standard names and prefixes, allows aliasing other terms
* for a unit. Note that Unit should be refered to by the symbol specified in
* the
* <a href=
* "https://javadoc.io/doc/tech.units/indriya/latest/tech/units/indriya/unit/Units.html">Indriya
* documentation</a>, but the aliases can be any string. However, OoM prefixes
* will not be applied to aliases. For example, "mK" would be understood as
* 0.001K, but if "Kelvin" is aliased than "mKelvin" will not be understood.
*
* @param aliasOptions String with the format "<symbolA>: <aliasA1> <aliasA2>,
* <symbolB>: <aliasB2> ..."
*/
public IcatUnits(String aliasOptions) {
for (String unitAliases : aliasOptions.split(",")) {
String[] splitUnitAliases = unitAliases.split(":");
Unit<?> unit = unitFormat.parse(splitUnitAliases[0].trim());
for (String alias : splitUnitAliases[1].trim().split("\\s+")) {
unitFormat.alias(unit, alias);
}
}
}

}
45 changes: 45 additions & 0 deletions src/test/java/org/icatproject/utils/TestIcatUnits.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.icatproject.utils;

import static org.junit.Assert.assertEquals;
import org.icatproject.utils.IcatUnits.SystemValue;
import org.junit.Test;

public class TestIcatUnits {
@Test
public void testArguments() {
// Both null
IcatUnits icatUnits = new IcatUnits();
SystemValue systemValue = icatUnits.new SystemValue(null, "impossible to parse");
assertEquals(null, systemValue.units);
assertEquals(null, systemValue.value);

// Unit parsed, value null
systemValue = icatUnits.new SystemValue(null, "K");
assertEquals("Kelvin", systemValue.units);
assertEquals(null, systemValue.value);

// Unit parsed, value converted
systemValue = icatUnits.new SystemValue(1., "GK");
assertEquals("Kelvin", systemValue.units);
assertEquals(new Double(1e9), systemValue.value);
}

@Test
public void testAliasing() {
IcatUnits icatUnits = new IcatUnits();
SystemValue systemValue = icatUnits.new SystemValue(null, "celsius");
assertEquals(null, systemValue.units);
systemValue = icatUnits.new SystemValue(null, "degC");
assertEquals(null, systemValue.units);
systemValue = icatUnits.new SystemValue(null, "kelvin");
assertEquals(null, systemValue.units);

icatUnits = new IcatUnits("\u2103: celsius degC, K: kelvin");
systemValue = icatUnits.new SystemValue(null, "celsius");
assertEquals("Kelvin", systemValue.units);
systemValue = icatUnits.new SystemValue(null, "degC");
assertEquals("Kelvin", systemValue.units);
systemValue = icatUnits.new SystemValue(null, "kelvin");
assertEquals("Kelvin", systemValue.units);
}
}

0 comments on commit fec327e

Please sign in to comment.