/* * Copyright (C) 2014 University of Dundee & Open Microscopy Environment. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package omero.model; import static ome.model.units.Conversion.Mul; import static ome.model.units.Conversion.Add; import static ome.model.units.Conversion.Int; import static ome.model.units.Conversion.Pow; import static ome.model.units.Conversion.Rat; import static ome.model.units.Conversion.Sym; import java.math.BigDecimal; import java.util.Collections; import java.util.Map; import java.util.EnumMap; import java.util.HashMap; import ome.model.ModelBased; import ome.model.units.BigResult; import ome.model.units.Conversion; import ome.units.unit.Unit; import ome.util.Filterable; import ome.util.ModelMapper; import ome.util.ReverseModelMapper; import ome.xml.model.enums.EnumerationException; import omero.model.enums.UnitsTemperature; /** * Blitz wrapper around the {@link ome.model.units.Temperature} class. * Like {@link Details} and {@link Permissions}, this object * is embedded into other objects and does not have a full life * cycle of its own. * * @author Josh Moore, josh at glencoesoftware.com */ public class TemperatureI extends Temperature implements ModelBased { private static final long serialVersionUID = 1L; private static Map<UnitsTemperature, Conversion> createMapCELSIUS() { EnumMap<UnitsTemperature, Conversion> c = new EnumMap<UnitsTemperature, Conversion>(UnitsTemperature.class); c.put(UnitsTemperature.FAHRENHEIT, Add(Mul(Rat(Int(9), Int(5)), Sym("c")), Int(32))); c.put(UnitsTemperature.KELVIN, Add(Sym("c"), Rat(Int(5463), Int(20)))); c.put(UnitsTemperature.RANKINE, Add(Mul(Rat(Int(9), Int(5)), Sym("c")), Rat(Int(49167), Int(100)))); return Collections.unmodifiableMap(c); } private static Map<UnitsTemperature, Conversion> createMapFAHRENHEIT() { EnumMap<UnitsTemperature, Conversion> c = new EnumMap<UnitsTemperature, Conversion>(UnitsTemperature.class); c.put(UnitsTemperature.CELSIUS, Add(Mul(Rat(Int(5), Int(9)), Sym("f")), Rat(Int(-160), Int(9)))); c.put(UnitsTemperature.KELVIN, Add(Mul(Rat(Int(5), Int(9)), Sym("f")), Rat(Int(45967), Int(180)))); c.put(UnitsTemperature.RANKINE, Add(Sym("f"), Rat(Int(45967), Int(100)))); return Collections.unmodifiableMap(c); } private static Map<UnitsTemperature, Conversion> createMapKELVIN() { EnumMap<UnitsTemperature, Conversion> c = new EnumMap<UnitsTemperature, Conversion>(UnitsTemperature.class); c.put(UnitsTemperature.CELSIUS, Add(Sym("k"), Rat(Int(-5463), Int(20)))); c.put(UnitsTemperature.FAHRENHEIT, Add(Mul(Rat(Int(9), Int(5)), Sym("k")), Rat(Int(-45967), Int(100)))); c.put(UnitsTemperature.RANKINE, Mul(Rat(Int(9), Int(5)), Sym("k"))); return Collections.unmodifiableMap(c); } private static Map<UnitsTemperature, Conversion> createMapRANKINE() { EnumMap<UnitsTemperature, Conversion> c = new EnumMap<UnitsTemperature, Conversion>(UnitsTemperature.class); c.put(UnitsTemperature.CELSIUS, Add(Mul(Rat(Int(5), Int(9)), Sym("r")), Rat(Int(-5463), Int(20)))); c.put(UnitsTemperature.FAHRENHEIT, Add(Sym("r"), Rat(Int(-45967), Int(100)))); c.put(UnitsTemperature.KELVIN, Mul(Rat(Int(5), Int(9)), Sym("r"))); return Collections.unmodifiableMap(c); } private static final Map<UnitsTemperature, Map<UnitsTemperature, Conversion>> conversions; static { Map<UnitsTemperature, Map<UnitsTemperature, Conversion>> c = new EnumMap<UnitsTemperature, Map<UnitsTemperature, Conversion>>(UnitsTemperature.class); c.put(UnitsTemperature.CELSIUS, createMapCELSIUS()); c.put(UnitsTemperature.FAHRENHEIT, createMapFAHRENHEIT()); c.put(UnitsTemperature.KELVIN, createMapKELVIN()); c.put(UnitsTemperature.RANKINE, createMapRANKINE()); conversions = Collections.unmodifiableMap(c); } private static final Map<UnitsTemperature, String> SYMBOLS; static { Map<UnitsTemperature, String> s = new HashMap<UnitsTemperature, String>(); s.put(UnitsTemperature.CELSIUS, "°C"); s.put(UnitsTemperature.FAHRENHEIT, "°F"); s.put(UnitsTemperature.KELVIN, "K"); s.put(UnitsTemperature.RANKINE, "°R"); SYMBOLS = s; } public static String lookupSymbol(UnitsTemperature unit) { return SYMBOLS.get(unit); } public static final Ice.ObjectFactory makeFactory(final omero.client client) { return new Ice.ObjectFactory() { public Ice.Object create(String arg0) { return new TemperatureI(); } public void destroy() { // no-op } }; }; // // CONVERSIONS // public static ome.xml.model.enums.UnitsTemperature makeXMLUnit(String unit) { try { return ome.xml.model.enums.UnitsTemperature .fromString((String) unit); } catch (EnumerationException e) { throw new RuntimeException("Bad Temperature unit: " + unit, e); } } public static ome.units.quantity.Temperature makeXMLQuantity(double d, String unit) { ome.units.unit.Unit<ome.units.quantity.Temperature> units = ome.xml.model.enums.handlers.UnitsTemperatureEnumHandler .getBaseUnit(makeXMLUnit(unit)); return new ome.units.quantity.Temperature(d, units); } /** * FIXME: this should likely take a default so that locations which don't * want an exception can have * * log.warn("Using new PositiveFloat(1.0)!", e); return new * PositiveFloat(1.0); * * or similar. */ public static ome.units.quantity.Temperature convert(Temperature t) { if (t == null) { return null; } Double v = t.getValue(); // Use the code/symbol-mapping in the ome.model.enums files // to convert to the specification value. String u = ome.model.enums.UnitsTemperature.valueOf( t.getUnit().toString()).getSymbol(); ome.xml.model.enums.UnitsTemperature units = makeXMLUnit(u); ome.units.unit.Unit<ome.units.quantity.Temperature> units2 = ome.xml.model.enums.handlers.UnitsTemperatureEnumHandler .getBaseUnit(units); return new ome.units.quantity.Temperature(v, units2); } // // REGULAR ICE CLASS // public final static Ice.ObjectFactory Factory = makeFactory(null); public TemperatureI() { super(); } public TemperatureI(double d, UnitsTemperature unit) { super(); this.setUnit(unit); this.setValue(d); } public TemperatureI(double d, Unit<ome.units.quantity.Temperature> unit) { this(d, ome.model.enums.UnitsTemperature.bySymbol(unit.getSymbol())); } /** * Copy constructor that converts the given {@link omero.model.Temperature} * based on the given ome-xml enum */ public TemperatureI(Temperature value, Unit<ome.units.quantity.Temperature> ul) throws BigResult { this(value, ome.model.enums.UnitsTemperature.bySymbol(ul.getSymbol()).toString()); } /** * Copy constructor that converts the given {@link omero.model.Temperature} * based on the given ome.model enum */ public TemperatureI(double d, ome.model.enums.UnitsTemperature ul) { this(d, UnitsTemperature.valueOf(ul.toString())); } /** * Copy constructor that converts the given {@link omero.model.Temperature} * based on the given enum string. * * @param target String representation of the CODE enum */ public TemperatureI(Temperature value, String target) throws BigResult { String source = value.getUnit().toString(); if (target.equals(source)) { setValue(value.getValue()); setUnit(value.getUnit()); } else { UnitsTemperature targetUnit = UnitsTemperature.valueOf(target); Conversion conversion = conversions.get(value.getUnit()).get(targetUnit); if (conversion == null) { throw new RuntimeException(String.format( "%f %s cannot be converted to %s", value.getValue(), value.getUnit(), target)); } double orig = value.getValue(); BigDecimal big = conversion.convert(orig); double converted = big.doubleValue(); if (Double.isInfinite(converted)) { throw new BigResult(big, "Failed to convert " + source + ":" + target); } setValue(converted); setUnit(targetUnit); } } /** * Copy constructor that converts between units if possible. * * @param target unit that is desired. non-null. */ public TemperatureI(Temperature value, UnitsTemperature target) throws BigResult { this(value, target.toString()); } /** * Convert a Bio-Formats {@link Length} to an OMERO Length. */ public TemperatureI(ome.units.quantity.Temperature value) { ome.model.enums.UnitsTemperature internal = ome.model.enums.UnitsTemperature.bySymbol(value.unit().getSymbol()); UnitsTemperature ul = UnitsTemperature.valueOf(internal.toString()); setValue(value.value().doubleValue()); setUnit(ul); } public double getValue(Ice.Current current) { return this.value; } public void setValue(double value , Ice.Current current) { this.value = value; } public UnitsTemperature getUnit(Ice.Current current) { return this.unit; } public void setUnit(UnitsTemperature unit, Ice.Current current) { this.unit = unit; } public String getSymbol(Ice.Current current) { return SYMBOLS.get(this.unit); } public Temperature copy(Ice.Current ignore) { TemperatureI copy = new TemperatureI(); copy.setValue(getValue()); copy.setUnit(getUnit()); return copy; } @Override public void copyObject(Filterable model, ModelMapper mapper) { if (model instanceof ome.model.units.Temperature) { ome.model.units.Temperature t = (ome.model.units.Temperature) model; this.value = t.getValue(); this.unit = UnitsTemperature.valueOf(t.getUnit().toString()); } else { throw new IllegalArgumentException( "Temperature cannot copy from " + (model==null ? "null" : model.getClass().getName())); } } @Override public Filterable fillObject(ReverseModelMapper mapper) { ome.model.enums.UnitsTemperature ut = ome.model.enums.UnitsTemperature.valueOf(getUnit().toString()); ome.model.units.Temperature t = new ome.model.units.Temperature(getValue(), ut); return t; } // ~ Java overrides // ========================================================================= @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((unit == null) ? 0 : unit.hashCode()); long temp; temp = Double.doubleToLongBits(value); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public String toString() { return "Temperature(" + value + " " + unit + ")"; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Temperature other = (Temperature) obj; if (unit != other.unit) return false; if (Double.doubleToLongBits(value) != Double .doubleToLongBits(other.value)) return false; return true; } }