001/*
002 *  Unit-API - Units of Measurement API for Java
003 *  Copyright (c) 2005-2015, Jean-Marie Dautelle, Werner Keil, V2COM.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
008 *
009 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
010 *
011 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
012 *
013 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
014 *
015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
017 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
022 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
024 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
025 */
026package systems.uom.common;
027
028import static tec.uom.se.unit.MetricPrefix.CENTI;
029import static tec.uom.se.unit.Units.AMPERE;
030import static tec.uom.se.unit.Units.BECQUEREL;
031import static tec.uom.se.unit.Units.COULOMB;
032import static tec.uom.se.unit.Units.GRAM;
033import static tec.uom.se.unit.Units.GRAY;
034import static tec.uom.se.unit.Units.JOULE;
035import static tec.uom.se.unit.Units.KELVIN;
036import static tec.uom.se.unit.Units.KILOGRAM;
037import static tec.uom.se.unit.Units.LUX;
038import static tec.uom.se.unit.Units.METRE;
039import static tec.uom.se.unit.Units.METRES_PER_SECOND;
040import static tec.uom.se.unit.Units.METRES_PER_SQUARE_SECOND;
041import static tec.uom.se.unit.Units.MOLE;
042import static tec.uom.se.unit.Units.NEWTON;
043import static tec.uom.se.unit.Units.ONE;
044import static tec.uom.se.unit.Units.PASCAL;
045import static tec.uom.se.unit.Units.RADIAN;
046import static tec.uom.se.unit.Units.SECOND;
047import static tec.uom.se.unit.Units.SIEVERT;
048import static tec.uom.se.unit.Units.SQUARE_METRE;
049import static tec.uom.se.unit.Units.STERADIAN;
050import static tec.uom.se.unit.Units.TESLA;
051import static tec.uom.se.unit.Units.WATT;
052import static tec.uom.se.unit.Units.WEBER;
053
054import javax.measure.Quantity;
055import javax.measure.Unit;
056import javax.measure.quantity.Acceleration;
057import javax.measure.quantity.AmountOfSubstance;
058import javax.measure.quantity.Angle;
059import javax.measure.quantity.Area;
060import javax.measure.quantity.Dimensionless;
061import javax.measure.quantity.ElectricCharge;
062import javax.measure.quantity.ElectricCurrent;
063import javax.measure.quantity.Energy;
064import javax.measure.quantity.Force;
065import javax.measure.quantity.Frequency;
066import javax.measure.quantity.Illuminance;
067import javax.measure.quantity.Length;
068import javax.measure.quantity.MagneticFlux;
069import javax.measure.quantity.MagneticFluxDensity;
070import javax.measure.quantity.Mass;
071import javax.measure.quantity.Power;
072import javax.measure.quantity.Pressure;
073import javax.measure.quantity.RadiationDoseAbsorbed;
074import javax.measure.quantity.RadiationDoseEffective;
075import javax.measure.quantity.Radioactivity;
076import javax.measure.quantity.SolidAngle;
077import javax.measure.quantity.Speed;
078import javax.measure.quantity.Temperature;
079import javax.measure.quantity.Time;
080
081import si.uom.quantity.DynamicViscosity;
082import si.uom.quantity.IonizingRadiation;
083import si.uom.quantity.KinematicViscosity;
084import systems.uom.quantity.Information;
085import systems.uom.quantity.InformationRate;
086import systems.uom.quantity.Resolution;
087import tec.uom.se.AbstractSystemOfUnits;
088import tec.uom.se.AbstractUnit;
089import tec.uom.se.function.LogConverter;
090import tec.uom.se.function.RationalConverter;
091import tec.uom.se.unit.AlternateUnit;
092import tec.uom.se.unit.ProductUnit;
093
094/**
095 * <p>
096 * This class contains units that are not part of the International System of
097 * Units, that is, they are outside the SI, but are important and widely used.
098 * </p>
099 * 
100 * <p>
101 * This is an internal collection of otherwise unassigned units used by
102 * <b>UCUM</b> or similar systems.
103 * </p>
104 * <p>
105 * This class is not intended to be implemented by clients.
106 * </p>
107 * 
108 * @noimplement This class is not intended to be implemented by clients.
109 * @noextend This class is not intended to be extended by clients.
110 * 
111 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
112 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
113 * @version 1.22, $Date: 2016-06-21$
114 */
115public class NonSI extends AbstractSystemOfUnits {
116    private static final String SYSTEM_NAME = "Non-SI Units";
117
118    /**
119     * Holds the standard gravity constant: 9.80665 m/s² exact.
120     */
121    private static final int STANDARD_GRAVITY_DIVIDEND = 980665;
122
123    private static final int STANDARD_GRAVITY_DIVISOR = 100000;
124
125    /**
126     * Holds the avoirdupois pound: 0.45359237 kg exact
127     */
128    static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
129
130    static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
131
132    /**
133     * Holds the Avogadro constant.
134     */
135    private static final double AVOGADRO_CONSTANT = 6.02214199e23; // (1/mol).
136
137    /**
138     * Holds the electric charge of one electron.
139     */
140    private static final double ELEMENTARY_CHARGE = 1.602176462e-19; // (C).
141
142    /**
143     * Default constructor (prevents this class from being instantiated).
144     */
145    private NonSI() {
146    }
147
148    /**
149     * Returns the unique instance of this class.
150     * 
151     * @return the NonSI instance.
152     */
153    public static NonSI getInstance() {
154        return INSTANCE;
155    }
156
157    private static final NonSI INSTANCE = new NonSI();
158
159    // /////////////////
160    // Dimensionless //
161    // /////////////////
162    /**
163     * A dimensionless unit equals to <code>pi</code> (standard name
164     * <code>Ï€</code>).
165     */
166    static final Unit<Dimensionless> PI = addUnit(ONE.multiply(StrictMath.PI));
167
168    /**
169     * A dimensionless unit equals to <code>0.01</code> (standard name
170     * <code>%</code>).
171     */
172    // static final Unit<Dimensionless> PERCENT = addUnit(ONE
173    // .divide(100));
174
175    /**
176     * A logarithmic unit used to describe a ratio (standard name
177     * <code>dB</code>).
178     */
179    static final Unit<Dimensionless> DECIBEL = addUnit(ONE
180            .transform(new LogConverter(10).inverse().concatenate(
181                    RationalConverter.of(1d, 10d))));
182
183    // ///////////////////////
184    // Amount of substance //
185    // ///////////////////////
186    /**
187     * A unit of amount of substance equals to one atom (standard name
188     * <code>atom</code>).
189     */
190    static final Unit<AmountOfSubstance> ATOM = addUnit(MOLE
191            .divide(AVOGADRO_CONSTANT));
192
193    // //////////
194    // Length //
195    // //////////
196
197    /**
198     * A unit of length equal to <code>0.3048 m</code> (standard name
199     * <code>ft</code>).
200     */
201    static final Unit<Length> FOOT = addUnit(METRE.multiply(3048).divide(10000));
202
203    /**
204     * A unit of length equal to <code>0.0254 m</code> (standard name
205     * <code>in</code>).
206     */
207    static final Unit<Length> INCH = addUnit(FOOT.divide(12));
208
209    /**
210     * A unit of length equal to <code>1E-10 m</code> (standard name
211     * <code>\u00C5ngstr\u00F6m</code>).
212     */
213    public static final Unit<Length> ANGSTROM = addUnit(METRE.divide(10000000000L));
214
215    /**
216     * A unit of length equal to the average distance from the center of the
217     * Earth to the center of the Sun (standard name <code>ua</code>).
218     */
219    static final Unit<Length> ASTRONOMICAL_UNIT = addUnit(METRE
220            .multiply(149597870691.0));
221
222    /**
223     * A unit of length equal to the distance that light travels in one year
224     * through a vacuum (standard name <code>ly</code>).
225     */
226    static final Unit<Length> LIGHT_YEAR = addUnit(METRE
227            .multiply(9.460528405e15));
228
229    /**
230     * A unit of length equal to the distance at which a star would appear to
231     * shift its position by one arcsecond over the course the time (about 3
232     * months) in which the Earth moves a distance of {@link #ASTRONOMICAL_UNIT}
233     * in the direction perpendicular to the direction to the star (standard
234     * name <code>pc</code>).
235     */
236    static final Unit<Length> PARSEC = addUnit(METRE.multiply(30856770e9));
237
238    /**
239     * A unit of length equal to <code>0.013837 {@link #INCH}</code> exactly
240     * (standard name <code>pt</code>).
241     * 
242     * @see #PIXEL
243     */
244    static final Unit<Length> POINT = addUnit(INCH.multiply(13837).divide(
245            1000000));
246
247    // ////////////
248    // Duration //
249    // ////////////
250    /**
251     * A unit of duration equal to <code>60 s</code> (standard name
252     * <code>min</code>).
253     */
254    static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
255
256    /**
257     * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
258     * name <code>h</code>).
259     */
260    static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
261
262    /**
263     * A unit of duration equal to <code>24 {@link #HOUR}</code> (standard name
264     * <code>d</code>).
265     */
266    static final Unit<Time> DAY = addUnit(HOUR.multiply(24));
267
268    /**
269     * A unit of duration equal to the time required for a complete rotation of
270     * the earth in reference to any star or to the vernal equinox at the
271     * meridian, equal to 23 hours, 56 minutes, 4.09 seconds (standard name
272     * <code>day_sidereal</code>).
273     */
274    static final Unit<Time> DAY_SIDEREAL = addUnit(SECOND.multiply(86164.09));
275
276    /**
277     * A unit of duration equal to 7 {@link #DAY} (standard name
278     * <code>week</code>).
279     */
280    static final Unit<Time> WEEK = addUnit(DAY.multiply(7));
281
282    /**
283     * A unit of duration equal to 365 {@link #DAY} (standard name
284     * <code>year</code>).
285     */
286    static final Unit<Time> YEAR_CALENDAR = addUnit(DAY.multiply(365));
287
288    /**
289     * A unit of duration equal to one complete revolution of the earth about
290     * the sun, relative to the fixed stars, or 365 days, 6 hours, 9 minutes,
291     * 9.54 seconds (standard name <code>year_sidereal</code>).
292     */
293    static final Unit<Time> YEAR_SIDEREAL = addUnit(SECOND
294            .multiply(31558149.54));
295
296    /**
297     * The Julian year, as used in astronomy and other sciences, is a time unit
298     * defined as exactly 365.25 days. This is the normal meaning of the unit
299     * "year" (symbol "a" from the Latin annus, annata) used in various
300     * scientific contexts.
301     */
302    static final Unit<Time> YEAR_JULIEN = addUnit(SECOND.multiply(31557600));
303
304    // ////////
305    // Mass //
306    // ////////
307    /**
308     * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
309     * name <code>u</code>).
310     */
311    static final Unit<Mass> ATOMIC_MASS = addUnit(KILOGRAM
312            .multiply(1e-3 / AVOGADRO_CONSTANT));
313
314    /**
315     * A unit of mass equal to the mass of the electron (standard name
316     * <code>me</code>).
317     */
318    static final Unit<Mass> ELECTRON_MASS = addUnit(KILOGRAM
319            .multiply(9.10938188e-31));
320
321    /**
322     * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
323     * standard name <code>lb</code>).
324     */
325    static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(
326            AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR));
327
328    // ///////////////////
329    // Electric charge //
330    // ///////////////////
331    /**
332     * A unit of electric charge equal to the charge on one electron (standard
333     * name <code>e</code>).
334     */
335    static final Unit<ElectricCharge> E = addUnit(COULOMB
336            .multiply(ELEMENTARY_CHARGE));
337
338    /**
339     * A unit of electric charge equal to equal to the product of Avogadro's
340     * number (see {@link SI#MOLE}) and the charge (1 e) on a single electron
341     * (standard name <code>Fd</code>).
342     */
343    static final Unit<ElectricCharge> FARADAY = addUnit(COULOMB
344            .multiply(ELEMENTARY_CHARGE * AVOGADRO_CONSTANT)); // e/mol
345
346    /**
347     * A unit of electric charge which exerts a force of one dyne on an equal
348     * charge at a distance of one centimeter (standard name <code>Fr</code>).
349     */
350    static final Unit<ElectricCharge> FRANKLIN = addUnit(COULOMB
351            .multiply(3.3356e-10));
352
353    // ///////////////
354    // Temperature //
355    // ///////////////
356    /**
357     * A unit of temperature equal to <code>5/9 °K</code> (standard name
358     * <code>°R</code>).
359     */
360    static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(
361            9));
362
363    // /////////
364    // Angle //
365    // /////////
366
367    /**
368     * A unit of angle equal to a full circle or <code>2<i>&pi;</i>
369     * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
370     */
371    static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2)
372            .multiply(Math.PI).asType(Angle.class));
373
374    // ////////////
375    // Velocity //
376    // ////////////
377    /**
378     * A unit of velocity relative to the speed of light (standard name
379     * <code>c</code>).
380     */
381    static final Unit<Speed> C = addUnit(METRES_PER_SECOND.multiply(299792458));
382
383    // ////////////////
384    // Acceleration //
385    // ////////////////
386    /**
387     * A unit of acceleration equal to the gravity at the earth's surface
388     * (standard name <code>grav</code>).
389     */
390    static final Unit<Acceleration> G = addUnit(METRES_PER_SQUARE_SECOND
391            .multiply(STANDARD_GRAVITY_DIVIDEND).divide(
392                    STANDARD_GRAVITY_DIVISOR));
393
394    // ////////
395    // Area //
396    // ////////
397    /**
398     * A unit of area equal to <code>100 m²</code> (standard name <code>a</code>
399     * ).
400     */
401    static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100));
402
403    // ///////////////
404    // Information //
405    // ///////////////
406    /**
407     * The unit for binary information (standard name <code>bit</code>).
408     */
409    static final Unit<Information> BIT = addUnit(
410            new AlternateUnit<Information>(ONE, "bit"), Information.class);
411
412    /**
413     * A unit of data amount equal to <code>8 {@link SI#BIT}</code> (BinarY
414     * TErm, standard name <code>byte</code>).
415     */
416    static final Unit<Information> BYTE = addUnit(BIT.multiply(8));
417
418    /**
419     * The unit for binary information rate (standard name <code>bit/s</code>).
420     */
421    static final ProductUnit<InformationRate> BITS_PER_SECOND = addUnit(
422            new ProductUnit<InformationRate>(BIT.divide(SECOND)),
423            InformationRate.class);
424
425    /**
426     * Equivalent {@link #BYTE}
427     */
428    static final Unit<Information> OCTET = BYTE;
429
430    /**
431     * A pixel has 4 channels which define transparency (alpha), red, green and
432     * blue color values. Each channel is one byte wide.
433     * 
434     * @see #BYTE
435     */
436    static final Unit<Information> PIXEL = addUnit(BYTE.multiply(4.0));
437
438    /**
439     * Pixel per inch describe the resolution for any output device (monitor,
440     * printer) that deals with outputting digital raster images.
441     * 
442     * @see #INCH
443     * @see #PIXEL
444     */
445    static final Unit<Resolution> PIXEL_PER_INCH = addUnit(PIXEL.divide(INCH)
446            .asType(Resolution.class));
447
448    /**
449     * Equivalent {@link #PIXEL}
450     */
451    static final Unit<Information> COMPUTER_POINT = PIXEL;
452
453    // ////////////////////
454    // Electric current //
455    // ////////////////////
456    /**
457     * A unit of electric charge equal to the centimeter-gram-second
458     * electromagnetic unit of magnetomotive force, equal to <code>10/4
459     * &pi;ampere-turn</code> (standard name <code>Gi</code>).
460     */
461    static final Unit<ElectricCurrent> GILBERT = addUnit(AMPERE.multiply(10)
462            .divide(4).multiply(PI).asType(ElectricCurrent.class));
463
464    // //////////
465    // Energy //
466    // //////////
467    /**
468     * A unit of energy equal to <code>1E-7 J</code> (standard name
469     * <code>erg</code>).
470     */
471    static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000));
472
473    /**
474     * A unit of energy equal to one electron-volt (standard name
475     * <code>eV</code>, also recognized <code>keV, MeV, GeV</code>).
476     */
477    static final Unit<Energy> ELECTRON_VOLT = addUnit(JOULE
478            .multiply(ELEMENTARY_CHARGE));
479
480    // ///////////////
481    // Illuminance //
482    // ///////////////
483    /**
484     * A unit of illuminance equal to <code>1E4 Lx</code> (standard name
485     * <code>La</code>).
486     */
487    static final Unit<Illuminance> LAMBERT = addUnit(LUX.multiply(10000));
488
489    // /////////////////
490    // Magnetic Flux //
491    // /////////////////
492    /**
493     * A unit of magnetic flux equal <code>1E-8 Wb</code> (standard name
494     * <code>Mx</code>).
495     */
496    static final Unit<MagneticFlux> MAXWELL = addUnit(WEBER.divide(100000000));
497
498    // /////////////////////////
499    // Magnetic Flux Density //
500    // /////////////////////////
501    /**
502     * A unit of magnetic flux density equal <code>1000 A/m</code> (standard
503     * name <code>G</code>).
504     */
505    static final Unit<MagneticFluxDensity> GAUSS = addUnit(TESLA.divide(10000));
506
507    // /////////
508    // Force //
509    // /////////
510    /**
511     * A unit of force equal to <code>1E-5 N</code> (standard name
512     * <code>dyn</code>).
513     */
514    static final Unit<Force> DYNE = addUnit(NEWTON.divide(100000));
515
516    /**
517     * A unit of force equal to <code>9.80665 N</code> (standard name
518     * <code>kgf</code>).
519     */
520    static final Unit<Force> KILOGRAM_FORCE = addUnit(NEWTON.multiply(
521            STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
522
523    /**
524     * A unit of force equal to <code>{@link #POUND}·{@link #G}</code>
525     * (standard name <code>lbf</code>).
526     */
527    static final Unit<Force> POUND_FORCE = addUnit(NEWTON.multiply(
528            1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND)
529            .divide(1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR));
530
531    // /////////
532    // Power //
533    // /////////
534    /**
535     * A unit of power equal to the power required to raise a mass of 75
536     * kilograms at a velocity of 1 meter per second (metric, standard name
537     * <code>hp</code>).
538     */
539    static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(735.499));
540
541    // ////////////
542    // Pressure //
543    // ////////////
544    /**
545     * A unit of pressure equal to the average pressure of the Earth's
546     * atmosphere at sea level (standard name <code>atm</code>).
547     */
548    static final Unit<Pressure> ATMOSPHERE = addUnit(PASCAL.multiply(101325));
549
550    /**
551     * A unit of pressure equal to <code>100 kPa</code> (standard name
552     * <code>bar</code>).
553     */
554    public static final Unit<Pressure> BAR = addUnit(PASCAL.multiply(100000));
555
556    /**
557     * A unit of pressure equal to the pressure exerted at the Earth's surface
558     * by a column of mercury 1 millimeter high (standard name <code>mmHg</code>
559     * ).
560     */
561    static final Unit<Pressure> MILLIMETRE_OF_MERCURY = addUnit(PASCAL
562            .multiply(133.322));
563
564    /**
565     * A unit of pressure equal to the pressure exerted at the Earth's surface
566     * by a column of mercury 1 inch high (standard name <code>inHg</code>).
567     */
568    static final Unit<Pressure> INCH_OF_MERCURY = addUnit(PASCAL
569            .multiply(3386.388));
570
571    // ///////////////////////////
572    // Radiation dose absorbed //
573    // ///////////////////////////
574    /**
575     * A unit of radiation dose absorbed equal to a dose of 0.01 joule of energy
576     * per kilogram of mass (J/kg) (standard name <code>rd</code>).
577     */
578    static final Unit<RadiationDoseAbsorbed> RAD = addUnit(GRAY.divide(100));
579
580    /**
581     * A unit of radiation dose effective equal to <code>0.01 Sv</code>
582     * (standard name <code>rem</code>).
583     */
584    static final Unit<RadiationDoseEffective> REM = addUnit(SIEVERT.divide(100));
585
586    // ////////////////////////
587    // Radioactive activity //
588    // ////////////////////////
589    /**
590     * A unit of radioctive activity equal to the activity of a gram of radium
591     * (standard name <code>Ci</code>).
592     */
593    static final Unit<Radioactivity> CURIE = addUnit(BECQUEREL
594            .multiply(37000000000L));
595
596    /**
597     * A unit of radioctive activity equal to 1 million radioactive
598     * disintegrations per second (standard name <code>Rd</code>).
599     */
600    static final Unit<Radioactivity> RUTHERFORD = addUnit(BECQUEREL
601            .multiply(1000000));
602
603    // ///////////////
604    // Solid angle //
605    // ///////////////
606    /**
607     * A unit of solid angle equal to <code>4 <i>&pi;</i> steradians</code>
608     * (standard name <code>sphere</code>).
609     */
610    static final Unit<SolidAngle> SPHERE = addUnit(STERADIAN.multiply(4)
611            .multiply(PI).asType(SolidAngle.class));
612
613    // //////////
614    // Volume //
615    // //////////
616
617    // /////////////
618    // Viscosity //
619    // /////////////
620    /**
621     * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit).
622     */
623    static final Unit<DynamicViscosity> POISE = addUnit(
624            GRAM.divide(CENTI(METRE).multiply(SECOND))).asType(
625            DynamicViscosity.class);
626
627    /**
628     * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit).
629     */
630    static final Unit<KinematicViscosity> STOKE = addUnit(
631            CENTI(METRE).pow(2).divide(SECOND))
632            .asType(KinematicViscosity.class);
633
634    // /////////////
635    // Frequency //
636    // /////////////
637    /**
638     * A unit used to measure the frequency (rate) at which an imaging device
639     * produces unique consecutive images (standard name <code>fps</code>).
640     */
641    static final Unit<Frequency> FRAMES_PER_SECOND = addUnit(ONE.divide(SECOND))
642            .asType(Frequency.class);
643
644    // //////////
645    // Others //
646    // //////////
647    /**
648     * A unit used to measure the ionizing ability of radiation (standard name
649     * <code>Roentgen</code>).
650     */
651    // static final Unit<IonizingRadiation> ROENTGEN = SI.ROENTGEN;
652
653    /**
654     * A unit used to measure the ionizing ability of radiation (standard name
655     * <code>Roentgen</code>).
656     */
657    @SuppressWarnings("unchecked")
658    public static final Unit<IonizingRadiation> ROENTGEN = (Unit<IonizingRadiation>) INSTANCE
659            .addUnit(COULOMB.divide(KILOGRAM).multiply(2.58e-4), "Roentgen");
660
661    public String getName() {
662        return SYSTEM_NAME;
663    }
664
665    /**
666     * Adds a new unit not mapped to any specified quantity type.
667     *
668     * @param unit
669     *            the unit being added.
670     * @return <code>unit</code>.
671     */
672    private static <U extends Unit<?>> U addUnit(U unit) {
673        INSTANCE.units.add(unit);
674        return unit;
675    }
676
677    /**
678     * Adds a new unit and maps it to the specified quantity type.
679     *
680     * @param unit
681     *            the unit being added.
682     * @param type
683     *            the quantity type.
684     * @return <code>unit</code>.
685     */
686    private static <U extends AbstractUnit<?>> U addUnit(U unit,
687            Class<? extends Quantity<?>> type) {
688        INSTANCE.units.add(unit);
689        INSTANCE.quantityToUnit.put(type, unit);
690        return unit;
691    }
692
693    /**
694     * Adds a new named unit to the collection.
695     * 
696     * @param unit
697     *            the unit being added.
698     * @param name
699     *            the name of the unit.
700     * @return <code>unit</code>.
701     */
702    // @SuppressWarnings("unchecked")
703    // protected static <U extends Unit<?>> U addUnit(U unit, String name) {
704    //
705    // }
706}