1# -*- coding: utf-8 -*- 2""" 3Test symbolic unit handling. 4 5 6 7 8""" 9 10# ----------------------------------------------------------------------------- 11# Copyright (c) 2018, yt Development Team. 12# 13# Distributed under the terms of the Modified BSD License. 14# 15# The full license is in the LICENSE file, distributed with this software. 16# ----------------------------------------------------------------------------- 17 18 19import numpy as np 20from numpy.testing import ( 21 assert_almost_equal, 22 assert_allclose, 23 assert_array_almost_equal_nulp, 24 assert_equal, 25) 26import operator 27import pickle 28import pytest 29from sympy import Symbol 30 31from unyt.array import unyt_quantity 32from unyt.testing import assert_allclose_units 33from unyt.unit_registry import UnitRegistry 34from unyt.dimensions import ( 35 mass, 36 length, 37 time, 38 temperature, 39 energy, 40 magnetic_field_cgs, 41 magnetic_field_mks, 42 power, 43 rate, 44) 45from unyt.exceptions import InvalidUnitOperation, UnitsNotReducible, UnitConversionError 46from unyt.unit_object import default_unit_registry, Unit, UnitParseError 47from unyt.unit_systems import cgs_unit_system, UnitSystem 48from unyt._unit_lookup_table import ( 49 default_unit_symbol_lut, 50 name_alternatives, 51 unit_prefixes, 52) 53import unyt.unit_symbols as unit_symbols 54from unyt._physical_ratios import ( 55 m_per_pc, 56 sec_per_year, 57 m_per_km, 58 m_per_mpc, 59 mass_sun_kg, 60) 61 62 63def test_no_conflicting_symbols(): 64 """ 65 Check unit symbol definitions for conflicts. 66 67 """ 68 full_set = set(default_unit_symbol_lut.keys()) 69 70 # go through all possible prefix combos 71 for symbol in default_unit_symbol_lut.keys(): 72 if default_unit_symbol_lut[symbol][4]: 73 keys = unit_prefixes.keys() 74 else: 75 keys = [symbol] 76 for prefix in keys: 77 new_symbol = "%s%s" % (prefix, symbol) 78 79 # test if we have seen this symbol 80 assert new_symbol not in full_set, "Duplicate symbol: %s" % new_symbol 81 82 full_set.add(new_symbol) 83 84 85def test_dimensionless(): 86 """ 87 Create dimensionless unit and check attributes. 88 89 """ 90 u1 = Unit() 91 92 assert u1.is_dimensionless 93 assert u1.expr == 1 94 assert u1.base_value == 1 95 assert u1.dimensions == 1 96 assert u1 != "hello!" 97 assert (u1 == "hello") is False 98 99 u2 = Unit("") 100 101 assert u2.is_dimensionless 102 assert u2.expr == 1 103 assert u2.base_value == 1 104 assert u2.dimensions == 1 105 106 assert_equal(u1.latex_repr, "") 107 assert_equal(u2.latex_repr, "") 108 109 110def test_create_from_string(): 111 """ 112 Create units with strings and check attributes. 113 114 """ 115 116 u1 = Unit("kg * m**2 * s**-2") 117 assert u1.dimensions == energy 118 assert u1.base_value == 1.0 119 120 # make sure order doesn't matter 121 u2 = Unit("m**2 * s**-2 * kg") 122 assert u2.dimensions == energy 123 assert u2.base_value == 1.0 124 125 # Test rationals 126 u3 = Unit("kg**0.5 * m**-0.5 * s**-1") 127 assert u3.dimensions == magnetic_field_cgs 128 assert u3.base_value == 1.0 129 130 # sqrt functions 131 u4 = Unit("sqrt(kg)/sqrt(m)/s") 132 assert u4.dimensions == magnetic_field_cgs 133 assert u4.base_value == 1.0 134 135 # commutative sqrt function 136 u5 = Unit("sqrt(kg/m)/s") 137 assert u5.dimensions == magnetic_field_cgs 138 assert u5.base_value == 1.0 139 140 # nonzero CGS conversion factor 141 u6 = Unit("Msun/pc**3") 142 assert u6.dimensions == mass / length ** 3 143 assert_array_almost_equal_nulp( 144 np.array([u6.base_value]), np.array([mass_sun_kg / m_per_pc ** 3]) 145 ) 146 147 with pytest.raises(UnitParseError): 148 Unit("m**m") 149 with pytest.raises(UnitParseError): 150 Unit("m**g") 151 with pytest.raises(UnitParseError): 152 Unit("m+g") 153 with pytest.raises(UnitParseError): 154 Unit("m-g") 155 with pytest.raises(UnitParseError): 156 Unit("hello!") 157 with pytest.raises(UnitParseError): 158 Unit("True") 159 with pytest.raises(UnitParseError): 160 Unit("else") 161 with pytest.raises(UnitParseError): 162 Unit("hello(37)") 163 with pytest.raises(UnitParseError): 164 Unit("hello(foo=37)") 165 166 cm = Unit("cm") 167 data = 1 * cm 168 169 assert Unit(data) == cm 170 assert Unit(b"cm") == cm 171 172 173def test_create_from_expr(): 174 """ 175 Create units from sympy Exprs and check attributes. 176 177 """ 178 pc_mks = m_per_pc 179 yr_mks = sec_per_year 180 181 # Symbol expr 182 s1 = Symbol("pc", positive=True) 183 s2 = Symbol("yr", positive=True) 184 # Mul expr 185 s3 = s1 * s2 186 # Pow expr 187 s4 = s1 ** 2 * s2 ** (-1) 188 189 u1 = Unit(s1) 190 u2 = Unit(s2) 191 u3 = Unit(s3) 192 u4 = Unit(s4) 193 194 assert u1.expr == s1 195 assert u2.expr == s2 196 assert u3.expr == s3 197 assert u4.expr == s4 198 199 assert_allclose_units(u1.base_value, pc_mks, 1e-12) 200 assert_allclose_units(u2.base_value, yr_mks, 1e-12) 201 assert_allclose_units(u3.base_value, pc_mks * yr_mks, 1e-12) 202 assert_allclose_units(u4.base_value, pc_mks ** 2 / yr_mks, 1e-12) 203 204 assert u1.dimensions == length 205 assert u2.dimensions == time 206 assert u3.dimensions == length * time 207 assert u4.dimensions == length ** 2 / time 208 209 210def test_create_with_duplicate_dimensions(): 211 """ 212 Create units with overlapping dimensions. Ex: km/Mpc. 213 214 """ 215 216 u1 = Unit("J * s**-1") 217 u2 = Unit("km/s/Mpc") 218 km_mks = m_per_km 219 Mpc_mks = m_per_mpc 220 221 assert u1.base_value == 1 222 assert u1.dimensions == power 223 224 assert_allclose_units(u2.base_value, km_mks / Mpc_mks, 1e-12) 225 assert u2.dimensions == rate 226 227 228def test_create_new_symbol(): 229 """ 230 Create unit with unknown symbol. 231 232 """ 233 u1 = Unit("abc", base_value=42, dimensions=(mass / time)) 234 235 assert u1.expr == Symbol("abc", positive=True) 236 assert u1.base_value == 42 237 assert u1.dimensions == mass / time 238 239 u1 = Unit("abc", base_value=42, dimensions=length ** 3) 240 241 assert u1.expr == Symbol("abc", positive=True) 242 assert u1.base_value == 42 243 assert u1.dimensions == length ** 3 244 245 u1 = Unit("abc", base_value=42, dimensions=length * (mass * length)) 246 247 assert u1.expr == Symbol("abc", positive=True) 248 assert u1.base_value == 42 249 assert u1.dimensions == length ** 2 * mass 250 251 with pytest.raises(UnitParseError): 252 Unit("abc", base_value=42, dimensions=length ** length) 253 with pytest.raises(UnitParseError): 254 Unit("abc", base_value=42, dimensions=length ** (length * length)) 255 with pytest.raises(UnitParseError): 256 Unit("abc", base_value=42, dimensions=length - mass) 257 with pytest.raises(UnitParseError): 258 Unit("abc", base_value=42, dimensions=length + mass) 259 260 261def test_create_fail_on_unknown_symbol(): 262 """ 263 Fail to create unit with unknown symbol, without base_value and dimensions. 264 265 """ 266 with pytest.raises(UnitParseError): 267 Unit(Symbol("jigawatts")) 268 269 270def test_create_fail_on_bad_symbol_type(): 271 """ 272 Fail to create unit with bad symbol type. 273 274 """ 275 with pytest.raises(UnitParseError): 276 Unit([1]) # something other than Expr and str 277 278 279def test_create_fail_on_bad_dimensions_type(): 280 """ 281 Fail to create unit with bad dimensions type. 282 283 """ 284 with pytest.raises(UnitParseError): 285 Unit("a", base_value=1, dimensions="(mass)") 286 287 288def test_create_fail_on_dimensions_content(): 289 """ 290 Fail to create unit with bad dimensions expr. 291 292 """ 293 a = Symbol("a") 294 with pytest.raises(UnitParseError): 295 Unit("a", base_value=1, dimensions=a) 296 297 298def test_create_fail_on_base_value_type(): 299 """ 300 Fail to create unit with bad base_value type. 301 302 """ 303 with pytest.raises(UnitParseError): 304 Unit("a", base_value="a", dimensions=(mass / time)) 305 306 307def test_string_representation(): 308 """ 309 Check unit string representation. 310 311 """ 312 pc = Unit("pc") 313 Myr = Unit("Myr") 314 speed = pc / Myr 315 dimensionless = Unit() 316 317 assert str(pc) == "pc" 318 assert str(Myr) == "Myr" 319 assert str(speed) == "pc/Myr" 320 assert repr(speed) == "pc/Myr" 321 assert str(dimensionless) == "dimensionless" 322 assert repr(dimensionless) == "(dimensionless)" 323 324 325def test_multiplication(): 326 """ 327 Multiply two units. 328 329 """ 330 msun_mks = mass_sun_kg 331 pc_mks = m_per_pc 332 333 # Create symbols 334 msun_sym = Symbol("Msun", positive=True) 335 pc_sym = Symbol("pc", positive=True) 336 s_sym = Symbol("s", positive=True) 337 338 # Create units 339 u1 = Unit("Msun") 340 u2 = Unit("pc") 341 342 # Mul operation 343 u3 = u1 * u2 344 345 assert u3.expr == msun_sym * pc_sym 346 assert_allclose_units(u3.base_value, msun_mks * pc_mks, 1e-12) 347 assert u3.dimensions == mass * length 348 349 # Pow and Mul operations 350 u4 = Unit("pc**2") 351 u5 = Unit("Msun * s") 352 353 u6 = u4 * u5 354 355 assert u6.expr == pc_sym ** 2 * msun_sym * s_sym 356 assert_allclose_units(u6.base_value, pc_mks ** 2 * msun_mks, 1e-12) 357 assert u6.dimensions == length ** 2 * mass * time 358 359 360def test_division(): 361 """ 362 Divide two units. 363 364 """ 365 pc_mks = m_per_pc 366 km_mks = m_per_km 367 368 # Create symbols 369 pc_sym = Symbol("pc", positive=True) 370 km_sym = Symbol("km", positive=True) 371 s_sym = Symbol("s", positive=True) 372 373 # Create units 374 u1 = Unit("pc") 375 u2 = Unit("km * s") 376 377 u3 = u1 / u2 378 379 assert u3.expr == pc_sym / (km_sym * s_sym) 380 assert_allclose_units(u3.base_value, pc_mks / km_mks, 1e-12) 381 assert u3.dimensions == 1 / time 382 383 384def test_power(): 385 """ 386 Take units to some power. 387 388 """ 389 from sympy import nsimplify 390 391 pc_mks = m_per_pc 392 mK_mks = 1e-3 393 u1_dims = mass * length ** 2 * time ** -3 * temperature ** 4 394 u1 = Unit("kg * pc**2 * s**-3 * mK**4") 395 396 u2 = u1 ** 2 397 398 assert u2.dimensions == u1_dims ** 2 399 assert_allclose_units(u2.base_value, (pc_mks ** 2 * mK_mks ** 4) ** 2, 1e-12) 400 401 u3 = u1 ** (-1.0 / 3) 402 403 assert u3.dimensions == nsimplify(u1_dims ** (-1.0 / 3)) 404 assert_allclose_units( 405 u3.base_value, (pc_mks ** 2 * mK_mks ** 4) ** (-1.0 / 3), 1e-12 406 ) 407 408 409def test_equality(): 410 """ 411 Check unit equality with different symbols, but same dimensions and 412 base_value. 413 414 """ 415 u1 = Unit("km * s**-1") 416 u2 = Unit("m * ms**-1") 417 418 assert u1 == u2 419 assert u1.copy() == u2 420 421 422def test_invalid_operations(): 423 u1 = Unit("cm") 424 u2 = Unit("m") 425 426 with pytest.raises(InvalidUnitOperation): 427 u1 + u2 428 with pytest.raises(InvalidUnitOperation): 429 u1 += u2 430 with pytest.raises(InvalidUnitOperation): 431 1 + u1 432 with pytest.raises(InvalidUnitOperation): 433 u1 + 1 434 with pytest.raises(InvalidUnitOperation): 435 u1 - u2 436 with pytest.raises(InvalidUnitOperation): 437 u1 -= u2 438 with pytest.raises(InvalidUnitOperation): 439 1 - u1 440 with pytest.raises(InvalidUnitOperation): 441 u1 - 1 442 with pytest.raises(InvalidUnitOperation): 443 u1 *= u2 444 with pytest.raises(InvalidUnitOperation): 445 u1 * "hello!" 446 with pytest.raises(InvalidUnitOperation): 447 u1 /= u2 448 with pytest.raises(InvalidUnitOperation): 449 u1 / "hello!" 450 with pytest.raises(InvalidUnitOperation): 451 Unit("B") * Unit("V") 452 with pytest.raises(InvalidUnitOperation): 453 Unit("V") * Unit("B") 454 with pytest.raises(InvalidUnitOperation): 455 Unit("V") / Unit("Np") 456 with pytest.raises(InvalidUnitOperation): 457 Unit("dB") / Unit("dB") 458 with pytest.raises(InvalidUnitOperation): 459 Unit("B") ** 2 460 461 462def test_base_equivalent(): 463 """ 464 Check base equivalent of a unit. 465 466 """ 467 Msun_mks = mass_sun_kg 468 Mpc_mks = m_per_mpc 469 470 u1 = Unit("Msun * Mpc**-3") 471 u2 = Unit("kg * m**-3") 472 u3 = u1.get_base_equivalent() 473 474 assert u2.expr == u3.expr 475 assert u2 == u3 476 477 assert_allclose_units(u1.base_value, Msun_mks / Mpc_mks ** 3, 1e-12) 478 assert u2.base_value == 1 479 assert u3.base_value == 1 480 481 mass_density = mass / length ** 3 482 483 assert u1.dimensions == mass_density 484 assert u2.dimensions == mass_density 485 assert u3.dimensions == mass_density 486 487 assert_allclose_units( 488 u1.get_conversion_factor(u3)[0], Msun_mks / Mpc_mks ** 3, 1e-12 489 ) 490 491 with pytest.raises(UnitConversionError): 492 u1.get_conversion_factor(Unit("m")) 493 494 with pytest.raises(UnitConversionError): 495 u1.get_conversion_factor(Unit("degF")) 496 497 reg = UnitRegistry(unit_system=cgs_unit_system) 498 499 u = Unit("kg", registry=reg) 500 501 assert u.get_base_equivalent() == Unit("g") 502 503 u = Unit("kg") 504 505 assert u.get_base_equivalent() == Unit("kg") 506 507 u = Unit("A") 508 assert u.get_base_equivalent(unit_system="mks") == Unit("A") 509 510 511def test_temperature_offsets(): 512 u1 = Unit("degC") 513 u2 = Unit("degF") 514 515 with pytest.raises(InvalidUnitOperation): 516 operator.mul(u1, u2) 517 with pytest.raises(InvalidUnitOperation): 518 operator.truediv(u1, u2) 519 520 521def test_latex_repr(): 522 registry = UnitRegistry() 523 524 # create a fake comoving unit 525 registry.add( 526 "pccm", 527 registry.lut["pc"][0] / (1 + 2), 528 length, 529 "\\rm{pc}/(1+z)", 530 prefixable=True, 531 ) 532 533 test_unit = Unit("Mpccm", registry=registry) 534 assert_almost_equal(test_unit.base_value, m_per_mpc / 3) 535 assert_equal(test_unit.latex_repr, r"\rm{Mpc}/(1+z)") 536 537 test_unit = Unit("cm**-3", base_value=1.0, registry=registry) 538 assert_equal(test_unit.latex_repr, "\\frac{1}{\\rm{cm}^{3}}") 539 540 test_unit = Unit("m_geom/l_geom**3") 541 assert_equal(test_unit.latex_repr, "\\frac{1}{\\rm{M}_\\odot^{2}}") 542 543 test_unit = Unit("1e9*cm") 544 assert_equal(test_unit.latex_repr, "1.0 \\times 10^{9}\\ \\rm{cm}") 545 546 test_unit = Unit("1.0*cm") 547 assert_equal(test_unit.latex_repr, "\\rm{cm}") 548 549 550def test_latitude_longitude(): 551 lat = unit_symbols.lat 552 lon = unit_symbols.lon 553 deg = unit_symbols.deg 554 assert_equal(lat.units.base_offset, 90.0) 555 assert_equal((deg * 90.0).in_units("lat").value, 0.0) 556 assert_equal((deg * 180).in_units("lat").value, -90.0) 557 assert_equal((lat * 0.0).in_units("deg"), deg * 90.0) 558 assert_equal((lat * -90).in_units("deg"), deg * 180) 559 560 assert_equal(lon.units.base_offset, -180.0) 561 assert_equal((deg * 0.0).in_units("lon").value, -180.0) 562 assert_equal((deg * 90.0).in_units("lon").value, -90.0) 563 assert_equal((deg * 180).in_units("lon").value, 0.0) 564 assert_equal((deg * 360).in_units("lon").value, 180.0) 565 566 assert_equal((lon * -180.0).in_units("deg"), deg * 0.0) 567 assert_equal((lon * -90.0).in_units("deg"), deg * 90.0) 568 assert_equal((lon * 0.0).in_units("deg"), deg * 180.0) 569 assert_equal((lon * 180.0).in_units("deg"), deg * 360) 570 571 572def test_creation_from_ytarray(): 573 from unyt import electrostatic_unit, elementary_charge_cgs 574 575 u1 = Unit(electrostatic_unit) 576 assert_equal(str(u1), "statC") 577 assert_equal(u1, Unit("esu")) 578 assert_equal(u1, electrostatic_unit.units) 579 580 u2 = Unit(elementary_charge_cgs) 581 assert_equal(str(u2), "4.80320467299766e-10*statC") 582 assert_equal(u2, Unit("4.80320467299766e-10*statC")) 583 assert_equal(u1, elementary_charge_cgs.units) 584 585 assert_allclose((u1 / u2).base_value, electrostatic_unit / elementary_charge_cgs) 586 587 with pytest.raises(UnitParseError): 588 Unit([1, 2, 3] * elementary_charge_cgs) 589 590 591def test_list_same_dimensions(): 592 from unyt import m 593 594 reg = default_unit_registry 595 for equiv in reg.list_same_dimensions(m): 596 assert Unit(equiv).dimensions is length 597 598 599def test_decagram(): 600 dag = Unit("dag") 601 g = Unit("g") 602 assert dag.get_conversion_factor(g) == (10.0, None) 603 604 605def test_pickle(): 606 cm = Unit("cm") 607 assert cm == pickle.loads(pickle.dumps(cm)) 608 609 610def test_preserve_offset(): 611 from unyt import degF, dimensionless 612 613 new_unit = degF * dimensionless 614 615 assert new_unit is not degF 616 assert new_unit == degF 617 assert new_unit.base_offset == degF.base_offset 618 619 new_unit = degF / dimensionless 620 621 assert new_unit is not degF 622 assert new_unit == degF 623 assert new_unit.base_offset == degF.base_offset 624 625 with pytest.raises(InvalidUnitOperation): 626 dimensionless / degF 627 628 629def test_code_unit(): 630 from unyt import UnitRegistry 631 632 ureg = UnitRegistry() 633 ureg.add("code_length", 10.0, length) 634 ureg.add("code_magnetic_field", 2.0, magnetic_field_mks) 635 u = Unit("code_length", registry=ureg) 636 assert u.is_code_unit is True 637 assert u.get_base_equivalent() == Unit("m") 638 u = Unit("cm") 639 assert u.is_code_unit is False 640 641 u = Unit("code_magnetic_field", registry=ureg) 642 assert u.get_base_equivalent("mks") == Unit("T") 643 with pytest.raises(UnitsNotReducible): 644 assert u.get_base_equivalent("cgs") 645 646 # see issue #60 647 u = Unit("s/m") 648 assert u.get_mks_equivalent() == Unit("s/m") 649 assert u.get_mks_equivalent() != Unit("ohm") 650 assert u.get_cgs_equivalent() == Unit("s/cm") 651 652 u = Unit("kC") 653 assert u.get_cgs_equivalent() == Unit("kesu") 654 assert u.get_cgs_equivalent().get_mks_equivalent() == u 655 656 UnitSystem(ureg.unit_system_id, "code_length", "kg", "s", registry=ureg) 657 658 u = Unit("cm", registry=ureg) 659 ue = u.get_base_equivalent("code") 660 661 assert str(ue) == "code_length" 662 assert ue.base_value == 10 663 assert ue.dimensions is length 664 665 class FakeDataset(object): 666 unit_registry = ureg 667 668 ds = FakeDataset() 669 670 UnitSystem(ds, "code_length", "kg", "s", registry=ureg) 671 672 u = Unit("cm", registry=ureg) 673 ue = u.get_base_equivalent(ds) 674 675 assert str(ue) == "code_length" 676 assert ue.base_value == 10 677 assert ue.dimensions is length 678 679 with pytest.raises(UnitParseError): 680 Unit("code_length") 681 682 683def test_bad_equivalence(): 684 from unyt import cm 685 686 with pytest.raises(KeyError): 687 cm.has_equivalent("dne") 688 689 690def test_em_unit_base_equivalent(): 691 from unyt import A, cm 692 693 with pytest.raises(UnitsNotReducible): 694 (A / cm).get_base_equivalent("cgs") 695 696 697def test_symbol_lut_length(): 698 for v in default_unit_symbol_lut.values(): 699 assert len(v) == 5 700 701 702def test_simplify(): 703 import unyt as u 704 705 answers = { 706 u.Hz * u.s: "dimensionless", 707 u.kg / u.g: "1000", 708 u.Hz * u.s * u.km: "km", 709 u.kHz * u.s: "1000", 710 u.kHz * u.s * u.km: "1000*km", 711 u.kHz * u.s ** 2: "1000*s", 712 u.kHz * u.s ** 2 * u.km: "1000*km*s", 713 u.Hz ** -1 * u.s: "s/Hz", 714 u.Hz ** -1 * u.s * u.km: "km*s/Hz", 715 u.Hz ** 1.5 * u.s ** 1.7: "sqrt(Hz)*s**(7/10)", 716 u.Hz ** 1.5 * u.s ** 1.7 * u.km: "sqrt(Hz)*km*s**(7/10)", 717 u.m ** 2 / u.cm ** 2: "10000", 718 } 719 720 for unit, answer in answers.items(): 721 assert str(unit.simplify()) == answer 722 723 724def test_micro_prefix(): 725 import unyt as u 726 727 # both versions of unicode mu work correctly 728 assert u.um == u.µm 729 assert u.um == u.μm 730 731 # parsing both versions works as well 732 assert u.ug == u.Unit("µg") 733 assert u.ug == u.Unit("μg") 734 735 736def test_name_alternatives(): 737 import unyt 738 from unyt._unit_lookup_table import ( 739 default_unit_name_alternatives, 740 name_alternatives, 741 inv_name_alternatives, 742 ) 743 744 # concatenated list of all alternative unit names 745 allowed_names = sum(name_alternatives.values(), []) 746 747 # ensure the values are all tuples and not e.g. strings 748 for val in default_unit_name_alternatives.values(): 749 assert isinstance(val, tuple) 750 751 # all names are unique 752 assert len(set(allowed_names)) == len(allowed_names) 753 # each allowed name has a key in the inverse dict 754 assert len(inv_name_alternatives.keys()) == len(allowed_names) 755 assert set(inv_name_alternatives.keys()) == set(allowed_names) 756 757 for name in allowed_names: 758 assert hasattr(unyt, name) 759 assert hasattr(unyt.unit_symbols, name) 760 761 762def test_solar_unit_name_alternatives(): 763 import unyt 764 from unyt import Unit 765 766 # check that m_sun, m_Sun, M_sun, M_Sun, msun, and Msun all work 767 for lower_name_prefix in "mrltz": 768 base_name = lower_name_prefix + "sun" 769 for name_prefix in [lower_name_prefix, lower_name_prefix.upper()]: 770 alternative_names = [name_prefix + suf for suf in ["sun", "_sun", "_Sun"]] 771 for name in alternative_names: 772 assert Unit(name) == Unit(base_name) 773 assert hasattr(unyt, name) 774 # only solar mass units are in physical constants 775 if lower_name_prefix == "m": 776 assert hasattr(unyt.physical_constants, name) 777 778 779def test_attosecond(): 780 from unyt import Unit, attosecond, second 781 782 assert Unit("as") == attosecond 783 assert str(Unit("as")) == "as" 784 assert Unit("as/s") == attosecond / second 785 786 787def test_micro(): 788 from unyt import Unit 789 790 assert str(Unit("um")) == "μm" 791 assert str(Unit("us")) == "μs" 792 793 794def test_show_all_units_doc_table_ops(): 795 for name in set(name_alternatives.keys()): 796 u = Unit(name) 797 (1 * u).in_mks() 798 try: 799 (1 * u).in_cgs() 800 except UnitsNotReducible: 801 pass 802 803 804def test_hPa_mbar(): 805 assert Unit("hPa").dimensions == Unit("bar").dimensions 806 assert (5 * Unit("hPa") == 5 * Unit("mbar")).all() 807 assert (5 * Unit("hPa") != 1 * Unit("bar")).all() 808 809 810def test_percent(): 811 a = 300 * Unit("percent") 812 b = 3.0 * Unit("dimensionless") 813 c = 300.0 * Unit("%") 814 d = 300.0 * Unit("V*%/V") 815 816 assert a == b 817 assert str(a) == "300 %" 818 assert repr(a) == "unyt_quantity(300, '%')" 819 820 assert a == c 821 assert c == d 822 823 824def test_equal_has_same_hash(): 825 a = Unit("m") 826 b = Unit("m") 827 c = Unit("m*s/s") 828 829 assert a == b 830 assert b == c 831 assert hash(a) == hash(b) 832 assert hash(b) == hash(c) 833 834 835def test_bel_neper(): 836 assert Unit("B").dimensions == Unit("Np").dimensions 837 a = 1 * Unit("B") / (np.log(10) / 2) 838 assert_allclose_units(a.to("Np"), 1 * Unit("Np")) 839 a = 2 * Unit("B") 840 b = 20 * Unit("decibel") 841 assert (a == b).all() 842 c = 2 * Unit("Np") 843 d = 20 * Unit("decineper") 844 assert (c == d).all() 845 assert Unit("dB") ** 1 == Unit("dB") 846 847 848def test_henry(): 849 assert (Unit("H") / Unit("Ω")).dimensions == time 850 851 852def test_degC(): 853 assert Unit("degree_celsius") == Unit("degC") 854 assert Unit("degree_Celsius") == Unit("degC") 855 assert Unit("Celsius") == Unit("degC") 856 assert Unit("°C") == Unit("degC") 857 a = 1 * Unit("degC") 858 assert str(a) == "1 °C" 859 860 861def test_delta_degC(): 862 a = 1 * Unit("delta_degC") 863 assert str(a) == "1 Δ°C" 864 865 866def test_degF(): 867 assert Unit("degree_fahrenheit") == Unit("degF") 868 assert Unit("degree_Fahrenheit") == Unit("degF") 869 assert Unit("Fahrenheit") == Unit("degF") 870 assert Unit("°F") == Unit("degF") 871 a = 1 * Unit("degF") 872 assert str(a) == "1 °F" 873 874 875def test_delta_degF(): 876 a = 1 * Unit("delta_degF") 877 assert str(a) == "1 Δ°F" 878 879 880def test_mixed_registry_operations(): 881 882 reg = UnitRegistry(unit_system="cgs") 883 reg.add("fake_length", 0.001, length) 884 a = unyt_quantity(1, units="fake_length", registry=reg) 885 b = unyt_quantity(1, "cm") 886 887 assert_almost_equal(a + b, b + a) 888 assert_almost_equal(a - b, -(b - a)) 889 assert_almost_equal(a * b, b * a) 890 assert_almost_equal(b / a, b / a.in_units("km")) 891 assert_almost_equal(a / b, a / b.in_units("km")) 892