use of tec.uom.se.function.RationalConverter in project n2a by frothga.
the class ImportJob method unit.
@SuppressWarnings({ "rawtypes", "unchecked" })
public void unit(Node node) {
String symbol = getAttribute(node, "symbol");
String dimension = getAttribute(node, "dimension");
int power = getAttribute(node, "power", 0);
double scale = getAttribute(node, "scale", 1.0);
double offset = getAttribute(node, "offset", 0.0);
Unit unit = dimensions.get(dimension);
// fall back, but in general something is broken about the file
if (unit == null)
unit = AbstractUnit.ONE;
if (power > 0)
unit = unit.transform(new RationalConverter(BigInteger.TEN.pow(power), BigInteger.ONE));
else if (power < 0)
unit = unit.transform(new RationalConverter(BigInteger.ONE, BigInteger.TEN.pow(-power)));
else {
if (scale == 1.0) {
unit = unit.shift(offset);
} else {
// UCUM only allows rational numbers, so convert scale
RationalConverter ratio = null;
if (scale < 1.0) {
// Attempt to find a simple ratio of 1/integer
double inverse = 1.0 / scale;
long integer = Math.round(inverse);
if (Math.abs(inverse - integer) < epsilon)
ratio = new RationalConverter(1, integer);
}
if (ratio == null) {
String s = getAttribute(node, "scale").toLowerCase();
String[] pieces = s.split("e");
int shift = 0;
if (pieces.length > 1)
shift = Integer.valueOf(pieces[1]);
pieces = pieces[0].split(".");
if (pieces.length > 1) {
shift -= pieces[1].length();
s = pieces[0] + pieces[1];
}
BigInteger numerator = new BigInteger(s);
BigInteger denominator = new BigDecimal(10).pow(shift).toBigInteger();
ratio = new RationalConverter(numerator, denominator);
}
unit = unit.transform(ratio).shift(offset);
}
}
// Since LEMS and NeuroML tend to follow certain naming practices, we may be able to retrieve
// a more parsimonious unit based on direct name translation.
String tempName = symbol;
tempName = tempName.replace("_per_", "/");
tempName = tempName.replace("per_", "/");
tempName = tempName.replace("_", ".");
tempName = tempName.replace("ohm", "Ohm");
tempName = tempName.replace("hour", "h");
Unit temp = null;
try {
temp = UCUM.parse(tempName);
} catch (ParserException | TokenException e) {
}
if (// found a unit with matching dimension ...
temp != null && temp.isCompatible(unit)) {
Number tempScale = temp.getConverterTo(temp.getSystemUnit()).convert(new Integer(1));
Number unitScale = temp.getConverterTo(unit.getSystemUnit()).convert(new Integer(1));
if (// ... and matching scale ...
tempScale.equals(unitScale)) {
int unitLength = UCUM.format(unit).length();
int tempLength = UCUM.format(temp).length();
if (// ... and at least as parsimonious
tempLength <= unitLength) {
unit = temp;
// Update dimension if this is directly equivalent, but strictly more parsimonious
if (power == 0 && scale == 1 && offset == 0 && tempLength < unitLength) {
dimensions.put(dimension, temp);
}
}
}
}
if (ExpressionParser.namedUnits == null)
ExpressionParser.namedUnits = new HashMap<String, Unit<?>>();
ExpressionParser.namedUnits.put(symbol, unit);
}
Aggregations