Unit Class Reference

A Unit is a combination of base unit terms, with a preferred power of 1000 multiple of the base unit for each term. More...

List of all members.


Public Member Functions

 Unit ()
 Default constructor.
 Unit (String unitstr) throws HDUnitException
 Constructor from string.
 Unit (Unit other)
 Copy constructor.
 Unit (UnitTerm term)
 Constructor from UnitTerm.
 Unit (Collection< UnitTerm > terms)
 Constructor from UnitTerms.
 Unit (UnitTerm terms[])
 Constructor from UnitTerms.
List< UnitTermgetUnitTerms ()
 Get the list of UnitTerms.
void setUnitTerms (List< UnitTerm > unitTerms)
 Set the list of UnitTerms.
void addUnitTerm (UnitTerm unitTerm)
 Add an entry to the list of UnitTerms.
boolean equals (Object obj)
 Is this Unit equivalent to another one?
Unit canonicalUnit ()
 Return the canonical (i.e.
Double convFactorToCanonical ()
 Get the conversion factor from this Unit *to* its canonical representation.
Double convFactorFromCanonical ()
 Get the conversion factor to this unit *from* its canonical representation.
boolean isCompatible (Unit unit)
 Determine whether this unit can be converted to the supplied unit and vice versa.
Double convFactorTo (Unit unit) throws HDUnitException
 Deduce the conversion factor from this Unit to the supplied Unit.
Double convFactorFrom (Unit unit) throws HDUnitException
 Deduce the conversion factor to this Unit from the supplied Unit.
String toString ()
 Provide string representation of this unit.
Unit fromString (String unitstr) throws HDUnitException
 Populate a Unit object from a string.

Static Public Member Functions

static Unit makeGeV ()
static Unit makeGeVc ()
static Unit makeGeVcsq ()

Static Package Attributes

static Logger log = Logger.getLogger(Unit.class)

Detailed Description

A Unit is a combination of base unit terms, with a preferred power of 1000 multiple of the base unit for each term.

Every Axis has a corresponding Unit. Any given Unit has a canonical representation, which is the form in which measurement values stored with that Unit will be stored in the database. The Unit associated with an Axis is the form in which values associated with that axis will be represented in HTML, plain text, XML, etc. output.

Be warned: this class is not intended to provide a "proper" reduction of units to their SI (or other) base units, as combining that with the HepData need to reproduce data in the form preferred by the reporting experiment would probably be fiddly. So, don't try converting between eV and m^-1, for example: we don't attempt to recognise that they are compatible units (and certainly not with the appropriate invisible power of c_light). The fact that this is a fiddly thing to do makes the author even more impressed by the Google calculator!

Todo:
Do c_light and number factors get seamlessly handled? (They should do.)
Todo:
Do we need to deal with subdivisions for degree into arcmin and arcsec? (See http://en.wikipedia.org/wiki/Arcsecond)
Author:
Andy Buckley
Version:
Id
Unit.java 1004 2007-06-07 15:36:26Z buckley

Definition at line 35 of file Unit.java.


Constructor & Destructor Documentation

Unit (  ) 

Default constructor.

Definition at line 46 of file Unit.java.

Referenced by Unit.canonicalUnit(), and Unit.makeGeV().

00046 {}

Unit ( String  unitstr  )  throws HDUnitException

Constructor from string.

Definition at line 49 of file Unit.java.

00049                                                        {
00050         this.fromString(unitstr);
00051     }

Unit ( Unit  other  ) 

Copy constructor.

Definition at line 54 of file Unit.java.

References Unit.getUnitTerms().

00054                             {
00055         for (UnitTerm term : other.getUnitTerms()) {
00056             this.addUnitTerm(new UnitTerm(term.baseunit, term.prefix, term.power));
00057         }
00058     }

Unit ( UnitTerm  term  ) 

Constructor from UnitTerm.

Definition at line 61 of file Unit.java.

00061                                {
00062         this.addUnitTerm(term);
00063     }

Unit ( Collection< UnitTerm terms  ) 

Constructor from UnitTerms.

Definition at line 66 of file Unit.java.

00066                                             {
00067         for (UnitTerm term : terms) {
00068             this.addUnitTerm(term);
00069         }
00070     }

Unit ( UnitTerm  terms[]  ) 

Constructor from UnitTerms.

Definition at line 73 of file Unit.java.

00073                                   {
00074         for (UnitTerm term : terms) {
00075             this.addUnitTerm(term);
00076         }
00077     }


Member Function Documentation

static Unit makeGeV (  )  [static]

Definition at line 84 of file Unit.java.

References Unit.Unit().

Referenced by Unit.makeGeVc(), and Unit.makeGeVcsq().

00084                                  {
00085         return new Unit(new UnitTerm(BaseUnit.EV, SiPrefix.GIGA, 1));
00086     }

static Unit makeGeVc (  )  [static]

Definition at line 87 of file Unit.java.

References Unit.addUnitTerm(), and Unit.makeGeV().

00087                                   {
00088         Unit gevc = makeGeV();
00089         gevc.addUnitTerm(new UnitTerm(BaseUnit.CLIGHT, SiPrefix.UNIT, -1));
00090         return gevc;
00091     }

static Unit makeGeVcsq (  )  [static]

Definition at line 92 of file Unit.java.

References Unit.addUnitTerm(), and Unit.makeGeV().

00092                                     {
00093         Unit gevcsq = makeGeV();
00094         gevcsq.addUnitTerm(new UnitTerm(BaseUnit.CLIGHT, SiPrefix.UNIT, -2));
00095         return gevcsq;
00096     }

List<UnitTerm> getUnitTerms (  ) 

Get the list of UnitTerms.

Definition at line 103 of file Unit.java.

Referenced by Unit.canonicalUnit(), Unit.convFactorTo(), Unit.convFactorToCanonical(), Unit.equals(), Unit.isCompatible(), Unit.toString(), and Unit.Unit().

00103                                          {
00104         return unitTerms;
00105     }

void setUnitTerms ( List< UnitTerm unitTerms  ) 

Set the list of UnitTerms.

Todo:
Should this be more careful about references vs. values?

Definition at line 109 of file Unit.java.

00109                                                        {
00110         this.unitTerms = unitTerms;
00111     }

void addUnitTerm ( UnitTerm  unitTerm  ) 

Add an entry to the list of UnitTerms.

Definition at line 114 of file Unit.java.

Referenced by Unit.canonicalUnit(), Unit.fromString(), Unit.makeGeVc(), and Unit.makeGeVcsq().

00114                                                {
00115         this.unitTerms.add(unitTerm);
00116     }

boolean equals ( Object  obj  ) 

Is this Unit equivalent to another one?

Definition at line 119 of file Unit.java.

References Unit.getUnitTerms().

Referenced by Unit.convFactorTo(), and Unit.isCompatible().

00119                                       {
00120         if (this == obj) return true;
00121         if (! (obj instanceof Unit)) return false;
00122 
00123         Unit test = (Unit) obj;
00124         List<UnitTerm> terms1 = getUnitTerms();
00125         List<UnitTerm> terms2 = test.getUnitTerms();
00126         if (terms1.size() != terms2.size()) return false;
00127 
00128         for (int i = 0; i < terms1.size(); ++i) {
00129             if (! terms1.get(i).equals(terms2.get(i)) ) return false;
00130         }
00131         return true;
00132     }

Unit canonicalUnit (  ) 

Return the canonical (i.e.

storage units for this Unit).

Definition at line 135 of file Unit.java.

References Unit.addUnitTerm(), Unit.getUnitTerms(), UnitTerm.prefix, and Unit.Unit().

Referenced by Unit.convFactorTo(), and Unit.isCompatible().

00135                                 {
00136         Unit cu = new Unit();
00137         for (UnitTerm term : getUnitTerms()) {
00138             UnitTerm cterm = new UnitTerm(term.baseunit, term.prefix, term.power);
00139             cterm.prefix = SiPrefix.UNIT;
00140             cu.addUnitTerm(cterm);
00141         }
00142         return cu;
00143     }

Double convFactorToCanonical (  ) 

Get the conversion factor from this Unit *to* its canonical representation.

Definition at line 146 of file Unit.java.

References Unit.getUnitTerms().

Referenced by Unit.convFactorFromCanonical(), and Unit.convFactorTo().

00146                                           {
00147         Double cf = 1.0;
00148         for (UnitTerm term : getUnitTerms()) {
00149             cf *= term.convFactor();
00150         }
00151         return cf;
00152     }

Double convFactorFromCanonical (  ) 

Get the conversion factor to this unit *from* its canonical representation.

Definition at line 155 of file Unit.java.

References Unit.convFactorToCanonical().

00155                                             {
00156         return 1.0 / convFactorToCanonical();
00157     }

boolean isCompatible ( Unit  unit  ) 

Determine whether this unit can be converted to the supplied unit and vice versa.

Definition at line 160 of file Unit.java.

References Unit.canonicalUnit(), Unit.equals(), Unit.getUnitTerms(), and Unit.log.

Referenced by Unit.convFactorTo().

00160                                            {
00161         Unit myCU = canonicalUnit();
00162         Unit otherCU = unit.canonicalUnit();
00163 
00164         // First test if their canonical representations are the same: it
00165         // makes things a lot easier if they are!
00166         if ( myCU.equals(otherCU) ) return true;
00167 
00168         // If they aren't exactly equal, eliminate matching elements from each
00169         // list and then see what's left over. First we have to make independent
00170         // copies of the term lists which we can mangle:
00171         List<UnitTerm> terms1 = new Vector<UnitTerm>();
00172         List<UnitTerm> terms2 = new Vector<UnitTerm>();
00173         for (UnitTerm term : myCU.getUnitTerms()) { terms1.add(new UnitTerm(term)); }
00174         for (UnitTerm term : otherCU.getUnitTerms()) { terms2.add(new UnitTerm(term)); }
00175 
00176         // Now strip out the stuff that matches from terms1
00177         for (UnitTerm term2 : otherCU.getUnitTerms()) {
00178             for (UnitTerm term1 : terms1) {
00179                 log.debug(term1 + "-" + term2 + ": " + term2.equals(term1));
00180                 if (term2.equals(term1)) {
00181                     terms1.remove(term1);
00182                     break;
00183                 }
00184             }
00185         }
00186         // Now strip out the stuff that matches from terms2
00187         for (UnitTerm term1 : myCU.getUnitTerms()) {
00188             for (UnitTerm term2 : terms2) {
00189                 log.debug(term2 + "-" + term1 + ": " + term1.equals(term2));
00190                 if (term1.equals(term2)) {
00191                     terms2.remove(term2);
00192                     break;
00193                 }
00194             }
00195         }
00196         log.info("T1: " + myCU.getUnitTerms() + " -> " + terms1);
00197         log.info("T2: " + otherCU.getUnitTerms() + " -> " + terms2);
00198 
00199         // Seeing what's left over: if it isn't a c_light, number or rad/deg
00200         // then it's incompatible. We also remove c_light and number on this pass,
00201         // so that we can match up rad/deg elements next...
00202         for (UnitTerm term : terms1) {
00203             if (term.baseunit.equals(BaseUnit.NUMBER) || term.baseunit.equals(BaseUnit.CLIGHT)) {
00204                 terms1.remove(term);
00205             } else if (term.baseunit.equals(BaseUnit.RADIAN) || term.baseunit.equals(BaseUnit.DEGREE)) {
00206                 log.info("Found a remaining angular unit: " + term.toString());
00207             } else {
00208                 return false;
00209             }
00210         }
00211         for (UnitTerm term : terms2) {
00212             if (term.baseunit.equals(BaseUnit.NUMBER) || term.baseunit.equals(BaseUnit.CLIGHT)) {
00213                 terms2.remove(term);
00214             } else if (term.baseunit.equals(BaseUnit.RADIAN) || term.baseunit.equals(BaseUnit.DEGREE)) {
00215                 log.info("Found a remaining angular unit: " + term.toString());
00216             } else {
00217                 return false;
00218             }
00219         }
00220         if (terms1.size() == 0 && terms2.size() == 0) return true;
00221         if (terms1.size() != terms2.size()) return false;
00222 
00223         // Try to match up remaining elements: check that the summed powers of angular
00224         // units are the same for both units
00225         int angPower1 = 0;
00226         int angPower2 = 0;
00227         for (UnitTerm t : terms1) angPower1 += t.power;
00228         for (UnitTerm t : terms2) angPower2 += t.power;
00229         if (angPower1 != angPower2) return false;
00230 
00231         // Finally, the units must be compatible (at last!)
00232         return true;
00233     }

Double convFactorTo ( Unit  unit  )  throws HDUnitException

Deduce the conversion factor from this Unit to the supplied Unit.

Todo:
Handle degrees, radians etc.

Definition at line 236 of file Unit.java.

References Unit.canonicalUnit(), Unit.convFactorToCanonical(), Unit.equals(), Unit.getUnitTerms(), Unit.isCompatible(), Unit.log, and Unit.toString().

Referenced by Unit.convFactorFrom().

00236                                                                  {
00238         if (isCompatible(unit)) {
00239             Double sifactor = convFactorToCanonical() * unit.convFactorFromCanonical();
00240             if (canonicalUnit().equals(unit.canonicalUnit())) {
00241                 return sifactor;
00242             } else {
00243                 int degPower1 = 0;
00244                 for (UnitTerm t : this.getUnitTerms()) {
00245                     if (t.baseunit == BaseUnit.DEGREE) degPower1 += 1;
00246                     if (t.baseunit == BaseUnit.RADIAN) degPower1 -= 1;
00247                 }
00248                 int degPower2 = 0;
00249                 for (UnitTerm t : unit.getUnitTerms()) {
00250                     if (t.baseunit == BaseUnit.DEGREE) degPower2 += 1;
00251                     if (t.baseunit == BaseUnit.RADIAN) degPower2 -= 1;
00252                 }
00253                 int deltaDegPower = degPower2 - degPower1;
00254                 assert deltaDegPower % 2 == 0 : "Shift in number of powers of degree is not even. How?!?";
00255                 log.debug(degPower1 + " -> " + degPower2 + " so shift is " + deltaDegPower);
00256                 Double angfactor = Math.pow(180.0/Math.PI, deltaDegPower/2.0);
00257                 return sifactor * angfactor;
00258             }
00259         } else {
00260             throw new HDUnitException("Units " + toString() + " and " + unit.toString() + " are not compatible");
00261         }
00262     }

Double convFactorFrom ( Unit  unit  )  throws HDUnitException

Deduce the conversion factor to this Unit from the supplied Unit.

Definition at line 265 of file Unit.java.

References Unit.convFactorTo().

00265                                                                    {
00266         return 1.0/ convFactorTo(unit);
00267     }

String toString (  ) 

Provide string representation of this unit.

Definition at line 270 of file Unit.java.

References Unit.getUnitTerms().

Referenced by Unit.convFactorTo().

00270                              {
00271         StringBuffer s = new StringBuffer();
00272         for (UnitTerm term : getUnitTerms()) {
00273             s.append(term.toString());
00274             s.append(" ");
00275         }
00276         return s.toString().trim();
00277     }

Unit fromString ( String  unitstr  )  throws HDUnitException

Populate a Unit object from a string.

Definition at line 280 of file Unit.java.

References Unit.addUnitTerm(), and Unit.log.

00280                                                                   {
00281         unitTerms.clear();
00282         String myunitstr = unitstr;
00283         if (myunitstr.length() == 0) {
00284             return this;
00285         }
00286 
00287         // Replace ** with ^, replace " *\* *" with " ", replace " */ *" with " /"
00288         myunitstr = myunitstr.replaceAll("\\*\\*", "^");
00289         log.debug("1. " + unitstr + " vs. " + myunitstr);
00290         myunitstr = myunitstr.replaceAll("\\ *\\*\\ *", " ");
00291         log.debug("2. " + unitstr + " vs. " + myunitstr);
00292         myunitstr = myunitstr.replaceAll("\\ */\\ *", " /");
00293         log.debug("3. " + unitstr + " vs. " + myunitstr);
00294 
00295         String[] unitatoms = myunitstr.split(" ");
00296         for (String atom : unitatoms) {
00297             UnitTerm term = new UnitTerm(atom);
00298             addUnitTerm(term);
00299         }
00300         return this;
00301     }


Member Data Documentation

Logger log = Logger.getLogger(Unit.class) [static, package]

Definition at line 36 of file Unit.java.

Referenced by Unit.convFactorTo(), Unit.fromString(), and Unit.isCompatible().


The documentation for this class was generated from the following file:


Generated on Tue Apr 21 15:54:56 2009 for HepData common classes by  doxygen 1.5.5