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