001/*
002 * Units of Measurement Systems
003 * Copyright (c) 2005-2019, Jean-Marie Dautelle, Werner Keil and others.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385, Units of Measurement nor the names of their contributors may be used to
017 *    endorse or promote products derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package systems.uom.ucum;
031
032//import static tech.units.indriya.unit.MetricPrefix.*;
033import static tech.units.indriya.unit.MetricPrefix.*;
034import static tech.units.indriya.AbstractUnit.ONE;
035
036import java.util.Objects;
037
038import si.uom.quantity.*;
039import systems.uom.quantity.Acidity;
040import systems.uom.quantity.Concentration;
041import systems.uom.quantity.Drag;
042import systems.uom.quantity.Information;
043import systems.uom.quantity.InformationRate;
044import systems.uom.quantity.Level;
045import si.uom.SI;
046import tech.units.indriya.*;
047import tech.units.indriya.format.SimpleUnitFormat;
048import tech.units.indriya.function.LogConverter;
049import tech.units.indriya.function.MultiplyConverter;
050import tech.units.indriya.function.PowersOfPiConverter;
051//import tech.units.indriya.function.PowersOfPiConverter;
052import tech.units.indriya.unit.AlternateUnit;
053import tech.units.indriya.unit.ProductUnit;
054import tech.units.indriya.unit.TransformedUnit;
055import tech.units.indriya.unit.Units;
056
057import javax.measure.Quantity;
058import javax.measure.Unit;
059import javax.measure.quantity.*;
060
061/**
062 * <p>
063 * This class contains {@link SI} and Non-SI units as defined in the
064 * <a href="http://unitsofmeasure.org/"> Unified Code for Units of Measure</a>.
065 * </p>
066 *
067 * <p>
068 * Compatibility with {@link SI} units has been given priority over strict
069 * adherence to the standard. We have attempted to note every place where the
070 * definitions in this class deviate from the UCUM standard, but such notes are
071 * likely to be incomplete.
072 * </p>
073 *
074 * @author <a href="mailto:eric-r@northwestern.edu">Eric Russell</a>
075 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
076 * @see <a href="http://www.unitsofmeasure.org">UCUM</a>
077 * @version 1.1, $Date: 2019-01-21 $
078 */
079public final class UCUM extends AbstractSystemOfUnits {
080
081    /**
082     * The singleton instance.
083     */
084    private static final UCUM INSTANCE = new UCUM();
085
086    /**
087     * Default constructor (prevents this class from being instantiated).
088     */
089    private UCUM() {
090    }
091
092    /**
093     * Returns the singleton instance of this class.
094     *
095     * @return the UCUM system instance.
096     */
097    public static UCUM getInstance() {
098        return INSTANCE;
099    }
100
101    //////////////////////////////
102    // BASE UNITS: UCUM 4.2 §28 //
103    //////////////////////////////
104    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
105    public static final Unit<Length> METER = addUnit(Units.METRE);
106    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
107    public static final Unit<Time> SECOND = addUnit(Units.SECOND);
108    /**
109     * We deviate slightly from the standard here, to maintain compatibility
110     * with the existing SI units. In UCUM, the gram is the base unit of mass,
111     * rather than the kilogram. This doesn't have much effect on the units
112     * themselves, but it does make formatting the units a challenge.
113     */
114    public static final Unit<Mass> GRAM = addUnit(Units.GRAM);
115    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
116    public static final Unit<Angle> RADIAN = addUnit(Units.RADIAN);
117    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
118    public static final Unit<Temperature> KELVIN = addUnit(Units.KELVIN);
119    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
120    public static final Unit<ElectricCharge> COULOMB = addUnit(Units.COULOMB);
121    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
122    public static final Unit<LuminousIntensity> CANDELA = addUnit(Units.CANDELA);
123
124    ///////////////////////////////////////////////
125    // DIMENSIONLESS DERIVED UNITS: UCUM 4.3 §29 //
126    ///////////////////////////////////////////////
127    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
128    public static final Unit<Dimensionless> TRILLIONS = addUnit(ONE.multiply(1000000000000L));
129    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
130    public static final Unit<Dimensionless> BILLIONS = addUnit(ONE.multiply(1000000000));
131    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
132    public static final Unit<Dimensionless> MILLIONS = addUnit(ONE.multiply(1000000));
133    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
134    public static final Unit<Dimensionless> THOUSANDS = addUnit(ONE.multiply(1000));
135    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
136    public static final Unit<Dimensionless> HUNDREDS = addUnit(ONE.multiply(100));
137    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
138    public static final Unit<Dimensionless> PI = addUnit(ONE.transform(PowersOfPiConverter.of(1)));
139    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
140    public static final Unit<Dimensionless> PERCENT = addUnit(ONE.divide(100));
141    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
142    public static final Unit<Dimensionless> PER_THOUSAND = addUnit(ONE.divide(1000));
143    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
144    public static final Unit<Dimensionless> PER_MILLION = addUnit(ONE.divide(1000000));
145    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
146    public static final Unit<Dimensionless> PER_BILLION = addUnit(ONE.divide(1000000000));
147    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
148    public static final Unit<Dimensionless> PER_TRILLION = addUnit(ONE.divide(1000000000000L));
149    ////////////////////////////
150    // SI UNITS: UCUM 4.3 §30 //
151    ////////////////////////////
152    /**
153     * We deviate slightly from the standard here, to maintain compatibility
154     * with the existing SI units. In UCUM, the mole is no longer a base unit,
155     * but is defined as <code>Unit.ONE.multiply(6.0221367E23)</code>.
156     */
157    public static final Unit<AmountOfSubstance> MOLE = addUnit(Units.MOLE);
158    /**
159     * We deviate slightly from the standard here, to maintain compatibility
160     * with the existing SI units. In UCUM, the steradian is defined as
161     * <code>RADIAN.pow(2)</code>.
162     */
163    public static final Unit<SolidAngle> STERADIAN = addUnit(Units.STERADIAN);
164    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
165    public static final Unit<Frequency> HERTZ = addUnit(Units.HERTZ);
166    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
167    public static final Unit<Force> NEWTON = addUnit(Units.NEWTON);
168    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
169    public static final Unit<Pressure> PASCAL = addUnit(Units.PASCAL);
170    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
171    public static final Unit<Energy> JOULE = addUnit(Units.JOULE);
172    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
173    public static final Unit<Power> WATT = addUnit(Units.WATT);
174    /**
175     * We deviate slightly from the standard here, to maintain compatibility
176     * with the existing SI units. In UCUM, the ampere is defined as
177     * <code>COULOMB.divide(SECOND)</code>.
178     */
179    public static final Unit<ElectricCurrent> AMPERE = addUnit(Units.AMPERE);
180    // public static final Unit<MagnetomotiveForce> AMPERE_TURN =
181    // addUnit(Units.AMPERE_TURN);
182    /**
183     * We deviate slightly from the standard here, to maintain compatibility
184     * with the existing SI units. In UCUM, the volt is defined as
185     * <code>JOULE.divide(COULOMB)</code>.
186     */
187    public static final Unit<ElectricPotential> VOLT = addUnit(Units.VOLT);
188    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
189    public static final Unit<ElectricCapacitance> FARAD = addUnit(Units.FARAD);
190    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
191    public static final Unit<ElectricResistance> OHM = addUnit(Units.OHM);
192    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
193    public static final Unit<ElectricConductance> SIEMENS = addUnit(Units.SIEMENS);
194    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
195    public static final Unit<MagneticFlux> WEBER = addUnit(Units.WEBER);
196    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
197    public static final Unit<Temperature> CELSIUS = addUnit(Units.CELSIUS);
198    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
199    public static final Unit<MagneticFluxDensity> TESLA = addUnit(Units.TESLA);
200    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
201    public static final Unit<ElectricInductance> HENRY = addUnit(Units.HENRY);
202    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
203    public static final Unit<LuminousFlux> LUMEN = addUnit(Units.LUMEN);
204    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
205    public static final Unit<Illuminance> LUX = addUnit(Units.LUX);
206    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
207    public static final Unit<Radioactivity> BECQUEREL = addUnit(Units.BECQUEREL);
208    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
209    public static final Unit<RadiationDoseAbsorbed> GRAY = addUnit(Units.GRAY);
210    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
211    public static final Unit<RadiationDoseEffective> SIEVERT = addUnit(Units.SIEVERT);
212
213    ///////////////////////////////////////////////////////////////////////
214    // OTHER UNITS FROM ISO 1000, ISO 2955, AND ANSI X3.50: UCUM 4.3 §31 //
215    ///////////////////////////////////////////////////////////////////////
216    // The order of GON and DEGREE has been inverted because GON is defined in
217    // terms of DEGREE
218    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
219    public static final Unit<Angle> DEGREE = addUnit(new ProductUnit<Angle>(PI.multiply(RADIAN.divide(180))));
220    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
221    public static final Unit<Angle> GRADE = addUnit(DEGREE.multiply(0.9));
222    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
223    public static final Unit<Angle> GON = GRADE;
224    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
225    public static final Unit<Angle> MINUTE_ANGLE = addUnit(DEGREE.divide(60));
226    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
227    public static final Unit<Angle> SECOND_ANGLE = addUnit(MINUTE_ANGLE.divide(60));
228    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
229    public static final Unit<Volume> LITER = addUnit(Units.LITRE,  "liter", "L", true);
230    /**
231     * As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. Liter has
232     * <b>two</b> definitions.
233     * 
234     * @see <a href="http://unitsofmeasure.org/ucum.html#iso1000">UCUM Table
235     *      5</a>
236     */
237    public static final Unit<Volume> LITER_DM3 = addUnit(DECI(Units.METRE).pow(3).asType(Volume.class), "liter", "l", true);
238    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
239    public static final Unit<Area> ARE = addUnit(Units.SQUARE_METRE.multiply(100));
240    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
241    public static final Unit<Time> MINUTE = addUnit(Units.MINUTE);
242    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
243    public static final Unit<Time> HOUR = addUnit(Units.HOUR);
244    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
245    public static final Unit<Time> DAY = addUnit(Units.DAY);
246    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
247    public static final Unit<Time> YEAR_TROPICAL = addUnit(Units.DAY.multiply(365.24219));
248    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
249    public static final Unit<Time> YEAR_JULIAN = addUnit(Units.DAY.multiply(365.25));
250    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
251    public static final Unit<Time> YEAR_GREGORIAN = addUnit(Units.DAY.multiply(365.2425));
252    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
253    public static final Unit<Time> YEAR = addUnit(Units.DAY.multiply(365.25));
254    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
255    public static final Unit<Time> WEEK = addUnit(Units.DAY.multiply(7));
256    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
257    public static final Unit<Time> MONTH_SYNODAL = addUnit(Units.DAY.multiply(29.53059));
258    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
259    public static final Unit<Time> MONTH_JULIAN = addUnit(YEAR_JULIAN.divide(12));
260    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
261    public static final Unit<Time> MONTH_GREGORIAN = addUnit(YEAR_GREGORIAN.divide(12));
262    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
263    public static final Unit<Time> MONTH = addUnit(YEAR_JULIAN.divide(12));
264    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
265    public static final Unit<Mass> TONNE = addUnit(Units.KILOGRAM.multiply(1000));
266    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
267    public static final Unit<Pressure> BAR = addUnit(Units.PASCAL.multiply(100000));
268    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
269    public static final Unit<Mass> ATOMIC_MASS_UNIT = addUnit(SI.UNIFIED_ATOMIC_MASS);
270    // public static final Unit<Mass> ATOMIC_MASS_UNIT = addUnit(
271    // new AlternateUnit<Mass>(Units.UNIFIED_ATOMIC_MASS,
272    // Units.UNIFIED_ATOMIC_MASS.getSymbol()), Mass.class);
273    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
274    public static final Unit<Energy> ELECTRON_VOLT = addUnit(SI.ELECTRON_VOLT);
275    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
276    public static final Unit<Length> ASTRONOMIC_UNIT = addUnit(SI.ASTRONOMICAL_UNIT);
277    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
278    public static final Unit<Length> PARSEC = addUnit(Units.METRE.multiply(3.085678E16));
279
280    /////////////////////////////////
281    // NATURAL UNITS: UCUM 4.3 §32 //
282    /////////////////////////////////
283    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
284    public static final Unit<Speed> VELOCITY_OF_LIGHT = addUnit(Units.METRE_PER_SECOND.multiply(299792458));
285    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
286    public static final Unit<Action> PLANCK = addUnit(SI.JOULE_SECOND.multiply(6.6260755E-34));
287    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
288    public static final Unit<?> BOLTZMAN = addUnit(JOULE.divide(KELVIN).multiply(1.380658E-23));
289    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
290    public static final Unit<ElectricPermittivity> PERMITTIVITY_OF_VACUUM = addUnit(
291            SI.FARAD_PER_METRE.multiply(8.854187817E-12));
292    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
293    public static final Unit<MagneticPermeability> PERMEABILITY_OF_VACUUM = addUnit(
294            new ProductUnit<MagneticPermeability>(SI.NEWTON_PER_SQUARE_AMPERE.multiply(PI.multiply(4).divide(1E7))),
295            MagneticPermeability.class);
296    // public static final Unit<MagneticPermeability> PERMEABILITY_OF_VACUUM =
297    // addUnit(
298    // new ProductUnit<MagneticPermeability>(Units.NEWTONS_PER_SQUARE_AMPERE
299    // .multiply(PI).multiply(4).divide(1E7)),
300    // MagneticPermeability.class);
301    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
302    public static final Unit<ElectricCharge> ELEMENTARY_CHARGE = addUnit(
303            Units.COULOMB.transform(((AbstractUnit<Energy>) SI.ELECTRON_VOLT).getSystemConverter()));
304    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
305    public static final Unit<Mass> ELECTRON_MASS = addUnit(GRAM.multiply(9.1093897E-28));
306    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
307    public static final Unit<Mass> PROTON_MASS = addUnit(GRAM.multiply(1.6726231E-24));
308    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
309    public static final Unit<?> NEWTON_CONSTANT_OF_GRAVITY = addUnit(
310            METER.pow(3).multiply(Units.KILOGRAM.pow(-1)).multiply(SECOND.pow(-2)).multiply(6.67259E-11));
311    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
312    public static final Unit<Acceleration> ACCELERATION_OF_FREEFALL = addUnit(
313            Units.METRE_PER_SQUARE_SECOND.multiply(9.80665));
314    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
315    public static final Unit<Pressure> ATMOSPHERE = addUnit(Units.PASCAL.multiply(101325));
316    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
317    public static final Unit<Length> LIGHT_YEAR = addUnit(
318            new ProductUnit<Length>(VELOCITY_OF_LIGHT.multiply(YEAR_JULIAN)));
319    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
320    public static final Unit<Force> GRAM_FORCE = addUnit(
321            new ProductUnit<Force>(GRAM.multiply(ACCELERATION_OF_FREEFALL)));
322    // POUND_FORCE contains a forward reference to avoirdupois pound weight, so
323    // it has been moved after section §39 below
324
325    /////////////////////////////
326    // CGS UNITS: UCUM 4.3 §33 //
327    /////////////////////////////
328    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
329    public static final Unit<WaveNumber> KAYSER = addUnit(SI.RECIPROCAL_METRE.divide(100));
330    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
331    public static final Unit<Acceleration> GAL = addUnit(
332            new ProductUnit<Acceleration>(CENTI(METER).divide(SECOND.pow(2))));
333    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
334    public static final Unit<Force> DYNE = addUnit(
335            new ProductUnit<Force>(Units.GRAM.multiply(CENTI(Units.METRE).divide(Units.SECOND.pow(2)))));
336    // public static final Unit<Force> DYNE = addUnit(new ProductUnit<Force>(
337    // Units.GRAM.multiply(new
338    // ProductUnit(CENTI(Units.METRE)).divide(Units.SECOND
339    // .pow(2)))));
340    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
341    public static final Unit<Energy> ERG = addUnit(new ProductUnit<Energy>(DYNE.multiply(CENTI(Units.METRE))));
342    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
343    public static final Unit<DynamicViscosity> POISE = addUnit(
344            new ProductUnit<DynamicViscosity>(DYNE.multiply(SECOND).divide(CENTI(Units.METRE).pow(2))));
345    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
346    public static final Unit<ElectricCurrent> BIOT = addUnit(AMPERE.multiply(10));
347    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
348    public static final Unit<KinematicViscosity> STOKES = addUnit(
349            new ProductUnit<KinematicViscosity>(CENTI(Units.METRE).pow(2).divide(Units.SECOND)));
350    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
351    public static final Unit<MagneticFlux> MAXWELL = addUnit(Units.WEBER.divide(1E8));
352    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
353    public static final Unit<MagneticFluxDensity> GAUSS = addUnit(Units.TESLA.divide(1E4));
354    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
355    public static final Unit<MagneticFieldStrength> OERSTED = addUnit(
356            new ProductUnit<MagneticFieldStrength>(SI.AMPERE_PER_METRE.multiply(250).divide(PI)));
357    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
358    public static final Unit<MagnetomotiveForce> GILBERT = addUnit(
359            new ProductUnit<MagnetomotiveForce>(OERSTED.multiply(CENTI(Units.METRE))));
360    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
361    public static final Unit<Luminance> STILB = addUnit(
362            new ProductUnit<Luminance>(CANDELA.divide(CENTI(METER).pow(2))));
363    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
364    public static final Unit<Luminance> LAMBERT = addUnit(new ProductUnit<Luminance>(STILB.divide(PI)));
365    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
366    public static final Unit<Illuminance> PHOT = addUnit(LUX.divide(1E4));
367    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
368    public static final Unit<Radioactivity> CURIE = addUnit(Units.BECQUEREL.multiply(3.7E10));
369    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
370    public static final Unit<IonizingRadiation> ROENTGEN = addUnit(SI.COULOMB_PER_KILOGRAM.multiply(2.58E-4));
371    // add later when JMQ issue fixed
372    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
373    public static final Unit<RadiationDoseAbsorbed> RAD = addUnit(
374            new ProductUnit<RadiationDoseAbsorbed>(ERG.divide(Units.GRAM.multiply(100))));
375    // public static final Unit<RadiationDoseAbsorbed> RAD = addUnit(new
376    // ProductUnit<RadiationDoseAbsorbed>(
377    // ERG.divide(Units.GRAM).multiply(100)));
378    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
379    public static final Unit<RadiationDoseEffective> REM = addUnit(
380            new ProductUnit<RadiationDoseEffective>(ERG.divide(Units.GRAM.multiply(100))));
381    // public static final Unit<RadiationDoseEffective> REM = addUnit(new
382    // AlternateUnit<RadiationDoseEffective>(
383    // RAD, RAD.getSymbol())); // TODO are symbols for RAD and REM same?
384    /////////////////////////////////////////////////
385    // INTERNATIONAL CUSTOMARY UNITS: UCUM 4.4 §34 //
386    /////////////////////////////////////////////////
387    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
388    public static final Unit<Length> INCH_INTERNATIONAL = addUnit(CENTI(METER).multiply(254).divide(100));
389    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
390    public static final Unit<Length> FOOT_INTERNATIONAL = addUnit(INCH_INTERNATIONAL.multiply(12));
391    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
392    public static final Unit<Length> YARD_INTERNATIONAL = addUnit(FOOT_INTERNATIONAL.multiply(3));
393    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
394    public static final Unit<Length> MILE_INTERNATIONAL = addUnit(FOOT_INTERNATIONAL.multiply(5280));
395    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
396    public static final Unit<Length> FATHOM_INTERNATIONAL = addUnit(FOOT_INTERNATIONAL.multiply(6));
397    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
398    public static final Unit<Length> NAUTICAL_MILE_INTERNATIONAL = addUnit(METER.multiply(1852));
399    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
400    public static final Unit<Speed> KNOT_INTERNATIONAL = addUnit(
401            new ProductUnit<Speed>(NAUTICAL_MILE_INTERNATIONAL.divide(HOUR)));
402    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
403    public static final Unit<Area> SQUARE_INCH_INTERNATIONAL = addUnit(
404            new ProductUnit<Area>(INCH_INTERNATIONAL.pow(2)));
405    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
406    public static final Unit<Area> SQUARE_FOOT_INTERNATIONAL = addUnit(
407            new ProductUnit<Area>(FOOT_INTERNATIONAL.pow(2)));
408    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
409    public static final Unit<Area> SQUARE_YARD_INTERNATIONAL = addUnit(
410            new ProductUnit<Area>(YARD_INTERNATIONAL.pow(2)));
411    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
412    public static final Unit<Volume> CUBIC_INCH_INTERNATIONAL = addUnit(
413            new ProductUnit<Volume>(INCH_INTERNATIONAL.pow(3)));
414    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
415    public static final Unit<Volume> CUBIC_FOOT_INTERNATIONAL = addUnit(
416            new ProductUnit<Volume>(FOOT_INTERNATIONAL.pow(3)));
417    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
418    public static final Unit<Volume> CUBIC_YARD_INTERNATIONAL = addUnit(
419            new ProductUnit<Volume>(YARD_INTERNATIONAL.pow(3)));
420    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
421    public static final Unit<Volume> BOARD_FOOT_INTERNATIONAL = addUnit(CUBIC_INCH_INTERNATIONAL.multiply(144));
422    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
423    public static final Unit<Volume> CORD_INTERNATIONAL = addUnit(CUBIC_FOOT_INTERNATIONAL.multiply(128));
424    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
425    public static final Unit<Length> MIL_INTERNATIONAL = addUnit(INCH_INTERNATIONAL.divide(1000));
426    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
427    public static final Unit<Area> CIRCULAR_MIL_INTERNATIONAL = addUnit(
428            new ProductUnit<Area>(MIL_INTERNATIONAL.pow(2).multiply(PI.divide(4))));
429    // public static final Unit<Area> CIRCULAR_MIL_INTERNATIONAL = addUnit(new
430    // ProductUnit<Area>(
431    // MIL_INTERNATIONAL.pow(2).multiply(PI).divide(4)));
432    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
433    public static final Unit<Length> HAND_INTERNATIONAL = addUnit(INCH_INTERNATIONAL.multiply(4));
434    //////////////////////////////////////////
435    // US SURVEY LENGTH UNITS: UCUM 4.4 §35 //
436    //////////////////////////////////////////
437    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
438    public static final Unit<Length> FOOT_US_SURVEY = addUnit(METER.multiply(1200).divide(3937));
439    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
440    public static final Unit<Length> YARD_US_SURVEY = addUnit(FOOT_US_SURVEY.multiply(3));
441    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
442    public static final Unit<Length> INCH_US_SURVEY = addUnit(FOOT_US_SURVEY.divide(12));
443    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
444    public static final Unit<Length> ROD_US_SURVEY = addUnit(FOOT_US_SURVEY.multiply(33).divide(2));
445    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
446    public static final Unit<Length> CHAIN_US_SURVEY = addUnit(ROD_US_SURVEY.multiply(4));
447    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
448    public static final Unit<Length> LINK_US_SURVEY = addUnit(CHAIN_US_SURVEY.divide(100));
449    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
450    public static final Unit<Length> RAMDEN_CHAIN_US_SURVEY = addUnit(FOOT_US_SURVEY.multiply(100));
451    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
452    public static final Unit<Length> RAMDEN_LINK_US_SURVEY = addUnit(CHAIN_US_SURVEY.divide(100));
453    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
454    public static final Unit<Length> FATHOM_US_SURVEY = addUnit(FOOT_US_SURVEY.multiply(6));
455    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
456    public static final Unit<Length> FURLONG_US_SURVEY = addUnit(ROD_US_SURVEY.multiply(40));
457    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
458    public static final Unit<Length> MILE_US_SURVEY = addUnit(FURLONG_US_SURVEY.multiply(8));
459    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
460    public static final Unit<Area> ACRE_US_SURVEY = addUnit(new ProductUnit<Area>(ROD_US_SURVEY.pow(2)).multiply(160));
461    // public static final Unit<Area> ACRE_US_SURVEY = addUnit(new
462    // ProductUnit<Area>(
463    // ROD_US_SURVEY.pow(2).multiply(160)));
464    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
465    public static final Unit<Area> SQUARE_ROD_US_SURVEY = addUnit(new ProductUnit<Area>(ROD_US_SURVEY.pow(2)));
466    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
467    public static final Unit<Area> SQUARE_MILE_US_SURVEY = addUnit(new ProductUnit<Area>(MILE_US_SURVEY.pow(2)));
468    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
469    public static final Unit<Area> SECTION_US_SURVEY = addUnit(new ProductUnit<Area>(MILE_US_SURVEY.pow(2)));
470    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
471    public static final Unit<Area> TOWNSHP_US_SURVEY = addUnit(SECTION_US_SURVEY.multiply(36));
472    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
473    public static final Unit<Length> MIL_US_SURVEY = addUnit(INCH_US_SURVEY.divide(1000));
474    /////////////////////////////////////////////////
475    // BRITISH IMPERIAL LENGTH UNITS: UCUM 4.4 §36 //
476    /////////////////////////////////////////////////
477    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
478    public static final Unit<Length> INCH_BRITISH = addUnit(CENTI(METER).multiply(2539998).divide(1000000));
479    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
480    public static final Unit<Length> FOOT_BRITISH = addUnit(INCH_BRITISH.multiply(12));
481    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
482    public static final Unit<Length> ROD_BRITISH = addUnit(FOOT_BRITISH.multiply(33).divide(2));
483    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
484    public static final Unit<Length> CHAIN_BRITISH = addUnit(ROD_BRITISH.multiply(4));
485    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
486    public static final Unit<Length> LINK_BRITISH = addUnit(CHAIN_BRITISH.divide(100));
487    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
488    public static final Unit<Length> FATHOM_BRITISH = addUnit(FOOT_BRITISH.multiply(6));
489    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
490    public static final Unit<Length> PACE_BRITISH = addUnit(FOOT_BRITISH.multiply(5).divide(2));
491    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
492    public static final Unit<Length> YARD_BRITISH = addUnit(FOOT_BRITISH.multiply(3));
493    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
494    public static final Unit<Length> MILE_BRITISH = addUnit(FOOT_BRITISH.multiply(5280));
495    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
496    public static final Unit<Length> NAUTICAL_MILE_BRITISH = addUnit(FOOT_BRITISH.multiply(6080));
497    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
498    public static final Unit<Speed> KNOT_BRITISH = addUnit(new ProductUnit<Speed>(NAUTICAL_MILE_BRITISH.divide(HOUR)));
499    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
500    public static final Unit<Area> ACRE_BRITISH = addUnit(new ProductUnit<Area>(YARD_BRITISH.pow(2)).multiply(4840));
501    // public static final Unit<Area> ACRE_BRITISH = addUnit(new
502    // ProductUnit<Area>(
503    // YARD_BRITISH.pow(2).multiply(4840)));
504    ///////////////////////////////////
505    // US VOLUME UNITS: UCUM 4.4 §37 //
506    ///////////////////////////////////
507    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
508    public static final Unit<Volume> GALLON_US = addUnit(CUBIC_INCH_INTERNATIONAL.multiply(231), "Queen Anne's wine gallon", "gal_us");
509    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
510    public static final Unit<Volume> BARREL_US = addUnit(GALLON_US.multiply(42), "barrel", "bbl_us");
511    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
512    public static final Unit<Volume> QUART_US = addUnit(GALLON_US.divide(4));
513    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
514    public static final Unit<Volume> PINT_US = addUnit(QUART_US.divide(2));
515    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
516    public static final Unit<Volume> GILL_US = addUnit(PINT_US.divide(4));
517    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
518    public static final Unit<Volume> FLUID_OUNCE_US = addUnit(GILL_US.divide(4));
519    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
520    public static final Unit<Volume> FLUID_DRAM_US = addUnit(FLUID_OUNCE_US.divide(8));
521    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
522    public static final Unit<Volume> MINIM_US = addUnit(FLUID_DRAM_US.divide(60));
523    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
524    public static final Unit<Volume> CORD_US = addUnit(CUBIC_FOOT_INTERNATIONAL.multiply(128));
525    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
526    public static final Unit<Volume> BUSHEL_US = addUnit(CUBIC_INCH_INTERNATIONAL.multiply(215042).divide(100));
527    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
528    public static final Unit<Volume> GALLON_WINCHESTER = addUnit(BUSHEL_US.divide(8));
529    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
530    public static final Unit<Volume> PECK_US = addUnit(BUSHEL_US.divide(4));
531    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
532    public static final Unit<Volume> DRY_QUART_US = addUnit(PECK_US.divide(8));
533    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
534    public static final Unit<Volume> DRY_PINT_US = addUnit(DRY_QUART_US.divide(2));
535    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
536    public static final Unit<Volume> TABLESPOON_US = addUnit(FLUID_OUNCE_US.divide(2));
537    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
538    public static final Unit<Volume> TEASPOON_US = addUnit(TABLESPOON_US.divide(3));
539    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
540    public static final Unit<Volume> CUP_US = addUnit(TABLESPOON_US.multiply(16));
541    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
542    public static final Unit<Volume> METRIC_FLUID_OUNCE_US = addUnit(MILLI(LITER).multiply(30));
543    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
544    public static final Unit<Volume> METRIC_CUP_US = addUnit(MILLI(LITER).multiply(240));
545    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
546    public static final Unit<Volume> METRIC_TEASPOON_CUP_US = addUnit(MILLI(LITER).multiply(5));
547    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
548    public static final Unit<Volume> METRIC_TABLESPOON_CUP_US = addUnit(MILLI(LITER).multiply(15));
549    /////////////////////////////////////////////////
550    // BRITISH IMPERIAL VOLUME UNITS: UCUM 4.4 §38 //
551    /////////////////////////////////////////////////
552    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
553    public static final Unit<Volume> GALLON_BRITISH = addUnit(LITER.multiply(454609).divide(100000));
554    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
555    public static final Unit<Volume> PECK_BRITISH = addUnit(GALLON_BRITISH.multiply(2));
556    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
557    public static final Unit<Volume> BUSHEL_BRITISH = addUnit(PECK_BRITISH.multiply(4));
558    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
559    public static final Unit<Volume> QUART_BRITISH = addUnit(GALLON_BRITISH.divide(4));
560    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
561    public static final Unit<Volume> PINT_BRITISH = addUnit(QUART_BRITISH.divide(2));
562    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
563    public static final Unit<Volume> GILL_BRITISH = addUnit(PINT_BRITISH.divide(4));
564    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
565    public static final Unit<Volume> FLUID_OUNCE_BRITISH = addUnit(GILL_BRITISH.divide(5));
566    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
567    public static final Unit<Volume> FLUID_DRAM_BRITISH = addUnit(FLUID_OUNCE_BRITISH.divide(8));
568    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
569    public static final Unit<Volume> MINIM_BRITISH = addUnit(FLUID_DRAM_BRITISH.divide(60));
570    ////////////////////////////////////////////
571    // AVOIRDUPOIS WIEGHT UNITS: UCUM 4.4 §39 //
572    ////////////////////////////////////////////
573    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
574    public static final Unit<Mass> GRAIN = addUnit(MILLI(GRAM).multiply(6479891).divide(100000));
575    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
576    public static final Unit<Mass> POUND = addUnit(GRAIN.multiply(7000));
577    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
578    public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16));
579    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
580    public static final Unit<Mass> DRAM = addUnit(OUNCE.divide(16));
581    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
582    public static final Unit<Mass> SHORT_HUNDREDWEIGHT = addUnit(POUND.multiply(100));
583    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
584    public static final Unit<Mass> LONG_HUNDREDWEIGHT = addUnit(POUND.multiply(112));
585    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
586    public static final Unit<Mass> SHORT_TON = addUnit(SHORT_HUNDREDWEIGHT.multiply(20));
587    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
588    public static final Unit<Mass> LONG_TON = addUnit(LONG_HUNDREDWEIGHT.multiply(20));
589    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
590    public static final Unit<Mass> STONE = addUnit(POUND.multiply(14));
591    // CONTINUED FROM SECTION §32
592    // contains a forward reference to POUND, so we had to move it here, below
593    // section §39
594    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
595    // public static final Unit<Force> POUND_FORCE = addUnit(new
596    // ProductUnit<Force>(
597    // POUND.multiply(ACCELERATION_OF_FREEFALL)));
598    public static final Unit<Force> POUND_FORCE = addUnit(
599            POUND.multiply(ACCELERATION_OF_FREEFALL).asType(Force.class));
600
601    // public static final Unit<InformationRate> POUND_FORCE2 =
602    // addUnit(POUND.multiply(ACCELERATION_OF_FREEFALL).asType(InformationRate.class));
603
604    /////////////////////////////////////
605    // TROY WEIGHT UNITS: UCUM 4.4 §40 //
606    /////////////////////////////////////
607    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
608    public static final Unit<Mass> PENNYWEIGHT_TROY = addUnit(GRAIN.multiply(24));
609    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
610    public static final Unit<Mass> OUNCE_TROY = addUnit(PENNYWEIGHT_TROY.multiply(20));
611    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
612    public static final Unit<Mass> POUND_TROY = addUnit(OUNCE_TROY.multiply(12));
613    /////////////////////////////////////////////
614    // APOTECARIES' WEIGHT UNITS: UCUM 4.4 §41 //
615    /////////////////////////////////////////////
616    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
617    public static final Unit<Mass> SCRUPLE_APOTHECARY = addUnit(GRAIN.multiply(20));
618    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
619    public static final Unit<Mass> DRAM_APOTHECARY = addUnit(SCRUPLE_APOTHECARY.multiply(3));
620    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
621    public static final Unit<Mass> OUNCE_APOTHECARY = addUnit(DRAM_APOTHECARY.multiply(8));
622    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
623    public static final Unit<Mass> POUND_APOTHECARY = addUnit(OUNCE_APOTHECARY.multiply(12));
624    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
625    public static final Unit<Mass> METRIC_OUNCE = addUnit(GRAM.multiply(28));
626
627    /////////////////////////////////////////////
628    // TYPESETTER'S LENGTH UNITS: UCUM 4.4 §42 //
629    /////////////////////////////////////////////
630    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
631    public static final Unit<Length> LINE = addUnit(INCH_INTERNATIONAL.divide(12));
632    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
633    public static final Unit<Length> POINT = addUnit(LINE.divide(6));
634    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
635    public static final Unit<Length> PICA = addUnit(POINT.multiply(12));
636    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
637    public static final Unit<Length> POINT_PRINTER = addUnit(INCH_INTERNATIONAL.multiply(13837).divide(1000000));
638    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
639    public static final Unit<Length> PICA_PRINTER = addUnit(POINT_PRINTER.multiply(12));
640    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
641    public static final Unit<Length> PIED = addUnit(CENTI(METER).multiply(3248).divide(100));
642    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
643    public static final Unit<Length> POUCE = addUnit(PIED.divide(12));
644    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
645    public static final Unit<Length> LIGNE = addUnit(POUCE.divide(12));
646    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
647    public static final Unit<Length> DIDOT = addUnit(LIGNE.divide(6));
648    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
649    public static final Unit<Length> CICERO = addUnit(DIDOT.multiply(12));
650    //////////////////////////////////////
651    // OTHER LEGACY UNITS: UCUM 4.5 §43 //
652    //////////////////////////////////////
653    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
654    public static final Unit<Temperature> RANKINE = addUnit(KELVIN.divide(9).multiply(5));
655    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
656    public static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE.shift(459.67));
657    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
658    public static final Unit<Temperature> REAUMUR = addUnit((KELVIN.multiply(4).divide(5)).shift(218.52));
659    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
660    public static final Unit<Energy> CALORIE_AT_15C = addUnit(JOULE.multiply(41858).divide(10000));
661    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
662    public static final Unit<Energy> CALORIE_AT_20C = addUnit(JOULE.multiply(41819).divide(10000));
663    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
664    public static final Unit<Energy> CALORIE_MEAN = addUnit(JOULE.multiply(419002).divide(100000));
665    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
666    public static final Unit<Energy> CALORIE_INTERNATIONAL_TABLE = addUnit(JOULE.multiply(41868).divide(10000));
667    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
668    public static final Unit<Energy> CALORIE_THERMOCHEMICAL = addUnit(JOULE.multiply(4184).divide(1000));
669    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
670    public static final Unit<Energy> CALORIE = addUnit(CALORIE_THERMOCHEMICAL);
671    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
672    public static final Unit<Energy> CALORIE_FOOD = addUnit(KILO(CALORIE_THERMOCHEMICAL));
673
674    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
675    public static final Unit<Energy> BTU_AT_39F = addUnit(KILO(JOULE).multiply(105967).divide(100000));
676    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
677    public static final Unit<Energy> BTU_AT_59F = addUnit(KILO(JOULE).multiply(105480).divide(100000));
678    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
679    public static final Unit<Energy> BTU_AT_60F = addUnit(KILO(JOULE).multiply(105468).divide(100000));
680    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
681    public static final Unit<Energy> BTU_MEAN = addUnit(KILO(JOULE).multiply(105587).divide(100000));
682    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
683    public static final Unit<Energy> BTU_INTERNATIONAL_TABLE = addUnit(
684            KILO(JOULE).multiply(105505585262L).divide(100000000000L));
685    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
686    public static final Unit<Energy> BTU_THERMOCHEMICAL = addUnit(KILO(JOULE).multiply(105435).divide(100000));
687    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
688    public static final Unit<Energy> BTU = addUnit(BTU_THERMOCHEMICAL);
689    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
690    public static final Unit<Power> HORSEPOWER = addUnit(
691            new ProductUnit<Power>(FOOT_INTERNATIONAL.multiply(POUND_FORCE).divide(SECOND)));
692
693    ////////////////////////////////////////////
694    // CLINICAL MEDICINE UNITS: UCUM 4.5 §44 //
695    ///////////////////////////////////////////
696    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
697    public static final Unit<Pressure> METER_OF_WATER_COLUMN = addUnit(KILO(PASCAL).multiply(980665).divide(100000));
698    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
699    public static final Unit<Pressure> METER_OF_MERCURY_COLUMN = addUnit(KILO(PASCAL).multiply(1333220).divide(10000));
700    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
701    public static final Unit<Pressure> INCH_OF_WATER_COLUMN = addUnit(
702            new ProductUnit<Pressure>(METER_OF_WATER_COLUMN.multiply(INCH_INTERNATIONAL).divide(METER)));
703    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
704    public static final Unit<Pressure> INCH_OF_MERCURY_COLUMN = addUnit(
705            new ProductUnit<Pressure>(METER_OF_MERCURY_COLUMN.multiply(INCH_INTERNATIONAL).divide(METER)));
706
707    public static final Unit<Drag> PERIPHERAL_VASCULAR_RESISTANCE = addUnit(
708            MILLI(METER_OF_MERCURY_COLUMN).multiply(SECOND).divide(MILLI(LITER)).asType(Drag.class));
709    public static final Unit<Drag> WOOD = addUnit(MILLI(METER_OF_MERCURY_COLUMN).multiply(MINUTE).divide(LITER).asType(Drag.class));
710    // public static final Unit DIOPTER = addUnit(ONE.divide(METER));
711    // public static final Unit PRISM_DIOPTER =
712    // addUnit(ONE.multiply(100).multiply(Math.tan(1)));
713    // public static final Unit PERCENT_OF_SLOPE =
714    // addUnit(ONE.multiply(100).multiply(Math.tan(1)));
715    // public static final Unit MESH = addUnit(ONE.divide(INCH_INTERNATIONAL));
716    // public static final Unit CHARRIERE = addUnit(MILLI(METER).divide(3));
717
718    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
719    public static final Unit<Volume> DROP = addUnit(MILLI(LITER).divide(20));
720
721    // public static final Unit HOUNSFIELD = addUnit(ONE);
722    // public static final Unit METABOLIC_EQUIVALENT =
723    // addUnit(MILLI(LITER).divide(MINUTE).divide(KILO(GRAM)));
724
725    // public static final Unit HOMEOPATHIC_POTENCY_OF_DECIMAL =
726    // addUnit(ONE.multiply(-1).multiply(Math.log10(1)));
727    // public static final Unit HOMEOPATHIC_POTENCY_OF_CENTESIMAL =
728    // addUnit(ONE.multiply(-1).multiply(Math.log(1)).divide(Math.log(100)));
729    // public static final Unit HOMEOPATHIC_POTENCY_OF_MILLESIMAL =
730    // addUnit(ONE.multiply(-1).multiply(Math.log(1)).divide(Math.log(1000)));
731    // public static final Unit HOMEOPATHIC_POTENCY_OF_QUINTALLESIMAL =
732    // addUnit(ONE.multiply(-1).multiply(Math.log(1)).divide(Math.log(50000)));
733
734    // public static final Unit HOMEOPATHIC_POTENCY_OF_DECIMAL_HAHNEMANNIAN =
735    // UNDEFINED;
736    // public static final Unit HOMEOPATHIC_POTENCY_OF_CENTESIMAL_HAHNEMANNIAN =
737    // UNDEFINED;
738    // public static final Unit HOMEOPATHIC_POTENCY_OF_MILLESIMAL_HAHNEMANNIAN =
739    // UNDEFINED;
740    // public static final Unit
741    // HOMEOPATHIC_POTENCY_OF_QUINTAMILLESIMAL_HAHNEMANNIAN = UNDEFINED;
742    // public static final Unit HOMEOPATHIC_POTENCY_OF_DECIMAL_KORSAKOVIAN =
743    // UNDEFINED;
744    // public static final Unit HOMEOPATHIC_POTENCY_OF_CENTESIMAL_KORSAKOVIAN =
745    // UNDEFINED;
746    // public static final Unit HOMEOPATHIC_POTENCY_OF_MILLESIMAL_KORSAKOVIAN =
747    // UNDEFINED;
748    // public static final Unit
749    // HOMEOPATHIC_POTENCY_OF_QUINTAMILLESIMAL_KORSAKOVIAN = UNDEFINED;
750
751    //////////////////////////////////////////////////
752    // CHEMICAL AND BIOCHEMICAL UNITS: UCUM 4.5 §45 //
753    //////////////////////////////////////////////////
754    // public static final Unit EQUIVALENTS = addUnit(MOLE);
755    // public static final Unit OSMOLE = addUnit(MOLE);
756
757    public static final Unit<Acidity> PH = addUnit(
758            MOLE.divide(LITER).transform(new LogConverter(10)).multiply(-1).asType(Acidity.class));
759
760    // @SuppressWarnings("unchecked")
761    @SuppressWarnings("unchecked")
762    public static final Unit<Concentration<Mass>> GRAM_PERCENT = addUnit(
763            GRAM.divide(DECI(LITER)).asType(Concentration.class));
764
765    // public static final Unit SVEDBERG = addUnit(SECOND.multiply(1E-13));
766
767    public static final Unit<Dimensionless> HIGH_POWER_FIELD = addUnit(ONE);
768    public static final Unit<Dimensionless> LOW_POWER_FIELD = addUnit(ONE.multiply(100));
769
770    // public static final Unit KATAL = addUnit(MOLE.divide(SECOND));
771    // public static final Unit UNIT = addUnit(MICRO(MOLE).divide(MINUTE));
772
773    // public static final Unit INTERNATIONAL_UNIT = UNDEFINED;
774    // public static final Unit ARBITRARY_UNIT = UNDEFINED;
775    // public static final Unit US_PHARMACOPEIA = UNDEFINED;
776    // public static final Unit GPL = UNDEFINED;
777    // public static final Unit MPL = UNDEFINED;
778    // public static final Unit APL = UNDEFINED;
779    // public static final Unit BETHESDA = UNDEFINED;
780    // public static final Unit ANTI_FACTOR_XA = UNDEFINED;
781    // public static final Unit TODD = UNDEFINED;
782    // public static final Unit DYE = UNDEFINED;
783    // public static final Unit SOMOGYI = UNDEFINED;
784    // public static final Unit BODANSKY = UNDEFINED;
785    // public static final Unit KING_ARMSTRONG = UNDEFINED;
786    // public static final Unit KUNKEL = UNDEFINED;
787    // public static final Unit MAC_LAGAN = UNDEFINED;
788    // public static final Unit TUBERCULIN = UNDEFINED;
789    // public static final Unit CELL_CULTURE_INFECTIOUS_50_PERCENT_DOSE =
790    // UNDEFINED;
791    // public static final Unit TISSUE_CULTURE_INFECTIOUS_50_PERCENT_DOSE =
792    // UNDEFINED;
793    // public static final Unit EMBRYO_CULTURE_INFECTIOUS_50_PERCENT_DOSE =
794    // UNDEFINED;
795    // public static final Unit PLAQUE_FORMING = UNDEFINED;
796    // public static final Unit FOCUS_FORMING = UNDEFINED;
797    // public static final Unit COLONY_FORMING = UNDEFINED;
798    // public static final Unit INDEX_OF_REACTIVITY = UNDEFINED;
799    // public static final Unit BIOEQUIVALENT_ALLERGEN = UNDEFINED;
800    // public static final Unit ALLERGEN = UNDEFINED;
801    // public static final Unit ALLERGEN_FOR_AMBROSIA_ARTEMISIIFOLIA =
802    // UNDEFINED;
803    // public static final Unit PROTEIN_NITROGEN = UNDEFINED;
804    // public static final Unit LIMIT_OF_FLOCCULATION = UNDEFINED;
805    // public static final Unit D_ANTIGEN = UNDEFINED;
806    // public static final Unit FIBRINOGEN_EQUIVALENT = UNDEFINED;
807    // public static final Unit ELISA = UNDEFINED;
808    // public static final Unit EHRLICH = UNDEFINED;
809    // public static final Unit CHEMICAL = UNDEFINED;
810
811    /////////////////////////////////
812    // LEVELS UNITS: UCUM 4.5 §46 //
813    ////////////////////////////////
814    @SuppressWarnings({ "unchecked", "rawtypes" })
815    public static final Unit<Level<Dimensionless>> NEPER = (Unit) addUnit(
816            ONE.transform(new LogConverter(Math.E)));
817    /**
818     * A logarithmic unit used to describe a power {@link Level} ratio (standard
819     * name <code>dB</code>).
820     */
821    // public static final Unit<Level<Power>> DECIBEL = addUnit(NEPER
822    // .transform(new LogConverter(10).inverse().concatenate(
823    // RationalConverter.of(1d, 10d))));
824
825    @SuppressWarnings({ "unchecked", "rawtypes" })
826    public static final Unit<Level<Dimensionless>> BEL = (Unit) addUnit(
827            ONE.transform(new LogConverter(10)));
828
829    @SuppressWarnings("unchecked")
830    public static final Unit<Level<Pressure>> BEL_SOUND = addUnit(
831            PASCAL.divide(1E5).multiply(2).transform(new LogConverter(10)).multiply(2).asType(Level.class));
832
833    @SuppressWarnings("unchecked")
834    public static final Unit<Level<ElectricPotential>> BEL_VOLT = addUnit(
835            VOLT.transform(new LogConverter(10)).multiply(2).asType(Level.class));
836
837    @SuppressWarnings("unchecked")
838    public static final Unit<Level<ElectricPotential>> BEL_MILLIVOLT = addUnit(
839            MILLI(VOLT).transform(new LogConverter(10)).multiply(2).asType(Level.class));
840
841    @SuppressWarnings("unchecked")
842    public static final Unit<Level<ElectricPotential>> BEL_MICROVOLT = addUnit(
843            MICRO(VOLT).transform(new LogConverter(10)).multiply(2).asType(Level.class));
844
845    @SuppressWarnings("unchecked")
846    public static final Unit<Level<ElectricPotential>> BEL_10_NANOVOLT = addUnit(
847            NANO(VOLT).multiply(10).transform(new LogConverter(10)).multiply(2).asType(Level.class));
848
849    @SuppressWarnings("unchecked")
850    public static final Unit<Level<ElectricPotential>> BEL_WATT = addUnit(
851            WATT.transform(new LogConverter(10)).asType(Level.class));
852
853    @SuppressWarnings("unchecked")
854    public static final Unit<Level<ElectricPotential>> BEL_KILOWATT = addUnit(
855            KILO(WATT).transform(new LogConverter(10)).asType(Level.class));
856
857    ///////////////////////////////////////
858    // MISCELLANEOUS UNITS: UCUM 4.5 §47 //
859    ///////////////////////////////////////
860    /** temporary helper for MHO */
861    private static final Unit<? extends Quantity<?>> TMP_MHO = SIEMENS.alternate("mho");
862
863    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
864    //public static final Unit<Volume> STERE = addUnit(new ProductUnit<Volume>(METER.pow(3)));
865    public static final Unit<Volume> STERE = addUnit(new TransformedUnit<Volume>("st", Units.CUBIC_METRE, Units.CUBIC_METRE, MultiplyConverter.IDENTITY));
866    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
867    public static final Unit<Length> ANGSTROM = addUnit(NANO(METER).divide(10));
868    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
869    public static final Unit<Area> BARN = addUnit(new ProductUnit<Area>(FEMTO(METER).pow(2)).multiply(100));
870    // public static final Unit<Area> BARN = addUnit(new
871    // ProductUnit<Area>(FEMTO(
872    // METER).pow(2).multiply(100)));
873    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
874    public static final Unit<Pressure> ATMOSPHERE_TECHNICAL = addUnit(
875            new ProductUnit<Pressure>(KILO(GRAM_FORCE).divide(CENTI(METER).pow(2))));
876    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
877    public static final Unit<ElectricConductance> MHO = addUnit(
878            new AlternateUnit<ElectricConductance>(TMP_MHO, TMP_MHO.getSymbol()));
879    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
880    public static final Unit<Pressure> POUND_PER_SQUARE_INCH = addUnit(
881            new ProductUnit<Pressure>(POUND_FORCE.divide(INCH_INTERNATIONAL.pow(2))));
882    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
883    public static final Unit<Angle> CIRCLE = addUnit(new ProductUnit<Angle>(PI.multiply(RADIAN.multiply(2))));
884    // public static final Unit<Angle> CIRCLE = addUnit(new
885    // ProductUnit<Angle>(PI
886    // .multiply(RADIAN).multiply(2)));
887    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
888    public static final Unit<SolidAngle> SPHERE = addUnit(
889            new ProductUnit<SolidAngle>(PI.multiply(STERADIAN.multiply(4))));
890    // public static final Unit<SolidAngle> SPHERE = addUnit(new
891    // ProductUnit<SolidAngle>(
892    // PI.multiply(STERADIAN).multiply(4)));
893    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
894    public static final Unit<Mass> CARAT_METRIC = addUnit(GRAM.divide(5));
895    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
896    public static final Unit<Dimensionless> CARAT_GOLD = addUnit(ONE.divide(24));
897    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
898    public static final Unit<Length> SMOOT = addUnit(INCH_INTERNATIONAL.multiply(67));
899
900    ////////////////////////////////////////////////
901    // INFORMATION TECHNOLOGY UNITS: UCUM 4.6 §48 //
902    ////////////////////////////////////////////////
903    /**
904     * The unit for binary information (standard name <code>bit</code>).
905     * As per <a href="http://unitsofmeasure.org/">UCUM</a> standard.
906     */
907    public static final Unit<Information> BIT = addUnit(new AlternateUnit<Information>(ONE, "bit"), Information.class);
908    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
909    public static final Unit<Information> BYTE = addUnit(BIT.multiply(8));
910    /**
911     * The SI unit for binary information rate (standard name
912     * <code>bit/s</code>).
913     */
914    protected static final ProductUnit<InformationRate> BITS_PER_SECOND = addUnit(
915            new ProductUnit<InformationRate>(BIT.divide(SECOND)), InformationRate.class);
916    /** As per <a href="http://unitsofmeasure.org/">UCUM</a> standard. */
917    public static final Unit<InformationRate> BAUD = addUnit(BITS_PER_SECOND);
918
919    /////////////////////
920    // Collection View //
921    /////////////////////
922
923    @Override
924    public String getName() {
925        return "Unified Code for Units of Measure";
926    }
927
928    private static <U extends Unit<Q>, Q extends Quantity<Q>> U addUnit(U unit) {
929        INSTANCE.units.add(unit);
930        return unit;
931    }
932
933    /**
934     * Adds a new unit and maps it to the specified quantity type.
935     *
936     * @param unit
937     *            the unit being added.
938     * @param type
939     *            the quantity type.
940     * @return <code>unit</code>.
941     */
942    private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) {
943        INSTANCE.units.add(unit);
944        INSTANCE.quantityToUnit.put(type, unit);
945        return unit;
946    }
947    
948    /**
949     * Adds a new unit not mapped to any specified quantity type and puts a text
950     * as symbol or label.
951     *
952     * @param unit
953     *            the unit being added.
954     * @param name
955     *            the string to use as name
956     * @param text
957     *            the string to use as label or symbol
958     * @param isLabel
959     *            if the string should be used as a label or not
960     * @return <code>unit</code>.
961     */
962    private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) {
963        if (isLabel) {
964            SimpleUnitFormat.getInstance().label(unit, text);
965        }
966        if (name != null && unit instanceof AbstractUnit) {
967            return Helper.addUnit(INSTANCE.units, unit, name);
968        } else {
969            INSTANCE.units.add(unit);
970        }
971        return unit;
972    }
973
974    /**
975     * Adds a new unit not mapped to any specified quantity type and puts a text
976     * as label.
977     *
978     * @param unit
979     *            the unit being added.
980     * @param name
981     *            the string to use as name
982     * @param text
983     *            the string to use as label
984     * @return <code>unit</code>.
985     */
986    private static <U extends Unit<?>> U addUnit(U unit, String name, String text) {
987        return addUnit(unit, name, text, true);
988    }
989    
990    ////////////////////////////////////////////////////////////////////////////
991    // Label adjustments for UCUM system
992    static {
993        SimpleUnitFormat.getInstance().label(ATOMIC_MASS_UNIT, "AMU");
994        //SimpleUnitFormat.getInstance().label(LITER, "L");
995        //SimpleUnitFormat.getInstance().label(LITER_DM3, "l");
996        SimpleUnitFormat.getInstance().label(OUNCE, "oz");
997        SimpleUnitFormat.getInstance().label(POUND, "lb");
998        SimpleUnitFormat.getInstance().label(PLANCK, "h");
999        // TODO maybe we can find a better solution, but it would require to
1000        // "harvest" the entire UCUMFormat ResourceBundle and label every
1001        // matching UCUM unit in a loop.
1002    }
1003}