Package park :: Package util :: Module magnitude

Source Code for Module park.util.magnitude

  1  # magnitude  -- a module for computing with numbers with units. 
  2  # 
  3  # Version 0.9.3, October 2007 
  4  # 
  5  # Copyright (C) 2006 Juan Reyero (http://juanreyero.com). 
  6  # 
  7  # Licensed under the Apache License, Version 2.0 (the 
  8  # "License"); you may not use this file except in compliance 
  9  # with the License.  You may obtain a copy of the License at 
 10  # 
 11  #      http://www.apache.org/licenses/LICENSE-2.0 
 12  # 
 13  # Unless required by applicable law or agreed to in writing, 
 14  # software distributed under the License is distributed on an 
 15  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 16  # either express or implied.  See the License for the specific 
 17  # language governing permissions and limitations under the 
 18  # License. 
 19  # 
 20  # Home page: http://juanreyero.com/magnitude/ 
 21   
 22  """ 
 23  A physical quantity is a number with a unit, like 10 km/h. Units can be any 
 24  of the SI units, plus a bunch of non-SI, bits, dollars, and any combination 
 25  of them. They can include the standard SI prefixes. Magnitude can operate 
 26  with physical quantities, parse their units, and print them. You don't have 
 27  to worry about unit consistency or conversions; everything is handled 
 28  transparently. By default output is done in basic SI units, but you can 
 29  specify any output unit, as long as it can be reduced to the basic units of 
 30  the physical quantity. 
 31   
 32  The basic units understood by the magnitude module are: 
 33   
 34      indicator    meaning 
 35      ---------    ------- 
 36      $            dollar ('dollar' is also acceptable) 
 37      A            amperes 
 38      bit          binary digit 
 39      cd           candela 
 40      K            degrees Kelvin 
 41      kg           kilograms 
 42      m            meters 
 43      mol          amount of substance 
 44      s            seconds 
 45   
 46  From these basic units you can derive many other units.  The magnitude 
 47  package predefines these derived units: 
 48   
 49      Bq           becquerel 
 50      C            coulomb 
 51      c            speed of light (m/s) 
 52      day 
 53      degC         degree Celsius 
 54      dpi          dots per inch 
 55      F            farad 
 56      ft           feet ("'" is also acceptable) 
 57      g            gram 
 58      gravity      acceleration due to gravity (m/s**2) 
 59      Gy           gray 
 60      H            henry 
 61      h            hour 
 62      Hz           Hertz 
 63      inch         ('"' is also acceptable) 
 64      ips          inches per second 
 65      J            joule 
 66      kat          byte 
 67      l            liter 
 68      lightyear    light year 
 69      lm           lumen 
 70      lpi          lines per inch 
 71      lux 
 72      min          minute 
 73      N            newton 
 74      ohm 
 75      Pa           pascal 
 76      S            siemens 
 77      Sv           sievert 
 78      T            tesla 
 79      V            volt 
 80      W            watt 
 81      Wb           weber 
 82      year 
 83   
 84  Two magnitudes have no units, 'rad' (radian - unit of plane angle) and 'sr' 
 85  (steradian - unit of solid angle). 
 86   
 87  Any of the above units can be augmented with the following set of scale 
 88  prefixes: 
 89   
 90      letter     scale    name 
 91      ------     -----    ---- 
 92      y          1e-24    yocto 
 93      z          1e-21    zepto 
 94      a          1e-18    atto 
 95      f          1e-15    femto 
 96      p          1e-12    pico 
 97      n          1e-9     nano 
 98      u          1e-6     micro 
 99      m          1e-3     mili 
100      c          1e-2     centi 
101      d          1e-1     deci 
102      k          1e3      kilo 
103      Ki         2^10     Kibi 
104      M          1e6      mega 
105      Mi         2^20     Mebi 
106      G          1e9      giga 
107      Gi         2^30     Gibi 
108      T          1e12     tera 
109      Ti         2^40     Tebi 
110      P          1e15     peta 
111      Pi         2^50     Pebi 
112      E          1e18     exa 
113      Ei         2^60     Exbi 
114      Z          1e21     zetta 
115      Y          1e24     yotta 
116   
117  You can define new magnitudes by instantiating the Magnitude class.  Suppose 
118  you want to define pounds as a magnitude and associate with it the unit 
119  'lb'.  A pound is 0.45359237 kilograms, so we have 
120   
121      >>> lb = Magnitude(0.45359237, kg=1) 
122   
123  To make it recognized automatically you also have to present it to the system: 
124   
125      >>> new_mag('lb', lb) 
126   
127  You can then use it as you would any other predefined physical quantity: 
128   
129      >>> me = mg(180, 'lb') 
130      >>> print me.ounit('kg').toval() 
131      81.6466266 
132   
133  The following online references provide more detail about physical units and 
134  the SI system. 
135   
136      http://physics.nist.gov/cuu/Units/units.html 
137      http://en.wikipedia.org/wiki/SI 
138      http://www.gnu.org/software/units/units.html for units.dat 
139      http://www.cip.physik.uni-muenchen.de/~tf/misc/etools.lisp 
140   
141  This code was very much inspired by 
142      http://www.cs.utexas.edu/users/novak/units.html 
143  and its associated paper, 
144      http://www.cs.utexas.edu/users/novak/units95.html 
145  """ 
146   
147  import re, math 
148  import types 
149   
150  # Base magnitude names and prefixes.  The _mags dictionary, initialized 
151  # at the end, will contain all the known magnitudes.  Units are 
152  # 9-element arrays, each element the exponent of the unit named by the 
153  # Uname in the same position. 
154   
155 -class MagnitudeError(Exception):
156 pass
157 158 _mags = {} 159 _unames = ['m', 's', 'K', 'kg', 'A', 'mol', 'cd', '$', 'bit'] 160 _prefix = {'y': 1e-24, # yocto 161 'z': 1e-21, # zepto 162 'a': 1e-18, # atto 163 'f': 1e-15, # femto 164 'p': 1e-12, # pico 165 'n': 1e-9, # nano 166 'u': 1e-6, # micro 167 'm': 1e-3, # mili 168 'c': 1e-2, # centi 169 'd': 1e-1, # deci 170 'k': 1e3, # kilo 171 'M': 1e6, # mega 172 'G': 1e9, # giga 173 'T': 1e12, # tera 174 'P': 1e15, # peta 175 'E': 1e18, # exa 176 'Z': 1e21, # zetta 177 'Y': 1e24, # yotta 178 179 # Binary prefixes, approved by the International 180 # Electrotechnical Comission in 1998. Since then, kb means 181 # 1000 bytes; for 1024 bytes use Kib (note the capital K in 182 # the binary version, and the lower case for the b of byte, 183 # see comment in byte definition below). 184 'Ki': 2 ** 10, # Kibi (<- kilo, 10^3) 185 'Mi': 2 ** 20, # Mebi (<- mega, 10^6) 186 'Gi': 2 ** 30, # Gibi (<- giga, 10^9) 187 'Ti': 2 ** 40, # Tebi (<- tera, 10^12) 188 'Pi': 2 ** 50, # Pebi (<- peta, 10^15) 189 'Ei': 2 ** 60 # Exbi (<- exa, 10^18) 190 } 191 192 _prn_format = "%.*f" 193 _prn_prec = 4 194 _prn_units = True 195
196 -def default_format(fmt=None):
197 """Change the default ouptut format. Include a fmt if and where 198 you need to specify the output precission. Defaults to %.*f, 199 where the * stands for the precission. Returns the default 200 format. 201 202 """ 203 global _prn_format 204 if fmt is not None: 205 _prn_format = fmt 206 return _prn_format
207
208 -def output_precision(prec=None):
209 """ Change the output precission. Default is 4. Returns it. """ 210 global _prn_prec 211 if prec is not None: 212 _prn_prec = prec 213 return _prn_prec
214
215 -def output_units(un=None):
216 """Set the units output. Default is True.""" 217 global _prn_units 218 if un is not None: 219 _prn_units = un 220 return _prn_units
221 222 # Resolution areas 223 224 # Dirty way, used in the printing industry, to denote the area of a 225 # pixel. Can be like [300x1200] or like [600] (=[600x600]), meaning 226 # the area of square pixels of size 1"/300 x 1"/1200 and 1"/600 x 227 # 1"/600. The square brackes are intended to show that we are talking 228 # about areas. The following functions make it easy to deal with them. 229
230 -def res2num(res):
231 match = re.search(r'(\d+)x(\d+)', res) 232 if match: 233 return int(match.group(1)), int(match.group(2)) 234 if (res[0] == '[') and (res[-1] == ']'): 235 return (int(res[1:-1]), int(res[1:-1]))
236
237 -def isres(res):
238 return (len(res) > 2) and (res[0] == '[') and (res[-1] == ']')
239
240 -def res2m2(res):
241 hr, vr = res2num(res) 242 return 0.0254 * 0.0254 / (vr * hr)
243 244 245 # Definition of the magnitude type. Includes operator overloads. 246
247 -def numberp(n): ## Python has to have a decent way to do this!
248 return (isinstance(n, types.ComplexType) or 249 isinstance(n, types.FloatType) or 250 isinstance(n, types.IntType) or 251 isinstance(n, types.LongType)) 252
253 -class Magnitude:
254 - def __init__(self, val, m=0, s=0, K=0, kg=0, A=0, mol=0, cd=0, dollar=0, 255 bit=0):
256 self.val = val 257 self.unit = [m, s, K, kg, A, mol, cd, dollar, bit] 258 self.out_unit = None 259 self.out_factor = None 260 self.oprec = None 261 self.oformat = None
262
263 - def copy(self):
264 return Magnitude(self.val, *self.unit)
265
266 - def toval(self, ounit=''):
267 m = self.copy() 268 if not ounit: 269 ounit = self.out_unit 270 if ounit: 271 out_factor = self.sunit2mag(ounit) 272 m.div_by(out_factor) 273 return m.val
274
275 - def __str__(self):
276 oformat = self.oformat 277 oprec = self.oprec 278 if oprec is None: 279 oprec = _prn_prec 280 if oformat is None: 281 oformat = _prn_format 282 if self.out_unit: 283 m = self.copy() 284 m.div_by(self.out_factor) 285 if '*' in oformat: # requires the precision arg 286 st = oformat % (oprec, m.val) 287 else: 288 st = oformat % (m.val) 289 if _prn_units: 290 return st + ' ' + self.out_unit 291 return st 292 293 if '*' in oformat: 294 st = oformat % (oprec, self.val) 295 else: 296 st = oformat % (self.val) 297 298 if not _prn_units: 299 return st 300 301 u = self.unit 302 num = ' ' # numerator 303 for i in range(len(_unames)): 304 if u[i] > 1: 305 num = num + _unames[i] + str(u[i]) + ' ' 306 elif u[i] == 1: 307 num = num + _unames[i] + ' ' 308 den = '' # denominator 309 for i in range(len(_unames)): 310 if u[i] < -1: 311 den = den + _unames[i] + str(-u[i]) + ' ' 312 elif u[i] == -1: 313 den = den + _unames[i] + ' ' 314 if den: 315 if num == ' ': 316 num += '1 ' 317 st += (num + '/ ' + den) 318 elif num != ' ': 319 st += num 320 return st
321
322 - def term2mag(self, s):
323 """Converts a string with units to a Magnitude. Can't divide: use 324 with the numerator and the denominator separately (hence the term). 325 326 """ 327 m = Magnitude(1.0) 328 units = re.split(r'\s', s) 329 for u in units: 330 if re.search(r'[^\s]', u): 331 exp = 1 332 if re.search(r'\d$', u): 333 exp = int(u[-1]) 334 u = u[0:-1] 335 if _mags.has_key(u): 336 u = _mags[u].copy() 337 elif ((len(u)>=3) and _prefix.has_key(u[0:2]) and 338 _mags.has_key(u[2:])): 339 pr = _prefix[u[0:2]] 340 u = _mags[u[2:]].copy(); u.val = pr * u.val 341 elif ((len(u)>=2) and _prefix.has_key(u[0]) and 342 _mags.has_key(u[1:])): 343 pr = _prefix[u[0]] 344 u = _mags[u[1:]].copy(); u.val = pr * u.val 345 elif isres(u): 346 u = Magnitude(res2m2(u), m=2) 347 elif u == '': 348 u = Magnitude(1.0) 349 else: 350 raise MagnitudeError("Don't know about unit %s" % u) 351 for i in range(exp): 352 m.mult_by(u) 353 return m
354
355 - def sunit2mag(self, unit=''):
356 """This is the good one: uses term2mag to convert a string 357 with units, possibly including a / to separate a numerator and 358 a denominator, to a Magnitude. 359 360 """ 361 m = Magnitude(1.0) 362 if unit: 363 q = re.split(r'/', unit) 364 if re.search(r'[^\s]', q[0]): 365 m.mult_by(self.term2mag(q[0])) 366 if (len(q) == 2) and re.search(r'[^\s]', q[1]): 367 m.div_by(self.term2mag(q[1])) 368 return m
369
370 - def dimensionless(self):
371 return self.unit == [0] * 9
372
373 - def dimension(self):
374 return self.unit[:]
375
376 - def has_dimension(self, u):
377 o = self.sunit2mag(u) 378 return (self.unit == o.unit)
379
380 - def mult_by(self, m):
381 self.val *= m.val 382 for i in range(len(self.unit)): 383 self.unit[i] = self.unit[i] + m.unit[i] 384 self.out_unit = None
385
386 - def div_by(self, m):
387 self.val /= m.val 388 for i in range(len(self.unit)): 389 self.unit[i] = self.unit[i] - m.unit[i] 390 self.out_unit = None
391
392 - def ounit(self, unit):
393 self.out_unit = unit 394 self.out_factor = self.sunit2mag(unit) 395 if self.out_factor.unit != self.unit: 396 raise MagnitudeError("Inconsistent Magnitude units: %s, %s" % 397 (self.out_factor.unit, self.unit)) 398 return self
399
400 - def output_prec(self, prec):
401 self.oprec = prec
402
403 - def output_format(self, oformat):
404 self.oformat = oformat
405
406 - def __coerce__(self, m):
407 if not isinstance(m, Magnitude): 408 if type(m) == tuple: 409 if len(m) == 2: 410 r = Magnitude(m[0]) 411 r.mult_by(self.sunit2mag(m[1])) 412 return self, r 413 elif len(m) == 1: 414 return self, Magnitude(m[0]) 415 else: 416 return None 417 elif numberp(m): 418 return self, Magnitude(m) 419 else: 420 return None 421 else: 422 return self, m
423
424 - def __add__(self, m):
425 if m.unit != self.unit: 426 raise MagnitudeError("Incompatible units: %s and %s" % 427 (m.unit, self.unit)) 428 r = self.copy() 429 r.val += m.val 430 return r
431
432 - def __radd__(self, m):
433 return self.__add__(m)
434
435 - def __iadd__(self, m):
436 if m.unit != self.unit: 437 raise MagnitudeError("Incompatible units: %s and %s" % 438 (m.unit, self.unit)) 439 self.val += m.val 440 return self
441
442 - def __sub__(self, m):
443 if m.unit != self.unit: 444 raise MagnitudeError("Incompatible units: %s and %s" % 445 (m.unit, self.unit)) 446 r = self.copy() 447 r.val -= m.val 448 return r
449
450 - def __rsub__(self, m):
451 return m.__sub__(self)
452
453 - def __isub__(self, m):
454 if m.unit != self.unit: 455 raise MagnitudeError("Incompatible units: %s and %s" % 456 (m.unit, self.unit)) 457 self.val -= m.val 458 return self
459
460 - def __mul__(self, m):
461 r = self.copy() 462 r.mult_by(m) 463 return r
464
465 - def __rmul__(self, m):
466 r = self.copy() 467 r.mult_by(m) 468 return r
469
470 - def __imul__(self, m):
471 self.mult_by(m) 472 return self
473
474 - def __div__(self, m):
475 r = self.copy() 476 r.div_by(m) 477 return r
478
479 - def __rdiv__(self, m):
480 r = self.copy() 481 m.div_by(r) 482 return m
483
484 - def __idiv__(self, m):
485 self.div_by(m) 486 return self
487
488 - def __mod__(self, n):
489 r = self.copy() 490 r.val = r.val % n.val 491 for i in range(len(r.unit)): 492 r.unit[i] = r.unit[i] - n.unit[i] 493 self.out_unit = None 494 return r
495
496 - def __imod__(self, n):
497 self.val %= n.val 498 for i in range(len(self.unit)): 499 self.unit[i] = self.unit[i] - n.unit[i] 500 self.out_unit = None 501 return self
502
503 - def __floordiv__(self, m):
504 r = self.copy() 505 r.div_by(m) 506 r.val = math.floor(r.val) 507 return r
508
509 - def __ifloordiv__(self, m):
510 self.div_by(m) 511 self.val = math.floor(self.val) 512 return self
513
514 - def __divmod__(self, m):
515 return (self.__floordiv__(m), self.__mod__(m))
516
517 - def __rdivmod__(self, m):
518 return (m.__floordiv__(self), m.__mod__(self))
519
520 - def __pow__(self, n, modulo=None):
521 r = self.copy() 522 if modulo and (r.val == math.floor(r.val)): # it's an integer 523 # might have been converted to float during creation, 524 # modulo only works when all are int 525 r.val = int(r.val) 526 if isinstance(n, Magnitude): # happens when called as a ** n 527 if not n.dimensionless(): 528 raise MagnitudeError("Cannot use a dimensional number as" 529 "exponent, %s" % (n)) 530 n = n.val 531 r.val = pow(r.val, n, modulo) 532 for i in range(len(r.unit)): 533 r.unit[i] *= n 534 return r
535
536 - def __ipow__(self, n):
537 if not n.dimensionless(): 538 raise MagnitudeError("Cannot use a dimensional number as" 539 "exponent, %s" % (n)) 540 n = n.val 541 self.val = pow(self.val, n) 542 for i in range(len(self.unit)): 543 self.unit[i] *= n 544 return self
545
546 - def __neg__(self):
547 r = self.copy() 548 r.val = -r.val 549 return r
550
551 - def __pos__(self):
552 return self.copy()
553
554 - def __abs__(self):
555 r = self.copy() 556 r.val = abs(r.val) 557 return r
558
559 - def __cmp__(self, m):
560 if m.unit != self.unit: 561 raise MagnitudeError("Incompatible units in comparison: %s and %s" % 562 (m.unit, self.unit)) 563 return cmp(self.val, m.val)
564
565 - def __int__(self):
566 return int(self.toval())
567
568 - def __long__(self):
569 return long(self.toval())
570
571 - def __float__(self):
572 return float(self.toval())
573
574 - def ceiling(self):
575 r = self.copy() 576 r.val = math.ceil(r.val) 577 return r
578
579 - def floor(self):
580 r = self.copy() 581 r.val = math.floor(r.val) 582 return r
583
584 - def round(self):
585 r = self.copy() 586 r.val = round(r.val) 587 return r
588
589 - def to_bits(self):
590 return Magnitude(math.ceil(math.log(self.val) / math.log(2.0)), 591 bit=1)
592
593 - def sqrt(self):
594 return self ** 0.5
595 596 597 # Some helper functions 598
599 -def mg(v, unit='', ounit=''):
600 """Builds a Magnitude from a number and a units string""" 601 m = Magnitude(v) 602 if unit: 603 u = m.sunit2mag(unit) 604 m.mult_by(u) 605 if not ounit: 606 ounit = unit 607 m.ounit(ounit) 608 return m
609
610 -def ensmg(m, unit=''):
611 """Ensures that something is a Magnitude.""" 612 if not isinstance(m, Magnitude): 613 if type(m) == tuple: 614 if len(m) == 2: 615 return mg(m[0], m[1], unit) 616 elif (len(m) == 1) and numberp(m[0]): 617 if unit: 618 return mg(m[0], unit) 619 return Magnitude(m[0]) 620 else: 621 raise MagnitudeError("Can't convert %s to Magnitude" % 622 (m,)) 623 elif numberp(m): 624 if unit: 625 return mg(m, unit) 626 return Magnitude(m) 627 else: 628 raise MagnitudeError("Can't convert %s to Magnitude" % 629 (m,)) 630 else: 631 return m
632 633 # These don't really help much, as it's much easier to use the 634 # overriden * and / operators. 635
636 -def mul(m1, *rest):
637 m = ensmg(m1) 638 for m2 in rest: m.mult_by(ensmg(m2)) 639 return m
640
641 -def div(m1, *rest):
642 if rest: 643 m = ensmg(m1) 644 for m2 in rest: m.div_by(ensmg(m2)) 645 return m 646 else: 647 m = Magnitude(1.0) 648 m.div_by(ensmg(m1)) 649 return m
650
651 -def new_mag(indicator, mag):
652 """Define a new magnitude understood by the package.""" 653 _mags[indicator] = mag
654 655 # Finally, define the Magnitudes and initialize _mags. 656
657 -def _init_mags():
658 # Magnitudes for the base SI units 659 new_mag('m', Magnitude(1.0, m=1)) 660 new_mag('s', Magnitude(1.0, s=1)) 661 new_mag('K', Magnitude(1.0, K=1)) 662 new_mag('kg', Magnitude(1.0, kg=1)) 663 new_mag('A', Magnitude(1.0, A=1)) 664 new_mag('mol', Magnitude(1.0, mol=1)) 665 new_mag('cd', Magnitude(1.0, cd=1)) 666 new_mag('$', Magnitude(1.0, dollar=1)) 667 new_mag('dollar', Magnitude(1.0, dollar=1)) 668 new_mag('bit', Magnitude(1.0, bit=1)) 669 670 # Magnitudes for derived SI units 671 new_mag('rad', Magnitude(1.0)) # radian 672 new_mag('sr', Magnitude(1.0)) # steradian 673 new_mag('Hz', Magnitude(1.0, s=-1)) # hertz 674 new_mag('g', Magnitude(1e-3, kg=1)) # gram 675 new_mag('N', Magnitude(1.0, m=1, kg=1, s=-2)) # newton 676 new_mag('Pa', Magnitude(1.0, m=-1, kg=1, s=-2)) # pascal 677 new_mag('J', Magnitude(1.0, m=2, kg=1, s=-2)) # joule 678 new_mag('W', Magnitude(1.0, m=2, kg=1, s=-3)) # watt 679 new_mag('C', Magnitude(1.0, s=1, A=1)) # coulomb 680 new_mag('V', Magnitude(1.0, m=2, kg=1, s=-3, A=-1)) # volt 681 new_mag('F', Magnitude(1.0, m=-2, kg=-1, s=4, A=2)) # farad, C/V 682 new_mag('ohm', Magnitude(1.0, m=2, kg=1, s=-3, A=-2)) # ohm, V/A 683 new_mag('S', Magnitude(1.0, m=-2, kg=-1, s=3, A=2)) # siemens, A/V, el cond. 684 new_mag('Wb', Magnitude(1.0, m=2, kg=1, s=-2, A=-1)) # weber, V.s, mag. flux 685 new_mag('T', Magnitude(1.0, kg=1, s=-2, A=-1)) # tesla, Wb/m2, mg flux dens. 686 new_mag('H', Magnitude(1.0, m=2, kg=1, s=-2, A=-2)) # henry, Wb/A, induct. 687 new_mag('degC', Magnitude(1.0, K=1)) # celsius, !! 688 new_mag('lm', Magnitude(1.0, cd=1)) # lumen, cd.sr (=cd)), luminous flux 689 new_mag('lux', Magnitude(1.0, m=-2, cd=1)) # lux, lm/m2, illuminance 690 new_mag('Bq', Magnitude(1.0, s=-1)) # becquerel, activity of a radionulide 691 new_mag('Gy', Magnitude(1.0, m=2, s=-2)) # gray, J/kg, absorbed dose 692 new_mag('Sv', Magnitude(1.0, m=2, s=-2)) # sievert, J/kg, dose equivalent 693 new_mag('kat', Magnitude(1.0, s=-1, mol=1)) # katal, catalitic activity 694 # Non-SI but almost: 695 new_mag('b', Magnitude(8.0, bit=1)) # byte, note that B is Bel, as in dB 696 697 # Funny Magnitudes with strange names 698 # length 699 new_mag("'", Magnitude(0.3048, m=1)) # feet 700 new_mag('ft', Magnitude(0.3048, m=1)) # feet 701 new_mag('inch', Magnitude(0.0254, m=1)) # inch 702 new_mag('"', Magnitude(0.0254, m=1)) # inch 703 new_mag('lightyear', Magnitude(2.99792458e8 * 365.25 * 86400, m=1)) 704 705 # volume 706 new_mag('l', Magnitude(0.001, m=3)) 707 708 # time 709 # year is tropical year, "the mean interval between vernal 710 # equinoxes. Differs from the sidereal year by 1 part in 26000 711 # due to precession of the earth about its rotational axis 712 # combined with precession of the perihelion of the earth's orbit" 713 # (from units.dat). 714 new_mag('year', Magnitude(31556925.974678401, s=1)) 715 new_mag('day', Magnitude(86400, s=1)) 716 new_mag('h', Magnitude(3600, s=1)) 717 new_mag('min', Magnitude(60, s=1)) 718 719 # Resolution 720 new_mag('dpi', Magnitude(1.0 / 0.0254, m=-1)) 721 new_mag('lpi', Magnitude(1.0 / 0.0254, m=-1)) 722 723 # Velocity 724 new_mag('ips', Magnitude(0.0254, m=1, s=-1)) 725 new_mag('c', Magnitude(2.99792458e8, m=1, s=-1)) 726 727 # Acceleration 728 new_mag('gravity', Magnitude(9.80665, m=1, s=-2))
729 730 731 if not _mags: 732 _init_mags() 733