doctests.py 21.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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
Justin MacCallum's avatar
Justin MacCallum committed
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
Justin MacCallum's avatar
Justin MacCallum committed
35

36
37
38
>>> 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
nanometer/(picosecond**2)

Examples

>>> meter.is_compatible(centimeter)
True
Justin MacCallum's avatar
Justin MacCallum committed
169
>>> meter.is_compatible(meter)
170
171
172
173
174
175
176
177
178
179
180
181
182
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
[10.0, 20.0, 30.0]

Numpy examples are commented out because not all systems have numpy installed
# >>> import numpy
Justin MacCallum's avatar
Justin MacCallum committed
264
# >>>
265
# >>> 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
# [ 10.  20.  30.]
Justin MacCallum's avatar
Justin MacCallum committed
270
# >>>
271
# >>> 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
# [[ 10.  20.  30.]
Justin MacCallum's avatar
Justin MacCallum committed
277
#  [ 40.  50.  60.]]
278
279
280
281
282

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
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
Justin MacCallum's avatar
Justin MacCallum committed
296
>>>
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
2000000002.0 nm
Justin MacCallum's avatar
Justin MacCallum committed
301
>>>
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
False
Justin MacCallum's avatar
Justin MacCallum committed
413
>>>
414
415
>>> def work(f, dx):
...   return f * dx
Justin MacCallum's avatar
Justin MacCallum committed
416
...
417
418
419
>>> F = 1.0 * kilogram * meter / second**2
>>> dx = 1.0 * meter
>>> E = work(F, dx)
Justin MacCallum's avatar
Justin MacCallum committed
420
>>>
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
dx =  1.0 m
Justin MacCallum's avatar
Justin MacCallum committed
425
>>>
426
427
>>> 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
...     return (P * V / (R * T)).in_units_of(mole)
Justin MacCallum's avatar
Justin MacCallum committed
431
...
432
433
434
435
436
437
438
439
>>> 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
Justin MacCallum's avatar
Justin MacCallum committed
440
>>>
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
0.1 nm
Justin MacCallum's avatar
Justin MacCallum committed
463
>>>
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
Traceback (most recent call last):
   ...
TypeError: Unit "degree" is not compatible with Unit "nanometer".
Justin MacCallum's avatar
Justin MacCallum committed
478
>>>
479
>>> 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
100000000.0
Justin MacCallum's avatar
Justin MacCallum committed
506
>>>
507
>>> 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
4.184

Dimensionless quantities return their unmodified values.
>>> Quantity(5, dimensionless).value_in_unit_system(md_unit_system)
5
Justin MacCallum's avatar
Justin MacCallum committed
522

523
524
525
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
2.0 /cm

Justin MacCallum's avatar
Justin MacCallum committed
584

585
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
586

587
        >>> 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
        4.3 m/s
        >>> x = [1,2,3]*centimeter
        >>> x/millimeter
        [10.0, 20.0, 30.0]

Justin MacCallum's avatar
Justin MacCallum committed
596

597
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
598

599
        >>> x = 1.2*meters
Peter Eastman's avatar
Peter Eastman committed
600
        >>> print(5*x)
601
        6.0 m
Justin MacCallum's avatar
Justin MacCallum committed
602

603
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
604

605
606
        >>> 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
        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'
Justin MacCallum's avatar
Justin MacCallum committed
623

624
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
625

626
627
628
629
630
631
        >>> 1.2*meters < 72*centimeters
        False
        >>> meter != None
        True
        >>> meter == None
        False
Justin MacCallum's avatar
Justin MacCallum committed
632

633
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
634

Peter Eastman's avatar
Peter Eastman committed
635
        >>> print(1.2 * meters - 72 * centimeters)
636
        0.48 m
Justin MacCallum's avatar
Justin MacCallum committed
637

638
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
639

Peter Eastman's avatar
Peter Eastman committed
640
        >>> print(1.2 * meters + 72 * centimeters)
641
        1.92 m
Justin MacCallum's avatar
Justin MacCallum committed
642

643
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
644

Peter Eastman's avatar
Peter Eastman committed
645
        >>> print(repr(1.2*meter))
646
647
        Quantity(value=1.2, unit=meter)

Justin MacCallum's avatar
Justin MacCallum committed
648

649
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
650

Peter Eastman's avatar
Peter Eastman committed
651
        >>> print(5.0 * nanometers)
652
        5.0 nm
Justin MacCallum's avatar
Justin MacCallum committed
653

654
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
655

656
657
        >>> Quantity(5.0, meters)
        Quantity(value=5.0, unit=meter)
Justin MacCallum's avatar
Justin MacCallum committed
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
        >>> 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)

Justin MacCallum's avatar
Justin MacCallum committed
687

688
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
689

690
691
        >>> x = 2.3*meters
        >>> y = x.in_units_of(centimeters)
Peter Eastman's avatar
Peter Eastman committed
692
        >>> print(y)
693
        230.0 cm
Justin MacCallum's avatar
Justin MacCallum committed
694

695
        >>> 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
        Traceback (most recent call last):
           ...
        TypeError: Unit "meter" is not compatible with Unit "second".
Justin MacCallum's avatar
Justin MacCallum committed
702

703
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
704

705
        >>> 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
        41.84 kJ/(nm mol)
Justin MacCallum's avatar
Justin MacCallum committed
728

729
        Examples
Justin MacCallum's avatar
Justin MacCallum committed
730

731
732
        >>> class Foo:
        ...     def bar(self):
Peter Eastman's avatar
Peter Eastman committed
733
        ...         print("bar")
Justin MacCallum's avatar
Justin MacCallum committed
734
        ...
735
736
737
738
739
740
        >>> x = Foo()
        >>> x.bar()
        bar
        >>> y = x * nanometers
        >>> y.bar()
        bar
Justin MacCallum's avatar
Justin MacCallum committed
741

742
    Examples
Justin MacCallum's avatar
Justin MacCallum committed
743

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
    meter**2

Justin MacCallum's avatar
Justin MacCallum committed
751

752
    Examples
Justin MacCallum's avatar
Justin MacCallum committed
753

Peter Eastman's avatar
Peter Eastman committed
754
    >>> print(meter / 2)
755
    0.5 m
Justin MacCallum's avatar
Justin MacCallum committed
756

757
    Examples
Justin MacCallum's avatar
Justin MacCallum committed
758

759
760
    >>> 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
    5.0 mK
Justin MacCallum's avatar
Justin MacCallum committed
763
764


765
766
767
768
769
770
        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
Justin MacCallum's avatar
Justin MacCallum committed
771

772
773
774
775
        Creating a new ScaledUnit:
        >>> mC = milli * ScaledUnit(4.184, joule, "calorie", "cal")
        >>> mC
        ScaledUnit(factor=0.0041840000000000002, master=joule, name='millicalorie', symbol='mcal')
Justin MacCallum's avatar
Justin MacCallum committed
776

777
778
779
780
        Creating a new Unit:
        >>> ms = milli * second
        >>> ms
        Unit({BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms"): 1.0})
Justin MacCallum's avatar
Justin MacCallum committed
781

782
783
784
785
786
        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.
Justin MacCallum's avatar
Justin MacCallum committed
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
    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
0.0585785776197
>>> assert( abs(y1 - y2) < 0.01)

# division of numpy arrays error
# April 2010, thanks to John Chodera for reporting
    >>> try:
    ...     import numpy
Justin MacCallum's avatar
Justin MacCallum committed
842
    ...     x = Quantity(numpy.array([1.,2.]), nanometer)
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
    ...     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)