doctests.py 21.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/env python

"""
Module simtk.unit.doctests

Lots of in-place doctests would no longer work after I rearranged
so that specific unit definitions are defined late.  So those tests
are here.

Examples

>>> furlong = BaseUnit(length_dimension, "furlong", "fur")

Examples

>>> furlong_base_unit = BaseUnit(length_dimension, "furlong", "fur")
>>> furlong_base_unit.define_conversion_factor_to(meter_base_unit, 201.16800)
>>> furlong_base_unit.conversion_factor_to(angstrom_base_unit)
2011680000000.0
        
Examples

>>> furlong_base_unit = BaseUnit(length_dimension, "furlong", "fur")
>>> furlong_base_unit.define_conversion_factor_to(meter_base_unit, 201.16800)

Examples

Some of these example test methods from Unit and Quantity

from unit.is_unit
>>> is_unit(meter)
True
>>> is_unit(5*meter)
False
    
>>> c = 1.0*calories
>>> c
Quantity(value=1.0, unit=calorie)
Peter Eastman's avatar
Peter Eastman committed
39
>>> print(calorie.conversion_factor_to(joule))
40
4.184
Peter Eastman's avatar
Peter Eastman committed
41
>>> print(joule.conversion_factor_to(calorie))
42
43
44
45
46
47
48
49
50
51
0.239005736138
>>> c.in_units_of(joules)
Quantity(value=4.1840000000000002, unit=joule)
>>> j = 1.0*joules
>>> j
Quantity(value=1.0, unit=joule)
>>> j.in_units_of(calories)
Quantity(value=0.23900573613766729, unit=calorie)
>>> j/joules
1.0
Peter Eastman's avatar
Peter Eastman committed
52
>>> print(j/calories)
53
0.239005736138
Peter Eastman's avatar
Peter Eastman committed
54
>>> print(c/joules)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
4.184
>>> c/calories
1.0
>>> c**2
Quantity(value=1.0, unit=calorie**2)
>>> (c**2).in_units_of(joule*joule)
Quantity(value=17.505856000000001, unit=joule**2)

>>> ScaledUnit(1000.0, kelvin, "kilokelvin", "kK")
ScaledUnit(factor=1000.0, master=kelvin, name='kilokelvin', symbol='kK')

>>> str(ScaledUnit(1000.0, kelvin, "kilokelvin", "kK"))
'kilokelvin'

Examples

>>> meters > centimeters
True
>>> angstroms > centimeters
False

Examples

Peter Eastman's avatar
Peter Eastman committed
78
>>> print(meter / second)
79
meter/second
Peter Eastman's avatar
Peter Eastman committed
80
>>> print(meter / meter)
81
82
83
dimensionless

Heterogeneous units are not reduced unless they are in a quantity.
Peter Eastman's avatar
Peter Eastman committed
84
>>> print(meter / centimeter)
85
86
87
88
89
meter/centimeter

Examples

>>> meters_per_second = Unit({meter_base_unit: 1.0, second_base_unit: -1.0})
Peter Eastman's avatar
Peter Eastman committed
90
>>> print(meters_per_second)
91
92
93
meter/second

>>> us = UnitSystem([ScaledUnit(1.0, coulomb/second, "ampere", "A"), second_base_unit])
Peter Eastman's avatar
Peter Eastman committed
94
>>> print(us.express_unit(second))
95
second
Peter Eastman's avatar
Peter Eastman committed
96
>>> print(us.express_unit(coulomb/second))
97
ampere
Peter Eastman's avatar
Peter Eastman committed
98
>>> print(us.express_unit(coulomb))
99
second*ampere
Peter Eastman's avatar
Peter Eastman committed
100
>>> print(us.express_unit(meter/second))
101
102
103
meter/second

>>> us = UnitSystem([ScaledUnit(1.0, coulomb/second, "ampere", "A"), second_base_unit])
Peter Eastman's avatar
Peter Eastman committed
104
>>> print(us)
105
106
107
108
109
110
111
112
113
UnitSystem([ampere, second])

Examples

>>> meter.is_dimensionless()
False
>>> (meter/meter).is_dimensionless()
True

Peter Eastman's avatar
Peter Eastman committed
114
>>> print((meter*meter).sqrt())
115
116
117
118
119
120
121
122
123
meter
>>> meter.sqrt()
Traceback (most recent call last):
  ...
ArithmeticError: Exponents in Unit.sqrt() must be even.
>>> (meter*meter*meter).sqrt()
Traceback (most recent call last):
  ...
ArithmeticError: Exponents in Unit.sqrt() must be even.
Peter Eastman's avatar
Peter Eastman committed
124
>>> print((meter*meter/second/second).sqrt())
125
126
127
meter/second

Mixture of BaseUnits and ScaledUnits should cause no trouble:
Peter Eastman's avatar
Peter Eastman committed
128
>>> print(sqrt(kilogram*joule))
129
kilogram*meter/second
Peter Eastman's avatar
Peter Eastman committed
130
>>> print(sqrt(kilogram*calorie))
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
kilogram*meter/second

Examples

>>> newton.get_name()
'newton'
>>> meter.get_name()
'meter'

Examples

>>> newton.get_symbol()
'N'
>>> meter.get_symbol()
'm'

Examples

Peter Eastman's avatar
Peter Eastman committed
149
>>> print(angstrom.in_unit_system(si_unit_system))
150
meter
Peter Eastman's avatar
Peter Eastman committed
151
>>> print(angstrom.in_unit_system(cgs_unit_system))
152
centimeter
Peter Eastman's avatar
Peter Eastman committed
153
>>> print(angstrom.in_unit_system(md_unit_system))
154
155
nanometer
>>> u = meter/second**2
Peter Eastman's avatar
Peter Eastman committed
156
>>> print(u)
157
meter/(second**2)
Peter Eastman's avatar
Peter Eastman committed
158
>>> print(u.in_unit_system(si_unit_system))
159
meter/(second**2)
Peter Eastman's avatar
Peter Eastman committed
160
>>> print(u.in_unit_system(cgs_unit_system))
161
centimeter/(second**2)
Peter Eastman's avatar
Peter Eastman committed
162
>>> print(u.in_unit_system(md_unit_system))
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
nanometer/(picosecond**2)

Examples

>>> meter.is_compatible(centimeter)
True
>>> meter.is_compatible(meter)     
True
>>> meter.is_compatible(kelvin)
False
>>> meter.is_compatible(meter/second)
False
>>> joule.is_compatible(calorie)
True

Examples

>>> meter.conversion_factor_to(centimeter)
100.0

Peter Eastman's avatar
Peter Eastman committed
183
>>> print((md_kilocalorie/mole/angstrom).conversion_factor_to(md_kilojoule/mole/nanometer))
184
185
186
187
41.84

Examples

Peter Eastman's avatar
Peter Eastman committed
188
>>> print(meter)
189
190
meter

Peter Eastman's avatar
Peter Eastman committed
191
>>> print(meter * second * second * kilogram)
192
kilogram*meter*second**2
Peter Eastman's avatar
Peter Eastman committed
193
>>> print(meter / second / second / kilogram)
194
195
196
197
meter/(kilogram*second**2)

Examples

Peter Eastman's avatar
Peter Eastman committed
198
>>> print(meter**3)
199
meter**3
Peter Eastman's avatar
Peter Eastman committed
200
>>> print(meter**3)
201
202
203
204
205
206
meter**3

>>> meter.get_conversion_factor_to_base_units()
1.0

Simple ScaledUnit in calorie
Peter Eastman's avatar
Peter Eastman committed
207
>>> print(calorie.get_conversion_factor_to_base_units())
208
209
210
4.184

Compound ScaledUnit in md_kilocalorie
Peter Eastman's avatar
Peter Eastman committed
211
>>> print(md_kilocalorie.get_conversion_factor_to_base_units())
212
213
214
4.184

calorie in a more complex unit
Peter Eastman's avatar
Peter Eastman committed
215
>>> print((md_kilocalorie/mole/angstrom).get_conversion_factor_to_base_units())
216
217
218
219
220
4.184

Examples

Create simple Quantities with either the multiply operator or the Quantity constructor.
Peter Eastman's avatar
Peter Eastman committed
221
>>> print(5 * centimeters)
222
5 cm
Peter Eastman's avatar
Peter Eastman committed
223
>>> print(Quantity(value=5, unit=centimeter))
224
5 cm
Peter Eastman's avatar
Peter Eastman committed
225
>>> print(Quantity(5, centimeter))
226
227
228
229
5 cm

Extract the underlying value using either division or the value_in_unit() method.
>>> i = 5 * centimeters
Peter Eastman's avatar
Peter Eastman committed
230
>>> print(i / millimeters)
231
50.0
Peter Eastman's avatar
Peter Eastman committed
232
>>> print(i.value_in_unit(millimeters))
233
234
235
236
50.0

Collections of numbers can also be used as values.
>>> s = [1,2,3] * centimeters
Peter Eastman's avatar
Peter Eastman committed
237
>>> print(s)
238
[1, 2, 3] cm
Peter Eastman's avatar
Peter Eastman committed
239
>>> print(s / millimeters)
240
241
[10.0, 20.0, 30.0]
>>> s2 = [[1,2,3],[4,5,6]] * centimeters
Peter Eastman's avatar
Peter Eastman committed
242
>>> print(s2)
243
[[1, 2, 3], [4, 5, 6]] cm
Peter Eastman's avatar
Peter Eastman committed
244
>>> print(s2 / millimeters)
245
246
[[10.0, 20.0, 30.0], [40.0, 50.0, 60.0]]
>>> s3 = [(1,2,3),(4,5,6)] * centimeters
Peter Eastman's avatar
Peter Eastman committed
247
>>> print(s3)
248
[(1, 2, 3), (4, 5, 6)] cm
Peter Eastman's avatar
Peter Eastman committed
249
>>> print(s3 / millimeters)
250
[(10.0, 20.0, 30.0), (40.0, 50.0, 60.0)]
251
>>> s4 = ((1,2,3),(4,5,6)) * centimeters
Peter Eastman's avatar
Peter Eastman committed
252
>>> print(s4)
253
((1, 2, 3), (4, 5, 6)) cm
Peter Eastman's avatar
Peter Eastman committed
254
>>> print(s4 / millimeters)
255
[(10.0, 20.0, 30.0), (40.0, 50.0, 60.0)]
256
>>> t = (1,2,3) * centimeters
Peter Eastman's avatar
Peter Eastman committed
257
>>> print(t)
258
(1, 2, 3) cm
Peter Eastman's avatar
Peter Eastman committed
259
>>> print(t / millimeters)
260
261
262
263
264
265
[10.0, 20.0, 30.0]

Numpy examples are commented out because not all systems have numpy installed
# >>> import numpy
# >>> 
# >>> a = Quantity(numpy.array([1,2,3]), centimeters)
Peter Eastman's avatar
Peter Eastman committed
266
# >>> print(a)
267
# [1 2 3] cm
Peter Eastman's avatar
Peter Eastman committed
268
# >>> print(a / millimeters)
269
270
271
# [ 10.  20.  30.]
# >>> 
# >>> a2 = Quantity(numpy.array([[1,2,3],[4,5,6]]), centimeters)
Peter Eastman's avatar
Peter Eastman committed
272
# >>> print(a2)
273
274
# [[1 2 3]
#  [4 5 6]] cm
Peter Eastman's avatar
Peter Eastman committed
275
# >>> print(a2 / millimeters)
276
277
278
279
280
281
282
# [[ 10.  20.  30.]
#  [ 40.  50.  60.]]     

Addition, subtraction, multiplication, division, and powers of Quantities
exhibit correct dimensional analysis and unit conversion.
>>> x = 1.3 * meters
>>> y = 75.2 * centimeters
Peter Eastman's avatar
Peter Eastman committed
283
>>> print(x + y)
284
2.052 m
Peter Eastman's avatar
Peter Eastman committed
285
>>> print(x - y)
286
0.548 m
Peter Eastman's avatar
Peter Eastman committed
287
>>> print(x/y)
288
1.72872340426
Peter Eastman's avatar
Peter Eastman committed
289
>>> print(x*y)
290
291
292
293
294
295
296
0.9776 m**2

The following examples are derived from the C++ Boost.Units examples at
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units/Examples.html
>>>
>>> l = 2.0 * meters
>>> 
Peter Eastman's avatar
Peter Eastman committed
297
>>> print(l + 2.0 * nanometers)
298
2.000000002 m
Peter Eastman's avatar
Peter Eastman committed
299
>>> print(2.0 * nanometers + l)
300
301
2000000002.0 nm
>>> 
Peter Eastman's avatar
Peter Eastman committed
302
>>> print(l)
303
2.0 m
Peter Eastman's avatar
Peter Eastman committed
304
>>> print(l+l)
305
4.0 m
Peter Eastman's avatar
Peter Eastman committed
306
>>> print(l-l)
307
0.0 m
Peter Eastman's avatar
Peter Eastman committed
308
>>> print(l*l)
309
4.0 m**2
Peter Eastman's avatar
Peter Eastman committed
310
>>> print(l/l)
311
1.0
Peter Eastman's avatar
Peter Eastman committed
312
>>> print(l * meter)
313
2.0 m**2
Peter Eastman's avatar
Peter Eastman committed
314
>>> print(kilograms * (l/seconds) * (l/seconds))
315
4.0 kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
316
>>> print(kilograms * (l/seconds)**2)
317
4.0 kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
318
>>> print(l ** 3)
319
8.0 m**3
Peter Eastman's avatar
Peter Eastman committed
320
>>> print(l ** (3.0/2.0))
321
2.82842712475 m**1.5
Peter Eastman's avatar
Peter Eastman committed
322
>>> print(l ** 0.5)
323
1.41421356237 m**0.5
Peter Eastman's avatar
Peter Eastman committed
324
>>> print(l ** (2.0/3.0))
325
326
327
1.58740105197 m**0.666667
>>> # complex example
>>> l = (3.0 + 4.0j) * meters
Peter Eastman's avatar
Peter Eastman committed
328
>>> print(l)
329
(3+4j) m
Peter Eastman's avatar
Peter Eastman committed
330
>>> print(l+l)
331
(6+8j) m
Peter Eastman's avatar
Peter Eastman committed
332
>>> print(l-l)
333
0j m
Peter Eastman's avatar
Peter Eastman committed
334
>>> print(l*l)
335
336
337
338
(-7+24j) m**2
>>> # Numerical error yields tiny imaginary component of l/l on linux CentOS5
>>> err = abs(l/l - 1)
>>> assert err < 1e-8
Peter Eastman's avatar
Peter Eastman committed
339
>>> print(l * meter)
340
(3+4j) m**2
Peter Eastman's avatar
Peter Eastman committed
341
>>> print(kilograms * (l/seconds) * (l/seconds))
342
(-7+24j) kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
343
>>> print(kilograms * (l/seconds)**2)
344
(-7+24j) kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
345
>>> print(l ** 3)
346
(-117+44j) m**3
Peter Eastman's avatar
Peter Eastman committed
347
>>> print(l ** (3.0/2.0))
348
(2+11j) m**1.5
Peter Eastman's avatar
Peter Eastman committed
349
>>> print(l ** 0.5)
350
(2+1j) m**0.5
Peter Eastman's avatar
Peter Eastman committed
351
>>> print(l ** (2.0/3.0))
352
353
354
355
356
357
358
359
360
(2.38285471252+1.69466313833j) m**0.666667
>>> # kitchen sink example
... s1 = 2.0
>>> x1 = 2
>>> x2 = 4.0/3.0
>>> u1 = kilogram * meter / second**2
>>> u2 = u1 * meter
>>> q1 = 1.0*u1
>>> q2 = 2.0*u2
Peter Eastman's avatar
Peter Eastman committed
361
>>> print(s1)
362
2.0
Peter Eastman's avatar
Peter Eastman committed
363
>>> print(x1)
364
2
Peter Eastman's avatar
Peter Eastman committed
365
>>> print(x2)
366
1.33333333333
Peter Eastman's avatar
Peter Eastman committed
367
>>> print(u1)
368
kilogram*meter/(second**2)
Peter Eastman's avatar
Peter Eastman committed
369
>>> print(u2)
370
kilogram*meter**2/(second**2)
Peter Eastman's avatar
Peter Eastman committed
371
>>> print(q1)
372
1.0 kg m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
373
>>> print(q2)
374
2.0 kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
375
>>> print(u1*s1)
376
2.0 kg m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
377
>>> print(s1*u1)
378
2.0 kg m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
379
>>> print(u1/s1)
380
0.5 kg m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
381
>>> print(s1/u1)
382
2.0 s**2/(kg m)
Peter Eastman's avatar
Peter Eastman committed
383
>>> print(u1*u1)
384
kilogram**2*meter**2/(second**4)
Peter Eastman's avatar
Peter Eastman committed
385
>>> print(u1/u1)
386
dimensionless
Peter Eastman's avatar
Peter Eastman committed
387
>>> print(u1*u2)
388
kilogram**2*meter**3/(second**4)
Peter Eastman's avatar
Peter Eastman committed
389
>>> print(u1/u2)
390
/meter
Peter Eastman's avatar
Peter Eastman committed
391
>>> print(u1**x1)
392
kilogram**2*meter**2/(second**4)
Peter Eastman's avatar
Peter Eastman committed
393
>>> print(u1**(1.0/x1))
394
kilogram**0.5*meter**0.5/second
Peter Eastman's avatar
Peter Eastman committed
395
>>> print(u1**x2)
396
kilogram**1.33333*meter**1.33333/(second**2.66667)
Peter Eastman's avatar
Peter Eastman committed
397
>>> print(u1**(1.0/x2))
398
399
400
kilogram**0.75*meter**0.75/(second**1.5)
>>> l1 = 1.0*meters
>>> l2 = 2.0*meters
Peter Eastman's avatar
Peter Eastman committed
401
>>> print(l1 == l2)
402
False
Peter Eastman's avatar
Peter Eastman committed
403
>>> print(l1 != l2)
404
True
Peter Eastman's avatar
Peter Eastman committed
405
>>> print(l1 <= l2)
406
True
Peter Eastman's avatar
Peter Eastman committed
407
>>> print(l1 < l2)
408
True
Peter Eastman's avatar
Peter Eastman committed
409
>>> print(l1 >= l2)
410
False
Peter Eastman's avatar
Peter Eastman committed
411
>>> print(l1 > l2)
412
413
414
415
416
417
418
419
420
False
>>> 
>>> def work(f, dx):
...   return f * dx
... 
>>> F = 1.0 * kilogram * meter / second**2
>>> dx = 1.0 * meter
>>> E = work(F, dx)
>>> 
Peter Eastman's avatar
Peter Eastman committed
421
>>> print("F = ", F)
422
F =  1.0 kg m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
423
>>> print("dx = ", dx)
424
425
426
427
dx =  1.0 m
>>> 
>>> def idealGasLaw(P, V, T):
...     R = MOLAR_GAS_CONSTANT_R
Peter Eastman's avatar
Peter Eastman committed
428
429
...     print("P * V = ", P * V)
...     print("R * T = ", R * T)
430
431
432
433
434
435
436
437
438
439
440
...     return (P * V / (R * T)).in_units_of(mole)
... 
>>> T = (273.0 + 37.0) * kelvin
>>> P = 1.01325e5 * pascals
>>> r = 0.5e-6 * meters
>>> V = 4.0/3.0 * 3.14159 * r**3
>>> n = idealGasLaw(P, V, T)
P * V =  5.3053601125e-14 m**3 Pa
R * T =  2577.48646608 J/mol
>>> R = MOLAR_GAS_CONSTANT_R
>>> 
Peter Eastman's avatar
Peter Eastman committed
441
>>> print("r = ", r)
442
r =  5e-07 m
Peter Eastman's avatar
Peter Eastman committed
443
>>> print("P = ", P)
444
P =  101325.0 Pa
Peter Eastman's avatar
Peter Eastman committed
445
>>> print("V = ", V)
446
V =  5.23598333333e-19 m**3
Peter Eastman's avatar
Peter Eastman committed
447
>>> print("T = ", T)
448
T =  310.0 K
Peter Eastman's avatar
Peter Eastman committed
449
>>> print("n = ", n)
450
n =  2.05834644811e-17 mol
Peter Eastman's avatar
Peter Eastman committed
451
>>> print("R = ", R)
452
R =  8.31447247122 J/(K mol)
Peter Eastman's avatar
Peter Eastman committed
453
>>> print("E = ", E)
454
E =  1.0 kg m**2/(s**2)
Peter Eastman's avatar
Peter Eastman committed
455
>>> print("is_quantity(V) = ", is_quantity(V))
456
is_quantity(V) =  True
Peter Eastman's avatar
Peter Eastman committed
457
>>> print((1.0*radians) / degrees)
458
57.2957795131
Peter Eastman's avatar
Peter Eastman committed
459
>>> print((1.0*radians).in_units_of(degrees))
460
57.2957795131 deg
Peter Eastman's avatar
Peter Eastman committed
461
>>> print((1.0*angstroms).in_units_of(nanometers))
462
463
0.1 nm
>>> 
Peter Eastman's avatar
Peter Eastman committed
464
>>> print((90*degrees)/radians)
465
1.57079632679
Peter Eastman's avatar
Peter Eastman committed
466
>>> print(sin(90*degrees))
467
468
469
1.0
>>> x = 90 * degrees
>>> x += 0.3 * radians
Peter Eastman's avatar
Peter Eastman committed
470
>>> print(x)
471
107.188733854 deg
Peter Eastman's avatar
Peter Eastman committed
472
>>> print(1 * nanometers > 1 * angstroms)
473
True
Peter Eastman's avatar
Peter Eastman committed
474
>>> print(1 * nanometers > 1 * degrees)
475
476
477
478
479
Traceback (most recent call last):
   ...
TypeError: Unit "degree" is not compatible with Unit "nanometer".
>>> 
>>> x = 1.5 * nanometers
Peter Eastman's avatar
Peter Eastman committed
480
>>> print(x / meters)
481
482
1.5e-09
>>> x = 1.5 * angstroms
Peter Eastman's avatar
Peter Eastman committed
483
>>> print(x / meters)
484
1.5e-10
Peter Eastman's avatar
Peter Eastman committed
485
>>> print(x / nanometers)
486
487
488
489
0.15

Examples

Peter Eastman's avatar
Peter Eastman committed
490
>>> print(is_quantity(meters))
491
False
Peter Eastman's avatar
Peter Eastman committed
492
>>> print(is_quantity(2.3*meters))
493
True
Peter Eastman's avatar
Peter Eastman committed
494
>>> print(is_quantity(2.3))
495
496
497
498
499
False

Examples

>>> x = 100.0 * millimeter
Peter Eastman's avatar
Peter Eastman committed
500
>>> print(x.value_in_unit_system(si_unit_system))
501
0.1
Peter Eastman's avatar
Peter Eastman committed
502
>>> print(x.value_in_unit_system(cgs_unit_system))
503
10.0
Peter Eastman's avatar
Peter Eastman committed
504
>>> print(x.value_in_unit_system(md_unit_system))
505
506
507
100000000.0
>>> 
>>> y = 20 * millimeters / millisecond**2
Peter Eastman's avatar
Peter Eastman committed
508
>>> print(y.value_in_unit_system(si_unit_system))
509
20000.0
Peter Eastman's avatar
Peter Eastman committed
510
>>> print(y.value_in_unit_system(cgs_unit_system))
511
2000000.0
Peter Eastman's avatar
Peter Eastman committed
512
>>> print(y.value_in_unit_system(md_unit_system))
513
514
515
2e-11
>>> eps = Quantity(1.0, md_kilocalorie/mole)
>>> epsQ = eps.value_in_unit_system(md_unit_system)
Peter Eastman's avatar
Peter Eastman committed
516
>>> print(epsQ)
517
518
519
520
521
522
523
524
525
4.184

Dimensionless quantities return their unmodified values.
>>> Quantity(5, dimensionless).value_in_unit_system(md_unit_system)
5
        
Examples

>>> x = 2.3*meters
Peter Eastman's avatar
Peter Eastman committed
526
>>> print(x.value_in_unit(centimeters))
527
528
529
530
230.0

Examples

Peter Eastman's avatar
Peter Eastman committed
531
>>> print(bool(2.3*meters))
532
True
Peter Eastman's avatar
Peter Eastman committed
533
>>> print(bool(0*meters))
534
535
536
537
538
False


Examples

Peter Eastman's avatar
Peter Eastman committed
539
>>> print(-(2.3*meters))
540
-2.3 m
Peter Eastman's avatar
Peter Eastman committed
541
>>> print(-(-2.3*meters))
542
543
544
545
2.3 m

Examples

Peter Eastman's avatar
Peter Eastman committed
546
>>> print(+(2.3*meters))
547
548
549
550
2.3 m

Examples

Peter Eastman's avatar
Peter Eastman committed
551
>>> print(abs(-2.3*meters))
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
2.3 m

>>> (9.0*meter*meter).sqrt()
Quantity(value=3.0, unit=meter)
>>> (9.0*meter).sqrt()
Traceback (most recent call last):
  ...
ArithmeticError: Exponents in Unit.sqrt() must be even.
>>> (9.0*meter*meter*meter).sqrt()
Traceback (most recent call last):
  ...
ArithmeticError: Exponents in Unit.sqrt() must be even.
>>> (9.0*meter*meter/second/second).sqrt()
Quantity(value=3.0, unit=meter/second)

Mixture of BaseUnits and ScaledUnits should cause no trouble:
>>> sqrt(1.0 * kilogram * joule)
Quantity(value=1.0, unit=kilogram*meter/second)
>>> sqrt(1.0 * kilogram * calorie)
Quantity(value=2.0454828280872954, unit=kilogram*meter/second)

Examples

Peter Eastman's avatar
Peter Eastman committed
575
>>> print((2.3*meters)**2)
576
577
578
579
580
5.29 m**2

Examples

>>> x = 4.2 * centimeters
Peter Eastman's avatar
Peter Eastman committed
581
>>> print(8.4 / x)
582
583
584
585
586
587
2.0 /cm

        
        Examples
        
        >>> x = 4.3 * meters
Peter Eastman's avatar
Peter Eastman committed
588
        >>> print(x/centimeters)
589
        430.0
Peter Eastman's avatar
Peter Eastman committed
590
        >>> print(x/seconds)
591
592
593
594
595
596
597
598
599
        4.3 m/s
        >>> x = [1,2,3]*centimeter
        >>> x/millimeter
        [10.0, 20.0, 30.0]

        
        Examples
        
        >>> x = 1.2*meters
Peter Eastman's avatar
Peter Eastman committed
600
        >>> print(5*x)
601
602
603
604
605
606
        6.0 m
        
        Examples
        
        >>> x = 1.2*meters
        >>> y = 72*centimeters
Peter Eastman's avatar
Peter Eastman committed
607
        >>> print(x*y)
608
609
610
611
612
613
614
615
        0.864 m**2
        >>> x = [1,2,3]*centimeter
        >>> x
        Quantity(value=[1, 2, 3], unit=centimeter)
        >>> x * meter
        Quantity(value=[100.0, 200.0, 300.0], unit=centimeter**2)

        >>> u = nanometer**2/angstrom**2
Peter Eastman's avatar
Peter Eastman committed
616
        >>> print(u)
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
        nanometer**2/(angstrom**2)
        >>> q = Quantity(2.0, u)
        >>> q
        Quantity(value=2.0, unit=nanometer**2/(angstrom**2))
        >>> "%.1f" % q.reduce_unit()
        '200.0'
        
        Examples
        
        >>> 1.2*meters < 72*centimeters
        False
        >>> meter != None
        True
        >>> meter == None
        False
        
        Examples
        
Peter Eastman's avatar
Peter Eastman committed
635
        >>> print(1.2 * meters - 72 * centimeters)
636
637
638
639
        0.48 m
        
        Examples
        
Peter Eastman's avatar
Peter Eastman committed
640
        >>> print(1.2 * meters + 72 * centimeters)
641
642
643
644
        1.92 m
        
        Examples
        
Peter Eastman's avatar
Peter Eastman committed
645
        >>> print(repr(1.2*meter))
646
647
648
649
650
        Quantity(value=1.2, unit=meter)

        
        Examples
        
Peter Eastman's avatar
Peter Eastman committed
651
        >>> print(5.0 * nanometers)
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
        5.0 nm
        
        Examples
        
        >>> Quantity(5.0, meters)
        Quantity(value=5.0, unit=meter)
        
        >>> Quantity([1*angstrom,2*nanometer,3*angstrom])
        Quantity(value=[1, 20.0, 3], unit=angstrom)
        >>> Quantity((1,2,3))
        Quantity(value=(1, 2, 3), unit=dimensionless)
        >>> Quantity([1*angstrom,2*nanometer,3*angstrom])
        Quantity(value=[1, 20.0, 3], unit=angstrom)
        >>> Quantity([1*angstrom,2*nanometer,3*second])
        Traceback (most recent call last):
          ...
        TypeError: Unit "second" is not compatible with Unit "angstrom".
        >>> Quantity(5)
        Quantity(value=5, unit=dimensionless)

        Passing a unit to the constructor yields a Quantity with an empty list value.
        >>> Quantity(angstrom)
        Quantity(value=[], unit=angstrom)

        >>> Quantity(5*angstrom)
        Quantity(value=5, unit=angstrom)
        >>> Quantity(([1*angstrom,2*nanometer,3*angstrom], [1*angstrom,4*nanometer,3*angstrom]))
        Quantity(value=([1, 20.0, 3], [1, 40.0, 3]), unit=angstrom)
        >>> Quantity([])
        Quantity(value=[], unit=dimensionless)

        A simple scalar Quantity can be used as the unit argument.
        >>> Quantity(value=5.0, unit=100.0*meters)
        Quantity(value=500.0, unit=meter)

        
        Examples
        
        >>> x = 2.3*meters
        >>> y = x.in_units_of(centimeters)
Peter Eastman's avatar
Peter Eastman committed
692
        >>> print(y)
693
694
695
        230.0 cm
        
        >>> x = 2.3*meters
Peter Eastman's avatar
Peter Eastman committed
696
        >>> print(x.in_units_of(centimeters))
697
        230.0 cm
Peter Eastman's avatar
Peter Eastman committed
698
        >>> print(x.in_units_of(seconds))
699
700
701
702
703
704
705
        Traceback (most recent call last):
           ...
        TypeError: Unit "meter" is not compatible with Unit "second".
        
        Examples
        
        >>> x = 100.0 * millimeter
Peter Eastman's avatar
Peter Eastman committed
706
        >>> print(x)
707
        100.0 mm
Peter Eastman's avatar
Peter Eastman committed
708
        >>> print(x.in_unit_system(si_unit_system))
709
        0.1 m
Peter Eastman's avatar
Peter Eastman committed
710
        >>> print(x.in_unit_system(cgs_unit_system))
711
        10.0 cm
Peter Eastman's avatar
Peter Eastman committed
712
        >>> print(x.in_unit_system(md_unit_system))
713
714
        100000000.0 nm
        >>> y = 20 * millimeters / millisecond**2
Peter Eastman's avatar
Peter Eastman committed
715
        >>> print(y)
716
        20 mm/(ms**2)
Peter Eastman's avatar
Peter Eastman committed
717
        >>> print(y.in_unit_system(si_unit_system))
718
        20000.0 m/(s**2)
Peter Eastman's avatar
Peter Eastman committed
719
        >>> print(y.in_unit_system(cgs_unit_system))
720
        2000000.0 cm/(s**2)
Peter Eastman's avatar
Peter Eastman committed
721
        >>> print(y.in_unit_system(md_unit_system))
722
723
724
725
        2e-11 nm/(ps**2)

        Sometimes mixed internal units have caused trouble:
        >>> q = 1.0 * md_kilocalorie/mole/angstrom
Peter Eastman's avatar
Peter Eastman committed
726
        >>> print(q.in_units_of(md_kilojoule/mole/nanometer))
727
728
729
730
731
732
        41.84 kJ/(nm mol)
        
        Examples
        
        >>> class Foo:
        ...     def bar(self):
Peter Eastman's avatar
Peter Eastman committed
733
        ...         print("bar")
734
735
736
737
738
739
740
741
742
743
        ... 
        >>> x = Foo()
        >>> x.bar()
        bar
        >>> y = x * nanometers
        >>> y.bar()
        bar
    
    Examples
    
Peter Eastman's avatar
Peter Eastman committed
744
    >>> print(meters * centimeters)
745
    centimeter*meter
Peter Eastman's avatar
Peter Eastman committed
746
    >>> print(meters * meters)
747
    meter**2
Peter Eastman's avatar
Peter Eastman committed
748
    >>> print(meter * meter )
749
750
751
752
753
    meter**2

    
    Examples
    
Peter Eastman's avatar
Peter Eastman committed
754
    >>> print(meter / 2)
755
756
757
758
759
760
    0.5 m
     
    Examples
     
    >>> define_prefixed_units(kelvin_base_unit, sys.modules["__main__"])
    >>> from __main__ import millikelvin
Peter Eastman's avatar
Peter Eastman committed
761
    >>> print(5.0 * millikelvin)
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
    5.0 mK
    
        
        Creating a new BaseUnit:
        >>> ms = milli * second_base_unit
        >>> ms
        BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms")
        >>> ms.conversion_factor_to(second_base_unit)
        0.001
        
        Creating a new ScaledUnit:
        >>> mC = milli * ScaledUnit(4.184, joule, "calorie", "cal")
        >>> mC
        ScaledUnit(factor=0.0041840000000000002, master=joule, name='millicalorie', symbol='mcal')
        
        Creating a new Unit:
        >>> ms = milli * second
        >>> ms
        Unit({BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms"): 1.0})
        
        Don't try a Quantity though:
        >>> ms = milli * (1.0 * second)
        Traceback (most recent call last):
           ...
        TypeError: Unit prefix "milli" can only be applied to a Unit, BaseUnit, or ScaledUnit.
        
    Comparison of dimensionless quantities issue (fixed in svn 513)
    >>> x = Quantity(1.0, dimensionless)
    >>> y = Quantity(1.0, dimensionless)
    >>> assert not x is y
    >>> assert x == y


    Formatting of Quantities
    >>> x = 5.439999999 * picosecond
    >>> x
    Quantity(value=5.4399999990000003, unit=picosecond)
    >>> x.format("%.3f")
    '5.440 ps'

    # Bug report Dec 17, 2009 from John Chodera
    # deepcopy of Quantity containing numpy array wrongly strips units
    >>> try:
    ...     import numpy
    ...     import copy
    ...     x = Quantity(numpy.zeros([2,3]), nanometer)
    ...     y = copy.deepcopy(x)
    ...     assert x[0][0] == y[0][0]
    ... except ImportError:
    ...     pass

    # Passing a string through Quantity constructor should return a string/dimensionless
    >>> x = Quantity("string").value_in_unit_system(md_unit_system)
    >>> assert x == "string"

# Trouble with complicated unit conversion factors
# Jan 29 1010 email from John Chodera
>>> p1 = 1.0 * atmosphere
>>> p2 = (1.0 * atmosphere).in_units_of(joule/nanometer**3)
>>> V = 2.4 * nanometer**3
>>> beta = 4.e-4 * mole/joule
>>> x1 = beta*p1*V
Peter Eastman's avatar
Peter Eastman committed
824
>>> # print(x1)
825
... y1 = x1 * AVOGADRO_CONSTANT_NA
Peter Eastman's avatar
Peter Eastman committed
826
>>> print(y1)
827
828
829
830
831
0.0585785776197

# Wrong answer is 5.85785776197e+25

>>> x2 = beta*p2*V
Peter Eastman's avatar
Peter Eastman committed
832
>>> # print(x2)
833
... y2 = x2 * AVOGADRO_CONSTANT_NA
Peter Eastman's avatar
Peter Eastman committed
834
>>> print(y2)
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
0.0585785776197
>>> assert( abs(y1 - y2) < 0.01)

# division of numpy arrays error
# April 2010, thanks to John Chodera for reporting
    >>> try:
    ...     import numpy
    ...     x = Quantity(numpy.array([1.,2.]), nanometer)            
    ...     y = Quantity(numpy.array([3.,4.]), picosecond)
    ...     assert str(x/y) == '[ 0.33333333  0.5       ] nm/ps'
    ... except ImportError:
    ...     pass


# another numpy problem from retarded implementation of == operator
# Thanks to Kyle Beauchamp July 2010
    >>> try:
    ...    import numpy
    ...    from simtk.unit.quantity import _is_string
    ...    a = numpy.array([[1,2,3],[4,5,6]])
    ...    assert isinstance("", str)
    ...    assert _is_string("")
    ...    assert _is_string("t")
    ...    assert _is_string("test")
    ...    assert not _is_string(3)
    ...    assert not _is_string(a)
    ... except ImportError:
    ...    pass

"""

Peter Eastman's avatar
Peter Eastman committed
866
867
from __future__ import print_function

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
__author__ = "Christopher M. Bruns"
__version__ = "0.5"

# This unit code might be found in different packages...
# So use local import
from baseunit import BaseUnit
from standard_dimensions import *
from unit import is_unit, dimensionless
from quantity import Quantity, is_quantity, is_dimensionless
from unit_definitions import *
from unit_math import *
from constants import *

# run module directly for testing
if __name__=='__main__':
    # Test the examples in the docstrings
    import doctest, sys
    (failed, passed) = doctest.testmod(sys.modules[__name__])
    # For use in automated testing, return number of failed tests as exit code
    exit(failed)