pax_global_header00006660000000000000000000000064141700336370014516gustar00rootroot0000000000000052 comment=ffd231e4859fb9e05aea5bf537311404183f51ad python-quantities-0.13.0/000077500000000000000000000000001417003363700153045ustar00rootroot00000000000000python-quantities-0.13.0/.gitattributes000066400000000000000000000000441417003363700201750ustar00rootroot00000000000000quantities/_version.py export-subst python-quantities-0.13.0/.github/000077500000000000000000000000001417003363700166445ustar00rootroot00000000000000python-quantities-0.13.0/.github/workflows/000077500000000000000000000000001417003363700207015ustar00rootroot00000000000000python-quantities-0.13.0/.github/workflows/test.yml000066400000000000000000000035211417003363700224040ustar00rootroot00000000000000name: Test on: [push, pull_request] env: FORCE_COLOR: 1 jobs: test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ ubuntu-latest ] python-version: [ "3.7", "3.8", "3.9" ] numpy-version: [ "1.16", "1.17", "1.18", "1.19", "1.20", "1.21" ] exclude: - python-version: "3.9" numpy-version: "1.16" os: ubuntu-latest - python-version: "3.9" numpy-version: "1.17" os: ubuntu-latest - python-version: "3.8" numpy-version: "1.17" os: ubuntu-latest include: - python-version: "3.10" numpy-version: "1.21" os: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Get pip cache dir id: pip-cache run: | echo "::set-output name=dir::$(pip cache dir)" - name: Cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ matrix.os }}-${{ matrix.python-version }}-${{ matrix.numpy-version }}-v1-${{ hashFiles('**/setup.py') }} restore-keys: | ${{ matrix.os }}-${{ matrix.python-version }}-${{ matrix.numpy-version }}-v1- - name: Install dependencies run: | python -m pip install -U pip python -m pip install -U wheel python -m pip install -U pytest python -m pip install "numpy==${{ matrix.numpy-version }}" - name: Install run: | python setup.py install - name: Test run: | PY_IGNORE_IMPORTMISMATCH=1 pytest python -m doctest README.rst python-quantities-0.13.0/.gitignore000066400000000000000000000001341417003363700172720ustar00rootroot00000000000000*.pyc quantities.egg-info build _build dist .project .pydevproject .settings .idea .*cache/ python-quantities-0.13.0/CHANGES.txt000066400000000000000000000142641417003363700171240ustar00rootroot00000000000000======= CHANGES ======= ------ 0.13.0 ------ - Dropped support for Python versions older than 3.7, in particular, for Python 2.7. - Dropped support for NumPy versions older than 1.16 - Switched test runner to pytest, and CI to Github Actions ------ 0.12.5 ------ - Added preferred units support for .rescale - Added dimensionless unit 'lsb' (least significant bit) - Added SI multiples for Kelvin - Fixed invalid escape sequence All changes *********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aclosed+closed%3A2020-01-08..2021-08-16 ------ 0.12.4 ------ - Fix broken support for `pq.Quanitty('mbar')` - Add a `__format__` implementation for Quantity - Fix `np.arctan2` regression due to newer numpy version - Fix " not supported" error - Test against Python 3.8 and NumPy 1.17 All changes *********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aclosed+closed%3A2019-02-23..2020-01-08+ ------ 0.12.3 ------ Updates to support NumPy up to version 1.16.1, and Python 3.7. Added microcoulomb and millicoulomb units. All changes *********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aclosed%20closed%3A2018-07-03..2019-02-22 ------ 0.12.2 ------ Added SI multiples for the byte unit (kB, MB, ...) and the IEC units (KiB, MiB...). All changes *********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aclosed%20closed%3A2017-09-01..2018-07-02 ------ 0.12.1 ------ Bugs fixed ********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aclosed%20closed%3A2017-08-02..2017-08-30 ----- 0.12.0 ----- Removed support for Python 2.6, since NumPy removed support for it as of version 1.12. Numpy-1.8.2 or later is now required. Added more ufuncs: equal, not_equal, less, less_equal, greater, greater_equal Bugs fixed ********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aissue%20is%3Aclosed%20closed%3A2015-12-06..2017-08-01 ----- 0.11.0 ----- Added many new unit definitions, including aliases for American/British spellings of liter/litre The Quantity class can now be subclassed. Supports `np.fabs` The test suite is now run with Travis CI Bugs fixed ********** https://github.com/python-quantities/python-quantities/issues?utf8=✓&q=is%3Aissue%20is%3Aclosed%20closed%3A2011-09-27..2015-12-06 ----- 0.10.0 ----- The dalton has been added as an alias for the unified atomic mass unit, in response to the 2005 IUPAP report recognizing that both terms should be officially recognized. Da is recognized as the symbol for the dalton. The test suite has been refactored to use the unittest package provided by the python-2.7 and python-3.2 standard library. With python-2.6 or python-3.{0,1}, unittest2 is required. The test suite is run with:: python setup.py test Quantities no longer requires or uses Distribute or Setuptools. The test framework has been refactored to use unittest exclusively (requires unittest2 with python-2.6, python-3.0, and python-3.1). The test suite is now run in the source directory:: python setup.py test Added a defintion for the centipoise. Bugs fixed ********** * #11 incorrect definition for millidarcy * #12 add definition of centipoise * #13 add ddof keyword for std, var methods * #16 add "latex" property to dimensionality for latex format strings * #19 Astronomical Unit definition updated to reflect 2009 spec ----- 0.9.0 ----- Numpy-1.4.0 or later is also required, in order to properly handle units during in-place arithmetic. Physical constants are now instances of Quantity, rather than UncertainQuantity. Development on UncertainQuantity is not as advanced, so hopefully this change will make the constants package more robust. Bugs fixed ********** * #1 use revolution/min instead of 1/min as definition of rpm * #2 silently fail to import test runner if nose is not installed * #4 remove the "jiffy", as there are conflicting definitions depending on (or even within a) discipline. * #5 fix the definition of femtometer ----- 0.8.0 ----- Quantities now requires Python-2.6 or later. Python-3 is supported. The fill method, and __setitem__ methods will now accept scalar values in addition to quantities. If a scalar is passed, an assumption is made that the change should only be applied to the quantity's magnitude. The fill method will also accept a quantity with incompatible units, and will overwrite the previous units. The log and exp functions have been removed. Quantities will work with numpy's version of these functions. Quantities development has migrated from bzr/launchpad to git/github. Please report problems to http://github.com/python-quantities/python-quantities or visit the mailing list at http://groups.google.com/group/python-quantities Bugs fixed ********** * #501563 incorrect conversion ratio for gills/pints * #515314 don't memoize simplified, fixes set_default_units * #526008 add definition of stone, used in UK to measure mass * #525991 support specifying units using unicode * #529266 fix conversion to gallons ----- 0.7.0 ----- A critical problem was identified, caused by a conflict between farad and Faraday identified in quantities <0.7. F is commonly used as a symbol for both the farad and Faraday's constant. This is problematic for quanitities, which registers its units so they can be accessed using a string corresponding to the unit name or symbol. In this case, the Faraday constant was registered after the farad, so any quantity that was expressed in terms of farads would be incorrectly simplified using the Faraday constant. This problem has been fixed and the registry has been improved to prevent overwriting previously registered names or symbols. F is now reserved for the farad. Addition and subtraction of quantities with different but compatible units is now supported. Additionally, changes have been made in the forthcoming numpy-1.4.0 to extend this compatibility to other ufuncs as well. Numpydoc, an external package developed to extend Sphinx for the numpy documentation project, is now required to build quantities' documentation. Bugs fixed ********** * #495181 epsilon_0 simplifies incorrectly * #490323 bad spelling for polarizabilities python-quantities-0.13.0/MANIFEST.in000066400000000000000000000002451417003363700170430ustar00rootroot00000000000000include distribute_setup.py include CHANGES.txt include py3tool.py include quantities/constants/NIST_codata.txt include versioneer.py include quantities/_version.py python-quantities-0.13.0/README.rst000066400000000000000000000046541417003363700170040ustar00rootroot00000000000000========== quantities ========== |pypi version|_ |Build status|_ .. |pypi version| image:: https://img.shields.io/pypi/v/quantities.png .. _`pypi version`: https://pypi.python.org/pypi/quantities .. |Build status| image:: https://github.com/python-quantities/python-quantities/actions/workflows/test.yml/badge.svg?branch=master .. _`Build status`: https://github.com/python-quantities/python-quantities/actions/workflows/test.yml A Python package for handling physical quantities. The source code and issue tracker are hosted on GitHub: https://www.github.com/python-quantities/python-quantities Download -------- Get the latest version of quantities from https://pypi.python.org/pypi/quantities/ To get the Git version do:: $ git clone git://github.com/python-quantities/python-quantities.git Documentation and usage ----------------------- You can find the official documentation at: http://python-quantities.readthedocs.io/ Here is a simple example: .. code:: python >>> import quantities as pq >>> distance = 42*pq.metre >>> time = 17*pq.second >>> velocity = distance / time >>> "%.3f %s" % (velocity.magnitude, velocity.dimensionality) '2.471 m/s' >>> velocity + 3 Traceback (most recent call last): ... ValueError: Unable to convert between units of "dimensionless" and "m/s" Installation ------------ quantities has a hard dependency on the `NumPy `_ library. You should install it first, please refer to the NumPy installation guide: http://docs.scipy.org/doc/numpy/user/install.html To install quantities itself, then simply run:: $ python setup.py install --user If you install it system-wide, you may need to prefix the previous command with ``sudo``:: $ sudo python setup.py install Tests ----- To execute all tests, install pytest:: $ python -m pip install pytest And run:: $ pytest in the current directory. The master branch is automatically tested by GitHub Actions. Author ------ quantities was originally written by Darren Dale, and has received contributions from `many people`_. .. _`many people`: https://github.com/python-quantities/python-quantities/graphs/contributors License ------- Quantities only uses BSD compatible code. See the Open Source Initiative `licenses page `_ for details on individual licenses. See `doc/user/license.rst `_ for further details on the license of quantities python-quantities-0.13.0/conda.recipe/000077500000000000000000000000001417003363700176365ustar00rootroot00000000000000python-quantities-0.13.0/conda.recipe/bld.bat000066400000000000000000000002701417003363700210660ustar00rootroot00000000000000git describe --tags --dirty > %SRC_DIR%/__conda_version__.txt %PYTHON% %RECIPE_DIR%/format_version.py %SRC_DIR%/__conda_version__.txt %PYTHON% setup.py install if errorlevel 1 exit 1 python-quantities-0.13.0/conda.recipe/build.sh000077500000000000000000000002341417003363700212730ustar00rootroot00000000000000git describe --tags --dirty > $SRC_DIR/__conda_version__.txt $PYTHON $RECIPE_DIR/format_version.py $SRC_DIR/__conda_version__.txt $PYTHON setup.py install python-quantities-0.13.0/conda.recipe/format_version.py000066400000000000000000000002471417003363700232500ustar00rootroot00000000000000import os import sys fn = sys.argv[1] with open(fn) as f: s = f.read().lstrip('v').replace('-', '+', 1).replace('-', '.') with open(fn, 'w') as f: f.write(s) python-quantities-0.13.0/conda.recipe/meta.yaml000066400000000000000000000005241417003363700214510ustar00rootroot00000000000000package: name: quantities version: master source: git_url: ../ git_tag: master build: number: 0 requirements: build: - python run: - python - numpy test: imports: - quantities about: license: BSD home: http://pythonhosted.org//quantities/ summary: Physical quantities with units, based upon Numpy python-quantities-0.13.0/conda.recipe/run_test.py000066400000000000000000000002141417003363700220500ustar00rootroot00000000000000import os import sys import unittest suite = unittest.TestLoader().discover('quantities') unittest.TextTestRunner(verbosity=1).run(suite) python-quantities-0.13.0/doc/000077500000000000000000000000001417003363700160515ustar00rootroot00000000000000python-quantities-0.13.0/doc/Makefile000066400000000000000000000060761417003363700175220ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/quantities.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/quantities.qhc" latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." python-quantities-0.13.0/doc/_templates/000077500000000000000000000000001417003363700202065ustar00rootroot00000000000000python-quantities-0.13.0/doc/_templates/indexsidebar.html000066400000000000000000000005241417003363700235360ustar00rootroot00000000000000

Download

Current version: {{ version }}

Get Quantities from the Python Package Index

Questions? Suggestions? Contributions?

Visit the Quantities project page at github

python-quantities-0.13.0/doc/conf.py000066400000000000000000000151541417003363700173560ustar00rootroot00000000000000# # quantities documentation build configuration file, created by # sphinx-quickstart on Sun Oct 25 09:49:05 2009. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.append(os.path.abspath('./sphinxext')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.autosummary', 'ipython_console_highlighting', 'numpydoc.numpydoc' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = 'quantities' copyright = '2009, Darren Dale' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # from quantities import __version__ # The short X.Y version. version = __version__ # The full version, including alpha/beta/rc tags. release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] #autosummary_generate = ['reference/intro.rst'] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. #html_theme = 'sphinxdoc' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. html_sidebars = {'index': 'indexsidebar.html'} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'quantitiesdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'quantities.tex', 'quantities Documentation', 'Darren Dale', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} python-quantities-0.13.0/doc/devel/000077500000000000000000000000001417003363700171505ustar00rootroot00000000000000python-quantities-0.13.0/doc/devel/devnotes.rst000066400000000000000000000005541417003363700215350ustar00rootroot00000000000000Development =========== Quantities development uses the principles of test-driven development. New features or bug fixes need to be accompanied by unit tests based on Python's unittest package. Unit tests can be run with the following:: python setup.py test This works with the version of unittest provided by the python-2.7 and python-3.2+ standard library. python-quantities-0.13.0/doc/devel/documenting.rst000066400000000000000000000224021417003363700222160ustar00rootroot00000000000000.. _documenting-quantities: ********************** Documenting Quantities ********************** Getting started =============== The documentation for Quantities is generated from ReStructured Text using the Sphinx_ documentation generation tool and the numpydoc_ Sphinx extension. Sphinx-0.6.3 or later is required. You can obtain Sphinx and numpydoc from the `Python Package Index`_ or by doing:: easy_install sphinx .. _Sphinx: http://sphinx.pocoo.org/ .. _numpydoc: http://pypi.python.org/pypi/numpydoc .. _`Python Package Index`: http://pypi.python.org/pypi The documentation sources are found in the :file:`doc/` directory in the trunk. The output produced by Sphinx can be configured by editing the :file:`conf.py` file located in the :file:`doc/` directory. To build the users guide in html format, run from the main quantities directory:: python setup.py build_sphinx and the html will be produced in `build/sphinx/html`. To build the pdf file:: python setup.py build_sphinx -b latex cd build/sphinx/latex make all-pdf Organization of Quantities' documentation ========================================== The actual ReStructured Text files are kept in :file:`doc`. The main entry point is :file:`doc/index.rst`, which pulls in the :file:`index.rst` file for the user guide and the developers guide. The documentation suite is built as a single document in order to make the most effective use of cross referencing, we want to make navigating the Quantities documentation as easy as possible. Additional files can be added to the various guides by including their base file name (the .rst extension is not necessary) in the table of contents. It is also possible to include other documents through the use of an include statement, such as:: .. include:: ../TODO .. _formatting-quantities-docs: Formatting ========== The Sphinx website contains plenty of documentation_ concerning ReST markup and working with Sphinx in general. Since quantities is so closely coupled with the numpy package, quantities will conform to numpy's documentation standards and use numpy's documentation tools. Please familiarize yourself with the `docstring standard`_ and the examples_ `like these`_. .. _`docstring standard`: http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard .. _examples: http://projects.scipy.org/scipy/numpy/browser/trunk/doc/example.py#L37 .. _`like these`: http://projects.scipy.org/scipy/numpy/browser/trunk/doc/EXAMPLE_DOCSTRING.txt Here are a few additional things to keep in mind: * Please familiarize yourself with the Sphinx directives for `inline markup`_. Quantities' documentation makes heavy use of cross-referencing and other semantic markup. For example, when referring to external files, use the ``:file:`` directive. * Function arguments and keywords should be referred to using the *emphasis* role. This will keep Quantities' documentation consistant with Python's documentation:: Here is a description of *argument* Please do not use the `default role`:: Please do not describe `argument` like this. nor the ``literal`` role:: Please do not describe ``argument`` like this. * Sphinx does not support tables with column- or row-spanning cells for latex output. Such tables can not be used when documenting Quantities. * Mathematical expressions can be rendered as png images in html, and in the usual way by latex. For example: ``:math:`\sin(x_n^2)``` yields: :math:`\sin(x_n^2)`, and:: .. math:: \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}} yields: .. math:: \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}} * Footnotes [#]_ can be added using ``[#]_``, followed later by:: .. rubric:: Footnotes .. [#] .. rubric:: Footnotes .. [#] For example. * Use the *note* and *warning* directives, sparingly, to draw attention to important comments:: .. note:: Here is a note yields: .. note:: here is a note also: .. warning:: here is a warning * Use the *deprecated* directive when appropriate:: .. deprecated:: 0.98 This feature is obsolete, use something else. yields: .. deprecated:: 0.98 This feature is obsolete, use something else. * Use the *versionadded* and *versionchanged* directives, which have similar syntax to the *deprecated* role:: .. versionadded:: 0.98 The transforms have been completely revamped. .. versionadded:: 0.98 The transforms have been completely revamped. * Use the *seealso* directive, for example:: .. seealso:: Using ReST :ref:`emacs-helpers`: One example A bit about :ref:`referring-to-quantities-docs`: One more yields: .. seealso:: Using ResT :ref:`emacs-helpers`: One example A bit about :ref:`referring-to-quantities-docs`: One more * The autodoc extension will handle index entries for the API, but additional entries in the index_ need to be explicitly added. .. _documentation: http://sphinx.pocoo.org/contents.html .. _`inline markup`: http://sphinx.pocoo.org/markup/inline.html .. _index: http://sphinx.pocoo.org/markup/para.html#index-generating-markup Docstrings ---------- In addition to the aforementioned formatting suggestions: * Please limit the text width of docstrings to 70 characters. * Keyword arguments should be described using a definition list. Figures ======= Dynamically generated figures ----------------------------- The top level :file:`doc` dir has a folder called :file:`pyplots` in which you should include any pyplot plotting scripts that you want to generate figures for the documentation. It is not necessary to explicitly save the figure in the script, this will be done automatically at build time to insure that the code that is included runs and produces the advertised figure. Several figures will be saved with the same basnename as the filename when the documentation is generated (low and high res PNGs, a PDF). Quantities includes a Sphinx extension (:file:`sphinxext/plot_directive.py`) for generating the images from the python script and including either a png copy for html or a pdf for latex:: .. plot:: pyplot_simple.py :include-source: The ``:scale:`` directive rescales the image to some percentage of the original size, though we don't recommend using this in most cases since it is probably better to choose the correct figure size and dpi in mpl and let it handle the scaling. ``:include-source:`` will present the contents of the file, marked up as source code. Static figures -------------- Any figures that rely on optional system configurations need to be handled a little differently. These figures are not to be generated during the documentation build, in order to keep the prerequisites to the documentation effort as low as possible. Please run the :file:`doc/pyplots/make.py` script when adding such figures, and commit the script **and** the images to svn. Please also add a line to the README in doc/pyplots for any additional requirements necessary to generate a new figure. Once these steps have been taken, these figures can be included in the usual way:: .. plot:: tex_unicode_demo.py :include-source .. _referring-to-quantities-docs: Referring to quantities documents ================================= In the documentation, you may want to include to a document in the Quantities src, e.g. a license file or an example. When you include these files, include them using the ``literalinclude`` directive:: .. literalinclude:: ../examples/some_example.py .. _internal-section-refs: Internal section references =========================== To maximize internal consistency in section labeling and references, use hypen separated, descriptive labels for section references, eg:: .. _howto-webapp: and refer to it using the standard reference syntax:: See :ref:`howto-webapp` Keep in mind that we may want to reorganize the contents later, so let's avoid top level names in references like ``user`` or ``devel`` or ``faq`` unless necessary, because for example the FAQ "what is a backend?" could later become part of the users guide, so the label:: .. _what-is-a-backend is better than:: .. _faq-backend In addition, since underscores are widely used by Sphinx itself, let's prefer hyphens to separate words. Section names, etc ================== For everything but top level chapters, please use ``Upper lower`` for section titles, eg ``Possible hangups`` rather than ``Possible Hangups`` .. _emacs-helpers: Emacs helpers ============= There is an emacs mode `rst.el `_ which automates many important ReST tasks like building and updating table-of-contents, and promoting or demoting section headings. Here is the basic ``.emacs`` configuration:: (require 'rst) (setq auto-mode-alist (append '(("\\.txt$" . rst-mode) ("\\.rst$" . rst-mode) ("\\.rest$" . rst-mode)) auto-mode-alist)) Some helpful functions:: C-c TAB - rst-toc-insert Insert table of contents at point C-c C-u - rst-toc-update Update the table of contents at point C-c C-l rst-shift-region-left Shift region to the left C-c C-r rst-shift-region-right Shift region to the right python-quantities-0.13.0/doc/devel/index.rst000066400000000000000000000002261417003363700210110ustar00rootroot00000000000000################# Developer's Guide ################# .. _dev-contents: .. toctree:: :maxdepth: 2 documenting.rst devnotes.rst release python-quantities-0.13.0/doc/devel/release.rst000066400000000000000000000033671417003363700213330ustar00rootroot00000000000000******** Releases ******** Creating Source Releases ======================== Quantities is distributed as a source release for Linux and Mac OS. To create a source release, just do:: python setup.py register python setup.py sdist --formats=zip,gztar twine upload dist/quantities-.* (replacing `x`, `y` and `z` appropriately). This will create the tgz source file and upload it to the Python Package Index. Uploading to PyPi requires a .pypirc file in your home directory, something like:: [server-login] username: password: You can create a source distribution without uploading by doing:: python setup.py sdist This creates a source distribution in the `dist/` directory. Creating Windows Installers =========================== We distribute binary installers for the windows platform. In order to build the windows installer, open a DOS window, cd into the quantities source directory and run:: python setup.py build python setup.py bdist_msi This creates the executable windows installer in the `dist/` directory. Building Quantities documentation ================================= The Quantities documentation is automatically built on readthedocs.io. Should you need to build the documentation locally, Sphinx_, LaTeX_ (preferably `TeX-Live`_), and dvipng_ are required. Once these are installed, do:: cd doc make html which will produce the html output and save it in build/sphinx/html. Then run:: make latex cd build/latex make all-pdf cp Quantities.pdf ../html which will generate a pdf file in the latex directory. .. _Sphinx: http://sphinx.pocoo.org/ .. _LaTeX: http://www.latex-project.org/ .. _`TeX-Live`: http://www.tug.org/texlive/ .. _dvipng: http://savannah.nongnu.org/projects/dvipng/ python-quantities-0.13.0/doc/index.rst000066400000000000000000000013251417003363700177130ustar00rootroot00000000000000 .. only:: html :Release: |version| :Date: |today| .. Download `PDF <./Quantities.pdf>`_ .. _contents: Quantities ========== Quantities is designed to handle arithmetic and conversions of physical quantities, which have a magnitude, dimensionality specified by various units, and possibly an uncertainty. Quantities builds on the popular numpy library and is designed to work with numpy's standard ufuncs, many of which are already supported. Quantities is actively developed, and while the current features and API are stable, test coverage is incomplete and the package is not ready for production use. Python-2.6.0 or later is required. .. toctree:: :maxdepth: 2 user/index.rst devel/index.rst python-quantities-0.13.0/doc/make.bat000066400000000000000000000060071417003363700174610ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation set SPHINXBUILD=sphinx-build set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\quantities.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\quantities.ghc goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end python-quantities-0.13.0/doc/rtd-requirements.txt000066400000000000000000000000111417003363700221140ustar00rootroot00000000000000numpydoc python-quantities-0.13.0/doc/sphinxext/000077500000000000000000000000001417003363700201035ustar00rootroot00000000000000python-quantities-0.13.0/doc/sphinxext/ipython_console_highlighting.py000066400000000000000000000101331417003363700264140ustar00rootroot00000000000000"""reST directive for syntax-highlighting ipython interactive sessions. XXX - See what improvements can be made based on the new (as of Sept 2009) 'pycon' lexer for the python console. At the very least it will give better highlighted tracebacks. """ #----------------------------------------------------------------------------- # Needed modules # Standard library import re # Third party from pygments.lexer import Lexer, do_insertions from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Comment, Generic from sphinx import highlighting #----------------------------------------------------------------------------- # Global constants line_re = re.compile('.*?\n') #----------------------------------------------------------------------------- # Code begins - classes and functions class IPythonConsoleLexer(Lexer): """ For IPython console output or doctests, such as: .. sourcecode:: ipython In [1]: a = 'foo' In [2]: a Out[2]: 'foo' In [3]: print a foo In [4]: 1 / 0 Notes: - Tracebacks are not currently supported. - It assumes the default IPython prompts, not customized ones. """ name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] input_prompt = re.compile(r"(In \[[0-9]+\]: )|( \.\.\.+:)") output_prompt = re.compile(r"(Out\[[0-9]+\]: )|( \.\.\.+:)") continue_prompt = re.compile(r" \.\.\.+:") tb_start = re.compile(r"\-+") def get_tokens_unprocessed(self, text): pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() input_prompt = self.input_prompt.match(line) continue_prompt = self.continue_prompt.match(line.rstrip()) output_prompt = self.output_prompt.match(line) if line.startswith("#"): insertions.append((len(curcode), [(0, Comment, line)])) elif input_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, input_prompt.group())])) curcode += line[input_prompt.end():] elif continue_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, continue_prompt.group())])) curcode += line[continue_prompt.end():] elif output_prompt is not None: # Use the 'error' token for output. We should probably make # our own token, but error is typicaly in a bright color like # red, so it works fine for our output prompts. insertions.append((len(curcode), [(0, Generic.Error, output_prompt.group())])) curcode += line[output_prompt.end():] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item def setup(app): """Setup as a sphinx extension.""" # This is only a lexer, so adding it below to pygments appears sufficient. # But if somebody knows that the right API usage should be to do that via # sphinx, by all means fix it here. At least having this setup.py # suppresses the sphinx warning we'd get without it. pass #----------------------------------------------------------------------------- # Register the extension as a valid pygments lexer highlighting.lexers['ipython'] = IPythonConsoleLexer() python-quantities-0.13.0/doc/user/000077500000000000000000000000001417003363700170275ustar00rootroot00000000000000python-quantities-0.13.0/doc/user/credits.rst000066400000000000000000000014041417003363700212150ustar00rootroot00000000000000.. _credits: ******* Credits ******* Quantities was written by Darren Dale, with the hope that additional developers will contribute to --- and take credit for --- its development. Special thanks to those who have made valuable contributions (roughly in order of first contribution by date) Charles Doutriaux wrote the python wrapper for unit conversions with the UDUnits library (no longer used) Enthought Inc. the original units registry was developed at Enthought for the Enthought Tool Suite. John Salvatier added support for the Quantity iterator, contributed to support for simplified representations of units, comparison operators, and contributed unit tests. Tony Yu contributed several bug fixes and contributed to the documentation. python-quantities-0.13.0/doc/user/index.rst000066400000000000000000000002531417003363700206700ustar00rootroot00000000000000############ User's Guide ############ .. _users-contents: .. toctree:: :maxdepth: 2 installation.rst tutorial.rst issues.rst license.rst credits.rst python-quantities-0.13.0/doc/user/installation.rst000066400000000000000000000015641417003363700222700ustar00rootroot00000000000000************ Installation ************ Prerequisites ============= Quantities has a few dependencies: * Python_ (>=3.7) * NumPy_ (>=1.16) (bearing in mind that not all combinations of Python and NumPy versions necessarily work). Source Code Installation ======================== To install Quantities, download the Quantites sourcecode from PyPI_ and run "python setup.py install" in the quantities source directory, or run "pip install quantities". Development =========== You can follow and contribute to Quantities' development using git:: git clone git@github.com:python-quantities/python-quantities.git Bugs, feature requests, and questions can be directed to the GitHub_ website. .. _Python: http://www.python.org/ .. _NumPy: http://www.scipy.org .. _PyPI: http://pypi.python.org/pypi/quantities .. _GitHub: http://github.com/python-quantities/python-quantities python-quantities-0.13.0/doc/user/issues.rst000066400000000000000000000050401417003363700210730ustar00rootroot00000000000000************ Known Issues ************ Quantities arrays are designed to work like normal numpy arrays. However, a few operations are not yet fully functioning. .. note:: In the following code examples, it's assumed that you've initiated the following imports: >>> import numpy as np >>> import quantities as pq Temperature conversion ====================== Quantities is not designed to handle coordinate systems that require a point of reference, like positions on a map or absolute temperature scales. Proper support of coordinate systems would be a fairly large undertaking and is outside the scope of this project. Furthermore, consider the following:: >>> T_0 = 100 * pq.K >>> T_1 = 200 * pq.K >>> dT = T_1-T_0 >>> dT.units = pq.degF To properly support the above example, quantities would have to distinguish absolute temperatures with temperature differences. It would have to know how to combine these two different animals, etc. The quantities project has therefore elected to limit the scope to relative quantities. As a consequence, quantities treats temperatures as a temperature difference. This is a distinction without a difference when considering Kelvin and Rankine, or transformations between the two scales, since both scales have zero offset. Temperature scales in Celsius and Fahrenheit are different and would require a non-zero offset, which is not supported in Quantities unit transformation framework. `umath` functions ================= Many common math functions ignore the dimensions of quantities. For example, trigonometric functions (e.g. `np.sin`) suffer this fate. For these functions, quantities arrays are treated like normal arrays and the calculations proceed as normal (except that a "not implemented" warning is raised). Note, however, this behavior is not ideal since some functions should behave differently for different units. For example, you would expect `np.sin` to give different results for an angle of 1° versus an angle of 1 radian; instead, `np.sin` extracts the magnitude of the input and assumes that it is already in radians. To properly handle quantities, use the corresponding quantities functions whenever possible. For example, `pq.sin` will properly handle the angle inputs described above. For an exhaustive list, see the functions defined in `pq.umath`. Functions which ignore/drop units ================================= There are additional numpy functions not in `pq.umath` that ignore and drop units. Below is a list known functions in this category * `vstack` * `interp` python-quantities-0.13.0/doc/user/license.rst000066400000000000000000000067041417003363700212120ustar00rootroot00000000000000.. _license: *********************************************** License *********************************************** Quantities only uses BSD compatible code. See the Open Source Initiative `licenses page `_ for details on individual licenses. License Agreement for Quantities ================================ Copyright (c) 2012, Darren Dale All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License Agreement for Scimath ============================= This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative. Copyright (c) 2006, Enthought, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Enthought, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-quantities-0.13.0/doc/user/tutorial.rst000066400000000000000000000001331417003363700214210ustar00rootroot00000000000000==================== Quick-start tutorial ==================== .. automodule:: quantities python-quantities-0.13.0/quantities/000077500000000000000000000000001417003363700174725ustar00rootroot00000000000000python-quantities-0.13.0/quantities/__init__.py000066400000000000000000000213311417003363700216030ustar00rootroot00000000000000""" Quantities is designed to handle arithmetic and conversions of physical quantities, which have a magnitude, dimensionality specified by various units, and possibly an uncertainty. Quantities is designed to work with numpy's standard ufuncs, many of which are already supported. The package is actively developed, and while the current features and API are stable, test coverage is incomplete and so the package is not suggested for production use. It is strongly suggested to import quantities to its own namespace, so units and constants variables are not accidentally overwritten:: >>> import quantities as pq Here pq stands for "physical quantities" or "python quantities". There are a number of ways to create a quantity. In practice, it is convenient to think of quantities as a combination of a magnitude and units. These two quantities are equivalent:: >>> import numpy as np >>> q = np.array([1,2,3]) * pq.J >>> q = [1,2,3] * pq.J >>> print q [ 1. 2. 3.] J The Quantity constructor can also be used to create quantities, similar to numpy.array. Units can be designated using a string containing standard unit abbreviations or unit names. For example:: >>> q = pq.Quantity([1,2,3], 'J') >>> q = pq.Quantity([1,2,3], 'joules') Units are also available as variables, and can be passed to Quantity:: >>> q = pq.Quantity([1,2,3], pq.J) You can modify a quantity's units in place:: >>> q = 1 * pq.m >>> q.units = pq.ft >>> print q 3.280839895013123 ft or equivalently:: >>> q = 1 * pq.meter >>> q.units = 'ft' # or 'foot' or 'feet' >>> print q 3.280839895013123 ft Note that, with strings, units can be designated using plural variants. Plural variants of the module variables are not available at this time, in the interest of keeping the units namespace somewhat manageable. `q.units = 'feet'` will work, `q.units = pq.feet` will not. The units themselves are special objects that can not be modified in place:: >>> pq.meter.units = 'feet' AttributeError: can not modify protected units Instead of modifying a quantity in place, you can create a new quantity, rescaled to the new units:: >>> q = 300 * pq.ft * 600 * pq.ft >>> q2 = q.rescale('US_survey_acre') >>> print q2 4.13221487605 US_survey_acre but rescaling will fail if the requested units fails a dimensional analysis:: >>> q = 10 * pq.joule >>> q2 = q.rescale(pq.watt) ValueError: Unable to convert between units of "J" and "W" Quantities can not be rescaled in place if the unit conversion fails a dimensional analysis:: >>> q = 10 * pq.joule >>> q.units = pq.watts ValueError: Unable to convert between units of "J" and "W" >>> print q 10.0 J Quantities will attempt to simplify units when the users intent is unambiguous: >>> q = (10 * pq.meter)**3 >>> q2 = q/(5*pq.meter)**2 >>> print q2 40 m Quantities will not try to guess in an ambiguous situation: >>> q = (10 * pq.meter)**3 >>> q2 = q/(5*pq.ft)**2 >>> print q2 40 m**3/ft**2 In that case, it is not clear whether the user wanted ft converted to meters, or meters to feet, or neither. Instead, you can obtain a new copy of the quantity in its irreducible units, which by default are SI units:: >>> q = (10 * pq.meter)**3 >>> q2 = q/(5*pq.ft)**2 >>> print q2 40 m**3/ft**2 >>> qs = q2.simplified >>> print qs 430.556416668 m It is also possible to customize the units in which simplified quantities are expressed:: >>> pq.set_default_units('cgs') >>> print pq.J.simplified 10000000.0 g*cm**2/s**2 >>> pq.set_default_units(length='m', mass='kg') There are times when you may want to treat a group of units as a single compound unit. For example, surface area per unit volume is a fairly common quantity in materials science. If expressed in the usual way, the quantity will be expressed in units that you may not recognize:: >>> q = 1 * pq.m**2 / pq.m**3 >>> print q 1.0 1/m Here are some tricks for working with these compound units, which can be preserved:: >>> q = 1 * pq.CompoundUnit("m**2/m**3") >>> print q 1.0 (m**2/m**3) and can be simplified:: >>> qs = q.simplified >>> qs 1.0 1/m and then rescaled back into compound units:: >>> q2 = qs.rescale(CompoundUnit("m**2/m**3")) >>> print q2 1.0 (m**2/m**3) Compound units can be combined with regular units as well: >>> q = 1 * pq.CompoundUnit('parsec/cm**3') * pq.cm**2 >>> print q 1.0 cm**2*(parsec/cm**3) It is easy to define a unit that is not already provided by quantities. For example:: >>> uK = pq.UnitQuantity('microkelvin', pq.degK/1e6, symbol='uK') >>> print uK 1 uK (microkelvin) >>> q = 1000*uK >>> print q.simplified 0.001 K There is also support for quantities with uncertainty:: >>> q = UncertainQuantity(4,J,.2) >>> q 4.0*J +/-0.2*J (1 sigma) By assuming that the uncertainties are uncorrelated, the uncertainty can be propagated during arithmetic operations:: >>> length = UncertainQuantity(2.0, m, .001) >>> width = UncertainQuantity(3.0, m, .001) >>> area = length*width >>> area 6.0*m**2 +/-0.00360555127546*m**2 (1 sigma) In that case, the measurements of the length and width were independent, and the two uncertainties presumed to be uncorrelated. Here is a warning though: >>> q*q 16.0*J**2 +/-1.1313708499*J**2 (1 sigma) This result is probably incorrect, since it assumes the uncertainties of the two multiplicands are uncorrelated. It would be more accurate in this case to use:: >>> q**2 16.0*J**2 +/-1.6*J**2 (1 sigma) There is an entire subpackage dedicated to physical constants. The values of all the constants are taken from values published by the National Institute of Standards and Technology at http://physics.nist.gov/constants . Most physical constants have some form of uncertainty, which has also been published by NIST. All uncertainties are one standard deviation. There are lots of constants and quantities includes them all (with one exception: F*, the Faraday constant for conventional electrical current, which is defined in units of C_90, for which I have not found a hard reference value). Physical constants are sort of similar to compound units, for example: >>> print pq.constants.proton_mass 1 m_p (proton_mass) >>> print pq.constants.proton_mass.simplified 1.672621637e-27 kg +/-8.3e-35 kg (1 sigma) A Latex representation of the dimensionality may be obtained in the following fashion:: >>> g = pq.Quantity(9.80665,'m/s**2') >>> mass = 50 * pq.kg >>> weight = mass*g >>> print weight.dimensionality.latex $\\mathrm{\\frac{kg{\\cdot}m}{s^{2}}}$ >>> weight.units = pq.N >>> print weight.dimensionality.latex $\\mathrm{N}$ The Latex output is compliant with the MathText subset used by Matplotlib. To add formatted units to the axis label of a Matplotlib figure, one could use:: >>> ax.set_ylabel('Weight ' + weight.dimensionality.latex) Greater customization is available via the markup.format_units_latex function. It allows the user to modify the font, the multiplication symbol, or to encapsulate the latex string in parentheses. Due to the complexity of CompoundUnits, the latex rendering of CompoundUnits will utilize the latex \\frac{num}{den} construct. Although it is not illustrated in this guide, unicode symbols can be used to provide a more compact representation of the units. This feature is disabled by default. It can be enabled by setting the following in your ~/.pythonrc.py:: quantities_unicode = True or you can change this setting on the fly by doing:: from quantities import markup markup.config.use_unicode = True # or False Even when unicode is enabled, when you pass strings to designate units, they should still conform to valid python expressions. .. attention:: Quantities is not a package for describing coordinate systems that require a point of reference, like positions on a map. In particular, Quantities does not support absolute temperature scales. Instead, temperatures are assumed to be temperature *differences*. For example: >>> T = 20 * pq.degC >>> print T.rescale('K') 20.0 K Proper support of coordinate systems would be a fairly large undertaking and is outside the scope of this project. """ from . import _version __version__ = _version.get_versions()['version'] from .registry import unit_registry from . import quantity from .quantity import Quantity from . import uncertainquantity from .uncertainquantity import UncertainQuantity from . import unitquantity from .unitquantity import * from .units import * from . import constants from .umath import * def test(verbosity=1): import unittest suite = unittest.TestLoader().discover('quantities') unittest.TextTestRunner(verbosity=verbosity).run(suite) python-quantities-0.13.0/quantities/_version.py000066400000000000000000000553231417003363700217000ustar00rootroot00000000000000 # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by # versioneer-0.21 (https://github.com/python-versioneer/python-versioneer) """Git implementation of _version.py.""" import errno import os import re import subprocess import sys from typing import Callable, Dict def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (HEAD -> master, tag: v0.13.0)" git_full = "ffd231e4859fb9e05aea5bf537311404183f51ad" git_date = "2022-01-13 14:30:55 +0000" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "pep440" cfg.tag_prefix = "v" cfg.parentdir_prefix = "quantities-" cfg.versionfile_source = "quantities/_version.py" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY: Dict[str, str] = {} HANDLERS: Dict[str, Dict[str, Callable]] = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None for command in commands: try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git process = subprocess.Popen([command] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None)) break except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands,)) return None, None stdout = process.communicate()[0].strip().decode() if process.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, process.returncode return stdout, process.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: with open(versionfile_abs, "r") as fobj: for line in fobj: if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) except OSError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if "refnames" not in keywords: raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') if not re.match(r'\d', r): continue if verbose: print("picking %s" % r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] TAG_PREFIX_REGEX = "*" if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] TAG_PREFIX_REGEX = r"\*" _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", "%s%s" % (tag_prefix, TAG_PREFIX_REGEX)], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") branch_name = branch_name.strip() if branch_name == "HEAD": # If we aren't exactly on a branch, pick a branch which represents # the current commit. If all else fails, we are on a branchless # commit. branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) # --contains was added in git-1.5.4 if rc != 0 or branches is None: raise NotThisMethod("'git branch --contains' returned error") branches = branches.split("\n") # Remove the first line if we're running detached if "(" in branches[0]: branches.pop(0) # Strip off the leading "* " from the list of branches. branches = [branch[2:] for branch in branches] if "master" in branches: branch_name = "master" elif not branches: branch_name = None else: # Pick the first branch that is returned. Good or bad. branch_name = branches[0] pieces["branch"] = branch_name # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%s'" % describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_branch(pieces): """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . The ".dev0" means not master branch. Note that .dev0 sorts backwards (a feature branch will appear "older" than the master branch). Exceptions: 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def pep440_split_post(ver): """Split pep440 version string at the post-release segment. Returns the release segments before the post-release and the post-release version number (or -1 if no post-release segment is present). """ vc = str.split(ver, ".post") return vc[0], int(vc[1] or 0) if len(vc) == 2 else None def render_pep440_pre(pieces): """TAG[.postN.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: if pieces["distance"]: # update the post release segment tag_version, post_version = pep440_split_post(pieces["closest-tag"]) rendered = tag_version if post_version is not None: rendered += ".post%d.dev%d" % (post_version+1, pieces["distance"]) else: rendered += ".post0.dev%d" % (pieces["distance"]) else: # no commits, use the tag as the version rendered = pieces["closest-tag"] else: # exception #1 rendered = "0.post0.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_post_branch(pieces): """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . The ".dev0" means not master branch. Exceptions: 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += "+g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-branch": rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-post-branch": rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for _ in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None} try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} python-quantities-0.13.0/quantities/constants/000077500000000000000000000000001417003363700215065ustar00rootroot00000000000000python-quantities-0.13.0/quantities/constants/NIST_codata.txt000066400000000000000000001006761417003363700243510ustar00rootroot00000000000000 Fundamental Physical Constants --- Complete Listing From: http://physics.nist.gov/constants Quantity Value Uncertainty Unit ------------------------------------------------------------------------------------------------------------------------ {220} lattice spacing of silicon 192.015 5762 e-12 0.000 0050 e-12 m alpha particle-electron mass ratio 7294.299 5365 0.000 0031 alpha particle mass 6.644 656 20 e-27 0.000 000 33 e-27 kg alpha particle mass energy equivalent 5.971 919 17 e-10 0.000 000 30 e-10 J alpha particle mass energy equivalent in MeV 3727.379 109 0.000 093 MeV alpha particle mass in u 4.001 506 179 127 0.000 000 000 062 u alpha particle molar mass 4.001 506 179 127 e-3 0.000 000 000 062 e-3 kg mol^-1 alpha particle-proton mass ratio 3.972 599 689 51 0.000 000 000 41 Angstrom star 1.000 014 98 e-10 0.000 000 90 e-10 m atomic mass constant 1.660 538 782 e-27 0.000 000 083 e-27 kg atomic mass constant energy equivalent 1.492 417 830 e-10 0.000 000 074 e-10 J atomic mass constant energy equivalent in MeV 931.494 028 0.000 023 MeV atomic mass unit-electron volt relationship 931.494 028 e6 0.000 023 e6 eV atomic mass unit-hartree relationship 3.423 177 7149 e7 0.000 000 0049 e7 E_h atomic mass unit-hertz relationship 2.252 342 7369 e23 0.000 000 0032 e23 Hz atomic mass unit-inverse meter relationship 7.513 006 671 e14 0.000 000 011 e14 m^-1 atomic mass unit-joule relationship 1.492 417 830 e-10 0.000 000 074 e-10 J atomic mass unit-kelvin relationship 1.080 9527 e13 0.000 0019 e13 K atomic mass unit-kilogram relationship 1.660 538 782 e-27 0.000 000 083 e-27 kg atomic unit of 1st hyperpolarizability 3.206 361 533 e-53 0.000 000 081 e-53 C^3 m^3 J^-2 atomic unit of 2nd hyperpolarizability 6.235 380 95 e-65 0.000 000 31 e-65 C^4 m^4 J^-3 atomic unit of action 1.054 571 628 e-34 0.000 000 053 e-34 J s atomic unit of charge 1.602 176 487 e-19 0.000 000 040 e-19 C atomic unit of charge density 1.081 202 300 e12 0.000 000 027 e12 C m^-3 atomic unit of current 6.623 617 63 e-3 0.000 000 17 e-3 A atomic unit of electric dipole mom. 8.478 352 81 e-30 0.000 000 21 e-30 C m atomic unit of electric field 5.142 206 32 e11 0.000 000 13 e11 V m^-1 atomic unit of electric field gradient 9.717 361 66 e21 0.000 000 24 e21 V m^-2 atomic unit of electric polarizability 1.648 777 2536 e-41 0.000 000 0034 e-41 C^2 m^2 J^-1 atomic unit of electric potential 27.211 383 86 0.000 000 68 V atomic unit of electric quadrupole mom. 4.486 551 07 e-40 0.000 000 11 e-40 C m^2 atomic unit of energy 4.359 743 94 e-18 0.000 000 22 e-18 J atomic unit of force 8.238 722 06 e-8 0.000 000 41 e-8 N atomic unit of length 0.529 177 208 59 e-10 0.000 000 000 36 e-10 m atomic unit of mag. dipole mom. 1.854 801 830 e-23 0.000 000 046 e-23 J T^-1 atomic unit of mag. flux density 2.350 517 382 e5 0.000 000 059 e5 T atomic unit of magnetizability 7.891 036 433 e-29 0.000 000 027 e-29 J T^-2 atomic unit of mass 9.109 382 15 e-31 0.000 000 45 e-31 kg atomic unit of momentum 1.992 851 565 e-24 0.000 000 099 e-24 kg m s^-1 atomic unit of permittivity 1.112 650 056... e-10 (exact) F m^-1 atomic unit of time 2.418 884 326 505e-17 0.000 000 000 016e-17 s atomic unit of velocity 2.187 691 2541 e6 0.000 000 0015 e6 m s^-1 Avogadro constant 6.022 141 79 e23 0.000 000 30 e23 mol^-1 Bohr magneton 927.400 915 e-26 0.000 023 e-26 J T^-1 Bohr magneton in eV/T 5.788 381 7555 e-5 0.000 000 0079 e-5 eV T^-1 Bohr magneton in Hz/T 13.996 246 04 e9 0.000 000 35 e9 Hz T^-1 Bohr magneton in inverse meters per tesla 46.686 4515 0.000 0012 m^-1 T^-1 Bohr magneton in K/T 0.671 7131 0.000 0012 K T^-1 Bohr radius 0.529 177 208 59 e-10 0.000 000 000 36 e-10 m Boltzmann constant 1.380 6504 e-23 0.000 0024 e-23 J K^-1 Boltzmann constant in eV/K 8.617 343 e-5 0.000 015 e-5 eV K^-1 Boltzmann constant in Hz/K 2.083 6644 e10 0.000 0036 e10 Hz K^-1 Boltzmann constant in inverse meters per kelvin 69.503 56 0.000 12 m^-1 K^-1 characteristic impedance of vacuum 376.730 313 461... (exact) ohm classical electron radius 2.817 940 2894 e-15 0.000 000 0058 e-15 m Compton wavelength 2.426 310 2175 e-12 0.000 000 0033 e-12 m Compton wavelength over 2 pi 386.159 264 59 e-15 0.000 000 53 e-15 m conductance quantum 7.748 091 7004 e-5 0.000 000 0053 e-5 S conventional value of Josephson constant 483 597.9 e9 (exact) Hz V^-1 conventional value of von Klitzing constant 25 812.807 (exact) ohm Cu x unit 1.002 076 99 e-13 0.000 000 28 e-13 m deuteron-electron mag. mom. ratio -4.664 345 537 e-4 0.000 000 039 e-4 deuteron-electron mass ratio 3670.482 9654 0.000 0016 deuteron g factor 0.857 438 2308 0.000 000 0072 deuteron mag. mom. 0.433 073 465 e-26 0.000 000 011 e-26 J T^-1 deuteron mag. mom. to Bohr magneton ratio 0.466 975 4556 e-3 0.000 000 0039 e-3 deuteron mag. mom. to nuclear magneton ratio 0.857 438 2308 0.000 000 0072 deuteron mass 3.343 583 20 e-27 0.000 000 17 e-27 kg deuteron mass energy equivalent 3.005 062 72 e-10 0.000 000 15 e-10 J deuteron mass energy equivalent in MeV 1875.612 793 0.000 047 MeV deuteron mass in u 2.013 553 212 724 0.000 000 000 078 u deuteron molar mass 2.013 553 212 724 e-3 0.000 000 000 078 e-3 kg mol^-1 deuteron-neutron mag. mom. ratio -0.448 206 52 0.000 000 11 deuteron-proton mag. mom. ratio 0.307 012 2070 0.000 000 0024 deuteron-proton mass ratio 1.999 007 501 08 0.000 000 000 22 deuteron rms charge radius 2.1402 e-15 0.0028 e-15 m electric constant 8.854 187 817... e-12 (exact) F m^-1 electron charge to mass quotient -1.758 820 150 e11 0.000 000 044 e11 C kg^-1 electron-deuteron mag. mom. ratio -2143.923 498 0.000 018 electron-deuteron mass ratio 2.724 437 1093 e-4 0.000 000 0012 e-4 electron g factor -2.002 319 304 3622 0.000 000 000 0015 electron gyromag. ratio 1.760 859 770 e11 0.000 000 044 e11 s^-1 T^-1 electron gyromag. ratio over 2 pi 28 024.953 64 0.000 70 MHz T^-1 electron mag. mom. -928.476 377 e-26 0.000 023 e-26 J T^-1 electron mag. mom. anomaly 1.159 652 181 11 e-3 0.000 000 000 74 e-3 electron mag. mom. to Bohr magneton ratio -1.001 159 652 181 11 0.000 000 000 000 74 electron mag. mom. to nuclear magneton ratio -1838.281 970 92 0.000 000 80 electron mass 9.109 382 15 e-31 0.000 000 45 e-31 kg electron mass energy equivalent 8.187 104 38 e-14 0.000 000 41 e-14 J electron mass energy equivalent in MeV 0.510 998 910 0.000 000 013 MeV electron mass in u 5.485 799 0943 e-4 0.000 000 0023 e-4 u electron molar mass 5.485 799 0943 e-7 0.000 000 0023 e-7 kg mol^-1 electron-muon mag. mom. ratio 206.766 9877 0.000 0052 electron-muon mass ratio 4.836 331 71 e-3 0.000 000 12 e-3 electron-neutron mag. mom. ratio 960.920 50 0.000 23 electron-neutron mass ratio 5.438 673 4459 e-4 0.000 000 0033 e-4 electron-proton mag. mom. ratio -658.210 6848 0.000 0054 electron-proton mass ratio 5.446 170 2177 e-4 0.000 000 0024 e-4 electron-tau mass ratio 2.875 64 e-4 0.000 47 e-4 electron to alpha particle mass ratio 1.370 933 555 70 e-4 0.000 000 000 58 e-4 electron to shielded helion mag. mom. ratio 864.058 257 0.000 010 electron to shielded proton mag. mom. ratio -658.227 5971 0.000 0072 electron volt 1.602 176 487 e-19 0.000 000 040 e-19 J electron volt-atomic mass unit relationship 1.073 544 188 e-9 0.000 000 027 e-9 u electron volt-hartree relationship 3.674 932 540 e-2 0.000 000 092 e-2 E_h electron volt-hertz relationship 2.417 989 454 e14 0.000 000 060 e14 Hz electron volt-inverse meter relationship 8.065 544 65 e5 0.000 000 20 e5 m^-1 electron volt-joule relationship 1.602 176 487 e-19 0.000 000 040 e-19 J electron volt-kelvin relationship 1.160 4505 e4 0.000 0020 e4 K electron volt-kilogram relationship 1.782 661 758 e-36 0.000 000 044 e-36 kg elementary charge 1.602 176 487 e-19 0.000 000 040 e-19 C elementary charge over h 2.417 989 454 e14 0.000 000 060 e14 A J^-1 Faraday constant 96 485.3399 0.0024 C mol^-1 Faraday constant for conventional electric current 96 485.3401 0.0048 C_90 mol^-1 Fermi coupling constant 1.166 37 e-5 0.000 01 e-5 GeV^-2 fine-structure constant 7.297 352 5376 e-3 0.000 000 0050 e-3 first radiation constant 3.741 771 18 e-16 0.000 000 19 e-16 W m^2 first radiation constant for spectral radiance 1.191 042 759 e-16 0.000 000 059 e-16 W m^2 sr^-1 hartree-atomic mass unit relationship 2.921 262 2986 e-8 0.000 000 0042 e-8 u hartree-electron volt relationship 27.211 383 86 0.000 000 68 eV Hartree energy 4.359 743 94 e-18 0.000 000 22 e-18 J Hartree energy in eV 27.211 383 86 0.000 000 68 eV hartree-hertz relationship 6.579 683 920 722 e15 0.000 000 000 044 e15 Hz hartree-inverse meter relationship 2.194 746 313 705 e7 0.000 000 000 015 e7 m^-1 hartree-joule relationship 4.359 743 94 e-18 0.000 000 22 e-18 J hartree-kelvin relationship 3.157 7465 e5 0.000 0055 e5 K hartree-kilogram relationship 4.850 869 34 e-35 0.000 000 24 e-35 kg helion-electron mass ratio 5495.885 2765 0.000 0052 helion mass 5.006 411 92 e-27 0.000 000 25 e-27 kg helion mass energy equivalent 4.499 538 64 e-10 0.000 000 22 e-10 J helion mass energy equivalent in MeV 2808.391 383 0.000 070 MeV helion mass in u 3.014 932 2473 0.000 000 0026 u helion molar mass 3.014 932 2473 e-3 0.000 000 0026 e-3 kg mol^-1 helion-proton mass ratio 2.993 152 6713 0.000 000 0026 hertz-atomic mass unit relationship 4.439 821 6294 e-24 0.000 000 0064 e-24 u hertz-electron volt relationship 4.135 667 33 e-15 0.000 000 10 e-15 eV hertz-hartree relationship 1.519 829 846 006e-16 0.000 000 000 010e-16 E_h hertz-inverse meter relationship 3.335 640 951... e-9 (exact) m^-1 hertz-joule relationship 6.626 068 96 e-34 0.000 000 33 e-34 J hertz-kelvin relationship 4.799 2374 e-11 0.000 0084 e-11 K hertz-kilogram relationship 7.372 496 00 e-51 0.000 000 37 e-51 kg inverse fine-structure constant 137.035 999 679 0.000 000 094 inverse meter-atomic mass unit relationship 1.331 025 0394 e-15 0.000 000 0019 e-15 u inverse meter-electron volt relationship 1.239 841 875 e-6 0.000 000 031 e-6 eV inverse meter-hartree relationship 4.556 335 252 760 e-8 0.000 000 000 030 e-8 E_h inverse meter-hertz relationship 299 792 458 (exact) Hz inverse meter-joule relationship 1.986 445 501 e-25 0.000 000 099 e-25 J inverse meter-kelvin relationship 1.438 7752 e-2 0.000 0025 e-2 K inverse meter-kilogram relationship 2.210 218 70 e-42 0.000 000 11 e-42 kg inverse of conductance quantum 12 906.403 7787 0.000 0088 ohm Josephson constant 483 597.891 e9 0.012 e9 Hz V^-1 joule-atomic mass unit relationship 6.700 536 41 e9 0.000 000 33 e9 u joule-electron volt relationship 6.241 509 65 e18 0.000 000 16 e18 eV joule-hartree relationship 2.293 712 69 e17 0.000 000 11 e17 E_h joule-hertz relationship 1.509 190 450 e33 0.000 000 075 e33 Hz joule-inverse meter relationship 5.034 117 47 e24 0.000 000 25 e24 m^-1 joule-kelvin relationship 7.242 963 e22 0.000 013 e22 K joule-kilogram relationship 1.112 650 056... e-17 (exact) kg kelvin-atomic mass unit relationship 9.251 098 e-14 0.000 016 e-14 u kelvin-electron volt relationship 8.617 343 e-5 0.000 015 e-5 eV kelvin-hartree relationship 3.166 8153 e-6 0.000 0055 e-6 E_h kelvin-hertz relationship 2.083 6644 e10 0.000 0036 e10 Hz kelvin-inverse meter relationship 69.503 56 0.000 12 m^-1 kelvin-joule relationship 1.380 6504 e-23 0.000 0024 e-23 J kelvin-kilogram relationship 1.536 1807 e-40 0.000 0027 e-40 kg kilogram-atomic mass unit relationship 6.022 141 79 e26 0.000 000 30 e26 u kilogram-electron volt relationship 5.609 589 12 e35 0.000 000 14 e35 eV kilogram-hartree relationship 2.061 486 16 e34 0.000 000 10 e34 E_h kilogram-hertz relationship 1.356 392 733 e50 0.000 000 068 e50 Hz kilogram-inverse meter relationship 4.524 439 15 e41 0.000 000 23 e41 m^-1 kilogram-joule relationship 8.987 551 787... e16 (exact) J kilogram-kelvin relationship 6.509 651 e39 0.000 011 e39 K lattice parameter of silicon 543.102 064 e-12 0.000 014 e-12 m Loschmidt constant (273.15 K, 101.325 kPa) 2.686 7774 e25 0.000 0047 e25 m^-3 mag. constant 12.566 370 614... e-7 (exact) N A^-2 mag. flux quantum 2.067 833 667 e-15 0.000 000 052 e-15 Wb molar gas constant 8.314 472 0.000 015 J mol^-1 K^-1 molar mass constant 1 e-3 (exact) kg mol^-1 molar mass of carbon-12 12 e-3 (exact) kg mol^-1 molar Planck constant 3.990 312 6821 e-10 0.000 000 0057 e-10 J s mol^-1 molar Planck constant times c 0.119 626 564 72 0.000 000 000 17 J m mol^-1 molar volume of ideal gas (273.15 K, 100 kPa) 22.710 981 e-3 0.000 040 e-3 m^3 mol^-1 molar volume of ideal gas (273.15 K, 101.325 kPa) 22.413 996 e-3 0.000 039 e-3 m^3 mol^-1 molar volume of silicon 12.058 8349 e-6 0.000 0011 e-6 m^3 mol^-1 Mo x unit 1.002 099 55 e-13 0.000 000 53 e-13 m muon Compton wavelength 11.734 441 04 e-15 0.000 000 30 e-15 m muon Compton wavelength over 2 pi 1.867 594 295 e-15 0.000 000 047 e-15 m muon-electron mass ratio 206.768 2823 0.000 0052 muon g factor -2.002 331 8414 0.000 000 0012 muon mag. mom. -4.490 447 86 e-26 0.000 000 16 e-26 J T^-1 muon mag. mom. anomaly 1.165 920 69 e-3 0.000 000 60 e-3 muon mag. mom. to Bohr magneton ratio -4.841 970 49 e-3 0.000 000 12 e-3 muon mag. mom. to nuclear magneton ratio -8.890 597 05 0.000 000 23 muon mass 1.883 531 30 e-28 0.000 000 11 e-28 kg muon mass energy equivalent 1.692 833 510 e-11 0.000 000 095 e-11 J muon mass energy equivalent in MeV 105.658 3668 0.000 0038 MeV muon mass in u 0.113 428 9256 0.000 000 0029 u muon molar mass 0.113 428 9256 e-3 0.000 000 0029 e-3 kg mol^-1 muon-neutron mass ratio 0.112 454 5167 0.000 000 0029 muon-proton mag. mom. ratio -3.183 345 137 0.000 000 085 muon-proton mass ratio 0.112 609 5261 0.000 000 0029 muon-tau mass ratio 5.945 92 e-2 0.000 97 e-2 natural unit of action 1.054 571 628 e-34 0.000 000 053 e-34 J s natural unit of action in eV s 6.582 118 99 e-16 0.000 000 16 e-16 eV s natural unit of energy 8.187 104 38 e-14 0.000 000 41 e-14 J natural unit of energy in MeV 0.510 998 910 0.000 000 013 MeV natural unit of length 386.159 264 59 e-15 0.000 000 53 e-15 m natural unit of mass 9.109 382 15 e-31 0.000 000 45 e-31 kg natural unit of momentum 2.730 924 06 e-22 0.000 000 14 e-22 kg m s^-1 natural unit of momentum in MeV/c 0.510 998 910 0.000 000 013 MeV/c natural unit of time 1.288 088 6570 e-21 0.000 000 0018 e-21 s natural unit of velocity 299 792 458 (exact) m s^-1 neutron Compton wavelength 1.319 590 8951 e-15 0.000 000 0020 e-15 m neutron Compton wavelength over 2 pi 0.210 019 413 82 e-15 0.000 000 000 31 e-15 m neutron-electron mag. mom. ratio 1.040 668 82 e-3 0.000 000 25 e-3 neutron-electron mass ratio 1838.683 6605 0.000 0011 neutron g factor -3.826 085 45 0.000 000 90 neutron gyromag. ratio 1.832 471 85 e8 0.000 000 43 e8 s^-1 T^-1 neutron gyromag. ratio over 2 pi 29.164 6954 0.000 0069 MHz T^-1 neutron mag. mom. -0.966 236 41 e-26 0.000 000 23 e-26 J T^-1 neutron mag. mom. to Bohr magneton ratio -1.041 875 63 e-3 0.000 000 25 e-3 neutron mag. mom. to nuclear magneton ratio -1.913 042 73 0.000 000 45 neutron mass 1.674 927 211 e-27 0.000 000 084 e-27 kg neutron mass energy equivalent 1.505 349 505 e-10 0.000 000 075 e-10 J neutron mass energy equivalent in MeV 939.565 346 0.000 023 MeV neutron mass in u 1.008 664 915 97 0.000 000 000 43 u neutron molar mass 1.008 664 915 97 e-3 0.000 000 000 43 e-3 kg mol^-1 neutron-muon mass ratio 8.892 484 09 0.000 000 23 neutron-proton mag. mom. ratio -0.684 979 34 0.000 000 16 neutron-proton mass ratio 1.001 378 419 18 0.000 000 000 46 neutron-tau mass ratio 0.528 740 0.000 086 neutron to shielded proton mag. mom. ratio -0.684 996 94 0.000 000 16 Newtonian constant of gravitation 6.674 28 e-11 0.000 67 e-11 m^3 kg^-1 s^-2 Newtonian constant of gravitation over h-bar c 6.708 81 e-39 0.000 67 e-39 (GeV/c^2)^-2 nuclear magneton 5.050 783 24 e-27 0.000 000 13 e-27 J T^-1 nuclear magneton in eV/T 3.152 451 2326 e-8 0.000 000 0045 e-8 eV T^-1 nuclear magneton in inverse meters per tesla 2.542 623 616 e-2 0.000 000 064 e-2 m^-1 T^-1 nuclear magneton in K/T 3.658 2637 e-4 0.000 0064 e-4 K T^-1 nuclear magneton in MHz/T 7.622 593 84 0.000 000 19 MHz T^-1 Planck constant 6.626 068 96 e-34 0.000 000 33 e-34 J s Planck constant in eV s 4.135 667 33 e-15 0.000 000 10 e-15 eV s Planck constant over 2 pi 1.054 571 628 e-34 0.000 000 053 e-34 J s Planck constant over 2 pi in eV s 6.582 118 99 e-16 0.000 000 16 e-16 eV s Planck constant over 2 pi times c in MeV fm 197.326 9631 0.000 0049 MeV fm Planck length 1.616 252 e-35 0.000 081 e-35 m Planck mass 2.176 44 e-8 0.000 11 e-8 kg Planck mass energy equivalent in GeV 1.220 892 e19 0.000 061 e19 GeV Planck temperature 1.416 785 e32 0.000 071 e32 K Planck time 5.391 24 e-44 0.000 27 e-44 s proton charge to mass quotient 9.578 833 92 e7 0.000 000 24 e7 C kg^-1 proton Compton wavelength 1.321 409 8446 e-15 0.000 000 0019 e-15 m proton Compton wavelength over 2 pi 0.210 308 908 61 e-15 0.000 000 000 30 e-15 m proton-electron mass ratio 1836.152 672 47 0.000 000 80 proton g factor 5.585 694 713 0.000 000 046 proton gyromag. ratio 2.675 222 099 e8 0.000 000 070 e8 s^-1 T^-1 proton gyromag. ratio over 2 pi 42.577 4821 0.000 0011 MHz T^-1 proton mag. mom. 1.410 606 662 e-26 0.000 000 037 e-26 J T^-1 proton mag. mom. to Bohr magneton ratio 1.521 032 209 e-3 0.000 000 012 e-3 proton mag. mom. to nuclear magneton ratio 2.792 847 356 0.000 000 023 proton mag. shielding correction 25.694 e-6 0.014 e-6 proton mass 1.672 621 637 e-27 0.000 000 083 e-27 kg proton mass energy equivalent 1.503 277 359 e-10 0.000 000 075 e-10 J proton mass energy equivalent in MeV 938.272 013 0.000 023 MeV proton mass in u 1.007 276 466 77 0.000 000 000 10 u proton molar mass 1.007 276 466 77 e-3 0.000 000 000 10 e-3 kg mol^-1 proton-muon mass ratio 8.880 243 39 0.000 000 23 proton-neutron mag. mom. ratio -1.459 898 06 0.000 000 34 proton-neutron mass ratio 0.998 623 478 24 0.000 000 000 46 proton rms charge radius 0.8768 e-15 0.0069 e-15 m proton-tau mass ratio 0.528 012 0.000 086 quantum of circulation 3.636 947 5199 e-4 0.000 000 0050 e-4 m^2 s^-1 quantum of circulation times 2 7.273 895 040 e-4 0.000 000 010 e-4 m^2 s^-1 Rydberg constant 10 973 731.568 527 0.000 073 m^-1 Rydberg constant times c in Hz 3.289 841 960 361 e15 0.000 000 000 022 e15 Hz Rydberg constant times hc in eV 13.605 691 93 0.000 000 34 eV Rydberg constant times hc in J 2.179 871 97 e-18 0.000 000 11 e-18 J Sackur-Tetrode constant (1 K, 100 kPa) -1.151 7047 0.000 0044 Sackur-Tetrode constant (1 K, 101.325 kPa) -1.164 8677 0.000 0044 second radiation constant 1.438 7752 e-2 0.000 0025 e-2 m K shielded helion gyromag. ratio 2.037 894 730 e8 0.000 000 056 e8 s^-1 T^-1 shielded helion gyromag. ratio over 2 pi 32.434 101 98 0.000 000 90 MHz T^-1 shielded helion mag. mom. -1.074 552 982 e-26 0.000 000 030 e-26 J T^-1 shielded helion mag. mom. to Bohr magneton ratio -1.158 671 471 e-3 0.000 000 014 e-3 shielded helion mag. mom. to nuclear magneton ratio -2.127 497 718 0.000 000 025 shielded helion to proton mag. mom. ratio -0.761 766 558 0.000 000 011 shielded helion to shielded proton mag. mom. ratio -0.761 786 1313 0.000 000 0033 shielded proton gyromag. ratio 2.675 153 362 e8 0.000 000 073 e8 s^-1 T^-1 shielded proton gyromag. ratio over 2 pi 42.576 3881 0.000 0012 MHz T^-1 shielded proton mag. mom. 1.410 570 419 e-26 0.000 000 038 e-26 J T^-1 shielded proton mag. mom. to Bohr magneton ratio 1.520 993 128 e-3 0.000 000 017 e-3 shielded proton mag. mom. to nuclear magneton ratio 2.792 775 598 0.000 000 030 speed of light in vacuum 299 792 458 (exact) m s^-1 standard acceleration of gravity 9.806 65 (exact) m s^-2 standard atmosphere 101 325 (exact) Pa Stefan-Boltzmann constant 5.670 400 e-8 0.000 040 e-8 W m^-2 K^-4 tau Compton wavelength 0.697 72 e-15 0.000 11 e-15 m tau Compton wavelength over 2 pi 0.111 046 e-15 0.000 018 e-15 m tau-electron mass ratio 3477.48 0.57 tau mass 3.167 77 e-27 0.000 52 e-27 kg tau mass energy equivalent 2.847 05 e-10 0.000 46 e-10 J tau mass energy equivalent in MeV 1776.99 0.29 MeV tau mass in u 1.907 68 0.000 31 u tau molar mass 1.907 68 e-3 0.000 31 e-3 kg mol^-1 tau-muon mass ratio 16.8183 0.0027 tau-neutron mass ratio 1.891 29 0.000 31 tau-proton mass ratio 1.893 90 0.000 31 Thomson cross section 0.665 245 8558 e-28 0.000 000 0027 e-28 m^2 triton-electron mag. mom. ratio -1.620 514 423 e-3 0.000 000 021 e-3 triton-electron mass ratio 5496.921 5269 0.000 0051 triton g factor 5.957 924 896 0.000 000 076 triton mag. mom. 1.504 609 361 e-26 0.000 000 042 e-26 J T^-1 triton mag. mom. to Bohr magneton ratio 1.622 393 657 e-3 0.000 000 021 e-3 triton mag. mom. to nuclear magneton ratio 2.978 962 448 0.000 000 038 triton mass 5.007 355 88 e-27 0.000 000 25 e-27 kg triton mass energy equivalent 4.500 387 03 e-10 0.000 000 22 e-10 J triton mass energy equivalent in MeV 2808.920 906 0.000 070 MeV triton mass in u 3.015 500 7134 0.000 000 0025 u triton molar mass 3.015 500 7134 e-3 0.000 000 0025 e-3 kg mol^-1 triton-neutron mag. mom. ratio -1.557 185 53 0.000 000 37 triton-proton mag. mom. ratio 1.066 639 908 0.000 000 010 triton-proton mass ratio 2.993 717 0309 0.000 000 0025 unified atomic mass unit 1.660 538 782 e-27 0.000 000 083 e-27 kg von Klitzing constant 25 812.807 557 0.000 018 ohm weak mixing angle 0.222 55 0.000 56 Wien frequency displacement law constant 5.878 933 e10 0.000 010 e10 Hz K^-1 Wien wavelength displacement law constant 2.897 7685 e-3 0.000 0051 e-3 m K python-quantities-0.13.0/quantities/constants/__init__.py000066400000000000000000000007211417003363700236170ustar00rootroot00000000000000from .alpha import * from .astronomy import * from .atomicunits import * from .deuteron import * from .electromagnetism import * from .electron import * from .helion import * from .mathematical import * from .muon import * from .naturalunits import * from .neutron import * from .proton import * from .quantum import * from .relationships import * from .statisticalmechanics import * from .tau import * from .triton import * from .weak import * from .xray import * python-quantities-0.13.0/quantities/constants/_codata.py000066400000000000000000001157021417003363700234600ustar00rootroot00000000000000# THIS FILE IS AUTOMATICALLY GENERATED # ANY CHANGES MADE HERE WILL BE LOST physical_constants = {} physical_constants['{220} lattice spacing of silicon'] = {'value': 192.0155762e-12, 'precision': 0.0000050e-12, 'units': 'm'} physical_constants['alpha particle-electron mass ratio'] = {'value': 7294.2995365, 'precision': 0.0000031, 'units': ''} physical_constants['alpha particle mass'] = {'value': 6.64465620e-27, 'precision': 0.00000033e-27, 'units': 'kg'} physical_constants['alpha particle mass energy equivalent'] = {'value': 5.97191917e-10, 'precision': 0.00000030e-10, 'units': 'J'} physical_constants['alpha particle mass energy equivalent in MeV'] = {'value': 3727.379109, 'precision': 0.000093, 'units': 'MeV'} physical_constants['alpha particle mass in u'] = {'value': 4.001506179127, 'precision': 0.000000000062, 'units': 'u'} physical_constants['alpha particle molar mass'] = {'value': 4.001506179127e-3, 'precision': 0.000000000062e-3, 'units': 'kg*mol**-1'} physical_constants['alpha particle-proton mass ratio'] = {'value': 3.97259968951, 'precision': 0.00000000041, 'units': ''} physical_constants['Angstrom star'] = {'value': 1.00001498e-10, 'precision': 0.00000090e-10, 'units': 'm'} physical_constants['atomic mass constant'] = {'value': 1.660538782e-27, 'precision': 0.000000083e-27, 'units': 'kg'} physical_constants['atomic mass constant energy equivalent'] = {'value': 1.492417830e-10, 'precision': 0.000000074e-10, 'units': 'J'} physical_constants['atomic mass constant energy equivalent in MeV'] = {'value': 931.494028, 'precision': 0.000023, 'units': 'MeV'} physical_constants['atomic mass unit-electron volt relationship'] = {'value': 931.494028e6, 'precision': 0.000023e6, 'units': 'eV'} physical_constants['atomic mass unit-hartree relationship'] = {'value': 3.4231777149e7, 'precision': 0.0000000049e7, 'units': 'E_h'} physical_constants['atomic mass unit-hertz relationship'] = {'value': 2.2523427369e23, 'precision': 0.0000000032e23, 'units': 'Hz'} physical_constants['atomic mass unit-inverse meter relationship'] = {'value': 7.513006671e14, 'precision': 0.000000011e14, 'units': 'm**-1'} physical_constants['atomic mass unit-joule relationship'] = {'value': 1.492417830e-10, 'precision': 0.000000074e-10, 'units': 'J'} physical_constants['atomic mass unit-kelvin relationship'] = {'value': 1.0809527e13, 'precision': 0.0000019e13, 'units': 'K'} physical_constants['atomic mass unit-kilogram relationship'] = {'value': 1.660538782e-27, 'precision': 0.000000083e-27, 'units': 'kg'} physical_constants['atomic unit of 1st hyperpolarizability'] = {'value': 3.206361533e-53, 'precision': 0.000000081e-53, 'units': 'C**3*m**3*J**-2'} physical_constants['atomic unit of 2nd hyperpolarizability'] = {'value': 6.23538095e-65, 'precision': 0.00000031e-65, 'units': 'C**4*m**4*J**-3'} physical_constants['atomic unit of action'] = {'value': 1.054571628e-34, 'precision': 0.000000053e-34, 'units': 'J*s'} physical_constants['atomic unit of charge'] = {'value': 1.602176487e-19, 'precision': 0.000000040e-19, 'units': 'C'} physical_constants['atomic unit of charge density'] = {'value': 1.081202300e12, 'precision': 0.000000027e12, 'units': 'C*m**-3'} physical_constants['atomic unit of current'] = {'value': 6.62361763e-3, 'precision': 0.00000017e-3, 'units': 'A'} physical_constants['atomic unit of electric dipole moment'] = {'value': 8.47835281e-30, 'precision': 0.00000021e-30, 'units': 'C*m'} physical_constants['atomic unit of electric field'] = {'value': 5.14220632e11, 'precision': 0.00000013e11, 'units': 'V*m**-1'} physical_constants['atomic unit of electric field gradient'] = {'value': 9.71736166e21, 'precision': 0.00000024e21, 'units': 'V*m**-2'} physical_constants['atomic unit of electric polarizability'] = {'value': 1.6487772536e-41, 'precision': 0.0000000034e-41, 'units': 'C**2*m**2*J**-1'} physical_constants['atomic unit of electric potential'] = {'value': 27.21138386, 'precision': 0.00000068, 'units': 'V'} physical_constants['atomic unit of electric quadrupole moment'] = {'value': 4.48655107e-40, 'precision': 0.00000011e-40, 'units': 'C*m**2'} physical_constants['atomic unit of energy'] = {'value': 4.35974394e-18, 'precision': 0.00000022e-18, 'units': 'J'} physical_constants['atomic unit of force'] = {'value': 8.23872206e-8, 'precision': 0.00000041e-8, 'units': 'N'} physical_constants['atomic unit of length'] = {'value': 0.52917720859e-10, 'precision': 0.00000000036e-10, 'units': 'm'} physical_constants['atomic unit of magnetic dipole moment'] = {'value': 1.854801830e-23, 'precision': 0.000000046e-23, 'units': 'J*T**-1'} physical_constants['atomic unit of magnetic flux density'] = {'value': 2.350517382e5, 'precision': 0.000000059e5, 'units': 'T'} physical_constants['atomic unit of magnetizability'] = {'value': 7.891036433e-29, 'precision': 0.000000027e-29, 'units': 'J*T**-2'} physical_constants['atomic unit of mass'] = {'value': 9.10938215e-31, 'precision': 0.00000045e-31, 'units': 'kg'} physical_constants['atomic unit of momentum'] = {'value': 1.992851565e-24, 'precision': 0.000000099e-24, 'units': 'kg*m*s**-1'} physical_constants['atomic unit of permittivity'] = {'value': 1.112650056e-10, 'precision': 0, 'units': 'F*m**-1'} physical_constants['atomic unit of time'] = {'value': 2.418884326505e-17, 'precision': 0.000000000016e-17, 'units': 's'} physical_constants['atomic unit of velocity'] = {'value': 2.1876912541e6, 'precision': 0.0000000015e6, 'units': 'm*s**-1'} physical_constants['Avogadro constant'] = {'value': 6.02214179e23, 'precision': 0.00000030e23, 'units': 'mol**-1'} physical_constants['Bohr magneton'] = {'value': 927.400915e-26, 'precision': 0.000023e-26, 'units': 'J*T**-1'} physical_constants['Bohr magneton in eV/T'] = {'value': 5.7883817555e-5, 'precision': 0.0000000079e-5, 'units': 'eV*T**-1'} physical_constants['Bohr magneton in Hz/T'] = {'value': 13.99624604e9, 'precision': 0.00000035e9, 'units': 'Hz*T**-1'} physical_constants['Bohr magneton in inverse meters per tesla'] = {'value': 46.6864515, 'precision': 0.0000012, 'units': 'm**-1*T**-1'} physical_constants['Bohr magneton in K/T'] = {'value': 0.6717131, 'precision': 0.0000012, 'units': 'K*T**-1'} physical_constants['Bohr radius'] = {'value': 0.52917720859e-10, 'precision': 0.00000000036e-10, 'units': 'm'} physical_constants['Boltzmann constant'] = {'value': 1.3806504e-23, 'precision': 0.0000024e-23, 'units': 'J*K**-1'} physical_constants['Boltzmann constant in eV/K'] = {'value': 8.617343e-5, 'precision': 0.000015e-5, 'units': 'eV*K**-1'} physical_constants['Boltzmann constant in Hz/K'] = {'value': 2.0836644e10, 'precision': 0.0000036e10, 'units': 'Hz*K**-1'} physical_constants['Boltzmann constant in inverse meters per kelvin'] = {'value': 69.50356, 'precision': 0.00012, 'units': 'm**-1*K**-1'} physical_constants['characteristic impedance of vacuum'] = {'value': 376.730313461, 'precision': 0, 'units': 'ohm'} physical_constants['classical electron radius'] = {'value': 2.8179402894e-15, 'precision': 0.0000000058e-15, 'units': 'm'} physical_constants['Compton wavelength'] = {'value': 2.4263102175e-12, 'precision': 0.0000000033e-12, 'units': 'm'} physical_constants['Compton wavelength over 2 pi'] = {'value': 386.15926459e-15, 'precision': 0.00000053e-15, 'units': 'm'} physical_constants['conductance quantum'] = {'value': 7.7480917004e-5, 'precision': 0.0000000053e-5, 'units': 'S'} physical_constants['conventional value of Josephson constant'] = {'value': 483597.9e9, 'precision': 0, 'units': 'Hz*V**-1'} physical_constants['conventional value of von Klitzing constant'] = {'value': 25812.807, 'precision': 0, 'units': 'ohm'} physical_constants['Cu x unit'] = {'value': 1.00207699e-13, 'precision': 0.00000028e-13, 'units': 'm'} physical_constants['deuteron-electron magnetic moment ratio'] = {'value': -4.664345537e-4, 'precision': 0.000000039e-4, 'units': ''} physical_constants['deuteron-electron mass ratio'] = {'value': 3670.4829654, 'precision': 0.0000016, 'units': ''} physical_constants['deuteron g factor'] = {'value': 0.8574382308, 'precision': 0.0000000072, 'units': ''} physical_constants['deuteron magnetic moment'] = {'value': 0.433073465e-26, 'precision': 0.000000011e-26, 'units': 'J*T**-1'} physical_constants['deuteron magnetic moment to Bohr magneton ratio'] = {'value': 0.4669754556e-3, 'precision': 0.0000000039e-3, 'units': ''} physical_constants['deuteron magnetic moment to nuclear magneton ratio'] = {'value': 0.8574382308, 'precision': 0.0000000072, 'units': ''} physical_constants['deuteron mass'] = {'value': 3.34358320e-27, 'precision': 0.00000017e-27, 'units': 'kg'} physical_constants['deuteron mass energy equivalent'] = {'value': 3.00506272e-10, 'precision': 0.00000015e-10, 'units': 'J'} physical_constants['deuteron mass energy equivalent in MeV'] = {'value': 1875.612793, 'precision': 0.000047, 'units': 'MeV'} physical_constants['deuteron mass in u'] = {'value': 2.013553212724, 'precision': 0.000000000078, 'units': 'u'} physical_constants['deuteron molar mass'] = {'value': 2.013553212724e-3, 'precision': 0.000000000078e-3, 'units': 'kg*mol**-1'} physical_constants['deuteron-neutron magnetic moment ratio'] = {'value': -0.44820652, 'precision': 0.00000011, 'units': ''} physical_constants['deuteron-proton magnetic moment ratio'] = {'value': 0.3070122070, 'precision': 0.0000000024, 'units': ''} physical_constants['deuteron-proton mass ratio'] = {'value': 1.99900750108, 'precision': 0.00000000022, 'units': ''} physical_constants['deuteron rms charge radius'] = {'value': 2.1402e-15, 'precision': 0.0028e-15, 'units': 'm'} physical_constants['electric constant'] = {'value': 8.854187817e-12, 'precision': 0, 'units': 'F*m**-1'} physical_constants['electron charge to mass quotient'] = {'value': -1.758820150e11, 'precision': 0.000000044e11, 'units': 'C*kg**-1'} physical_constants['electron-deuteron magnetic moment ratio'] = {'value': -2143.923498, 'precision': 0.000018, 'units': ''} physical_constants['electron-deuteron mass ratio'] = {'value': 2.7244371093e-4, 'precision': 0.0000000012e-4, 'units': ''} physical_constants['electron g factor'] = {'value': -2.0023193043622, 'precision': 0.0000000000015, 'units': ''} physical_constants['electron gyromagnetic ratio'] = {'value': 1.760859770e11, 'precision': 0.000000044e11, 'units': 's**-1*T**-1'} physical_constants['electron gyromagnetic ratio over 2 pi'] = {'value': 28024.95364, 'precision': 0.00070, 'units': 'MHz*T**-1'} physical_constants['electron magnetic moment'] = {'value': -928.476377e-26, 'precision': 0.000023e-26, 'units': 'J*T**-1'} physical_constants['electron magnetic moment anomaly'] = {'value': 1.15965218111e-3, 'precision': 0.00000000074e-3, 'units': ''} physical_constants['electron magnetic moment to Bohr magneton ratio'] = {'value': -1.00115965218111, 'precision': 0.00000000000074, 'units': ''} physical_constants['electron magnetic moment to nuclear magneton ratio'] = {'value': -1838.28197092, 'precision': 0.00000080, 'units': ''} physical_constants['electron mass'] = {'value': 9.10938215e-31, 'precision': 0.00000045e-31, 'units': 'kg'} physical_constants['electron mass energy equivalent'] = {'value': 8.18710438e-14, 'precision': 0.00000041e-14, 'units': 'J'} physical_constants['electron mass energy equivalent in MeV'] = {'value': 0.510998910, 'precision': 0.000000013, 'units': 'MeV'} physical_constants['electron mass in u'] = {'value': 5.4857990943e-4, 'precision': 0.0000000023e-4, 'units': 'u'} physical_constants['electron molar mass'] = {'value': 5.4857990943e-7, 'precision': 0.0000000023e-7, 'units': 'kg*mol**-1'} physical_constants['electron-muon magnetic moment ratio'] = {'value': 206.7669877, 'precision': 0.0000052, 'units': ''} physical_constants['electron-muon mass ratio'] = {'value': 4.83633171e-3, 'precision': 0.00000012e-3, 'units': ''} physical_constants['electron-neutron magnetic moment ratio'] = {'value': 960.92050, 'precision': 0.00023, 'units': ''} physical_constants['electron-neutron mass ratio'] = {'value': 5.4386734459e-4, 'precision': 0.0000000033e-4, 'units': ''} physical_constants['electron-proton magnetic moment ratio'] = {'value': -658.2106848, 'precision': 0.0000054, 'units': ''} physical_constants['electron-proton mass ratio'] = {'value': 5.4461702177e-4, 'precision': 0.0000000024e-4, 'units': ''} physical_constants['electron-tau mass ratio'] = {'value': 2.87564e-4, 'precision': 0.00047e-4, 'units': ''} physical_constants['electron to alpha particle mass ratio'] = {'value': 1.37093355570e-4, 'precision': 0.00000000058e-4, 'units': ''} physical_constants['electron to shielded helion magnetic moment ratio'] = {'value': 864.058257, 'precision': 0.000010, 'units': ''} physical_constants['electron to shielded proton magnetic moment ratio'] = {'value': -658.2275971, 'precision': 0.0000072, 'units': ''} physical_constants['electron volt'] = {'value': 1.602176487e-19, 'precision': 0.000000040e-19, 'units': 'J'} physical_constants['electron volt-atomic mass unit relationship'] = {'value': 1.073544188e-9, 'precision': 0.000000027e-9, 'units': 'u'} physical_constants['electron volt-hartree relationship'] = {'value': 3.674932540e-2, 'precision': 0.000000092e-2, 'units': 'E_h'} physical_constants['electron volt-hertz relationship'] = {'value': 2.417989454e14, 'precision': 0.000000060e14, 'units': 'Hz'} physical_constants['electron volt-inverse meter relationship'] = {'value': 8.06554465e5, 'precision': 0.00000020e5, 'units': 'm**-1'} physical_constants['electron volt-joule relationship'] = {'value': 1.602176487e-19, 'precision': 0.000000040e-19, 'units': 'J'} physical_constants['electron volt-kelvin relationship'] = {'value': 1.1604505e4, 'precision': 0.0000020e4, 'units': 'K'} physical_constants['electron volt-kilogram relationship'] = {'value': 1.782661758e-36, 'precision': 0.000000044e-36, 'units': 'kg'} physical_constants['elementary charge'] = {'value': 1.602176487e-19, 'precision': 0.000000040e-19, 'units': 'C'} physical_constants['elementary charge over h'] = {'value': 2.417989454e14, 'precision': 0.000000060e14, 'units': 'A*J**-1'} physical_constants['Faraday constant'] = {'value': 96485.3399, 'precision': 0.0024, 'units': 'C*mol**-1'} physical_constants['Faraday constant for conventional electric current'] = {'value': 96485.3401, 'precision': 0.0048, 'units': 'C_90*mol**-1'} physical_constants['Fermi coupling constant'] = {'value': 1.16637e-5, 'precision': 0.00001e-5, 'units': 'GeV**-2'} physical_constants['fine-structure constant'] = {'value': 7.2973525376e-3, 'precision': 0.0000000050e-3, 'units': ''} physical_constants['first radiation constant'] = {'value': 3.74177118e-16, 'precision': 0.00000019e-16, 'units': 'W*m**2'} physical_constants['first radiation constant for spectral radiance'] = {'value': 1.191042759e-16, 'precision': 0.000000059e-16, 'units': 'W*m**2*sr**-1'} physical_constants['hartree-atomic mass unit relationship'] = {'value': 2.9212622986e-8, 'precision': 0.0000000042e-8, 'units': 'u'} physical_constants['hartree-electron volt relationship'] = {'value': 27.21138386, 'precision': 0.00000068, 'units': 'eV'} physical_constants['Hartree energy'] = {'value': 4.35974394e-18, 'precision': 0.00000022e-18, 'units': 'J'} physical_constants['Hartree energy in eV'] = {'value': 27.21138386, 'precision': 0.00000068, 'units': 'eV'} physical_constants['hartree-hertz relationship'] = {'value': 6.579683920722e15, 'precision': 0.000000000044e15, 'units': 'Hz'} physical_constants['hartree-inverse meter relationship'] = {'value': 2.194746313705e7, 'precision': 0.000000000015e7, 'units': 'm**-1'} physical_constants['hartree-joule relationship'] = {'value': 4.35974394e-18, 'precision': 0.00000022e-18, 'units': 'J'} physical_constants['hartree-kelvin relationship'] = {'value': 3.1577465e5, 'precision': 0.0000055e5, 'units': 'K'} physical_constants['hartree-kilogram relationship'] = {'value': 4.85086934e-35, 'precision': 0.00000024e-35, 'units': 'kg'} physical_constants['helion-electron mass ratio'] = {'value': 5495.8852765, 'precision': 0.0000052, 'units': ''} physical_constants['helion mass'] = {'value': 5.00641192e-27, 'precision': 0.00000025e-27, 'units': 'kg'} physical_constants['helion mass energy equivalent'] = {'value': 4.49953864e-10, 'precision': 0.00000022e-10, 'units': 'J'} physical_constants['helion mass energy equivalent in MeV'] = {'value': 2808.391383, 'precision': 0.000070, 'units': 'MeV'} physical_constants['helion mass in u'] = {'value': 3.0149322473, 'precision': 0.0000000026, 'units': 'u'} physical_constants['helion molar mass'] = {'value': 3.0149322473e-3, 'precision': 0.0000000026e-3, 'units': 'kg*mol**-1'} physical_constants['helion-proton mass ratio'] = {'value': 2.9931526713, 'precision': 0.0000000026, 'units': ''} physical_constants['hertz-atomic mass unit relationship'] = {'value': 4.4398216294e-24, 'precision': 0.0000000064e-24, 'units': 'u'} physical_constants['hertz-electron volt relationship'] = {'value': 4.13566733e-15, 'precision': 0.00000010e-15, 'units': 'eV'} physical_constants['hertz-hartree relationship'] = {'value': 1.519829846006e-16, 'precision': 0.000000000010e-16, 'units': 'E_h'} physical_constants['hertz-inverse meter relationship'] = {'value': 3.335640951e-9, 'precision': 0, 'units': 'm**-1'} physical_constants['hertz-joule relationship'] = {'value': 6.62606896e-34, 'precision': 0.00000033e-34, 'units': 'J'} physical_constants['hertz-kelvin relationship'] = {'value': 4.7992374e-11, 'precision': 0.0000084e-11, 'units': 'K'} physical_constants['hertz-kilogram relationship'] = {'value': 7.37249600e-51, 'precision': 0.00000037e-51, 'units': 'kg'} physical_constants['inverse fine-structure constant'] = {'value': 137.035999679, 'precision': 0.000000094, 'units': ''} physical_constants['inverse meter-atomic mass unit relationship'] = {'value': 1.3310250394e-15, 'precision': 0.0000000019e-15, 'units': 'u'} physical_constants['inverse meter-electron volt relationship'] = {'value': 1.239841875e-6, 'precision': 0.000000031e-6, 'units': 'eV'} physical_constants['inverse meter-hartree relationship'] = {'value': 4.556335252760e-8, 'precision': 0.000000000030e-8, 'units': 'E_h'} physical_constants['inverse meter-hertz relationship'] = {'value': 299792458, 'precision': 0, 'units': 'Hz'} physical_constants['inverse meter-joule relationship'] = {'value': 1.986445501e-25, 'precision': 0.000000099e-25, 'units': 'J'} physical_constants['inverse meter-kelvin relationship'] = {'value': 1.4387752e-2, 'precision': 0.0000025e-2, 'units': 'K'} physical_constants['inverse meter-kilogram relationship'] = {'value': 2.21021870e-42, 'precision': 0.00000011e-42, 'units': 'kg'} physical_constants['inverse of conductance quantum'] = {'value': 12906.4037787, 'precision': 0.0000088, 'units': 'ohm'} physical_constants['Josephson constant'] = {'value': 483597.891e9, 'precision': 0.012e9, 'units': 'Hz*V**-1'} physical_constants['joule-atomic mass unit relationship'] = {'value': 6.70053641e9, 'precision': 0.00000033e9, 'units': 'u'} physical_constants['joule-electron volt relationship'] = {'value': 6.24150965e18, 'precision': 0.00000016e18, 'units': 'eV'} physical_constants['joule-hartree relationship'] = {'value': 2.29371269e17, 'precision': 0.00000011e17, 'units': 'E_h'} physical_constants['joule-hertz relationship'] = {'value': 1.509190450e33, 'precision': 0.000000075e33, 'units': 'Hz'} physical_constants['joule-inverse meter relationship'] = {'value': 5.03411747e24, 'precision': 0.00000025e24, 'units': 'm**-1'} physical_constants['joule-kelvin relationship'] = {'value': 7.242963e22, 'precision': 0.000013e22, 'units': 'K'} physical_constants['joule-kilogram relationship'] = {'value': 1.112650056e-17, 'precision': 0, 'units': 'kg'} physical_constants['kelvin-atomic mass unit relationship'] = {'value': 9.251098e-14, 'precision': 0.000016e-14, 'units': 'u'} physical_constants['kelvin-electron volt relationship'] = {'value': 8.617343e-5, 'precision': 0.000015e-5, 'units': 'eV'} physical_constants['kelvin-hartree relationship'] = {'value': 3.1668153e-6, 'precision': 0.0000055e-6, 'units': 'E_h'} physical_constants['kelvin-hertz relationship'] = {'value': 2.0836644e10, 'precision': 0.0000036e10, 'units': 'Hz'} physical_constants['kelvin-inverse meter relationship'] = {'value': 69.50356, 'precision': 0.00012, 'units': 'm**-1'} physical_constants['kelvin-joule relationship'] = {'value': 1.3806504e-23, 'precision': 0.0000024e-23, 'units': 'J'} physical_constants['kelvin-kilogram relationship'] = {'value': 1.5361807e-40, 'precision': 0.0000027e-40, 'units': 'kg'} physical_constants['kilogram-atomic mass unit relationship'] = {'value': 6.02214179e26, 'precision': 0.00000030e26, 'units': 'u'} physical_constants['kilogram-electron volt relationship'] = {'value': 5.60958912e35, 'precision': 0.00000014e35, 'units': 'eV'} physical_constants['kilogram-hartree relationship'] = {'value': 2.06148616e34, 'precision': 0.00000010e34, 'units': 'E_h'} physical_constants['kilogram-hertz relationship'] = {'value': 1.356392733e50, 'precision': 0.000000068e50, 'units': 'Hz'} physical_constants['kilogram-inverse meter relationship'] = {'value': 4.52443915e41, 'precision': 0.00000023e41, 'units': 'm**-1'} physical_constants['kilogram-joule relationship'] = {'value': 8.987551787e16, 'precision': 0, 'units': 'J'} physical_constants['kilogram-kelvin relationship'] = {'value': 6.509651e39, 'precision': 0.000011e39, 'units': 'K'} physical_constants['lattice parameter of silicon'] = {'value': 543.102064e-12, 'precision': 0.000014e-12, 'units': 'm'} physical_constants['Loschmidt constant (273.15 K, 101.325 kPa)'] = {'value': 2.6867774e25, 'precision': 0.0000047e25, 'units': 'm**-3'} physical_constants['magnetic constant'] = {'value': 12.566370614e-7, 'precision': 0, 'units': 'N*A**-2'} physical_constants['magnetic flux quantum'] = {'value': 2.067833667e-15, 'precision': 0.000000052e-15, 'units': 'Wb'} physical_constants['molar gas constant'] = {'value': 8.314472, 'precision': 0.000015, 'units': 'J*mol**-1*K**-1'} physical_constants['molar mass constant'] = {'value': 1e-3, 'precision': 0, 'units': 'kg*mol**-1'} physical_constants['molar mass of carbon-12'] = {'value': 12e-3, 'precision': 0, 'units': 'kg*mol**-1'} physical_constants['molar Planck constant'] = {'value': 3.9903126821e-10, 'precision': 0.0000000057e-10, 'units': 'J*s*mol**-1'} physical_constants['molar Planck constant times c'] = {'value': 0.11962656472, 'precision': 0.00000000017, 'units': 'J*m*mol**-1'} physical_constants['molar volume of ideal gas (273.15 K, 100 kPa)'] = {'value': 22.710981e-3, 'precision': 0.000040e-3, 'units': 'm**3*mol**-1'} physical_constants['molar volume of ideal gas (273.15 K, 101.325 kPa)'] = {'value': 22.413996e-3, 'precision': 0.000039e-3, 'units': 'm**3*mol**-1'} physical_constants['molar volume of silicon'] = {'value': 12.0588349e-6, 'precision': 0.0000011e-6, 'units': 'm**3*mol**-1'} physical_constants['Mo x unit'] = {'value': 1.00209955e-13, 'precision': 0.00000053e-13, 'units': 'm'} physical_constants['muon Compton wavelength'] = {'value': 11.73444104e-15, 'precision': 0.00000030e-15, 'units': 'm'} physical_constants['muon Compton wavelength over 2 pi'] = {'value': 1.867594295e-15, 'precision': 0.000000047e-15, 'units': 'm'} physical_constants['muon-electron mass ratio'] = {'value': 206.7682823, 'precision': 0.0000052, 'units': ''} physical_constants['muon g factor'] = {'value': -2.0023318414, 'precision': 0.0000000012, 'units': ''} physical_constants['muon magnetic moment'] = {'value': -4.49044786e-26, 'precision': 0.00000016e-26, 'units': 'J*T**-1'} physical_constants['muon magnetic moment anomaly'] = {'value': 1.16592069e-3, 'precision': 0.00000060e-3, 'units': ''} physical_constants['muon magnetic moment to Bohr magneton ratio'] = {'value': -4.84197049e-3, 'precision': 0.00000012e-3, 'units': ''} physical_constants['muon magnetic moment to nuclear magneton ratio'] = {'value': -8.89059705, 'precision': 0.00000023, 'units': ''} physical_constants['muon mass'] = {'value': 1.88353130e-28, 'precision': 0.00000011e-28, 'units': 'kg'} physical_constants['muon mass energy equivalent'] = {'value': 1.692833510e-11, 'precision': 0.000000095e-11, 'units': 'J'} physical_constants['muon mass energy equivalent in MeV'] = {'value': 105.6583668, 'precision': 0.0000038, 'units': 'MeV'} physical_constants['muon mass in u'] = {'value': 0.1134289256, 'precision': 0.0000000029, 'units': 'u'} physical_constants['muon molar mass'] = {'value': 0.1134289256e-3, 'precision': 0.0000000029e-3, 'units': 'kg*mol**-1'} physical_constants['muon-neutron mass ratio'] = {'value': 0.1124545167, 'precision': 0.0000000029, 'units': ''} physical_constants['muon-proton magnetic moment ratio'] = {'value': -3.183345137, 'precision': 0.000000085, 'units': ''} physical_constants['muon-proton mass ratio'] = {'value': 0.1126095261, 'precision': 0.0000000029, 'units': ''} physical_constants['muon-tau mass ratio'] = {'value': 5.94592e-2, 'precision': 0.00097e-2, 'units': ''} physical_constants['natural unit of action'] = {'value': 1.054571628e-34, 'precision': 0.000000053e-34, 'units': 'J*s'} physical_constants['natural unit of action in eV s'] = {'value': 6.58211899e-16, 'precision': 0.00000016e-16, 'units': 'eV*s'} physical_constants['natural unit of energy'] = {'value': 8.18710438e-14, 'precision': 0.00000041e-14, 'units': 'J'} physical_constants['natural unit of energy in MeV'] = {'value': 0.510998910, 'precision': 0.000000013, 'units': 'MeV'} physical_constants['natural unit of length'] = {'value': 386.15926459e-15, 'precision': 0.00000053e-15, 'units': 'm'} physical_constants['natural unit of mass'] = {'value': 9.10938215e-31, 'precision': 0.00000045e-31, 'units': 'kg'} physical_constants['natural unit of momentum'] = {'value': 2.73092406e-22, 'precision': 0.00000014e-22, 'units': 'kg*m*s**-1'} physical_constants['natural unit of momentum in MeV/c'] = {'value': 0.510998910, 'precision': 0.000000013, 'units': 'MeV/c'} physical_constants['natural unit of time'] = {'value': 1.2880886570e-21, 'precision': 0.0000000018e-21, 'units': 's'} physical_constants['natural unit of velocity'] = {'value': 299792458, 'precision': 0, 'units': 'm*s**-1'} physical_constants['neutron Compton wavelength'] = {'value': 1.3195908951e-15, 'precision': 0.0000000020e-15, 'units': 'm'} physical_constants['neutron Compton wavelength over 2 pi'] = {'value': 0.21001941382e-15, 'precision': 0.00000000031e-15, 'units': 'm'} physical_constants['neutron-electron magnetic moment ratio'] = {'value': 1.04066882e-3, 'precision': 0.00000025e-3, 'units': ''} physical_constants['neutron-electron mass ratio'] = {'value': 1838.6836605, 'precision': 0.0000011, 'units': ''} physical_constants['neutron g factor'] = {'value': -3.82608545, 'precision': 0.00000090, 'units': ''} physical_constants['neutron gyromagnetic ratio'] = {'value': 1.83247185e8, 'precision': 0.00000043e8, 'units': 's**-1*T**-1'} physical_constants['neutron gyromagnetic ratio over 2 pi'] = {'value': 29.1646954, 'precision': 0.0000069, 'units': 'MHz*T**-1'} physical_constants['neutron magnetic moment'] = {'value': -0.96623641e-26, 'precision': 0.00000023e-26, 'units': 'J*T**-1'} physical_constants['neutron magnetic moment to Bohr magneton ratio'] = {'value': -1.04187563e-3, 'precision': 0.00000025e-3, 'units': ''} physical_constants['neutron magnetic moment to nuclear magneton ratio'] = {'value': -1.91304273, 'precision': 0.00000045, 'units': ''} physical_constants['neutron mass'] = {'value': 1.674927211e-27, 'precision': 0.000000084e-27, 'units': 'kg'} physical_constants['neutron mass energy equivalent'] = {'value': 1.505349505e-10, 'precision': 0.000000075e-10, 'units': 'J'} physical_constants['neutron mass energy equivalent in MeV'] = {'value': 939.565346, 'precision': 0.000023, 'units': 'MeV'} physical_constants['neutron mass in u'] = {'value': 1.00866491597, 'precision': 0.00000000043, 'units': 'u'} physical_constants['neutron molar mass'] = {'value': 1.00866491597e-3, 'precision': 0.00000000043e-3, 'units': 'kg*mol**-1'} physical_constants['neutron-muon mass ratio'] = {'value': 8.89248409, 'precision': 0.00000023, 'units': ''} physical_constants['neutron-proton magnetic moment ratio'] = {'value': -0.68497934, 'precision': 0.00000016, 'units': ''} physical_constants['neutron-proton mass ratio'] = {'value': 1.00137841918, 'precision': 0.00000000046, 'units': ''} physical_constants['neutron-tau mass ratio'] = {'value': 0.528740, 'precision': 0.000086, 'units': ''} physical_constants['neutron to shielded proton magnetic moment ratio'] = {'value': -0.68499694, 'precision': 0.00000016, 'units': ''} physical_constants['Newtonian constant of gravitation'] = {'value': 6.67428e-11, 'precision': 0.00067e-11, 'units': 'm**3*kg**-1*s**-2'} physical_constants['Newtonian constant of gravitation over h-bar c'] = {'value': 6.70881e-39, 'precision': 0.00067e-39, 'units': '(GeV/c**2)**-2'} physical_constants['nuclear magneton'] = {'value': 5.05078324e-27, 'precision': 0.00000013e-27, 'units': 'J*T**-1'} physical_constants['nuclear magneton in eV/T'] = {'value': 3.1524512326e-8, 'precision': 0.0000000045e-8, 'units': 'eV*T**-1'} physical_constants['nuclear magneton in inverse meters per tesla'] = {'value': 2.542623616e-2, 'precision': 0.000000064e-2, 'units': 'm**-1*T**-1'} physical_constants['nuclear magneton in K/T'] = {'value': 3.6582637e-4, 'precision': 0.0000064e-4, 'units': 'K*T**-1'} physical_constants['nuclear magneton in MHz/T'] = {'value': 7.62259384, 'precision': 0.00000019, 'units': 'MHz*T**-1'} physical_constants['Planck constant'] = {'value': 6.62606896e-34, 'precision': 0.00000033e-34, 'units': 'J*s'} physical_constants['Planck constant in eV s'] = {'value': 4.13566733e-15, 'precision': 0.00000010e-15, 'units': 'eV*s'} physical_constants['Planck constant over 2 pi'] = {'value': 1.054571628e-34, 'precision': 0.000000053e-34, 'units': 'J*s'} physical_constants['Planck constant over 2 pi in eV s'] = {'value': 6.58211899e-16, 'precision': 0.00000016e-16, 'units': 'eV*s'} physical_constants['Planck constant over 2 pi times c in MeV fm'] = {'value': 197.3269631, 'precision': 0.0000049, 'units': 'MeV*fm'} physical_constants['Planck length'] = {'value': 1.616252e-35, 'precision': 0.000081e-35, 'units': 'm'} physical_constants['Planck mass'] = {'value': 2.17644e-8, 'precision': 0.00011e-8, 'units': 'kg'} physical_constants['Planck mass energy equivalent in GeV'] = {'value': 1.220892e19, 'precision': 0.000061e19, 'units': 'GeV'} physical_constants['Planck temperature'] = {'value': 1.416785e32, 'precision': 0.000071e32, 'units': 'K'} physical_constants['Planck time'] = {'value': 5.39124e-44, 'precision': 0.00027e-44, 'units': 's'} physical_constants['proton charge to mass quotient'] = {'value': 9.57883392e7, 'precision': 0.00000024e7, 'units': 'C*kg**-1'} physical_constants['proton Compton wavelength'] = {'value': 1.3214098446e-15, 'precision': 0.0000000019e-15, 'units': 'm'} physical_constants['proton Compton wavelength over 2 pi'] = {'value': 0.21030890861e-15, 'precision': 0.00000000030e-15, 'units': 'm'} physical_constants['proton-electron mass ratio'] = {'value': 1836.15267247, 'precision': 0.00000080, 'units': ''} physical_constants['proton g factor'] = {'value': 5.585694713, 'precision': 0.000000046, 'units': ''} physical_constants['proton gyromagnetic ratio'] = {'value': 2.675222099e8, 'precision': 0.000000070e8, 'units': 's**-1*T**-1'} physical_constants['proton gyromagnetic ratio over 2 pi'] = {'value': 42.5774821, 'precision': 0.0000011, 'units': 'MHz*T**-1'} physical_constants['proton magnetic moment'] = {'value': 1.410606662e-26, 'precision': 0.000000037e-26, 'units': 'J*T**-1'} physical_constants['proton magnetic moment to Bohr magneton ratio'] = {'value': 1.521032209e-3, 'precision': 0.000000012e-3, 'units': ''} physical_constants['proton magnetic moment to nuclear magneton ratio'] = {'value': 2.792847356, 'precision': 0.000000023, 'units': ''} physical_constants['proton magnetic shielding correction'] = {'value': 25.694e-6, 'precision': 0.014e-6, 'units': ''} physical_constants['proton mass'] = {'value': 1.672621637e-27, 'precision': 0.000000083e-27, 'units': 'kg'} physical_constants['proton mass energy equivalent'] = {'value': 1.503277359e-10, 'precision': 0.000000075e-10, 'units': 'J'} physical_constants['proton mass energy equivalent in MeV'] = {'value': 938.272013, 'precision': 0.000023, 'units': 'MeV'} physical_constants['proton mass in u'] = {'value': 1.00727646677, 'precision': 0.00000000010, 'units': 'u'} physical_constants['proton molar mass'] = {'value': 1.00727646677e-3, 'precision': 0.00000000010e-3, 'units': 'kg*mol**-1'} physical_constants['proton-muon mass ratio'] = {'value': 8.88024339, 'precision': 0.00000023, 'units': ''} physical_constants['proton-neutron magnetic moment ratio'] = {'value': -1.45989806, 'precision': 0.00000034, 'units': ''} physical_constants['proton-neutron mass ratio'] = {'value': 0.99862347824, 'precision': 0.00000000046, 'units': ''} physical_constants['proton rms charge radius'] = {'value': 0.8768e-15, 'precision': 0.0069e-15, 'units': 'm'} physical_constants['proton-tau mass ratio'] = {'value': 0.528012, 'precision': 0.000086, 'units': ''} physical_constants['quantum of circulation'] = {'value': 3.6369475199e-4, 'precision': 0.0000000050e-4, 'units': 'm**2*s**-1'} physical_constants['quantum of circulation times 2'] = {'value': 7.273895040e-4, 'precision': 0.000000010e-4, 'units': 'm**2*s**-1'} physical_constants['Rydberg constant'] = {'value': 10973731.568527, 'precision': 0.000073, 'units': 'm**-1'} physical_constants['Rydberg constant times c in Hz'] = {'value': 3.289841960361e15, 'precision': 0.000000000022e15, 'units': 'Hz'} physical_constants['Rydberg constant times hc in eV'] = {'value': 13.60569193, 'precision': 0.00000034, 'units': 'eV'} physical_constants['Rydberg constant times hc in J'] = {'value': 2.17987197e-18, 'precision': 0.00000011e-18, 'units': 'J'} physical_constants['Sackur-Tetrode constant (1 K, 100 kPa)'] = {'value': -1.1517047, 'precision': 0.0000044, 'units': ''} physical_constants['Sackur-Tetrode constant (1 K, 101.325 kPa)'] = {'value': -1.1648677, 'precision': 0.0000044, 'units': ''} physical_constants['second radiation constant'] = {'value': 1.4387752e-2, 'precision': 0.0000025e-2, 'units': 'm*K'} physical_constants['shielded helion gyromagnetic ratio'] = {'value': 2.037894730e8, 'precision': 0.000000056e8, 'units': 's**-1*T**-1'} physical_constants['shielded helion gyromagnetic ratio over 2 pi'] = {'value': 32.43410198, 'precision': 0.00000090, 'units': 'MHz*T**-1'} physical_constants['shielded helion magnetic moment'] = {'value': -1.074552982e-26, 'precision': 0.000000030e-26, 'units': 'J*T**-1'} physical_constants['shielded helion magnetic moment to Bohr magneton ratio'] = {'value': -1.158671471e-3, 'precision': 0.000000014e-3, 'units': ''} physical_constants['shielded helion magnetic moment to nuclear magneton ratio'] = {'value': -2.127497718, 'precision': 0.000000025, 'units': ''} physical_constants['shielded helion to proton magnetic moment ratio'] = {'value': -0.761766558, 'precision': 0.000000011, 'units': ''} physical_constants['shielded helion to shielded proton magnetic moment ratio'] = {'value': -0.7617861313, 'precision': 0.0000000033, 'units': ''} physical_constants['shielded proton gyromagnetic ratio'] = {'value': 2.675153362e8, 'precision': 0.000000073e8, 'units': 's**-1*T**-1'} physical_constants['shielded proton gyromagnetic ratio over 2 pi'] = {'value': 42.5763881, 'precision': 0.0000012, 'units': 'MHz*T**-1'} physical_constants['shielded proton magnetic moment'] = {'value': 1.410570419e-26, 'precision': 0.000000038e-26, 'units': 'J*T**-1'} physical_constants['shielded proton magnetic moment to Bohr magneton ratio'] = {'value': 1.520993128e-3, 'precision': 0.000000017e-3, 'units': ''} physical_constants['shielded proton magnetic moment to nuclear magneton ratio'] = {'value': 2.792775598, 'precision': 0.000000030, 'units': ''} physical_constants['speed of light in vacuum'] = {'value': 299792458, 'precision': 0, 'units': 'm*s**-1'} physical_constants['standard acceleration of gravity'] = {'value': 9.80665, 'precision': 0, 'units': 'm*s**-2'} physical_constants['standard atmosphere'] = {'value': 101325, 'precision': 0, 'units': 'Pa'} physical_constants['Stefan-Boltzmann constant'] = {'value': 5.670400e-8, 'precision': 0.000040e-8, 'units': 'W*m**-2*K**-4'} physical_constants['tau Compton wavelength'] = {'value': 0.69772e-15, 'precision': 0.00011e-15, 'units': 'm'} physical_constants['tau Compton wavelength over 2 pi'] = {'value': 0.111046e-15, 'precision': 0.000018e-15, 'units': 'm'} physical_constants['tau-electron mass ratio'] = {'value': 3477.48, 'precision': 0.57, 'units': ''} physical_constants['tau mass'] = {'value': 3.16777e-27, 'precision': 0.00052e-27, 'units': 'kg'} physical_constants['tau mass energy equivalent'] = {'value': 2.84705e-10, 'precision': 0.00046e-10, 'units': 'J'} physical_constants['tau mass energy equivalent in MeV'] = {'value': 1776.99, 'precision': 0.29, 'units': 'MeV'} physical_constants['tau mass in u'] = {'value': 1.90768, 'precision': 0.00031, 'units': 'u'} physical_constants['tau molar mass'] = {'value': 1.90768e-3, 'precision': 0.00031e-3, 'units': 'kg*mol**-1'} physical_constants['tau-muon mass ratio'] = {'value': 16.8183, 'precision': 0.0027, 'units': ''} physical_constants['tau-neutron mass ratio'] = {'value': 1.89129, 'precision': 0.00031, 'units': ''} physical_constants['tau-proton mass ratio'] = {'value': 1.89390, 'precision': 0.00031, 'units': ''} physical_constants['Thomson cross section'] = {'value': 0.6652458558e-28, 'precision': 0.0000000027e-28, 'units': 'm**2'} physical_constants['triton-electron magnetic moment ratio'] = {'value': -1.620514423e-3, 'precision': 0.000000021e-3, 'units': ''} physical_constants['triton-electron mass ratio'] = {'value': 5496.9215269, 'precision': 0.0000051, 'units': ''} physical_constants['triton g factor'] = {'value': 5.957924896, 'precision': 0.000000076, 'units': ''} physical_constants['triton magnetic moment'] = {'value': 1.504609361e-26, 'precision': 0.000000042e-26, 'units': 'J*T**-1'} physical_constants['triton magnetic moment to Bohr magneton ratio'] = {'value': 1.622393657e-3, 'precision': 0.000000021e-3, 'units': ''} physical_constants['triton magnetic moment to nuclear magneton ratio'] = {'value': 2.978962448, 'precision': 0.000000038, 'units': ''} physical_constants['triton mass'] = {'value': 5.00735588e-27, 'precision': 0.00000025e-27, 'units': 'kg'} physical_constants['triton mass energy equivalent'] = {'value': 4.50038703e-10, 'precision': 0.00000022e-10, 'units': 'J'} physical_constants['triton mass energy equivalent in MeV'] = {'value': 2808.920906, 'precision': 0.000070, 'units': 'MeV'} physical_constants['triton mass in u'] = {'value': 3.0155007134, 'precision': 0.0000000025, 'units': 'u'} physical_constants['triton molar mass'] = {'value': 3.0155007134e-3, 'precision': 0.0000000025e-3, 'units': 'kg*mol**-1'} physical_constants['triton-neutron magnetic moment ratio'] = {'value': -1.55718553, 'precision': 0.00000037, 'units': ''} physical_constants['triton-proton magnetic moment ratio'] = {'value': 1.066639908, 'precision': 0.000000010, 'units': ''} physical_constants['triton-proton mass ratio'] = {'value': 2.9937170309, 'precision': 0.0000000025, 'units': ''} physical_constants['unified atomic mass unit'] = {'value': 1.660538782e-27, 'precision': 0.000000083e-27, 'units': 'kg'} physical_constants['von Klitzing constant'] = {'value': 25812.807557, 'precision': 0.000018, 'units': 'ohm'} physical_constants['weak mixing angle'] = {'value': 0.22255, 'precision': 0.00056, 'units': ''} physical_constants['Wien frequency displacement law constant'] = {'value': 5.878933e10, 'precision': 0.000010e10, 'units': 'Hz*K**-1'} physical_constants['Wien wavelength displacement law constant'] = {'value': 2.8977685e-3, 'precision': 0.0000051e-3, 'units': 'm*K'} python-quantities-0.13.0/quantities/constants/_utils.py000066400000000000000000000006221417003363700233570ustar00rootroot00000000000000from ._codata import physical_constants from quantities.quantity import Quantity from quantities.uncertainquantity import UncertainQuantity def _cd(name): entry = physical_constants[name] if False: #entry['precision']: return UncertainQuantity( entry['value'], entry['units'], entry['precision'] ) else: return Quantity(entry['value'], entry['units']) python-quantities-0.13.0/quantities/constants/alpha.py000066400000000000000000000024011417003363700231420ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_alpha = alpha_particle_mass = UnitConstant( 'alpha_particle_mass', _cd('alpha particle mass'), symbol='m_alpha', u_symbol='m_α' ) alpha_particle_mass_energy_equivalent = UnitConstant( 'alpha_particle_mass_energy_equivalent', _cd('alpha particle mass energy equivalent'), symbol='(m_alpha*c**2)', u_symbol='(m_α·c²)' ) alpha_particle_mass_energy_equivalent_in_MeV = UnitConstant( 'alpha_particle_mass_energy_equivalent_in_MeV', _cd('alpha particle mass energy equivalent in MeV'), ) alpha_particle_mass_in_u = UnitConstant( 'alpha_particle_mass_in_u', _cd('alpha particle mass in u') ) alpha_particle_molar_mass = UnitConstant( 'alpha_particle_molar_mass', _cd('alpha particle molar mass'), symbol='M_alpha', u_symbol='M_α' ) alpha_particle_electron_mass_ratio = UnitConstant( 'alpha_particle_electron_mass_ratio', _cd('alpha particle-electron mass ratio'), symbol='(m_alpha/m_e)', u_symbol='(m_α/mₑ)' ) alpha_particle_proton_mass_ratio = UnitConstant( 'alpha_particle_proton_mass_ratio', _cd('alpha particle-proton mass ratio'), symbol='(m_alpha/m_p)', u_symbol='(m_α/m_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/astronomy.py000066400000000000000000000007761417003363700241250ustar00rootroot00000000000000""" """ from ._utils import _cd from ..uncertainquantity import UncertainQuantity from ..unitquantity import UnitConstant au = astronomical_unit = UnitConstant( 'astronomical_unit', UncertainQuantity(149597870700, 'm', 3), symbol='au', doc='http://en.wikipedia.org/wiki/Astronomical_unit' ) G = Newtonian_constant_of_gravitation = UnitConstant( 'Newtonian_constant_of_gravitation', _cd('Newtonian constant of gravitation'), symbol='G' ) del UnitConstant, UncertainQuantity, _cd python-quantities-0.13.0/quantities/constants/atomicunits.py000066400000000000000000000207641417003363700244300ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant amu = atomic_mass_constant = UnitConstant( 'atomic_mass_constant', _cd('atomic mass constant'), symbol='m_u', u_symbol='mᵤ' ) atomic_unit_of_1st_hyperpolarizability = UnitConstant( 'atomic_unit_of_1st_hyperpolarizability', _cd('atomic unit of 1st hyperpolarizability'), symbol='(e**3*a_0**3/E_h**2)', u_symbol='(e³·a₀³/E_h²)' ) atomic_unit_of_2nd_hyperpolarizability = UnitConstant( 'atomic_unit_of_2nd_hyperpolarizability', _cd('atomic unit of 2nd hyperpolarizability'), symbol='(e**4*a_0**4/E_h**3)', u_symbol='(e⁴·a₀⁴/E_h³)' ) hbar = atomic_unit_of_action = UnitConstant( 'atomic_unit_of_action', _cd('atomic unit of action'), symbol='hbar', u_symbol='ħ' ) atomic_unit_of_charge = UnitConstant( 'atomic_unit_of_charge', _cd('atomic unit of charge'), symbol='e' ) atomic_unit_of_charge_density = UnitConstant( 'atomic_unit_of_charge_density', _cd('atomic unit of charge density'), symbol='(e/a_0**3)', u_symbol='(e/a₀³)' ) atomic_unit_of_current = UnitConstant( 'atomic_unit_of_current', _cd('atomic unit of current'), symbol='(e*E_h/hbar)', u_symbol='(e·E_h/ħ)' ) atomic_unit_of_electric_dipole_moment = UnitConstant( 'atomic_unit_of_electric_dipole_moment', _cd('atomic unit of electric dipole moment'), symbol='(e*a_0)', u_symbol='(e·a₀)' ) atomic_unit_of_electric_field = UnitConstant( 'atomic_unit_of_electric_field', _cd('atomic unit of electric field'), symbol='(E_h/(e*a_0))', u_symbol='(E_h/(e·a₀))' ) atomic_unit_of_electric_field_gradient = UnitConstant( 'atomic_unit_of_electric_field_gradient', _cd('atomic unit of electric field gradient'), symbol='(E_h/(e*a_0**2))', u_symbol='(E_h/(e·a₀²))' ) atomic_unit_of_electric_polarizability = UnitConstant( 'atomic_unit_of_electric_polarizability', _cd('atomic unit of electric polarizability'), symbol='(e**2*a_0**2/E_h)', u_symbol='(e²·a₀²/E_h)' ) atomic_unit_of_electric_potential = UnitConstant( 'atomic_unit_of_electric_potential', _cd('atomic unit of electric potential'), symbol='(E_h/e)' ) atomic_unit_of_electric_quadrupole_moment = UnitConstant( 'atomic_unit_of_electric_quadrupole_moment', _cd('atomic unit of electric quadrupole moment'), symbol='(e*a_0**2)', u_symbol='(e·a₀²)' ) atomic_unit_of_energy = UnitConstant( 'atomic_unit_of_energy', _cd('atomic unit of energy'), ) atomic_unit_of_force = UnitConstant( 'atomic_unit_of_force', _cd('atomic unit of force'), symbol='(E_h/a_0)', u_symbol='(E_h/a₀)' ) a_0 = atomic_unit_of_length = UnitConstant( 'atomic_unit_of_length', _cd('atomic unit of length'), symbol='a_0', u_symbol='a₀' ) Bohr_radius = UnitConstant( 'Bohr_radius', _cd('Bohr radius'), symbol='a_0', u_symbol='a₀' ) atomic_unit_of_magnetic_dipole_moment = UnitConstant( 'atomic_unit_of_magnetic_dipole_moment', _cd('atomic unit of magnetic dipole moment'), symbol='(hbar*e/m_e)', u_symbol='(ħ·e/mₑ)' ) atomic_unit_of_magnetic_flux_density = UnitConstant( 'atomic_unit_of_magnetic_flux_density', _cd('atomic unit of magnetic flux density'), symbol='(hbar*e/a_0**2)', u_symbol='(ħ·e/a₀²)' ) atomic_unit_of_magnetizability = UnitConstant( 'atomic_unit_of_magnetizability', _cd('atomic unit of magnetizability'), symbol='(e**2a_0**2/m_e)', u_symbol='(e²·a₀²/mₑ)' ) m_e = atomic_unit_of_mass = UnitConstant( 'atomic_unit_of_mass', _cd('atomic unit of mass'), symbol='m_e', u_symbol='mₑ' ) atomic_unit_of_momentum = UnitConstant( 'atomic_unit_of_momentum', _cd('atomic unit of momentum'), symbol='(hbar/a_0)', u_symbol='(ħ/a₀)' ) atomic_unit_of_permittivity = UnitConstant( 'atomic_unit_of_permittivity', _cd('atomic unit of permittivity'), symbol='(e**2/(a_0*E_h))', u_symbol='(e²/(a₀·E_h))' ) atomic_unit_of_time = UnitConstant( 'atomic_unit_of_time', _cd('atomic unit of time'), symbol='(hbar/E_h)', u_symbol='(ħ/E_h)' ) atomic_unit_of_velocity = UnitConstant( 'atomic_unit_of_velocity', _cd('atomic unit of velocity'), symbol='(a_0*E_h/hbar)', u_symbol='(a₀·E_h/ħ)' ) E_h = Hartree_energy = UnitConstant( 'Hartree_energy', _cd('Hartree energy'), symbol='E_h' ) u = unified_atomic_mass_unit = UnitConstant( 'unified_atomic_mass_unit', _cd('unified atomic mass unit'), symbol='u' ) molar_mass_of_carbon_12 = UnitConstant( 'molar_mass_of_carbon_12', _cd('molar mass of carbon-12'), symbol='M_C12', u_symbol='M_¹²C' ) atomic_mass_constant_energy_equivalent = UnitConstant( 'atomic_mass_constant_energy_equivalent', _cd('atomic mass constant energy equivalent'), symbol='(m_u*c**2)', u_symbol='(mᵤ·c²)' ) atomic_mass_constant_energy_equivalent_in_MeV = UnitConstant( 'atomic_mass_constant_energy_equivalent_in_MeV', _cd('atomic mass constant energy equivalent in MeV') ) Hartree_energy_in_eV = UnitConstant( 'Hartree_energy_in_eV', _cd('Hartree energy in eV') ) atomic_mass_unit_electron_volt_relationship = UnitConstant( 'atomic_mass_unit_electron_volt_relationship', _cd('atomic mass unit-electron volt relationship'), ) atomic_mass_unit_hartree_relationship = UnitConstant( 'atomic_mass_unit_hartree_relationship', _cd('atomic mass unit-hartree relationship') ) atomic_mass_unit_hertz_relationship = UnitConstant( 'atomic_mass_unit_hertz_relationship', _cd('atomic mass unit-hertz relationship') ) atomic_mass_unit_inverse_meter_relationship = UnitConstant( 'atomic_mass_unit_inverse_meter_relationship', _cd('atomic mass unit-inverse meter relationship') ) atomic_mass_unit_joule_relationship = UnitConstant( 'atomic_mass_unit_joule_relationship', _cd('atomic mass unit-joule relationship'), symbol='(u*c**2)', u_symbol='(u·c²)' ) atomic_mass_unit_kelvin_relationship = UnitConstant( 'atomic_mass_unit_kelvin_relationship', _cd('atomic mass unit-kelvin relationship') ) atomic_mass_unit_kilogram_relationship = UnitConstant( 'atomic_mass_unit_kilogram_relationship', _cd('atomic mass unit-kilogram relationship') ) hartree_atomic_mass_unit_relationship = UnitConstant( 'hartree_atomic_mass_unit_relationship', _cd('hartree-atomic mass unit relationship') ) hartree_electron_volt_relationship = UnitConstant( 'hartree_electron_volt_relationship', _cd('hartree-electron volt relationship') ) hartree_hertz_relationship = UnitConstant( 'hartree_hertz_relationship', _cd('hartree-hertz relationship') ) hartree_inverse_meter_relationship = UnitConstant( 'hartree_inverse_meter_relationship', _cd('hartree-inverse meter relationship') ) hartree_joule_relationship = UnitConstant( 'hartree_joule_relationship', _cd('hartree-joule relationship') ) hartree_kelvin_relationship = UnitConstant( 'hartree_kelvin_relationship', _cd('hartree-kelvin relationship') ) hartree_kilogram_relationship = UnitConstant( 'hartree_kilogram_relationship', _cd('hartree-kilogram relationship') ) hertz_atomic_mass_unit_relationship = UnitConstant( 'hertz_atomic_mass_unit_relationship', _cd('hertz-atomic mass unit relationship') ) hertz_hartree_relationship = UnitConstant( 'hertz_hartree_relationship', _cd('hertz-hartree relationship') ) inverse_meter_atomic_mass_unit_relationship = UnitConstant( 'inverse_meter_atomic_mass_unit_relationship', _cd('inverse meter-atomic mass unit relationship') ) inverse_meter_hartree_relationship = UnitConstant( 'inverse_meter_hartree_relationship', _cd('inverse meter-hartree relationship') ) joule_atomic_mass_unit_relationship = UnitConstant( 'joule_atomic_mass_unit_relationship', _cd('joule-atomic mass unit relationship') ) joule_hartree_relationship = UnitConstant( 'joule_hartree_relationship', _cd('joule-hartree relationship') ) kelvin_atomic_mass_unit_relationship = UnitConstant( 'kelvin_atomic_mass_unit_relationship', _cd('kelvin-atomic mass unit relationship') ) kelvin_hartree_relationship = UnitConstant( 'kelvin_hartree_relationship', _cd('kelvin-hartree relationship') ) kilogram_atomic_mass_unit_relationship = UnitConstant( 'kilogram_atomic_mass_unit_relationship', _cd('kilogram-atomic mass unit relationship') ) kilogram_hartree_relationship = UnitConstant( 'kilogram_hartree_relationship', _cd('kilogram-hartree relationship') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/deuteron.py000066400000000000000000000050131417003363700237040ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant R_d = deuteron_rms_charge_radius = UnitConstant( 'deuteron_rms_charge_radius', _cd('deuteron rms charge radius'), symbol='R_d' ) m_d = deuteron_mass = UnitConstant( 'deuteron_mass', _cd('deuteron mass'), symbol='m_d' ) g_d = deuteron_g_factor = UnitConstant( 'deuteron_g_factor', _cd('deuteron g factor'), symbol='g_d' ) mu_d = deuteron_magnetic_moment = UnitConstant( 'deuteron_magnetic_moment', _cd('deuteron magnetic moment'), symbol='mu_d', u_symbol='μ_d' ) deuteron_mass_energy_equivalent = UnitConstant( 'deuteron_mass_energy_equivalent', _cd('deuteron mass energy equivalent'), symbol='(m_d*c**2)', u_symbol='(m_d·c²)' ) deuteron_mass_energy_equivalent_in_MeV = UnitConstant( 'deuteron_mass_energy_equivalent_in_MeV', _cd('deuteron mass energy equivalent in MeV') ) deuteron_mass_in_u = UnitConstant( 'deuteron_mass_in_u', _cd('deuteron mass in u') ) deuteron_molar_mass = UnitConstant( 'deuteron_molar_mass', _cd('deuteron molar mass'), symbol='M_d' ) deuteron_electron_mass_ratio = UnitConstant( 'deuteron_electron_mass_ratio', _cd('deuteron-electron mass ratio'), symbol='(m_d/m_e)', u_symbol='(m_d/mₑ)' ) deuteron_proton_mass_ratio = UnitConstant( 'deuteron_proton_mass_ratio', _cd('deuteron-proton mass ratio'), symbol='(m_d/m_n)' ) deuteron_electron_magnetic_moment_ratio = UnitConstant( 'deuteron_electron_magnetic_moment_ratio', _cd('deuteron-electron magnetic moment ratio'), symbol='(mu_d/mu_e)', u_symbol='(μ_d/μₑ)' ) deuteron_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'deuteron_magnetic_moment_to_Bohr_magneton_ratio', _cd('deuteron magnetic moment to Bohr magneton ratio'), symbol='(mu_d/mu_B)', u_symbol='(μ_d/μ_B)' ) deuteron_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'deuteron_magnetic_moment_to_nuclear_magneton_ratio', _cd('deuteron magnetic moment to nuclear magneton ratio'), symbol='(mu_d/mu_N)', u_symbol='(μ_d/μ_N)' ) deuteron_neutron_magnetic_moment_ratio = UnitConstant( 'deuteron_neutron_magnetic_moment_ratio', _cd('deuteron-neutron magnetic moment ratio'), symbol='(mu_d/mu_n)', u_symbol='(μ_d/μ_n)' ) deuteron_proton_magnetic_moment_ratio = UnitConstant( 'deuteron_proton_magnetic_moment_ratio', _cd('deuteron-proton magnetic moment ratio'), symbol='(mu_d/mu_p)', u_symbol='(μ_d/μ_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/electromagnetism.py000066400000000000000000000011531417003363700254220ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant Z_0 = impedence_of_free_space = characteristic_impedance_of_vacuum = UnitConstant( 'characteristic_impedance_of_vacuum', _cd('characteristic impedance of vacuum'), symbol='Z_0', u_symbol='Z₀' ) vacuum_permittivity = epsilon_0 = electric_constant = UnitConstant( 'electric_constant', _cd('electric constant'), symbol='epsilon_0', u_symbol='ε₀' ) mu_0 = magnetic_constant = UnitConstant( 'magnetic_constant', _cd('magnetic constant'), symbol='mu_0', u_symbol='μ₀' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/electron.py000066400000000000000000000177331417003363700237060ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant e = elementary_charge = UnitConstant( 'elementary_charge', _cd('elementary charge'), symbol='e' ) elementary_charge_over_h = UnitConstant( 'elementary_charge_over_h', _cd('elementary charge over h'), symbol='e/h' ) Faraday_constant = UnitConstant( 'Faraday_constant', _cd('Faraday constant'), symbol='F' ) #F_star = Faraday_constant_for_conventional_electric_current = UnitConstant( # _cd('Faraday constant for conventional electric current') what is a unit of C_90? r_e = classical_electron_radius = UnitConstant( 'classical_electron_radius', _cd('classical electron radius'), symbol='r_e', u_symbol='rₑ' ) m_e = electron_mass = UnitConstant( 'electron_mass', _cd('electron mass'), symbol='m_e', u_symbol='mₑ' ) lambda_C = Compton_wavelength = UnitConstant( 'Compton_wavelength', _cd('Compton wavelength'), symbol='lambda_C', u_symbol='λ_C' ) Compton_wavelength_over_2_pi = UnitConstant( 'Compton_wavelength_over_2_pi', _cd('Compton wavelength over 2 pi'), symbol='lambdabar_C', u_symbol='ƛ_C' ) electron_charge_to_mass_quotient = UnitConstant( 'electron_charge_to_mass_quotient', _cd('electron charge to mass quotient'), symbol='(-e/m_e)', u_symbol='(-e/mₑ)' ) g_e = electron_g_factor = UnitConstant( 'electron_g_factor', _cd('electron g factor'), symbol='g_e', u_symbol='gₑ' ) gamma_e = electron_gyromagnetic_ratio = UnitConstant( 'electron_gyromagnetic_ratio', _cd('electron gyromagnetic ratio'), symbol='gamma_e', u_symbol='γₑ' ) electron_gyromagnetic_ratio_over_2_pi = UnitConstant( 'electron_gyromagnetic_ratio_over_2_pi', _cd('electron gyromagnetic ratio over 2 pi'), symbol='gamma_e/(2*pi)', u_symbol='γₑ/(2·π)' ) mu_e = electron_magnetic_moment = UnitConstant( 'electron_magnetic_moment', _cd('electron magnetic moment'), symbol='mu_e', u_symbol='μₑ' ) a_e = electron_magnetic_moment_anomaly = UnitConstant( 'electron_magnetic_moment_anomaly', _cd('electron magnetic moment anomaly'), symbol='a_e', u_symbol='aₑ' ) eV = electron_volt = UnitConstant( 'electron_volt', _cd('electron volt'), symbol='eV' ) sigma_e = Thomson_cross_section = UnitConstant( 'Thomson_cross_section', _cd('Thomson cross section'), symbol='sigma_e', u_symbol='σₑ' ) mu_B = Bohr_magneton = UnitConstant( 'Bohr_magneton', _cd('Bohr magneton'), symbol='mu_B', u_symbol='μ_B' ) Bohr_magneton_in_Hz_per_T = UnitConstant( 'Bohr_magneton_in_Hz_per_T', _cd('Bohr magneton in Hz/T') ) Bohr_magneton_in_inverse_meters_per_tesla = UnitConstant( 'Bohr_magneton_in_inverse_meters_per_tesla', _cd('Bohr magneton in inverse meters per tesla') ) Bohr_magneton_in_K_per_T = UnitConstant( 'Bohr_magneton_in_K_per_T', _cd('Bohr magneton in K/T') ) electron_mass_energy_equivalent = UnitConstant( 'electron_mass_energy_equivalent', _cd('electron mass energy equivalent'), symbol='(m_e*c**2)', u_symbol='(mₑ·c²)' ) electron_mass_energy_equivalent_in_MeV = UnitConstant( 'electron_mass_energy_equivalent_in_MeV', _cd('electron mass energy equivalent in MeV') ) electron_mass_in_u = UnitConstant( 'electron_mass_in_u', _cd('electron mass in u') ) electron_molar_mass = UnitConstant( 'electron_molar_mass', _cd('electron molar mass'), symbol='M_e', u_symbol='Mₑ' ) electron_deuteron_mass_ratio = UnitConstant( 'electron_deuteron_mass_ratio', _cd('electron-deuteron mass ratio'), symbol='(m_e/m_d)', u_symbol='(mₑ/m_d)' ) electron_muon_mass_ratio = UnitConstant( 'electron_muon_mass_ratio', _cd('electron-muon mass ratio'), symbol='(m_e/m_mu)', u_symbol='(mₑ/m_μ)' ) electron_neutron_mass_ratio = UnitConstant( 'electron_neutron_mass_ratio', _cd('electron-neutron mass ratio'), symbol='(m_e/m_n)', u_symbol='(mₑ/m_n)' ) electron_proton_mass_ratio = UnitConstant( 'electron_proton_mass_ratio', _cd('electron-proton mass ratio'), symbol='(m_e/m_p)', u_symbol='(mₑ/m_p)' ) electron_tau_mass_ratio = UnitConstant( 'electron_tau_mass_ratio', _cd('electron-tau mass ratio'), symbol='(m_e/m_tau)', u_symbol='(mₑ/m_τ)' ) electron_to_alpha_particle_mass_ratio = UnitConstant( 'electron_to_alpha_particle_mass_ratio', _cd('electron to alpha particle mass ratio'), symbol='(m_e/m_alpha)', u_symbol='(mₑ/m_α)' ) electron_deuteron_magnetic_moment_ratio = UnitConstant( 'electron_deuteron_magnetic_moment_ratio', _cd('electron-deuteron magnetic moment ratio'), symbol='(mu_e/mu_d)', u_symbol='(μₑ/μ_d)' ) electron_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'electron_magnetic_moment_to_Bohr_magneton_ratio', _cd('electron magnetic moment to Bohr magneton ratio'), symbol='(mu_e/mu_B)', u_symbol='(μₑ/μ_B)' ) electron_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'electron_magnetic_moment_to_nuclear_magneton_ratio', _cd('electron magnetic moment to nuclear magneton ratio'), symbol='(mu_e/mu_N)', u_symbol='(μₑ/μ_N)' ) electron_muon_magnetic_moment_ratio = UnitConstant( 'electron_muon_magnetic_moment_ratio', _cd('electron-muon magnetic moment ratio'), symbol='(mu_e/mu_mu)', u_symbol='(μₑ/μ_μ)' ) electron_neutron_magnetic_moment_ratio = UnitConstant( 'electron_neutron_magnetic_moment_ratio', _cd('electron-neutron magnetic moment ratio'), symbol='(mu_e/mu_n)', u_symbol='(μₑ/μ_n)' ) electron_proton_magnetic_moment_ratio = UnitConstant( 'electron_proton_magnetic_moment_ratio', _cd('electron-proton magnetic moment ratio'), symbol='(mu_e/mu_p)', u_symbol='(μₑ/μ_p)' ) electron_to_shielded_helion_magnetic_moment_ratio = UnitConstant( 'electron_to_shielded_helion_magnetic_moment_ratio', _cd('electron to shielded helion magnetic moment ratio'), symbol='(mu_e/muprime_h)', u_symbol='(μₑ/μ′_h)' ) electron_to_shielded_proton_magnetic_moment_ratio = UnitConstant( 'electron_to_shielded_proton_magnetic_moment_ratio', _cd('electron to shielded proton magnetic moment ratio'), symbol='(mu_e/muprime_p)', u_symbol='(μₑ/μ′_p)' ) electron_volt_atomic_mass_unit_relationship = UnitConstant( 'electron_volt_atomic_mass_unit_relationship', _cd('electron volt-atomic mass unit relationship') ) electron_volt_hartree_relationship = UnitConstant( 'electron_volt_hartree_relationship', _cd('electron volt-hartree relationship') ) electron_volt_hertz_relationship = UnitConstant( 'electron_volt_hertz_relationship', _cd('electron volt-hertz relationship') ) electron_volt_inverse_meter_relationship = UnitConstant( 'electron_volt_inverse_meter_relationship', _cd('electron volt-inverse meter relationship') ) electron_volt_joule_relationship = UnitConstant( 'electron_volt_joule_relationship', _cd('electron volt-joule relationship') ) electron_volt_kelvin_relationship = UnitConstant( 'electron_volt_kelvin_relationship', _cd('electron volt-kelvin relationship') ) electron_volt_kilogram_relationship = UnitConstant( 'electron_volt_kilogram_relationship', _cd('electron volt-kilogram relationship') ) hertz_electron_volt_relationship = UnitConstant( 'hertz_electron_volt_relationship', _cd('hertz-electron volt relationship') ) inverse_meter_electron_volt_relationship = UnitConstant( 'inverse_meter_electron_volt_relationship', _cd('inverse meter-electron volt relationship') ) joule_electron_volt_relationship = UnitConstant( 'joule_electron_volt_relationship', _cd('joule-electron volt relationship') ) kelvin_electron_volt_relationship = UnitConstant( 'kelvin_electron_volt_relationship', _cd('kelvin-electron volt relationship') ) kilogram_electron_volt_relationship = UnitConstant( 'kilogram_electron_volt_relationship', _cd('kilogram-electron volt relationship') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/helion.py000066400000000000000000000052331417003363700233410ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_h = helion_mass = UnitConstant( 'helion_mass', _cd('helion mass'), symbol='m_h' ) gamma_prime_h = shielded_helion_gyromagnetic_ratio = UnitConstant( 'shielded_helion_gyromagnetic_ratio', _cd('shielded helion gyromagnetic ratio'), symbol='gammaprime_h', u_symbol='γ′_h' ) shielded_helion_gyromagnetic_ratio_over_2_pi = UnitConstant( 'shielded_helion_gyromagnetic_ratio_over_2_pi', _cd('shielded helion gyromagnetic ratio over 2 pi'), symbol='(gammaprime_h/(2*pi))', u_symbol='(γ′_h/(2·π))' ) mu_prime_h = shielded_helion_magnetic_moment = UnitConstant( 'shielded_helion_magnetic_moment', _cd('shielded helion magnetic moment'), symbol='muprime_h', u_symbol='μ′_h' ) helion_mass_energy_equivalent = UnitConstant( 'helion_mass_energy_equivalent', _cd('helion mass energy equivalent'), symbol='(m_h*c**2)', u_symbol='(m_h·c²)' ) helion_mass_energy_equivalent_in_MeV = UnitConstant( 'helion_mass_energy_equivalent_in_MeV', _cd('helion mass energy equivalent in MeV') ) helion_mass_in_u = UnitConstant( 'helion_mass_in_u', _cd('helion mass in u') ) helion_molar_mass = UnitConstant( 'helion_molar_mass', _cd('helion molar mass'), symbol='M_h' ) helion_electron_mass_ratio = UnitConstant( 'helion_electron_mass_ratio', _cd('helion-electron mass ratio'), symbol='(m_h/m_e)', u_symbol='(m_h/mₑ)' ) helion_proton_mass_ratio = UnitConstant( 'helion_proton_mass_ratio', _cd('helion-proton mass ratio'), symbol='(m_h/m_p)' ) shielded_helion_to_proton_magnetic_moment_ratio = UnitConstant( 'shielded_helion_to_proton_magnetic_moment_ratio', _cd('shielded helion to proton magnetic moment ratio'), symbol='(muprime_h/mu_p)', u_symbol='(μ′_h/μ_p)' ) shielded_helion_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'shielded_helion_magnetic_moment_to_Bohr_magneton_ratio', _cd('shielded helion magnetic moment to Bohr magneton ratio'), symbol='(muprime_h/mu_B)', u_symbol='(μ′_h/μ_B)' ) shielded_helion_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'shielded_helion_magnetic_moment_to_nuclear_magneton_ratio', _cd('shielded helion magnetic moment to nuclear magneton ratio'), symbol='(muprime_h/mu_N)', u_symbol='(μ′_h/μ_N)' ) shielded_helion_to_shielded_proton_magnetic_moment_ratio = UnitConstant( 'shielded_helion_to_shielded_proton_magnetic_moment_ratio', _cd('shielded helion to shielded proton magnetic moment ratio'), symbol='(muprime_h/muprime_p)', u_symbol='(μ′_h/μ′_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/mathematical.py000066400000000000000000000004001417003363700245030ustar00rootroot00000000000000import math as _math from ..unitquantity import UnitConstant pi = UnitConstant( 'pi', _math.pi, u_symbol='π' ) golden = golden_ratio = UnitConstant( 'golden_ratio', (1 + _math.sqrt(5)) / 2, u_symbol='ϕ', aliases='golden' ) python-quantities-0.13.0/quantities/constants/muon.py000066400000000000000000000054111417003363700230370ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_mu = muon_mass = UnitConstant( 'muon_mass', _cd('muon mass'), symbol='m_mu', u_symbol='m_μ' ) lambda_C_mu = muon_Compton_wavelength = UnitConstant( 'muon_Compton_wavelength', _cd('muon Compton wavelength'), symbol='lambdabar_C_mu', u_symbol='λ_C_μ' ) muon_Compton_wavelength_over_2_pi = UnitConstant( 'muon_Compton_wavelength_over_2_pi', _cd('muon Compton wavelength over 2 pi'), symbol='lambdabar_Cmu', u_symbol='ƛ_C_μ' ) g_mu = muon_g_factor = UnitConstant( 'muon_g_factor', _cd('muon g factor'), symbol='g_mu', u_symbol='g_μ' ) mu_mu = muon_magnetic_moment = UnitConstant( 'muon_magnetic_moment', _cd('muon magnetic moment'), symbol='mu_mu', u_symbol='μ_μ' ) a_mu = muon_magnetic_moment_anomaly = UnitConstant( 'muon_magnetic_moment_anomaly', _cd('muon magnetic moment anomaly'), symbol='a_mu', u_symbol='a_μ' ) muon_mass_energy_equivalent = UnitConstant( 'muon_mass_energy_equivalent', _cd('muon mass energy equivalent'), symbol='(m_mu*c**2)', u_symbol='(m_μ·c²)' ) muon_mass_energy_equivalent_in_MeV = UnitConstant( 'muon_mass_energy_equivalent_in_MeV', _cd('muon mass energy equivalent in MeV') ) muon_mass_in_u = UnitConstant( 'muon_mass_in_u', _cd('muon mass in u') ) muon_molar_mass = UnitConstant( 'muon_molar_mass', _cd('muon molar mass'), symbol='M_mu', u_symbol='M_μ' ) muon_electron_mass_ratio = UnitConstant( 'muon_electron_mass_ratio', _cd('muon-electron mass ratio'), symbol='(m_mu/m_e)', u_symbol='(m_μ/mₑ)' ) muon_neutron_mass_ratio = UnitConstant( 'muon_neutron_mass_ratio', _cd('muon-neutron mass ratio'), symbol='(m_mu/m_n)', u_symbol='(m_μ/m_n)' ) muon_proton_mass_ratio = UnitConstant( 'muon_proton_mass_ratio', _cd('muon-proton mass ratio'), symbol='(m_mu/m_p)', u_symbol='(m_μ/m_p)' ) muon_tau_mass_ratio = UnitConstant( 'muon_tau_mass_ratio', _cd('muon-tau mass ratio'), symbol='(m_mu/m_tau)', u_symbol='(m_μ/m_τ)' ) muon_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'muon_magnetic_moment_to_Bohr_magneton_ratio', _cd('muon magnetic moment to Bohr magneton ratio'), symbol='(mu_mu/mu_B)', u_symbol='(μ_μ/μ_B)' ) muon_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'muon_magnetic_moment_to_nuclear_magneton_ratio', _cd('muon magnetic moment to nuclear magneton ratio'), symbol='(mu_mu/mu_N)', u_symbol='(μ_μ/μ_N)' ) muon_proton_magnetic_moment_ratio = UnitConstant( 'muon_proton_magnetic_moment_ratio', _cd('muon-proton magnetic moment ratio'), symbol='(mu_mu/mu_p)', u_symbol='(μ_μ/μ_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/naturalunits.py000066400000000000000000000030051417003363700246070ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant natural_unit_of_action = UnitConstant( 'natural_unit_of_action', _cd('natural unit of action'), symbol='hbar', u_symbol='ħ' ) natural_unit_of_energy = UnitConstant( 'natural_unit_of_energy', _cd('natural unit of energy'), symbol='(m_e*c**2)', u_symbol='(mₑ·c²)' ) natural_unit_of_length = UnitConstant( 'natural_unit_of_length', _cd('natural unit of length'), symbol='lambdabar_C', u_symbol='ƛ_C' ) natural_unit_of_mass = UnitConstant( 'natural_unit_of_mass', _cd('natural unit of mass'), symbol='m_e', u_symbol='mₑ' ) natural_unit_of_momentum = UnitConstant( 'natural_unit_of_momentum', _cd('natural unit of momentum'), symbol='(m_e*c)', u_symbol='(mₑ·c)' ) natural_unit_of_time = UnitConstant( 'natural_unit_of_time', _cd('natural unit of time'), symbol='(hbar/(m_e*c**2))', u_symbol='(ħ/(mₑ·c²))' ) natural_unit_of_velocity = UnitConstant( 'natural_unit_of_velocity', _cd('natural unit of velocity'), symbol='c' ) natural_unit_of_action_in_eV_s = UnitConstant( 'natural_unit_of_action_in_eV_s', _cd('natural unit of action in eV s') ) natural_unit_of_energy_in_MeV = UnitConstant( 'natural_unit_of_energy_in_MeV', _cd('natural unit of energy in MeV') ) natural_unit_of_momentum_in_MeV_per_c = UnitConstant( 'natural_unit_of_momentum_in_MeV_per_c', _cd('natural unit of momentum in MeV/c') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/neutron.py000066400000000000000000000067131417003363700235610ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_n = neutron_mass = UnitConstant( 'neutron_mass', _cd('neutron mass'), symbol='m_n' ) lambda_C_n = neutron_Compton_wavelength = UnitConstant( 'neutron_Compton_wavelength', _cd('neutron Compton wavelength'), symbol='lambda_C_n', u_symbol='λ_C_n' ) neutron_Compton_wavelength_over_2_pi = UnitConstant( 'neutron_Compton_wavelength_over_2_pi', _cd('neutron Compton wavelength over 2 pi'), symbol='lambdabar_C_n', u_symbol='ƛ_C_n' ) g_n = neutron_g_factor = UnitConstant( 'neutron_g_factor', _cd('neutron g factor'), symbol='g_n' ) gamma_n = neutron_gyromagnetic_ratio = UnitConstant( 'neutron_gyromagnetic_ratio', _cd('neutron gyromagnetic ratio'), symbol='gamma_n', u_symbol='γ_n' ) neutron_gyromagnetic_ratio_over_2_pi = UnitConstant( 'neutron_gyromagnetic_ratio_over_2_pi', _cd('neutron gyromagnetic ratio over 2 pi'), symbol='(gamma_n/(2*pi))', u_symbol='(γ_n/(2·π))' ) mu_n = neutron_magnetic_moment = UnitConstant( 'neutron_magnetic_moment', _cd('neutron magnetic moment'), symbol='mu_n', u_symbol='μ_n' ) neutron_mass_energy_equivalent = UnitConstant( 'neutron_mass_energy_equivalent', _cd('neutron mass energy equivalent'), symbol='(m_n*c**2)', u_symbol='(m_n·c²)' ) neutron_mass_energy_equivalent_in_MeV = UnitConstant( 'neutron_mass_energy_equivalent_in_MeV', _cd('neutron mass energy equivalent in MeV') ) neutron_mass_in_u = UnitConstant( 'neutron_mass_in_u', _cd('neutron mass in u') ) neutron_molar_mass = UnitConstant( 'neutron_molar_mass', _cd('neutron molar mass'), symbol='M_n' ) neutron_electron_mass_ratio = UnitConstant( 'neutron_electron_mass_ratio', _cd('neutron-electron mass ratio'), symbol='(m_n/m_e)', u_symbol='(m_n/mₑ)' ) neutron_muon_mass_ratio = UnitConstant( 'neutron_muon_mass_ratio', _cd('neutron-muon mass ratio'), symbol='(m_n/m_mu)', u_symbol='(m_n/m_μ)' ) neutron_proton_mass_ratio = UnitConstant( 'neutron_proton_mass_ratio', _cd('neutron-proton mass ratio'), symbol='(m_n/m_p)', u_symbol='(m_n/m_p)' ) neutron_tau_mass_ratio = UnitConstant( 'neutron_tau_mass_ratio', _cd('neutron-tau mass ratio'), symbol='(m_n/m_tau)', u_symbol='(m_n/m_τ)' ) neutron_electron_magnetic_moment_ratio = UnitConstant( 'neutron_electron_magnetic_moment_ratio', _cd('neutron-electron magnetic moment ratio'), symbol='(mu_n/mu_e)', u_symbol='(μ_n/μₑ)' ) neutron_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'neutron_magnetic_moment_to_Bohr_magneton_ratio', _cd('neutron magnetic moment to Bohr magneton ratio'), symbol='(mu_n/mu_B)', u_symbol='(μ_n/μ_B)' ) neutron_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'neutron_magnetic_moment_to_nuclear_magneton_ratio', _cd('neutron magnetic moment to nuclear magneton ratio'), symbol='(mu_n/mu_N)', u_symbol='(μ_n/μ_N)' ) neutron_proton_magnetic_moment_ratio = UnitConstant( 'neutron_proton_magnetic_moment_ratio', _cd('neutron-proton magnetic moment ratio'), symbol='(mu_n/mu_p)', u_symbol='(μ_n/μ_p)' ) neutron_to_shielded_proton_magnetic_moment_ratio = UnitConstant( 'neutron_to_shielded_proton_magnetic_moment_ratio', _cd('neutron to shielded proton magnetic moment ratio'), symbol='(mu_n/muprime_p)', u_symbol='(μ_n/μ′_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/proton.py000066400000000000000000000123411417003363700234020ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_p = proton_mass = UnitConstant( 'proton_mass', _cd('proton mass'), symbol='m_p' ) lambda_C_p = proton_Compton_wavelength = UnitConstant( 'proton_Compton_wavelength', _cd('proton Compton wavelength'), symbol='lambda_C_p', u_symbol='λ_C_p' ) proton_Compton_wavelength_over_2_pi = UnitConstant( 'proton_Compton_wavelength_over_2_pi', _cd('proton Compton wavelength over 2 pi'), symbol='lambdabar_C_p', u_symbol='ƛ_C_p' ) R_p = proton_rms_charge_radius = UnitConstant( 'proton_rms_charge_radius', _cd('proton rms charge radius'), symbol='R_p' ) proton_charge_to_mass_quotient = UnitConstant( 'proton_charge_to_mass_quotient', _cd('proton charge to mass quotient'), symbol='(e/m_p)' ) g_p = proton_g_factor = UnitConstant( 'proton_g_factor', _cd('proton g factor'), symbol='g_p' ) gamma_p = proton_gyromagnetic_ratio = UnitConstant( 'proton_gyromagnetic_ratio', _cd('proton gyromagnetic ratio'), symbol='gamma_p', u_symbol='γ_p' ) proton_gyromagnetic_ratio_over_2_pi = UnitConstant( 'proton_gyromagnetic_ratio_over_2_pi', _cd('proton gyromagnetic ratio over 2 pi'), symbol='(gamma_p/(2*pi))', u_symbol='(γ_p/(2·π))' ) mu_p = proton_magnetic_moment = UnitConstant( 'proton_magnetic_moment', _cd('proton magnetic moment'), symbol='mu_p', u_symbol='μ_p' ) sigma_prime_p = proton_magnetic_shielding_correction = UnitConstant( 'proton_magnetic_shielding_correction', _cd('proton magnetic shielding correction'), symbol='sigmaprime_p', u_symbol='σ′_p' ) gamma_prime_p = shielded_proton_gyromagnetic_ratio = UnitConstant( 'shielded_proton_gyromagnetic_ratio', _cd('shielded proton gyromagnetic ratio'), symbol='gammaprime_p', u_symbol='γ′_p' ) shielded_proton_gyromagnetic_ratio_over_2_pi = UnitConstant( 'shielded_proton_gyromagnetic_ratio_over_2_pi', _cd('shielded proton gyromagnetic ratio over 2 pi'), symbol='(gammaprime_p/(2*pi))', u_symbol='(γ′_p/(2·π))' ) mu_prime_p = shielded_proton_magnetic_moment = UnitConstant( 'shielded_proton_magnetic_moment', _cd('shielded proton magnetic moment'), symbol='muprime_p', u_symbol='μ′_p' ) mu_N = nuclear_magneton = UnitConstant( 'nuclear_magneton', _cd('nuclear magneton'), symbol='mu_N', u_symbol='μ_N' ) nuclear_magneton_in_eV_per_T = UnitConstant( 'nuclear_magneton_in_eV_per_T', _cd('nuclear magneton in eV/T') ) nuclear_magneton_in_inverse_meters_per_tesla = UnitConstant( 'nuclear_magneton_in_inverse_meters_per_tesla', _cd('nuclear magneton in inverse meters per tesla') ) nuclear_magneton_in_K_per_T = UnitConstant( 'nuclear_magneton_in_K_per_T', _cd('nuclear magneton in K/T') ) nuclear_magneton_in_MHz_per_T = UnitConstant( 'nuclear_magneton_in_MHz_per_T', _cd('nuclear magneton in MHz/T') ) proton_mass_energy_equivalent = UnitConstant( 'proton_mass_energy_equivalent', _cd('proton mass energy equivalent'), symbol='(m_p*c**2)', u_symbol='(m_p·c²)' ) proton_mass_energy_equivalent_in_MeV = UnitConstant( 'proton_mass_energy_equivalent_in_MeV', _cd('proton mass energy equivalent in MeV') ) proton_mass_in_u = UnitConstant( 'proton_mass_in_u', _cd('proton mass in u') ) proton_molar_mass = UnitConstant( 'proton_molar_mass', _cd('proton molar mass'), symbol='M_p' ) proton_electron_mass_ratio = UnitConstant( 'proton_electron_mass_ratio', _cd('proton-electron mass ratio'), symbol='(m_p/m_e)', u_symbol='(m_p/mₑ)' ) proton_muon_mass_ratio = UnitConstant( 'proton_muon_mass_ratio', _cd('proton-muon mass ratio'), symbol='(m_p/m_mu)', u_symbol='(m_p/m_μ)' ) proton_neutron_mass_ratio = UnitConstant( 'proton_neutron_mass_ratio', _cd('proton-neutron mass ratio'), symbol='(m_p/m_n)', ) proton_tau_mass_ratio = UnitConstant( 'proton_tau_mass_ratio', _cd('proton-tau mass ratio'), symbol='(m_p/m_tau)', u_symbol='(m_p/m_τ)' ) proton_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'proton_magnetic_moment_to_Bohr_magneton_ratio', _cd('proton magnetic moment to Bohr magneton ratio'), symbol='(mu_p/mu_B)', u_symbol='(μ_p/μ_B)' ) proton_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'proton_magnetic_moment_to_nuclear_magneton_ratio', _cd('proton magnetic moment to nuclear magneton ratio'), symbol='(mu_p/mu_N)', u_symbol='(μ_p/μ_N)' ) proton_neutron_magnetic_moment_ratio = UnitConstant( 'proton_neutron_magnetic_moment_ratio', _cd('proton-neutron magnetic moment ratio'), symbol='(mu_p/mu_n)', u_symbol='(μ_p/μ_n)' ) shielded_proton_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'shielded_proton_magnetic_moment_to_Bohr_magneton_ratio', _cd('shielded proton magnetic moment to Bohr magneton ratio'), symbol='(muprime_p/mu_B)', u_symbol='(μ′_p/μ_B)' ) shielded_proton_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'shielded_proton_magnetic_moment_to_nuclear_magneton_ratio', _cd('shielded proton magnetic moment to nuclear magneton ratio'), symbol='(muprime_p/mu_N)', u_symbol='(μ′_p/μ_N)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/quantum.py000066400000000000000000000132151417003363700235540ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant molar_Planck_constant = UnitConstant( 'molar_Planck_constant', _cd('molar Planck constant'), symbol='(N_A*h)', u_symbol='(N_A·h)' ) molar_Planck_constant_times_c = UnitConstant( 'molar_Planck_constant_times_c', _cd('molar Planck constant times c'), symbol='(N_A*h*c)', u_symbol='(N_A·h·c)' ) h = Planck_constant = UnitConstant( 'Planck_constant', _cd('Planck constant'), symbol='h' ) hbar = Planck_constant_over_2_pi = UnitConstant( 'Planck_constant_over_2_pi', _cd('Planck constant over 2 pi'), symbol='(h/(2*pi))', u_symbol='ħ' ) quantum_of_circulation = UnitConstant( 'quantum_of_circulation', _cd('quantum of circulation'), symbol='(h/(2*m_e))', u_symbol='(h/(2·mₑ))' ) quantum_of_circulation_times_2 = UnitConstant( 'quantum_of_circulation_times_2', _cd('quantum of circulation times 2'), symbol='(h/m_e)', u_symbol='(h/mₑ)' ) l_P = Planck_length = UnitConstant( 'Planck_length', _cd('Planck length'), symbol='l_P' ) m_P = Planck_mass = UnitConstant( 'Planck_mass', _cd('Planck mass'), symbol='m_P' ) T_P = Planck_temperature = UnitConstant( 'Planck_temperature', _cd('Planck temperature'), symbol='T_P' ) t_P = Planck_time = UnitConstant( 'Planck_time', _cd('Planck time'), symbol='t_P' ) R_infinity = Rydberg_constant = UnitConstant( 'Rydberg_constant', _cd('Rydberg constant'), symbol='R_infinity', u_symbol='R_∞' ) Rydberg_constant_times_c_in_Hz = UnitConstant( 'Rydberg_constant_times_c_in_Hz', _cd('Rydberg constant times c in Hz') ) Rydberg_constant_times_hc_in_eV = UnitConstant( 'Rydberg_constant_times_hc_in_eV', _cd('Rydberg constant times hc in eV') ) Rydberg_constant_times_hc_in_J = UnitConstant( 'Rydberg_constant_times_hc_in_J', _cd('Rydberg constant times hc in J'), symbol='(R_infinity*h*c)', u_symbol='(R_∞·h·c)' ) G_0 = conductance_quantum = UnitConstant( 'conductance_quantum', _cd('conductance quantum'), symbol='G_0', u_symbol='G₀' ) K_J90 = conventional_value_of_Josephson_constant = UnitConstant( 'conventional_value_of_Josephson_constant', _cd('conventional value of Josephson constant') ) R_K90 = conventional_value_of_von_Klitzing_constant = UnitConstant( 'conventional_value_of_von_Klitzing_constant', _cd('conventional value of von Klitzing constant') ) Fermi_coupling_constant = UnitConstant( 'Fermi_coupling_constant', _cd('Fermi coupling constant'), symbol='(G_F/(hbar*c)**3)', u_symbol='(G_F/(ħ·c)³)' ) alpha = fine_structure_constant = UnitConstant( 'fine_structure_constant', _cd('fine-structure constant'), symbol='alpha', u_symbol='α' ) inverse_fine_structure_constant = UnitConstant( 'inverse_fine_structure_constant', _cd('inverse fine-structure constant'), symbol='alpha**-1', u_symbol='α⁻¹' ) c_1 = first_radiation_constant = UnitConstant( 'first_radiation_constant', _cd('first radiation constant'), symbol='c_1', u_symbol='c₁' ) c_1L = first_radiation_constant_for_spectral_radiance = UnitConstant( 'first_radiation_constant_for_spectral_radiance', _cd('first radiation constant for spectral radiance'), symbol='c_1L', u_symbol='c₁_L' ) inverse_of_conductance_quantum = UnitConstant( 'inverse_of_conductance_quantum', _cd('inverse of conductance quantum'), symbol='G_0**-1', u_symbol='G₀⁻¹' ) Josephson_constant = K_J = UnitConstant( 'Josephson_constant', _cd('Josephson constant'), symbol='K_J' ) Phi_0 = magnetic_flux_quantum = UnitConstant( 'magnetic_flux_quantum', _cd('magnetic flux quantum'), symbol='Phi_0', u_symbol='Φ₀' ) Newtonian_constant_of_gravitation_over_h_bar_c = UnitConstant( 'Newtonian_constant_of_gravitation_over_h_bar_c', _cd('Newtonian constant of gravitation over h-bar c'), symbol='(G/(hbar*c))', u_symbol='(G/(ħ·c))' ) Sackur_Tetrode_constant_ST_100kPa = UnitConstant( 'Sackur_Tetrode_constant_ST_100kPa', _cd('Sackur-Tetrode constant (1 K, 100 kPa)') ) Sackur_Tetrode_constant_STP = UnitConstant( 'Sackur_Tetrode_constant_STP', _cd('Sackur-Tetrode constant (1 K, 101.325 kPa)') ) c_2 = second_radiation_constant = UnitConstant( 'second_radiation_constant', _cd('second radiation constant'), symbol='c_2', u_symbol='c₂' ) sigma = Stefan_Boltzmann_constant = UnitConstant( 'Stefan_Boltzmann_constant', _cd('Stefan-Boltzmann constant'), symbol='sigma', u_symbol='σ' ) R_K = von_Klitzing_constant = UnitConstant( 'von_Klitzing_constant', _cd('von Klitzing constant'), symbol='R_K' ) b_prime = Wien_frequency_displacement_law_constant = UnitConstant( 'Wien_frequency_displacement_law_constant', _cd('Wien frequency displacement law constant'), symbol='bprime', u_symbol='b′' ) b = Wien_wavelength_displacement_law_constant = UnitConstant( 'Wien_wavelength_displacement_law_constant', _cd('Wien wavelength displacement law constant'), symbol='b' ) Planck_constant_in_eV_s = UnitConstant( 'Planck_constant_in_eV_s', _cd('Planck constant in eV s') ) Planck_constant_over_2_pi_in_eV_s = UnitConstant( 'Planck_constant_over_2_pi_in_eV_s', _cd('Planck constant over 2 pi in eV s') ) Planck_constant_over_2_pi_times_c_in_MeV_fm = UnitConstant( 'Planck_constant_over_2_pi_times_c_in_MeV_fm', _cd('Planck constant over 2 pi times c in MeV fm') ) Planck_mass_energy_equivalent_in_GeV = UnitConstant( 'Planck_mass_energy_equivalent_in_GeV', _cd('Planck mass energy equivalent in GeV') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/relationships.py000066400000000000000000000050561417003363700247520ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant hertz_inverse_meter_relationship = UnitConstant( 'hertz_inverse_meter_relationship', _cd('hertz-inverse meter relationship') ) hertz_joule_relationship = UnitConstant( 'hertz_joule_relationship', _cd('hertz-joule relationship') ) hertz_kelvin_relationship = UnitConstant( 'hertz_kelvin_relationship', _cd('hertz-kelvin relationship') ) hertz_kilogram_relationship = UnitConstant( 'hertz_kilogram_relationship', _cd('hertz-kilogram relationship') ) inverse_meter_hertz_relationship = UnitConstant( 'inverse_meter_hertz_relationship', _cd('inverse meter-hertz relationship') ) inverse_meter_joule_relationship = UnitConstant( 'inverse_meter_joule_relationship', _cd('inverse meter-joule relationship') ) inverse_meter_kelvin_relationship = UnitConstant( 'inverse_meter_kelvin_relationship', _cd('inverse meter-kelvin relationship') ) inverse_meter_kilogram_relationship = UnitConstant( 'inverse_meter_kilogram_relationship', _cd('inverse meter-kilogram relationship') ) joule_hertz_relationship = UnitConstant( 'joule_hertz_relationship', _cd('joule-hertz relationship') ) joule_inverse_meter_relationship = UnitConstant( 'joule_inverse_meter_relationship', _cd('joule-inverse meter relationship') ) joule_kelvin_relationship = UnitConstant( 'joule_kelvin_relationship', _cd('joule-kelvin relationship') ) joule_kilogram_relationship = UnitConstant( 'joule_kilogram_relationship', _cd('joule-kilogram relationship') ) kelvin_hertz_relationship = UnitConstant( 'kelvin_hertz_relationship', _cd('kelvin-hertz relationship') ) kelvin_inverse_meter_relationship = UnitConstant( 'kelvin_inverse_meter_relationship', _cd('kelvin-inverse meter relationship') ) kelvin_joule_relationship = UnitConstant( 'kelvin_joule_relationship', _cd('kelvin-joule relationship') ) kelvin_kilogram_relationship = UnitConstant( 'kelvin_kilogram_relationship', _cd('kelvin-kilogram relationship') ) kilogram_hertz_relationship = UnitConstant( 'kilogram_hertz_relationship', _cd('kilogram-hertz relationship') ) kilogram_inverse_meter_relationship = UnitConstant( 'kilogram_inverse_meter_relationship', _cd('kilogram-inverse meter relationship') ) kilogram_joule_relationship = UnitConstant( 'kilogram_joule_relationship', _cd('kilogram-joule relationship') ) kilogram_kelvin_relationship = UnitConstant( 'kilogram_kelvin_relationship', _cd('kilogram-kelvin relationship') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/statisticalmechanics.py000066400000000000000000000030611417003363700262570ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant N_A = L = Avogadro_constant = UnitConstant( 'Avogadro_constant', _cd('Avogadro constant'), symbol='N_A' ) n_0 = Loschmidt_constant = UnitConstant( 'Loschmidt_constant', _cd('Loschmidt constant (273.15 K, 101.325 kPa)'), symbol='n_0', u_symbol='n₀' ) R = molar_gas_constant = UnitConstant( 'molar_gas_constant', _cd('molar gas constant'), symbol='R' ) k = Boltzmann_constant = UnitConstant( 'Boltzmann_constant', _cd('Boltzmann constant'), symbol='k' ) Boltzmann_constant_in_eV_per_K = UnitConstant( 'Boltzmann_constant_in_eV_per_K', _cd('Boltzmann constant in eV/K') ) Boltzmann_constant_in_Hz_per_K = UnitConstant( 'Boltzmann_constant_in_Hz_per_K', _cd('Boltzmann constant in Hz/K') ) Boltzmann_constant_in_inverse_meters_per_kelvin = UnitConstant( 'Boltzmann_constant_in_inverse_meters_per_kelvin', _cd('Boltzmann constant in inverse meters per kelvin') ) M_u = molar_mass_constant = UnitConstant( 'molar_mass_constant', _cd('molar mass constant'), symbol='M_u', u_symbol='Mᵤ' ) molar_volume_of_ideal_gas_ST_100kPa = UnitConstant( 'molar_volume_of_ideal_gas_ST_100kPa', _cd('molar volume of ideal gas (273.15 K, 100 kPa)') ) molar_volume_of_ideal_gas_STP = UnitConstant( 'molar_volume_of_ideal_gas_STP', _cd('molar volume of ideal gas (273.15 K, 101.325 kPa)') ) molar_volume_of_silicon = UnitConstant( 'molar_volume_of_silicon', _cd('molar volume of silicon') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/tau.py000066400000000000000000000032501417003363700226510ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_tau = tau_mass = UnitConstant( 'tau_mass', _cd('tau mass'), symbol='m_tau', u_symbol='m_τ' ) lambda_C_tau = tau_Compton_wavelength = UnitConstant( 'tau_Compton_wavelength', _cd('tau Compton wavelength'), symbol='lambda_C_tau', u_symbol='λ_C_τ' ) tau_Compton_wavelength_over_2_pi = UnitConstant( 'tau_Compton_wavelength_over_2_pi', _cd('tau Compton wavelength over 2 pi'), symbol='lambda_C_tau', u_symbol='ƛ_C_τ' ) tau_mass_energy_equivalent = UnitConstant( 'tau_mass_energy_equivalent', _cd('tau mass energy equivalent'), symbol='(m_tau*c**2)', u_symbol='(m_τ·c²)' ) tau_mass_energy_equivalent_in_MeV = UnitConstant( 'tau_mass_energy_equivalent_in_MeV', _cd('tau mass energy equivalent in MeV') ) tau_mass_in_u = UnitConstant( 'tau_mass_in_u', _cd('tau mass in u') ) tau_molar_mass = UnitConstant( 'tau_molar_mass', _cd('tau molar mass'), symbol='M_tau', u_symbol='M_τ' ) tau_electron_mass_ratio = UnitConstant( 'tau_electron_mass_ratio', _cd('tau-electron mass ratio'), symbol='(m_tau/m_e)', u_symbol='(m_τ/mₑ)' ) tau_muon_mass_ratio = UnitConstant( 'tau_muon_mass_ratio', _cd('tau-muon mass ratio'), symbol='(m_tau/m_mu)', u_symbol='(m_τ/m_μ)' ) tau_neutron_mass_ratio = UnitConstant( 'tau_neutron_mass_ratio', _cd('tau-neutron mass ratio'), symbol='(m_tau/m_n)', u_symbol='(m_τ/m_n)' ) tau_proton_mass_ratio = UnitConstant( 'tau_proton_mass_ratio', _cd('tau-proton mass ratio'), symbol='(m_tau/m_p)', u_symbol='(m_τ/m_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/triton.py000066400000000000000000000045061417003363700234040ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant m_t = triton_mass = UnitConstant( 'triton_mass', _cd('triton mass'), symbol='m_t' ) g_t = triton_g_factor = UnitConstant( 'triton_g_factor', _cd('triton g factor'), symbol='g_t' ) mu_t = triton_magnetic_moment = UnitConstant( 'triton_magnetic_moment', _cd('triton magnetic moment'), symbol='mu_t', u_symbol='μ_t' ) triton_mass_energy_equivalent = UnitConstant( 'triton_mass_energy_equivalent', _cd('triton mass energy equivalent'), symbol='(m_t*c**2)', u_symbol='(m_t·c²)' ) triton_mass_energy_equivalent_in_MeV = UnitConstant( 'triton_mass_energy_equivalent_in_MeV', _cd('triton mass energy equivalent in MeV') ) triton_mass_in_u = UnitConstant( 'triton_mass_in_u', _cd('triton mass in u') ) triton_molar_mass = UnitConstant( 'triton_molar_mass', _cd('triton molar mass'), symbol='M_t' ) triton_electron_mass_ratio = UnitConstant( 'triton_electron_mass_ratio', _cd('triton-electron mass ratio'), symbol='(m_t/m_e)', u_symbol='(m_t/mₑ)' ) triton_proton_mass_ratio = UnitConstant( 'triton_proton_mass_ratio', _cd('triton-proton mass ratio'), symbol='(m_t/m_p)', u_symbol='(m_t/m_p)' ) triton_electron_magnetic_moment_ratio = UnitConstant( 'triton_electron_magnetic_moment_ratio', _cd('triton-electron magnetic moment ratio'), symbol='(mu_t/mu_e)', u_symbol='(μ_t/μₑ)' ) triton_magnetic_moment_to_Bohr_magneton_ratio = UnitConstant( 'triton_magnetic_moment_to_Bohr_magneton_ratio', _cd('triton magnetic moment to Bohr magneton ratio'), symbol='(mu_t/mu_B)', u_symbol='(μ_t/μ_B)' ) triton_magnetic_moment_to_nuclear_magneton_ratio = UnitConstant( 'triton_magnetic_moment_to_nuclear_magneton_ratio', _cd('triton magnetic moment to nuclear magneton ratio'), symbol='(mu_t/mu_N)', u_symbol='(μ_t/μ_N)' ) triton_neutron_magnetic_moment_ratio = UnitConstant( 'triton_neutron_magnetic_moment_ratio', _cd('triton-neutron magnetic moment ratio'), symbol='(mu_t/mu_n)', u_symbol='(μ_t/μ_n)' ) triton_proton_magnetic_moment_ratio = UnitConstant( 'triton_proton_magnetic_moment_ratio', _cd('triton-proton magnetic moment ratio'), symbol='(mu_t/mu_p)', u_symbol='(μ_t/μ_p)' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/weak.py000066400000000000000000000002741417003363700230120ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant weak_mixing_angle = UnitConstant( 'weak_mixing_angle', _cd('weak mixing angle') ) del UnitConstant, _cd python-quantities-0.13.0/quantities/constants/xray.py000066400000000000000000000014061417003363700230440ustar00rootroot00000000000000""" """ from ._utils import _cd from ..unitquantity import UnitConstant Angstrom_star = UnitConstant( 'Angstrom_star', _cd('Angstrom star'), symbol='A*', u_symbol='Å*' ) d_220 = a_Si_220 = silicon_220_lattice_spacing = UnitConstant( 'silicon_220_lattice_spacing', _cd('{220} lattice spacing of silicon'), symbol='d_220', u_symbol='d₂₂₀' ) Cu_x_unit = UnitConstant( 'Cu_x_unit', _cd('Cu x unit'), symbol='CuKalpha_1', u_symbol='CuKα₁' ) a = a_Si_100 = lattice_parameter_of_silicon = UnitConstant( 'lattice_parameter_of_silicon', _cd('lattice parameter of silicon') ) Mo_x_unit = UnitConstant( 'Mo_x_unit', _cd('Mo x unit'), symbol='MoKalpha_1', u_symbol='MoKα₁' ) del UnitConstant, _cd python-quantities-0.13.0/quantities/decorators.py000066400000000000000000000123641417003363700222170ustar00rootroot00000000000000import inspect import os import re import string import sys import warnings from functools import partial, wraps def memoize(f, cache={}): @wraps(f) def g(*args, **kwargs): key = (f, tuple(args), frozenset(kwargs.items())) if key not in cache: cache[key] = f(*args, **kwargs) return cache[key].copy() return g class with_doc: """ This decorator combines the docstrings of the provided and decorated objects to produce the final docstring for the decorated object. """ def __init__(self, method, use_header=True): self.method = method if use_header: self.header = \ """ Notes ----- """ else: self.header = '' def __call__(self, new_method): new_doc = new_method.__doc__ original_doc = self.method.__doc__ header = self.header if original_doc and new_doc: new_method.__doc__ = """ {} {} {} """.format(original_doc, header, new_doc) elif original_doc: new_method.__doc__ = original_doc return new_method def quantitizer(base_function, handler_function = lambda *args, **kwargs: 1.0): """ wraps a function so that it works properly with physical quantities (Quantities). arguments: base_function - the function to be wrapped handler_function - a function which takes the same arguments as the base_function and returns a Quantity (or tuple of Quantities) which has (have) the units that the output of base_function should have. returns: a wrapped version of base_function that takes the same arguments and works with physical quantities. It will have almost the same __name__ and almost the same __doc__. """ from .quantity import Quantity # define a function which will wrap the base function so that it works # with Quantities def wrapped_function(*args , **kwargs): # run the arguments through the handler function, this should # return a tuple of Quantities which have the correct units # for the output of the function we are wrapping handler_quantities= handler_function( *args, **kwargs) # now we need to turn Quantities into ndarrays so they behave # correctly # # first we simplify all units so that addition and subtraction work # there may be another way to ensure this, but I do not have any good # ideas # in order to modify the args tuple, we have to turn it into a list args = list(args) #replace all the quantities in the argument list with ndarrays for i in range(len(args)): #test if the argument is a quantity if isinstance(args[i], Quantity): #convert the units to the base units args[i] = args[i].simplified #view the array as an ndarray args[i] = args[i].magnitude #convert the list back to a tuple so it can be used as an output args = tuple (args) #replace all the quantities in the keyword argument #dictionary with ndarrays for i in kwargs: #test if the argument is a quantity if isinstance(kwargs[i], Quantity): #convert the units to the base units kwargs[i] = kwargs[i].simplifed() #view the array as an ndarray kwargs[i] = kwargs[i].magnitude #get the result for the function result = base_function( *args, **kwargs) # since we have to modify the result, convert it to a list result = list(result) #iterate through the handler_quantities and get the correct # units length = min( len(handler_quantities) , len(result) ) for i in range(length): # if the output of the handler is a quantity make the # output of the wrapper function be a quantity with correct # units if isinstance(handler_quantities[i], Quantity): # the results should have simplified units since that's what # the inputs were (they were simplified earlier) # (reasons why this would not be true?) result[i] = Quantity( result[i], handler_quantities[i] .dimensionality.simplified ) #now convert the quantity to the appropriate units result[i] = result[i].rescale( handler_quantities[i].dimensionality) #need to convert the result back to a tuple result = tuple(result) return result # give the wrapped function a similar name to the base function wrapped_function.__name__ = base_function.__name__ + "_QWrap" # give the wrapped function a similar doc string to the base function's # doc string but add an annotation to the beginning wrapped_function.__doc__ = ( "this function has been wrapped to work with Quantities\n" + base_function.__doc__) return wrapped_function python-quantities-0.13.0/quantities/dimensionality.py000066400000000000000000000256411417003363700231040ustar00rootroot00000000000000""" """ import operator import numpy as np from . import markup from .registry import unit_registry from .decorators import memoize def assert_isinstance(obj, types): try: assert isinstance(obj, types) except AssertionError: raise TypeError( f"arg {obj!r} must be of type {types!r}, got {type(obj)!r}" ) class Dimensionality(dict): """ """ @property def ndims(self): return sum(abs(i) for i in self.simplified.values()) @property def simplified(self): if len(self): rq = 1*unit_registry['dimensionless'] for u, d in self.items(): rq = rq * u.simplified**d return rq.dimensionality else: return self @property def string(self): return markup.format_units(self) @property def unicode(self): return markup.format_units_unicode(self) @property def latex(self): return markup.format_units_latex(self) @property def html(self): return markup.format_units_html(self) def __hash__(self): res = hash(unit_registry['dimensionless']) for key in sorted(self.keys(), key=operator.attrgetter('format_order')): val = self[key] if val < 0: # can you believe that hash(-1)==hash(-2)? val -= 1 res ^= hash((key, val)) return res def __add__(self, other): assert_isinstance(other, Dimensionality) try: assert self == other except AssertionError: raise ValueError( 'can not add units of %s and %s'\ %(str(self), str(other)) ) return self.copy() __radd__ = __add__ def __iadd__(self, other): assert_isinstance(other, Dimensionality) try: assert self == other except AssertionError: raise ValueError( 'can not add units of %s and %s'\ %(str(self), str(other)) ) return self def __sub__(self, other): assert_isinstance(other, Dimensionality) try: assert self == other except AssertionError: raise ValueError( 'can not subtract units of %s and %s'\ %(str(self), str(other)) ) return self.copy() __rsub__ = __sub__ def __isub__(self, other): assert_isinstance(other, Dimensionality) try: assert self == other except AssertionError: raise ValueError( 'can not add units of %s and %s'\ %(str(self), str(other)) ) return self def __mul__(self, other): assert_isinstance(other, Dimensionality) new = Dimensionality(self) for unit, power in other.items(): try: new[unit] += power if new[unit] == 0: new.pop(unit) except KeyError: new[unit] = power return new def __imul__(self, other): assert_isinstance(other, Dimensionality) for unit, power in other.items(): try: self[unit] += power if self[unit] == 0: self.pop(unit) except KeyError: self[unit] = power return self def __truediv__(self, other): assert_isinstance(other, Dimensionality) new = Dimensionality(self) for unit, power in other.items(): try: new[unit] -= power if new[unit] == 0: new.pop(unit) except KeyError: new[unit] = -power return new def __itruediv__(self, other): assert_isinstance(other, Dimensionality) for unit, power in other.items(): try: self[unit] -= power if self[unit] == 0: self.pop(unit) except KeyError: self[unit] = -power return self def __pow__(self, other): try: assert np.isscalar(other) except AssertionError: raise TypeError('exponent must be a scalar, got %r' % other) if other == 0: return Dimensionality() new = Dimensionality(self) for i in new: new[i] *= other return new def __ipow__(self, other): try: assert np.isscalar(other) except AssertionError: raise TypeError('exponent must be a scalar, got %r' % other) if other == 0: self.clear() return self for i in self: self[i] *= other return self def __repr__(self): return 'Dimensionality({%s})' \ % ', '.join(['%s: %s'% (u.name, e) for u, e in self.items()]) def __str__(self): if markup.config.use_unicode: return self.unicode else: return self.string def __eq__(self, other): return hash(self) == hash(other) def __ne__(self, other): return hash(self) != hash(other) __neq__ = __ne__ def __gt__(self, other): return self.ndims > other.ndims def __ge__(self, other): return self.ndims >= other.ndims def __lt__(self, other): return self.ndims < other.ndims def __le__(self, other): return self.ndims <= other.ndims def copy(self): return Dimensionality(self) p_dict = {} def _d_multiply(q1, q2, out=None): try: return q1._dimensionality * q2._dimensionality except AttributeError: try: return q1.dimensionality except: return q2.dimensionality p_dict[np.multiply] = _d_multiply p_dict[np.cross] = _d_multiply def _d_divide(q1, q2, out=None): try: return q1._dimensionality / q2._dimensionality except AttributeError: try: return q1.dimensionality except: return q2.dimensionality**-1 p_dict[np.divide] = _d_divide p_dict[np.true_divide] = _d_divide def _d_check_uniform(q1, q2, out=None): try: assert q1._dimensionality == q2._dimensionality return q1.dimensionality except AssertionError: raise ValueError( 'quantities must have identical units, got "%s" and "%s"' % (q1.units, q2.units) ) except AttributeError: try: if hasattr(q1, 'dimensionality'): # q2 was not a quantity if not q1._dimensionality or not np.asarray(q2).any(): return q1.dimensionality else: raise ValueError elif hasattr(q2, 'dimensionality'): # q1 was not a quantity if not q2._dimensionality or not np.asarray(q1).any(): return q2.dimensionality else: raise ValueError except ValueError: raise ValueError( 'quantities must have identical units, got "%s" and "%s"' % (q1.units, q2.units) ) p_dict[np.add] = _d_check_uniform p_dict[np.subtract] = _d_check_uniform p_dict[np.mod] = _d_check_uniform p_dict[np.fmod] = _d_check_uniform p_dict[np.remainder] = _d_check_uniform p_dict[np.floor_divide] = _d_check_uniform p_dict[np.hypot] = _d_check_uniform p_dict[np.equal] = _d_check_uniform p_dict[np.not_equal] = _d_check_uniform p_dict[np.less] = _d_check_uniform p_dict[np.less_equal] = _d_check_uniform p_dict[np.greater] = _d_check_uniform p_dict[np.greater_equal] = _d_check_uniform def _d_arctan2(q1, q2, out=None): try: assert q1._dimensionality == q2._dimensionality return Dimensionality() except AssertionError: raise ValueError( 'quantities must have identical units, got "%s" and "%s"' % (q1.units, q2.units) ) p_dict[np.arctan2] = _d_arctan2 def _d_power(q1, q2, out=None): if getattr(q2, 'dimensionality', None): raise ValueError("exponent must be dimensionless") try: q2 = np.array(q2) p = q2.min() if p != q2.max(): raise ValueError('Quantities must be raised to a uniform power') return q1._dimensionality**p except AttributeError: return Dimensionality() p_dict[np.power] = _d_power def _d_square(q1, out=None): return q1._dimensionality**2 p_dict[np.square] = _d_square def _d_reciprocal(q1, out=None): return q1._dimensionality**-1 p_dict[np.reciprocal] = _d_reciprocal def _d_copy(q1, out=None): return q1.dimensionality p_dict[np.fabs] = _d_copy p_dict[np.absolute] = _d_copy p_dict[np.conjugate] = _d_copy p_dict[np.negative] = _d_copy p_dict[np.ones_like] = _d_copy p_dict[np.rint] = _d_copy p_dict[np.floor] = _d_copy p_dict[np.fix] = _d_copy p_dict[np.ceil] = _d_copy def _d_clip(a1, a2, a3, q): return q.dimensionality try: p_dict[np.core.umath.clip] = _d_clip except AttributeError: pass # For compatibility with Numpy < 1.17 when clip wasn't a ufunc yet def _d_sqrt(q1, out=None): return q1._dimensionality**0.5 p_dict[np.sqrt] = _d_sqrt def _d_radians(q1, out=None): try: assert q1.units == unit_registry['degree'] except AssertionError: raise ValueError( 'expected units of degrees, got "%s"' % q1._dimensionality ) return unit_registry['radian'].dimensionality p_dict[np.radians] = _d_radians def _d_degrees(q1, out=None): try: assert q1.units == unit_registry['radian'] except AssertionError: raise ValueError( 'expected units of radians, got "%s"' % q1._dimensionality ) return unit_registry['degree'].dimensionality p_dict[np.degrees] = _d_degrees def _d_dimensionless(q1, out=None): if getattr(q1, 'dimensionality', None): raise ValueError("quantity must be dimensionless") return Dimensionality() p_dict[np.log] = _d_dimensionless p_dict[np.log10] = _d_dimensionless p_dict[np.log2] = _d_dimensionless p_dict[np.log1p] = _d_dimensionless p_dict[np.exp] = _d_dimensionless p_dict[np.expm1] = _d_dimensionless p_dict[np.logaddexp] = _d_dimensionless p_dict[np.logaddexp2] = _d_dimensionless def _d_trig(q1, out=None): try: assert q1.units == unit_registry['radian'] except AssertionError: raise ValueError( 'expected units of radians, got "%s"' % q1._dimensionality ) return Dimensionality() p_dict[np.sin] = _d_trig p_dict[np.sinh] = _d_trig p_dict[np.cos] = _d_trig p_dict[np.cosh] = _d_trig p_dict[np.tan] = _d_trig p_dict[np.tanh] = _d_trig def _d_arctrig(q1, out=None): if getattr(q1, 'dimensionality', None): raise ValueError("quantity must be dimensionless") return unit_registry['radian'].dimensionality p_dict[np.arcsin] = _d_arctrig p_dict[np.arcsinh] = _d_arctrig p_dict[np.arccos] = _d_arctrig p_dict[np.arccosh] = _d_arctrig p_dict[np.arctan] = _d_arctrig p_dict[np.arctanh] = _d_arctrig python-quantities-0.13.0/quantities/markup.py000066400000000000000000000110631417003363700213440ustar00rootroot00000000000000""" """ import copy import operator import re import threading class _Config: @property def lock(self): return self._lock @property def use_unicode(self): with self.lock: return copy.copy(self._use_unicode) @use_unicode.setter def use_unicode(self, val): self._use_unicode = bool(val) def __init__(self): self._lock = threading.RLock() self._use_unicode = False config = _Config() superscripts = ['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹'] def superscript(val): items = re.split(r'\*{2}([\d]+)(?!\.)', val) ret = [] while items: try: s = items.pop(0) e = items.pop(0) ret.append(s+''.join(superscripts[int(i)] for i in e)) except IndexError: ret.append(s) return ''.join(ret) def format_units(udict): ''' create a string representation of the units contained in a dimensionality ''' num = [] den = [] keys = [k for k, o in sorted( ((k, k.format_order) for k in udict), key=operator.itemgetter(1) ) ] for key in keys: d = udict[key] if config.use_unicode: u = key.u_symbol else: u = key.symbol if d>0: if d != 1: u = u + ('**%s'%d).rstrip('0').rstrip('.') num.append(u) elif d<0: d = -d if d != 1: u = u + ('**%s'%d).rstrip('0').rstrip('.') den.append(u) res = '*'.join(num) if len(den): if not res: res = '1' fmt = '(%s)' if len(den) > 1 else '%s' res = res + '/' + fmt%('*'.join(den)) if not res: res = 'dimensionless' return res def format_units_unicode(udict): res = format_units(udict) res = superscript(res) res = res.replace('**', '^').replace('*','·') return res def format_units_latex(udict,font='mathrm',mult=r'\\cdot',paren=False): ''' Replace the units string provided with an equivalent latex string. Division (a/b) will be replaced by \frac{a}{b}. Exponentiation (m**2) will be replaced with superscripts (m^{2}) The latex is set with the font argument, and the default is the normal, non-italicized font mathrm. Other useful options include 'mathnormal', 'mathit', 'mathsf', and 'mathtt'. Multiplication (*) are replaced with the symbol specified by the mult argument. By default this is the latex \\cdot symbol. Other useful options may be '' or '*'. If paren=True, encapsulate the string in '\\left(' and '\\right)' The result of format_units_latex is encapsulated in $. This allows the result to be used directly in Latex in normal text mode, or in Matplotlib text via the MathText feature. Restrictions: This routine will not put CompoundUnits into a fractional form. ''' res = format_units(udict) if res.startswith('(') and res.endswith(')'): # Compound Unit compound = True else: # Not a compound unit compound = False # Replace division (num/den) with \frac{num}{den} res = re.sub(r'(?P.+)/(?P.+)',r'\\frac{\g}{\g}',res) # Replace exponentiation (**exp) with ^{exp} res = re.sub(r'\*{2,2}(?P\d+)',r'^{\g}',res) # Remove multiplication signs res = re.sub(r'\*','{'+mult+'}',res) if paren and not compound: res = r'\left(%s\right)' % res res = fr'$\{font}{{{res}}}$' return res def format_units_html(udict,font='%s',mult=r'⋅',paren=False): ''' Replace the units string provided with an equivalent html string. Exponentiation (m**2) will be replaced with superscripts (m2}) No formating is done, change `font` argument to e.g.: '%s' to have text be colored blue. Multiplication (*) are replaced with the symbol specified by the mult argument. By default this is the latex ⋅ symbol. Other useful options may be '' or '*'. If paren=True, encapsulate the string in '(' and ')' ''' res = format_units(udict) if res.startswith('(') and res.endswith(')'): # Compound Unit compound = True else: # Not a compound unit compound = False # Replace exponentiation (**exp) with ^{exp} res = re.sub(r'\*{2,2}(?P\d+)',r'\g',res) # Remove multiplication signs res = re.sub(r'\*',mult,res) if paren and not compound: res = '(%s)' % res res = font % res return res python-quantities-0.13.0/quantities/quantity.py000066400000000000000000000627771417003363700217450ustar00rootroot00000000000000""" """ import copy from functools import wraps import numpy as np from . import markup from .dimensionality import Dimensionality, p_dict from .registry import unit_registry from .decorators import with_doc PREFERRED = [] # List of preferred quantities for each symbol, # e.g. PREFERRED = [pq.mV, pq.pA, pq.UnitQuantity('femtocoulomb', 1e-15*pq.C, 'fC')] # Intended to be overwritten in down-stream packages def validate_unit_quantity(value): try: assert isinstance(value, Quantity) assert value.shape in ((), (1, )) assert value.magnitude == 1 except AssertionError: raise ValueError( 'units must be a scalar Quantity with unit magnitude, got %s'\ %value ) return value def validate_dimensionality(value): if isinstance(value, str): try: return unit_registry[value].dimensionality except (KeyError, UnicodeDecodeError): return unit_registry[str(value)].dimensionality elif isinstance(value, Quantity): validate_unit_quantity(value) return value.dimensionality elif isinstance(value, Dimensionality): return value.copy() else: raise TypeError( 'units must be a quantity, string, or dimensionality, got %s'\ %type(value) ) def get_conversion_factor(from_u, to_u): validate_unit_quantity(from_u) validate_unit_quantity(to_u) from_u = from_u._reference to_u = to_u._reference assert from_u.dimensionality == to_u.dimensionality return from_u.magnitude / to_u.magnitude def scale_other_units(f): @wraps(f) def g(self, other, *args): other = np.asanyarray(other) if not isinstance(other, Quantity): other = other.view(type=Quantity) if other._dimensionality != self._dimensionality: other = other.rescale(self.units) return f(self, other, *args) return g def protected_multiplication(f): @wraps(f) def g(self, other, *args): if getattr(other, 'dimensionality', None): try: assert not isinstance(self.base, Quantity) except AssertionError: raise ValueError('can not modify units of a view of a Quantity') return f(self, other, *args) return g def check_uniform(f): @wraps(f) def g(self, other, *args): if getattr(other, 'dimensionality', None): raise ValueError("exponent must be dimensionless") other = np.asarray(other) try: assert other.min() == other.max() except AssertionError: raise ValueError('Quantities must be raised to a uniform power') return f(self, other, *args) return g def protected_power(f): @wraps(f) def g(self, other, *args): if other != 1: try: assert not isinstance(self.base, Quantity) except AssertionError: raise ValueError('can not modify units of a view of a Quantity') return f(self, other, *args) return g def wrap_comparison(f): @wraps(f) def g(self, other): if isinstance(other, Quantity): if other._dimensionality != self._dimensionality: other = other.rescale(self._dimensionality) other = other.magnitude return f(self, other) return g class Quantity(np.ndarray): # TODO: what is an appropriate value? __array_priority__ = 21 def __new__(cls, data, units='', dtype=None, copy=True): if isinstance(data, Quantity): if units: data = data.rescale(units) if isinstance(data, unit_registry['UnitQuantity']): return 1*data return np.array(data, dtype=dtype, copy=copy, subok=True).view(cls) ret = np.array(data, dtype=dtype, copy=copy).view(cls) ret._dimensionality.update(validate_dimensionality(units)) return ret @property def dimensionality(self): return self._dimensionality.copy() @property def _reference(self): """The reference quantity used to perform conversions""" rq = 1*unit_registry['dimensionless'] for u, d in self.dimensionality.items(): rq = rq * u._reference**d return rq * self.magnitude @property def magnitude(self): return self.view(type=np.ndarray) @property def real(self): return Quantity(self.magnitude.real, self.dimensionality) @real.setter def real(self, r): self.magnitude.real = Quantity(r, self.dimensionality).magnitude @property def imag(self): return Quantity(self.magnitude.imag, self.dimensionality) @imag.setter def imag(self, i): self.magnitude.imag = Quantity(i, self.dimensionality).magnitude @property def simplified(self): rq = 1*unit_registry['dimensionless'] for u, d in self.dimensionality.items(): rq = rq * u.simplified**d return rq * self.magnitude @property def units(self): return Quantity(1.0, (self.dimensionality)) @units.setter def units(self, units): try: assert not isinstance(self.base, Quantity) except AssertionError: raise ValueError('can not modify units of a view of a Quantity') try: assert self.flags.writeable except AssertionError: raise ValueError('array is not writeable') to_dims = validate_dimensionality(units) if self._dimensionality == to_dims: return to_u = Quantity(1.0, to_dims) from_u = Quantity(1.0, self._dimensionality) try: cf = get_conversion_factor(from_u, to_u) except AssertionError: raise ValueError( 'Unable to convert between units of "%s" and "%s"' %(from_u._dimensionality, to_u._dimensionality) ) mag = self.magnitude mag *= cf self._dimensionality = to_u.dimensionality def rescale(self, units=None): """ Return a copy of the quantity converted to the specified units. If `units` is `None`, an attempt will be made to rescale the quantity to preferred units (see `rescale_preferred`). """ if units is None: try: return self.rescale_preferred() except Exception as e: raise Exception('No argument passed to `.rescale` and %s' % e) to_dims = validate_dimensionality(units) if self.dimensionality == to_dims: return self.astype(self.dtype) to_u = Quantity(1.0, to_dims) from_u = Quantity(1.0, self.dimensionality) try: cf = get_conversion_factor(from_u, to_u) except AssertionError: raise ValueError( 'Unable to convert between units of "%s" and "%s"' %(from_u._dimensionality, to_u._dimensionality) ) return Quantity(cf*self.magnitude, to_u) def rescale_preferred(self): """ Return a copy of the quantity converted to the preferred units and scale. These will be identified from among the compatible units specified in the list PREFERRED in this module. For example, a voltage quantity might be converted to `mV`: ``` import quantities as pq pq.quantity.PREFERRED = [pq.mV, pq.pA] old = 3.1415 * pq.V new = old.rescale_preferred() # `new` will be 3141.5 mV. ``` """ units_str = str(self.simplified.dimensionality) for preferred in PREFERRED: if units_str == str(preferred.simplified.dimensionality): return self.rescale(preferred) raise Exception("Preferred units for '%s' (or equivalent) not specified in " "quantites.quantity.PREFERRED." % self.dimensionality) @with_doc(np.ndarray.astype) def astype(self, dtype=None, **kwargs): '''Scalars are returned as scalar Quantity arrays.''' ret = super(Quantity, self.view(Quantity)).astype(dtype, **kwargs) # scalar quantities get converted to plain numbers, so we fix it # might be related to numpy ticket # 826 if not isinstance(ret, type(self)): if self.__array_priority__ >= Quantity.__array_priority__: ret = type(self)(ret, self._dimensionality) else: ret = Quantity(ret, self._dimensionality) return ret def __array_finalize__(self, obj): self._dimensionality = getattr(obj, 'dimensionality', Dimensionality()) def __array_prepare__(self, obj, context=None): if self.__array_priority__ >= Quantity.__array_priority__: res = obj if isinstance(obj, type(self)) else obj.view(type(self)) else: # don't want a UnitQuantity res = obj.view(Quantity) if context is None: return res uf, objs, huh = context if uf.__name__.startswith('is'): return obj #print self, obj, res, uf, objs try: res._dimensionality = p_dict[uf](*objs) except KeyError: raise ValueError( """ufunc %r not supported by quantities please file a bug report at https://github.com/python-quantities """ % uf ) return res def __array_wrap__(self, obj, context=None): if not isinstance(obj, Quantity): # backwards compatibility with numpy-1.3 obj = self.__array_prepare__(obj, context) return obj @with_doc(np.ndarray.__add__) @scale_other_units def __add__(self, other): return super().__add__(other) @with_doc(np.ndarray.__radd__) @scale_other_units def __radd__(self, other): return np.add(other, self) return super().__radd__(other) @with_doc(np.ndarray.__iadd__) @scale_other_units def __iadd__(self, other): return super().__iadd__(other) @with_doc(np.ndarray.__sub__) @scale_other_units def __sub__(self, other): return super().__sub__(other) @with_doc(np.ndarray.__rsub__) @scale_other_units def __rsub__(self, other): return np.subtract(other, self) return super().__rsub__(other) @with_doc(np.ndarray.__isub__) @scale_other_units def __isub__(self, other): return super().__isub__(other) @with_doc(np.ndarray.__mod__) @scale_other_units def __mod__(self, other): return super().__mod__(other) @with_doc(np.ndarray.__imod__) @scale_other_units def __imod__(self, other): return super().__imod__(other) @with_doc(np.ndarray.__imul__) @protected_multiplication def __imul__(self, other): return super().__imul__(other) @with_doc(np.ndarray.__rmul__) def __rmul__(self, other): return np.multiply(other, self) return super().__rmul__(other) @with_doc(np.ndarray.__itruediv__) @protected_multiplication def __itruediv__(self, other): return super().__itruediv__(other) @with_doc(np.ndarray.__rtruediv__) def __rtruediv__(self, other): return np.true_divide(other, self) return super().__rtruediv__(other) @with_doc(np.ndarray.__pow__) @check_uniform def __pow__(self, other): return np.power(self, other) @with_doc(np.ndarray.__ipow__) @check_uniform @protected_power def __ipow__(self, other): return super().__ipow__(other) def __round__(self, decimals=0): return np.around(self, decimals) @with_doc(np.ndarray.__repr__) def __repr__(self): return '%s * %s'%( repr(self.magnitude), self.dimensionality.string ) @with_doc(np.ndarray.__str__) def __str__(self): if markup.config.use_unicode: dims = self.dimensionality.unicode else: dims = self.dimensionality.string return '%s %s'%(str(self.magnitude), dims) if tuple(map(int, np.__version__.split('.')[:2])) >= (1, 14): # in numpy 1.14 the formatting of scalar values was changed # see https://github.com/numpy/numpy/pull/9883 def __format__(self, format_spec): ret = super().__format__(format_spec) if self.ndim: return ret return ret + f' {self.dimensionality}' @with_doc(np.ndarray.__getitem__) def __getitem__(self, key): ret = super().__getitem__(key) if isinstance(ret, Quantity): return ret else: return Quantity(ret, self._dimensionality) @with_doc(np.ndarray.__setitem__) def __setitem__(self, key, value): if not isinstance(value, Quantity): value = Quantity(value) if self._dimensionality != value._dimensionality: value = value.rescale(self._dimensionality) self.magnitude[key] = value @with_doc(np.ndarray.__lt__) @wrap_comparison def __lt__(self, other): return self.magnitude < other @with_doc(np.ndarray.__le__) @wrap_comparison def __le__(self, other): return self.magnitude <= other @with_doc(np.ndarray.__eq__) def __eq__(self, other): if isinstance(other, Quantity): try: other = other.rescale(self._dimensionality).magnitude except ValueError: return np.zeros(self.shape, '?') return self.magnitude == other @with_doc(np.ndarray.__ne__) def __ne__(self, other): if isinstance(other, Quantity): try: other = other.rescale(self._dimensionality).magnitude except ValueError: return np.ones(self.shape, '?') return self.magnitude != other @with_doc(np.ndarray.__ge__) @wrap_comparison def __ge__(self, other): return self.magnitude >= other @with_doc(np.ndarray.__gt__) @wrap_comparison def __gt__(self, other): return self.magnitude > other #I don't think this implementation is particularly efficient, #perhaps there is something better @with_doc(np.ndarray.tolist) def tolist(self): #first get a dummy array from the ndarray method work_list = self.magnitude.tolist() #now go through and replace all numbers with the appropriate Quantity if isinstance(work_list, list): self._tolist(work_list) else: work_list = Quantity(work_list, self.dimensionality) return work_list def _tolist(self, work_list): for i in range(len(work_list)): #if it's a list then iterate through that list if isinstance(work_list[i], list): self._tolist(work_list[i]) else: #if it's a number then replace it # with the appropriate quantity work_list[i] = Quantity(work_list[i], self.dimensionality) #need to implement other Array conversion methods: # item, itemset, tofile, dump, byteswap @with_doc(np.ndarray.sum) def sum(self, axis=None, dtype=None, out=None): ret = self.magnitude.sum(axis, dtype, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.nansum) def nansum(self, axis=None, dtype=None, out=None): import numpy as np return Quantity( np.nansum(self.magnitude, axis, dtype, out), self.dimensionality, copy=False ) @with_doc(np.ndarray.fill) def fill(self, value): self.magnitude.fill(value) try: self._dimensionality = value.dimensionality except AttributeError: pass @with_doc(np.ndarray.put) def put(self, indicies, values, mode='raise'): """ performs the equivalent of ndarray.put() but enforces units values - must be an Quantity with the same units as self """ if not isinstance(values, Quantity): values = Quantity(values) if values._dimensionality != self._dimensionality: values = values.rescale(self.units) self.magnitude.put(indicies, values, mode) # choose does not function correctly, and it is not clear # how it would function, so for now it will not be implemented @with_doc(np.ndarray.argsort) def argsort(self, axis=-1, kind='quick', order=None): return self.magnitude.argsort(axis, kind, order) @with_doc(np.ndarray.searchsorted) def searchsorted(self,values, side='left'): if not isinstance (values, Quantity): values = Quantity(values, copy=False) if values._dimensionality != self._dimensionality: raise ValueError("values does not have the same units as self") return self.magnitude.searchsorted(values.magnitude, side) @with_doc(np.ndarray.nonzero) def nonzero(self): return self.magnitude.nonzero() @with_doc(np.ndarray.max) def max(self, axis=None, out=None): ret = self.magnitude.max(axis, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.argmax) def argmax(self, axis=None, out=None): return self.magnitude.argmax(axis, out) @with_doc(np.nanmax) def nanmax(self, axis=None, out=None): return Quantity( np.nanmax(self.magnitude), self.dimensionality, copy=False ) @with_doc(np.ndarray.min) def min(self, axis=None, out=None): ret = self.magnitude.min(axis, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.nanmin) def nanmin(self, axis=None, out=None): return Quantity( np.nanmin(self.magnitude), self.dimensionality, copy=False ) @with_doc(np.ndarray.argmin) def argmin(self, axis=None, out=None): return self.magnitude.argmin(axis, out) @with_doc(np.nanargmin) def nanargmin(self,axis=None, out=None): return np.nanargmin(self.magnitude) @with_doc(np.nanargmax) def nanargmax(self,axis=None, out=None): return np.nanargmax(self.magnitude) @with_doc(np.ndarray.ptp) def ptp(self, axis=None, out=None): ret = self.magnitude.ptp(axis, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.clip) def clip(self, min=None, max=None, out=None): if min is None and max is None: raise ValueError("at least one of min or max must be set") else: if min is None: min = Quantity(-np.Inf, self._dimensionality) if max is None: max = Quantity(np.Inf, self._dimensionality) if self.dimensionality and not \ (isinstance(min, Quantity) and isinstance(max, Quantity)): raise ValueError( "both min and max must be Quantities with compatible units" ) clipped = self.magnitude.clip( min.rescale(self._dimensionality).magnitude, max.rescale(self._dimensionality).magnitude, out ) dim = self.dimensionality if out is None: return Quantity(clipped, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.round) def round(self, decimals=0, out=None): ret = self.magnitude.round(decimals, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.trace) def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): ret = self.magnitude.trace(offset, axis1, axis2, dtype, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.squeeze) def squeeze(self, axis=None): return Quantity( self.magnitude.squeeze(axis), self.dimensionality, copy=False ) @with_doc(np.ndarray.mean) def mean(self, axis=None, dtype=None, out=None): ret = self.magnitude.mean(axis, dtype, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.nanmean) def nanmean(self, axis=None, dtype=None, out=None): import numpy as np return Quantity( np.nanmean(self.magnitude, axis, dtype, out), self.dimensionality, copy=False) @with_doc(np.ndarray.var) def var(self, axis=None, dtype=None, out=None, ddof=0): ret = self.magnitude.var(axis, dtype, out, ddof) dim = self._dimensionality**2 if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.std) def std(self, axis=None, dtype=None, out=None, ddof=0): ret = self.magnitude.std(axis, dtype, out, ddof) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.nanstd) def nanstd(self, axis=None, dtype=None, out=None, ddof=0): return Quantity( np.nanstd(self.magnitude, axis, dtype, out, ddof), self._dimensionality, copy=False ) @with_doc(np.ndarray.prod) def prod(self, axis=None, dtype=None, out=None): if axis == None: power = self.size else: power = self.shape[axis] ret = self.magnitude.prod(axis, dtype, None if out is None else out.magnitude) dim = self._dimensionality**power if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.cumsum) def cumsum(self, axis=None, dtype=None, out=None): ret = self.magnitude.cumsum(axis, dtype, None if out is None else out.magnitude) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if not isinstance(out, Quantity): raise TypeError("out parameter must be a Quantity") out._dimensionality = dim return out @with_doc(np.ndarray.cumprod) def cumprod(self, axis=None, dtype=None, out=None): if self._dimensionality: # different array elements would have different dimensionality raise ValueError( "Quantity must be dimensionless, try using simplified" ) ret = self.magnitude.cumprod(axis, dtype, out) dim = self.dimensionality if out is None: return Quantity(ret, dim, copy=False) if isinstance(out, Quantity): out._dimensionality = dim return out # list of unsupported functions: [choose] def __setstate__(self, state): ndarray_state = state[:-1] units = state[-1] np.ndarray.__setstate__(self, ndarray_state) self._dimensionality = units def __reduce__(self): """ Return a tuple for pickling a Quantity. """ reconstruct,reconstruct_args,state = super().__reduce__() state = state + (self._dimensionality,) return (_reconstruct_quantity, (self.__class__, np.ndarray, (0, ), 'b', ), state) def __deepcopy__(self, memo_dict): # constructor copies by default return Quantity(self.magnitude, self.dimensionality) def _reconstruct_quantity(subtype, baseclass, baseshape, basetype,): """Internal function that builds a new MaskedArray from the information stored in a pickle. """ _data = np.ndarray.__new__(baseclass, baseshape, basetype) return subtype.__new__(subtype, _data, dtype=basetype,) python-quantities-0.13.0/quantities/registry.py000066400000000000000000000033151417003363700217160ustar00rootroot00000000000000""" """ import copy import re class UnitRegistry: class __Registry: __shared_state = {} def __init__(self): self.__dict__ = self.__shared_state self.__context = {} def __getitem__(self, string): try: return eval(string, self.__context) except NameError: # could return self['UnitQuantity'](string) raise LookupError( 'Unable to parse units: "%s"'%string ) def __setitem__(self, string, val): assert isinstance(string, str) try: assert string not in self.__context except AssertionError: if val == self.__context[string]: return raise KeyError( '%s has already been registered for %s' % (string, self.__context[string]) ) self.__context[string] = val __regex = re.compile(r'([A-Za-z])\.([A-Za-z])') __registry = __Registry() def __getattr__(self, attr): return getattr(self.__registry, attr) def __setitem__(self, label, value): self.__registry.__setitem__(label, value) def __getitem__(self, label): """Parses a string description of a unit e.g., 'g/cc'""" label = self.__regex.sub( r"\g<1>*\g<2>", label.replace('^', '**').replace('·', '*')) # make sure we can parse the label .... if label == '': label = 'dimensionless' if "%" in label: label = label.replace("%", "percent") if label.lower() == "in": label = "inch" return self.__registry[label] unit_registry = UnitRegistry() python-quantities-0.13.0/quantities/tests/000077500000000000000000000000001417003363700206345ustar00rootroot00000000000000python-quantities-0.13.0/quantities/tests/__init__.py000066400000000000000000000000001417003363700227330ustar00rootroot00000000000000python-quantities-0.13.0/quantities/tests/common.py000066400000000000000000000024001417003363700224720ustar00rootroot00000000000000import sys import unittest import numpy as np from ..quantity import Quantity from ..units import set_default_units class TestCase(unittest.TestCase): def setUp(self): set_default_units('SI') def tearDown(self): set_default_units('SI') def assertQuantityEqual(self, q1, q2, msg=None, delta=None): """ Make sure q1 and q2 are the same quantities to within the given precision. """ delta = 1e-5 if delta is None else delta msg = '' if msg is None else ' (%s)' % msg q1 = Quantity(q1) q2 = Quantity(q2) if q1.shape != q2.shape: raise self.failureException( f"Shape mismatch ({q1.shape} vs {q2.shape}){msg}" ) if not np.all(np.abs(q1.magnitude - q2.magnitude) < delta): raise self.failureException( "Magnitudes differ by more than %g (%s vs %s)%s" % (delta, q1.magnitude, q2.magnitude, msg) ) d1 = getattr(q1, '_dimensionality', None) d2 = getattr(q2, '_dimensionality', None) if (d1 or d2) and not (d1 == d2): raise self.failureException( f"Dimensionalities are not equal ({d1} vs {d2}){msg}" ) python-quantities-0.13.0/quantities/tests/test_arithmetic.py000066400000000000000000000270071417003363700244040ustar00rootroot00000000000000import operator as op from functools import partial import sys import numpy as np from .. import units as pq from ..quantity import Quantity from .common import TestCase if sys.version.startswith('3'): long = int def rand(dtype, *args): if np.dtype(dtype).kind == 'c': return dtype( 10*np.random.rand(*args)+10j*np.random.rand(*args), ) else: return dtype(10*np.random.rand(*args)) def check(f, *args, **kwargs): new = partial(f, *args) new.__name__ = f.__name__ new.__module__ = f.__module__ try: new = kwargs['fails_if'](new) except KeyError: pass desc = [f.__name__] for arg in args: try: desc.append(arg[0].dtype.name) except AttributeError: desc.append(arg[0].__class__.__name__) except (IndexError, TypeError): try: desc.append(arg.dtype.name) except AttributeError: pass c = arg.__class__.__name__ if c != desc[-1]: desc.append(c) new.description = '_'.join(desc) return (new, ) class iter_dtypes: def __init__(self): self._i = 1 self._typeDict = np.typeDict.copy() self._typeDict[17] = int self._typeDict[18] = long self._typeDict[19] = float self._typeDict[20] = complex def __iter__(self): return self def __next__(self): if self._i > 20: raise StopIteration i = self._i self._i += 1 return self._typeDict[i] def next(self): return self.__next__() def get_dtypes(): return list(iter_dtypes()) class iter_types: def __init__(self, dtype): self._index = -1 self._dtype = dtype def __iter__(self): return self def __next__(self): self._index += 1 if self._index > 2: raise StopIteration if self._index > 0 and self._dtype in (int, long, float, complex): raise StopIteration if self._index == 0: return rand(self._dtype) if self._index == 1: return rand(self._dtype, 5).tolist() if self._index == 2: return rand(self._dtype, 5) def next(self): return self.__next__() class TestDTypes(TestCase): def check_mul(self, m1, m2): self.assertQuantityEqual(pq.m*m2, Quantity(m2, 'm')) q1 = Quantity(m1, 'm') q2 = Quantity(m2, 's') a1 = np.asarray(m1) a2 = np.asarray(m2) self.assertQuantityEqual(q1*m2, Quantity(a1*a2, 'm')) self.assertQuantityEqual(q1*q2, Quantity(a1*a2, 'm*s')) def check_rmul(self, m1, m2): self.assertQuantityEqual(m1*pq.m, Quantity(m1, 'm')) q2 = Quantity(m2, 's') a1 = np.asarray(m1) a2 = np.asarray(m2) self.assertQuantityEqual(m1*q2, Quantity(a1*a2, 's')) def test_mul(self): dtypes = get_dtypes() for i in get_dtypes()[::3]: for j in get_dtypes()[::3]: for x in iter_types(i): for y in iter_types(j): self.check_mul(x, y) self.check_rmul(x, y) dtypes.pop(0) def test_mixed_addition(self): self.assertQuantityEqual(1*pq.ft + 1*pq.m, 4.280839895 * pq.ft) self.assertQuantityEqual(1*pq.ft + pq.m, 4.280839895 * pq.ft) self.assertQuantityEqual(pq.ft + 1*pq.m, 4.280839895 * pq.ft) self.assertQuantityEqual(pq.ft + pq.m, 4.280839895 * pq.ft) self.assertQuantityEqual(op.iadd(1*pq.ft, 1*pq.m), 4.280839895 * pq.ft) self.assertRaises(ValueError, lambda: 10*pq.J + 3*pq.m) self.assertRaises(ValueError, lambda: op.iadd(10*pq.J, 3*pq.m)) def test_mod(self): self.assertQuantityEqual(10*pq.m % (3*pq.m), 1*pq.m) self.assertQuantityEqual( 10*pq.m % (3*pq.m).rescale('ft'), 10*pq.m % (3*pq.m) ) self.assertRaises(ValueError, lambda: 10*pq.J % (3*pq.m)) def test_imod(self): x = 10*pq.m x %= 3*pq.m self.assertQuantityEqual(x, 1*pq.m) x = 10*pq.m x %= (3*pq.m).rescale('ft') self.assertQuantityEqual(x, 10*pq.m % (3*pq.m)) self.assertRaises(ValueError, lambda: op.imod(10*pq.J, 3*pq.m)) def test_fmod(self): self.assertQuantityEqual(np.fmod(10*pq.m, (3*pq.m)), 1*pq.m) self.assertRaises(ValueError, np.fmod, 10*pq.J, 3*pq.m) def test_remainder(self): self.assertQuantityEqual(np.remainder(10*pq.m, (3*pq.m)), 1*pq.m) self.assertRaises(ValueError, np.remainder, 10*pq.J, 3*pq.m) def test_negative(self): self.assertQuantityEqual( -pq.m, Quantity(-1, 'm') ) self.assertQuantityEqual( -Quantity(5, 'm'), Quantity(-5, 'm') ) self.assertQuantityEqual( -Quantity(-5.0, 'm'), Quantity(5.0, 'm') ) def test_addition(self): self.assertQuantityEqual( pq.eV + pq.eV, 2*pq.eV ) self.assertQuantityEqual( pq.eV + -pq.eV, 0*pq.eV ) self.assertQuantityEqual( pq.eV + 5*pq.eV, 6*pq.eV ) self.assertQuantityEqual( 5*pq.eV + pq.eV, 6*pq.eV ) self.assertQuantityEqual( 5*pq.eV + 6*pq.eV, 11*pq.eV ) self.assertQuantityEqual( pq.rem + [1, 2, 3]*pq.rem, [2, 3, 4]*pq.rem ) self.assertQuantityEqual( [1, 2, 3]*pq.rem + pq.rem, [2, 3, 4]*pq.rem ) self.assertQuantityEqual( 5*pq.rem + [1, 2, 3]*pq.rem, [6, 7, 8]*pq.rem ) self.assertQuantityEqual( [1, 2, 3]*pq.rem + 5*pq.rem, [6, 7, 8]*pq.rem ) self.assertQuantityEqual( [1, 2, 3]*pq.hp + [1, 2, 3]*pq.hp, [2, 4, 6]*pq.hp ) self.assertRaises(ValueError, op.add, pq.kPa, pq.lb) self.assertRaises(ValueError, op.add, pq.kPa, 10) self.assertRaises(ValueError, op.add, 1*pq.kPa, 5*pq.lb) self.assertRaises(ValueError, op.add, 1*pq.kPa, pq.lb) self.assertRaises(ValueError, op.add, 1*pq.kPa, 5) self.assertRaises(ValueError, op.add, [1, 2, 3]*pq.kPa, [1, 2, 3]*pq.lb) self.assertRaises(ValueError, op.add, [1, 2, 3]*pq.kPa, 5*pq.lb) self.assertRaises(ValueError, op.add, [1, 2, 3]*pq.kPa, pq.lb) self.assertRaises(ValueError, op.add, [1, 2, 3]*pq.kPa, 5) def test_in_place_addition(self): x = 1*pq.m x += pq.m self.assertQuantityEqual(x, pq.m+pq.m) x = 1*pq.m x += -pq.m self.assertQuantityEqual(x, 0*pq.m) x = [1, 2, 3, 4]*pq.m x += pq.m self.assertQuantityEqual(x, [2, 3, 4, 5]*pq.m) x = [1, 2, 3, 4]*pq.m x += x self.assertQuantityEqual(x, [2, 4, 6, 8]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] += pq.m self.assertQuantityEqual(x, [2, 3, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] += -pq.m self.assertQuantityEqual(x, [0, 1, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] += [1, 2]*pq.m self.assertQuantityEqual(x, [2, 4, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[::2] += [1, 2]*pq.m self.assertQuantityEqual(x, [2, 2, 5, 4]*pq.m) self.assertRaises(ValueError, op.iadd, 1*pq.m, 1) self.assertRaises(ValueError, op.iadd, 1*pq.m, pq.J) self.assertRaises(ValueError, op.iadd, 1*pq.m, 5*pq.J) self.assertRaises(ValueError, op.iadd, [1, 2, 3]*pq.m, 1) self.assertRaises(ValueError, op.iadd, [1, 2, 3]*pq.m, pq.J) self.assertRaises(ValueError, op.iadd, [1, 2, 3]*pq.m, 5*pq.J) def test_subtraction(self): self.assertQuantityEqual( pq.eV - pq.eV, 0*pq.eV ) self.assertQuantityEqual( 5*pq.eV - pq.eV, 4*pq.eV ) self.assertQuantityEqual( pq.eV - 4*pq.eV, -3*pq.eV ) self.assertQuantityEqual( pq.rem - [1, 2, 3]*pq.rem, [0, -1, -2]*pq.rem ) self.assertQuantityEqual( [1, 2, 3]*pq.rem - pq.rem, [0, 1, 2]*pq.rem ) self.assertQuantityEqual( 5*pq.rem - [1, 2, 3]*pq.rem, [4, 3, 2]*pq.rem ) self.assertQuantityEqual( [1, 2, 3]*pq.rem - 5*pq.rem, [-4, -3, -2]*pq.rem ) self.assertQuantityEqual( [3, 3, 3]*pq.hp - [1, 2, 3]*pq.hp, [2, 1, 0]*pq.hp ) self.assertRaises(ValueError, op.sub, pq.kPa, pq.lb) self.assertRaises(ValueError, op.sub, pq.kPa, 10) self.assertRaises(ValueError, op.sub, 1*pq.kPa, 5*pq.lb) self.assertRaises(ValueError, op.sub, 1*pq.kPa, pq.lb) self.assertRaises(ValueError, op.sub, 1*pq.kPa, 5) self.assertRaises(ValueError, op.sub, [1, 2, 3]*pq.kPa, [1, 2, 3]*pq.lb) self.assertRaises(ValueError, op.sub, [1, 2, 3]*pq.kPa, 5*pq.lb) self.assertRaises(ValueError, op.sub, [1, 2, 3]*pq.kPa, pq.lb) self.assertRaises(ValueError, op.sub, [1, 2, 3]*pq.kPa, 5) def test_in_place_subtraction(self): x = 1*pq.m x -= pq.m self.assertQuantityEqual(x, 0*pq.m) x = 1*pq.m x -= -pq.m self.assertQuantityEqual(x, 2*pq.m) x = [1, 2, 3, 4]*pq.m x -= pq.m self.assertQuantityEqual(x, [0, 1, 2, 3]*pq.m) x = [1, 2, 3, 4]*pq.m x -= [1, 1, 1, 1]*pq.m self.assertQuantityEqual(x, [0, 1, 2, 3]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] -= pq.m self.assertQuantityEqual(x, [0, 1, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] -= -pq.m self.assertQuantityEqual(x, [2, 3, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[:2] -= [1, 2]*pq.m self.assertQuantityEqual(x, [0, 0, 3, 4]*pq.m) x = [1, 2, 3, 4]*pq.m x[::2] -= [1, 2]*pq.m self.assertQuantityEqual(x, [0, 2, 1, 4]*pq.m) self.assertRaises(ValueError, op.isub, 1*pq.m, 1) self.assertRaises(ValueError, op.isub, 1*pq.m, pq.J) self.assertRaises(ValueError, op.isub, 1*pq.m, 5*pq.J) self.assertRaises(ValueError, op.isub, [1, 2, 3]*pq.m, 1) self.assertRaises(ValueError, op.isub, [1, 2, 3]*pq.m, pq.J) self.assertRaises(ValueError, op.isub, [1, 2, 3]*pq.m, 5*pq.J) def test_powering(self): # test raising a quantity to a power self.assertQuantityEqual((5.5 * pq.cm)**5, (5.5**5) * (pq.cm**5)) self.assertQuantityEqual((5.5 * pq.cm)**0, (5.5**0) * pq.dimensionless) # must also work with compound units self.assertQuantityEqual((5.5 * pq.J)**5, (5.5**5) * (pq.J**5)) # does powering work with arrays? self.assertQuantityEqual( (np.array([1, 2, 3, 4, 5]) * pq.kg)**3, np.array([1, 8, 27, 64, 125]) * pq.kg**3 ) def q_pow_r(q1, q2): return q1 ** q2 self.assertRaises(ValueError, q_pow_r, 10.0 * pq.m, 10 * pq.J) self.assertRaises(ValueError, q_pow_r, 10.0 * pq.m, np.array([1, 2, 3])) self.assertQuantityEqual( (10 * pq.J) ** (2 * pq.J/pq.J) , 100 * pq.J**2 ) # test rpow here self.assertRaises(ValueError, q_pow_r, 10.0, 10 * pq.J) self.assertQuantityEqual(10**(2*pq.J/pq.J), 100) def ipow(q1, q2): q1 -= q2 self.assertRaises(ValueError, ipow, 1*pq.m, [1, 2]) python-quantities-0.13.0/quantities/tests/test_comparison.py000066400000000000000000000115551417003363700244260ustar00rootroot00000000000000import operator as op from .. import units as pq from .common import TestCase class TestComparison(TestCase): def test_scalar_equality(self): self.assertEqual(pq.J == pq.J, [True]) self.assertEqual(1*pq.J == pq.J, [True]) self.assertEqual(str(1*pq.J) == '1.0 J', True) self.assertEqual(pq.J == pq.kg*pq.m**2/pq.s**2, [True]) self.assertEqual(pq.J == pq.erg, [False]) self.assertEqual(2*pq.J == pq.J, [False]) self.assertEqual(pq.J == 2*pq.kg*pq.m**2/pq.s**2, [False]) self.assertEqual(pq.J == pq.kg, [False]) def test_scalar_inequality(self): self.assertEqual(pq.J != pq.erg, [True]) self.assertEqual(2*pq.J != pq.J, [True]) self.assertEqual(str(2*pq.J) != str(pq.J), True) self.assertEqual(pq.J != 2*pq.kg*pq.m**2/pq.s**2, [True]) self.assertEqual(pq.J != pq.J, [False]) self.assertEqual(1*pq.J != pq.J, [False]) self.assertEqual(pq.J != 1*pq.kg*pq.m**2/pq.s**2, [False]) def test_scalar_comparison(self): self.assertEqual(2*pq.J > pq.J, [True]) self.assertEqual(2*pq.J > 1*pq.J, [True]) self.assertEqual(1*pq.J >= pq.J, [True]) self.assertEqual(1*pq.J >= 1*pq.J, [True]) self.assertEqual(2*pq.J >= pq.J, [True]) self.assertEqual(2*pq.J >= 1*pq.J, [True]) self.assertEqual(0.5*pq.J < pq.J, [True]) self.assertEqual(0.5*pq.J < 1*pq.J, [True]) self.assertEqual(0.5*pq.J <= pq.J, [True]) self.assertEqual(0.5*pq.J <= 1*pq.J, [True]) self.assertEqual(1.0*pq.J <= pq.J, [True]) self.assertEqual(1.0*pq.J <= 1*pq.J, [True]) self.assertEqual(2*pq.J < pq.J, [False]) self.assertEqual(2*pq.J < 1*pq.J, [False]) self.assertEqual(2*pq.J <= pq.J, [False]) self.assertEqual(2*pq.J <= 1*pq.J, [False]) self.assertEqual(0.5*pq.J > pq.J, [False]) self.assertEqual(0.5*pq.J > 1*pq.J, [False]) self.assertEqual(0.5*pq.J >= pq.J, [False]) self.assertEqual(0.5*pq.J >= 1*pq.J, [False]) def test_array_equality(self): self.assertQuantityEqual( [1, 2, 3, 4]*pq.J == [1, 22, 3, 44]*pq.J, [1, 0, 1, 0] ) self.assertQuantityEqual( [1, 2, 3, 4]*pq.J == [1, 22, 3, 44]*pq.kg, [0, 0, 0, 0] ) self.assertQuantityEqual( [1, 2, 3, 4]*pq.J == [1, 22, 3, 44], [1, 0, 1, 0] ) def test_array_inequality(self): self.assertQuantityEqual( [1, 2, 3, 4]*pq.J != [1, 22, 3, 44]*pq.J, [0, 1, 0, 1] ) self.assertQuantityEqual( [1, 2, 3, 4]*pq.J != [1, 22, 3, 44]*pq.kg, [1, 1, 1, 1] ) self.assertQuantityEqual( [1, 2, 3, 4]*pq.J != [1, 22, 3, 44], [0, 1, 0, 1] ) def test_quantity_less_than(self): self.assertQuantityEqual( [1, 2, 33]*pq.J < [1, 22, 3]*pq.J, [0, 1, 0] ) self.assertQuantityEqual( [50, 100, 150]*pq.cm < [1, 1, 1]*pq.m, [1, 0, 0] ) self.assertQuantityEqual( [1, 2, 33]*pq.J < [1, 22, 3], [0, 1, 0] ) self.assertRaises( ValueError, op.lt, [1, 2, 33]*pq.J, [1, 22, 3]*pq.kg, ) def test_quantity_less_than_or_equal(self): self.assertQuantityEqual( [1, 2, 33]*pq.J <= [1, 22, 3]*pq.J, [1, 1, 0] ) self.assertQuantityEqual( [50, 100, 150]*pq.cm <= [1, 1, 1]*pq.m, [1, 1, 0] ) self.assertQuantityEqual( [1, 2, 33]*pq.J <= [1, 22, 3], [1, 1, 0] ) self.assertRaises( ValueError, op.le, [1, 2, 33]*pq.J, [1, 22, 3]*pq.kg, ) def test_quantity_greater_than_or_equal(self): self.assertQuantityEqual( [1, 2, 33]*pq.J >= [1, 22, 3]*pq.J, [1, 0, 1] ) self.assertQuantityEqual( [50, 100, 150]*pq.cm >= [1, 1, 1]*pq.m, [0, 1, 1] ) self.assertQuantityEqual( [1, 2, 33]*pq.J >= [1, 22, 3], [1, 0, 1] ) self.assertRaises( ValueError, op.ge, [1, 2, 33]*pq.J, [1, 22, 3]*pq.kg, ) def test_quantity_greater_than(self): self.assertQuantityEqual( [1, 2, 33]*pq.J > [1, 22, 3]*pq.J, [0, 0, 1] ) self.assertQuantityEqual( [50, 100, 150]*pq.cm > [1, 1, 1]*pq.m, [0, 0, 1] ) self.assertQuantityEqual( [1, 2, 33]*pq.J > [1, 22, 3], [0, 0, 1] ) self.assertRaises( ValueError, op.gt, [1, 2, 33]*pq.J, [1, 22, 3]*pq.kg, ) python-quantities-0.13.0/quantities/tests/test_constants.py000066400000000000000000000001301417003363700242530ustar00rootroot00000000000000from .. import units as pq from .. import constants as pc from .common import TestCase python-quantities-0.13.0/quantities/tests/test_conversion.py000066400000000000000000000120341417003363700244320ustar00rootroot00000000000000import unittest from .. import units as pq from .. import quantity from .common import TestCase class TestConversion(TestCase): def test_inplace_conversion(self): for u in ('ft', 'feet', pq.ft): q = 10*pq.m q.units = u self.assertQuantityEqual(q, 32.80839895 * pq.ft) def test_rescale(self): for u in ('ft', 'feet', pq.ft): self.assertQuantityEqual((10*pq.m).rescale(u), 32.80839895 * pq.ft) def test_rescale_preferred(self): quantity.PREFERRED = [pq.mV, pq.pA] q = 10*pq.V self.assertQuantityEqual(q.rescale_preferred(), q.rescale(pq.mV)) q = 5*pq.A self.assertQuantityEqual(q.rescale_preferred(), q.rescale(pq.pA)) quantity.PREFERRED = [] def test_rescale_preferred_failure(self): quantity.PREFERRED = [pq.pA] q = 10*pq.V try: self.assertQuantityEqual(q.rescale_preferred(), q.rescale(pq.mV)) except: self.assertTrue(True) else: self.assertTrue(False) quantity.PREFERRED = [] def test_rescale_noargs(self): quantity.PREFERRED = [pq.mV, pq.pA] q = 10*pq.V self.assertQuantityEqual(q.rescale(), q.rescale(pq.mV)) q = 5*pq.A self.assertQuantityEqual(q.rescale(), q.rescale(pq.pA)) quantity.PREFERRED = [] def test_rescale_noargs_failure(self): quantity.PREFERRED = [pq.pA] q = 10*pq.V try: self.assertQuantityEqual(q.rescale_preferred(), q.rescale(pq.mV)) except: self.assertTrue(True) else: self.assertTrue(False) quantity.PREFERRED = [] def test_compound_reduction(self): pc_per_cc = pq.CompoundUnit("pc/cm**3") temp = pc_per_cc * pq.CompoundUnit('m/m**3') self.assertQuantityEqual( temp.simplified, 3.08568025e+22 / pq.m**4, delta=1e17 ) self.assertQuantityEqual( temp.rescale('pc**-4'), 2.79740021556e+88 / pq.pc**4, delta=1e83 ) class TestDefaultUnits(TestCase): def test_default_length(self): pq.set_default_units(length='mm') self.assertQuantityEqual(pq.m.simplified, 1000*pq.mm) pq.set_default_units(length='m') self.assertQuantityEqual(pq.m.simplified, pq.m) self.assertQuantityEqual(pq.mm.simplified, 0.001*pq.m) def test_default_system(self): pq.set_default_units('cgs') self.assertQuantityEqual(pq.kg.simplified, 1000*pq.g) self.assertQuantityEqual(pq.m.simplified, 100*pq.cm) pq.set_default_units('SI') self.assertQuantityEqual(pq.g.simplified, 0.001*pq.kg) self.assertQuantityEqual(pq.mm.simplified, 0.001*pq.m) pq.set_default_units('cgs', length='mm') self.assertQuantityEqual(pq.kg.simplified, 1000*pq.g) self.assertQuantityEqual(pq.m.simplified, 1000*pq.mm) class TestUnitInformation(TestCase): def test_si(self): pq.set_default_units(information='B') self.assertQuantityEqual(pq.kB.simplified, pq.B*pq.kilo) self.assertQuantityEqual(pq.MB.simplified, pq.B*pq.mega) self.assertQuantityEqual(pq.GB.simplified, pq.B*pq.giga) self.assertQuantityEqual(pq.TB.simplified, pq.B*pq.tera) self.assertQuantityEqual(pq.PB.simplified, pq.B*pq.peta) self.assertQuantityEqual(pq.EB.simplified, pq.B*pq.exa) self.assertQuantityEqual(pq.ZB.simplified, pq.B*pq.zetta) self.assertQuantityEqual(pq.YB.simplified, pq.B*pq.yotta) def test_si_aliases(self): prefixes = ['kilo', 'mega', 'giga', 'tera', 'peta', 'exa', 'zetta', 'yotta'] for prefix in prefixes: self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'bytes')) self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'octet')) self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'octets')) def test_iec(self): pq.set_default_units(information='B') self.assertQuantityEqual(pq.KiB.simplified, pq.B*pq.kibi) self.assertQuantityEqual(pq.MiB.simplified, pq.B*pq.mebi) self.assertQuantityEqual(pq.GiB.simplified, pq.B*pq.gibi) self.assertQuantityEqual(pq.TiB.simplified, pq.B*pq.tebi) self.assertQuantityEqual(pq.PiB.simplified, pq.B*pq.pebi) self.assertQuantityEqual(pq.EiB.simplified, pq.B*pq.exbi) self.assertQuantityEqual(pq.ZiB.simplified, pq.B*pq.zebi) self.assertQuantityEqual(pq.YiB.simplified, pq.B*pq.yobi) def test_iec_aliases(self): prefixes = ['kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi', 'zebi', 'yobi'] for prefix in prefixes: self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'bytes')) self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'octet')) self.assertQuantityEqual(pq.B.rescale(prefix + 'byte'), pq.B.rescale(prefix + 'octets')) python-quantities-0.13.0/quantities/tests/test_dimensionality.py000066400000000000000000000143301417003363700252760ustar00rootroot00000000000000import operator as op from .. import units as pq from ..dimensionality import Dimensionality from .common import TestCase meter = Dimensionality({pq.m: 1}) meter_str = 'm' centimeter = Dimensionality({pq.cm: 1}) centimeter_str = 'cm' joule = Dimensionality({pq.kg: 1, pq.m: 2, pq.s: -2}) joule_str = 'kg*m**2/s**2' joule_uni = 'kg·m²/s²' joule_tex = r'$\mathrm{\frac{kg{\cdot}m^{2}}{s^{2}}}$' joule_htm = 'kg⋅m2/s2' Joule = Dimensionality({pq.J: 1}) Joule_str = 'J' class TestDimensionality(TestCase): def test_dimensionality_str(self): self.assertEqual(str(meter), meter_str) self.assertEqual(joule.string, joule_str) self.assertEqual(joule.unicode, joule_uni) self.assertEqual(joule.latex, joule_tex) self.assertEqual(joule.html, joule_htm) self.assertEqual(Joule.string, 'J') def test_equality(self): self.assertTrue(meter == meter) self.assertTrue(joule == joule) self.assertFalse(meter == Joule) self.assertFalse(joule == Joule) def test_inequality(self): self.assertFalse(meter != meter) self.assertFalse(joule != joule) self.assertTrue(meter != Joule) self.assertTrue(joule != Joule) def test_copy(self): temp = meter.copy() self.assertTrue(temp is not meter) self.assertTrue(isinstance(temp, Dimensionality)) self.assertTrue(temp == meter) temp[pq.m] += 1 self.assertFalse(temp == meter) def test_addition(self): self.assertTrue(meter + meter is not meter) self.assertRaises(ValueError, op.add, meter, joule) self.assertRaises(ValueError, op.add, Joule, joule) self.assertRaises(TypeError, op.add, Joule, 0) self.assertRaises(TypeError, op.add, 0, joule) def test_inplace_addition(self): temp = meter.copy() temp += meter self.assertEqual(temp, meter) self.assertRaises(ValueError, op.iadd, meter, joule) self.assertRaises(ValueError, op.iadd, Joule, joule) self.assertRaises(TypeError, op.iadd, Joule, 0) self.assertRaises(TypeError, op.iadd, 0, joule) def test_subtraction(self): self.assertTrue(meter - meter is not meter) self.assertRaises(ValueError, op.sub, meter, joule) self.assertRaises(ValueError, op.sub, Joule, joule) self.assertRaises(TypeError, op.sub, Joule, 0) self.assertRaises(TypeError, op.sub, 0, joule) def test_inplace_subtraction(self): temp = meter.copy() temp -= meter self.assertEqual(temp, meter) self.assertRaises(ValueError, op.isub, meter, joule) self.assertRaises(ValueError, op.isub, Joule, joule) self.assertRaises(TypeError, op.isub, Joule, 0) self.assertRaises(TypeError, op.isub, 0, joule) def test_multiplication(self): self.assertEqual(meter*meter, Dimensionality({pq.m: 2})) self.assertEqual(meter*centimeter, Dimensionality({pq.m: 1, pq.cm: 1})) self.assertEqual(joule*meter, Dimensionality({pq.kg: 1, pq.m: 3, pq.s: -2})) self.assertRaises(TypeError, op.mul, Joule, 0) self.assertRaises(TypeError, op.mul, 0, joule) def test_inplace_multiplication(self): temp = meter.copy() temp *= meter self.assertEqual(temp, meter*meter) temp *= centimeter self.assertEqual(temp, meter*meter*centimeter) temp *= centimeter**-1 self.assertEqual(temp, meter*meter) self.assertRaises(TypeError, op.imul, Joule, 0) self.assertRaises(TypeError, op.imul, 0, joule) def test_division(self): self.assertEqual(meter/meter, Dimensionality()) self.assertEqual(joule/meter, Dimensionality({pq.kg: 1, pq.m: 1, pq.s: -2})) self.assertRaises(TypeError, op.truediv, Joule, 0) self.assertRaises(TypeError, op.truediv, 0, joule) def test_inplace_division(self): temp = meter.copy() temp /= meter self.assertEqual(temp, meter/meter) temp /= centimeter self.assertEqual(temp, meter/meter/centimeter) temp /= centimeter**-1 self.assertEqual(temp, meter/meter) self.assertRaises(TypeError, op.itruediv, Joule, 0) self.assertRaises(TypeError, op.itruediv, 0, joule) def test_power(self): self.assertEqual(meter**2, meter*meter) self.assertEqual(meter**0, Dimensionality()) self.assertEqual(joule**2, Dimensionality({pq.kg: 2, pq.m: 4, pq.s: -4})) self.assertRaises(TypeError, op.pow, Joule, joule) self.assertRaises(TypeError, op.pow, joule, Joule) self.assertEqual(meter**-1 == meter**-2, False) def test_inplace_power(self): temp = meter.copy() temp **= 2 self.assertEqual(temp, meter**2) temp = joule.copy() temp **= 2 self.assertEqual(temp, joule**2) temp = meter.copy() temp **= 0 self.assertEqual(temp, Dimensionality()) self.assertRaises(TypeError, op.ipow, Joule, joule) self.assertRaises(TypeError, op.ipow, joule, Joule) def test_simplification(self): self.assertEqual(Joule.simplified.string, 'kg*m**2/s**2') self.assertEqual(Joule.simplified, joule) def test_gt(self): self.assertTrue(joule > meter) self.assertTrue(Joule > meter) self.assertFalse(meter > joule) self.assertFalse(meter > Joule) self.assertFalse(joule > joule) self.assertFalse(joule > Joule) def test_ge(self): self.assertTrue(joule >= meter) self.assertTrue(Joule >= meter) self.assertFalse(meter >= joule) self.assertFalse(meter >= Joule) self.assertTrue(joule >= joule) self.assertTrue(joule >= Joule) def test_lt(self): self.assertTrue(meter < joule) self.assertTrue(meter < Joule) self.assertFalse(joule < meter) self.assertFalse(Joule < meter) self.assertFalse(joule < joule) self.assertFalse(Joule < joule) def test_le(self): self.assertTrue(meter <= joule) self.assertTrue(meter <= Joule) self.assertFalse(joule <= meter) self.assertFalse(Joule <= meter) self.assertTrue(joule <= joule) self.assertTrue(joule <= Joule) python-quantities-0.13.0/quantities/tests/test_formatting.py000066400000000000000000000006671417003363700244300ustar00rootroot00000000000000from .. import units as pq from .common import TestCase class TestFormatting(TestCase): @staticmethod def _check(quantity, formatted): assert str(quantity) == formatted assert f'{quantity}' == formatted assert f'{quantity!s}' == formatted def test_str_format_scalar(self): self._check(1*pq.J, '1.0 J') def test_str_format_non_scalar(self): self._check([1, 2]*pq.J, '[1. 2.] J') python-quantities-0.13.0/quantities/tests/test_methods.py000066400000000000000000000265751417003363700237270ustar00rootroot00000000000000from .. import units as pq from .common import TestCase import numpy as np class TestQuantityMethods(TestCase): def setUp(self): self.q = [[1, 2], [3, 4]] * pq.m def test_tolist(self): self.assertEqual(self.q.tolist(), [[1*pq.m, 2*pq.m], [3*pq.m, 4*pq.m]]) q_singleton = 1 * pq.m self.assertEqual(q_singleton.tolist(), q_singleton) def test_sum(self): self.assertQuantityEqual(self.q.sum(), 10*pq.m) self.assertQuantityEqual(self.q.sum(0), [4, 6]*pq.m) self.assertQuantityEqual(self.q.sum(1), [3, 7]*pq.m) def test_nansum(self): import numpy as np qnan = [[1,2], [3,4], [np.nan,np.nan]] * pq.m self.assertQuantityEqual(qnan.nansum(), 10*pq.m ) self.assertQuantityEqual(qnan.nansum(0), [4,6]*pq.m ) def test_fill(self): self.q.fill(6 * pq.ft) self.assertQuantityEqual(self.q, [[6, 6], [6, 6]] * pq.ft) self.q.fill(5) self.assertQuantityEqual(self.q, [[5, 5], [5, 5]] * pq.ft) def test_reshape(self): self.assertQuantityEqual(self.q.reshape([1,4]), [[1, 2, 3, 4]] * pq.m) def test_transpose(self): self.assertQuantityEqual(self.q.transpose(), [[1, 3], [2, 4]] * pq.m) def test_flatten(self): self.assertQuantityEqual(self.q.flatten(), [1, 2, 3, 4] * pq.m) def test_ravel(self): self.assertQuantityEqual(self.q.ravel(), [1, 2, 3, 4] * pq.m) def test_squeeze(self): self.assertQuantityEqual( self.q.reshape([1,4]).squeeze(), [1, 2, 3, 4] * pq.m ) def test_take(self): self.assertQuantityEqual(self.q.take([0,1,2,3]), self.q.flatten()) def test_put(self): q = self.q.flatten() q.put([0,2], [10,20]*pq.m) self.assertQuantityEqual(q, [10, 2, 20, 4]*pq.m) q = self.q.flatten() q.put([0, 2], [1, 2]*pq.mm) self.assertQuantityEqual(q, [0.001, 2, 0.002, 4]*pq.m) q = self.q.flatten()/pq.mm q.put([0, 2], [1, 2]) self.assertQuantityEqual(q.simplified, [1, 2000, 2, 4000]) self.assertQuantityEqual(q, [0.001, 2, 0.002, 4]*pq.m/pq.mm) q = self.q.flatten() self.assertRaises(ValueError, q.put, [0, 2], [4, 6] * pq.J) self.assertRaises(ValueError, q.put, [0, 2], [4, 6]) def test_repeat(self): self.assertQuantityEqual(self.q.repeat(2), [1,1,2,2,3,3,4,4]*pq.m) def test_sort(self): q = [4, 5, 2, 3, 1, 6] * pq.m q.sort() self.assertQuantityEqual(q, [1, 2, 3, 4, 5, 6] * pq.m) def test_argsort(self): q = [1, 4, 5, 6, 2, 9] * pq.MeV self.assertQuantityEqual(q.argsort(), [0, 4, 1, 2, 3, 5]) def test_diagonal(self): q = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] * pq.m self.assertQuantityEqual(q.diagonal(offset=1), [2, 3] * pq.m) def test_compress(self): self.assertQuantityEqual( self.q.compress([False, True], axis=0), [[3, 4]] * pq.m ) self.assertQuantityEqual( self.q.compress([False, True], axis=1), [[2], [4]] * pq.m ) def test_searchsorted(self): self.assertQuantityEqual( self.q.flatten().searchsorted([1.5, 2.5] * pq.m), [1, 2] ) self.assertRaises(ValueError, self.q.flatten().searchsorted, [1.5, 2.5]) def test_nonzero(self): q = [1, 0, 5, 6, 0, 9] * pq.m self.assertQuantityEqual(q.nonzero()[0], [0, 2, 3, 5]) def methodWithOut(self, name, result, q=None, *args, **kw): import numpy as np from .. import Quantity if q is None: q = self.q self.assertQuantityEqual( getattr(q.copy(), name)(*args,**kw), result ) if isinstance(result, Quantity): # deliberately using an incompatible unit out = Quantity(np.empty_like(result.magnitude), pq.s, copy=False) else: out = np.empty_like(result) ret = getattr(q.copy(), name)(*args, out=out, **kw) self.assertQuantityEqual( ret, result ) # returned array should be the same as out self.assertEqual(id(ret),id(out)) # but the units had to be adjusted if isinstance(result, Quantity): self.assertEqual(ret.units,result.units) else: self.assertEqual( getattr(ret, 'units', pq.dimensionless), pq.dimensionless ) def test_max(self): self.methodWithOut('max', 4 * pq.m) self.methodWithOut('max', [3, 4] * pq.m, axis=0) self.methodWithOut('max', [2, 4] * pq.m, axis=1) def test_nanmax(self): q = np.append(self.q, np.nan) * self.q.units self.assertQuantityEqual(q.nanmax(), 4*pq.m) def test_argmax(self): import numpy as np self.assertQuantityEqual(self.q.argmax(), 3) self.assertQuantityEqual(self.q.argmax(axis=0), [1, 1]) self.assertQuantityEqual(self.q.argmax(axis=1), [1, 1]) # apparently, numpy's argmax does not return the same object when out is specified. # instead, we test here for shared data out = np.r_[0, 0] ret = self.q.argmax(axis=0,out=out) self.assertQuantityEqual(ret, [1, 1]) self.assertEqual(ret.ctypes.data, out.ctypes.data) def test_nanargmax(self): q = np.append(self.q, np.nan) * self.q.units self.assertEqual(self.q.nanargmax(), 3) def test_min(self): self.methodWithOut('min', 1 * pq.m) self.methodWithOut('min', [1, 2] * pq.m, axis=0) self.methodWithOut('min', [1, 3] * pq.m, axis=1) def test_nanmin(self): q = np.append(self.q, np.nan) * self.q.units self.assertQuantityEqual(q.nanmin(), 1*pq.m) def test_argmin(self): import numpy as np self.assertQuantityEqual(self.q.argmin(), 0) self.assertQuantityEqual(self.q.argmin(axis=0), [0, 0]) self.assertQuantityEqual(self.q.argmin(axis=1), [0, 0]) # apparently, numpy's argmax does not return the same object when out is specified. # instead, we test here for shared data out = np.r_[2, 2] ret = self.q.argmin(axis=0,out=out) self.assertQuantityEqual(ret, [0, 0]) self.assertEqual(ret.ctypes.data, out.ctypes.data) def test_nanargmax(self): q = np.append(self.q, np.nan) * self.q.units self.assertEqual(self.q.nanargmin(), 0) def test_ptp(self): self.methodWithOut('ptp', 3 * pq.m) self.methodWithOut('ptp', [2, 2] * pq.m, axis=0) self.methodWithOut('ptp', [1, 1] * pq.m, axis=1) def test_clip(self): self.methodWithOut( 'clip', [[1, 2], [2, 2]] * pq.m, max=2*pq.m, ) self.methodWithOut( 'clip', [[3, 3], [3, 4]] * pq.m, min=3*pq.m, ) self.methodWithOut( 'clip', [[2, 2], [3, 3]] * pq.m, min=2*pq.m, max=3*pq.m ) self.assertRaises(ValueError, self.q.clip, pq.J) self.assertRaises(ValueError, self.q.clip, 1) def test_round(self): q = [1, 1.33, 5.67, 22] * pq.m self.methodWithOut( 'round', [1, 1, 6, 22] * pq.m, q=q, decimals=0, ) self.methodWithOut( 'round', [0, 0, 10, 20] * pq.m, q=q, decimals=-1, ) self.methodWithOut( 'round', [1, 1.3, 5.7, 22] * pq.m, q=q, decimals=1, ) def test_trace(self): self.methodWithOut('trace', (1+4) * pq.m) def test_cumsum(self): self.methodWithOut('cumsum', [1, 3, 6, 10] * pq.m) self.methodWithOut('cumsum', [[1, 2], [4, 6]] * pq.m, axis=0) self.methodWithOut('cumsum', [[1, 3], [3, 7]] * pq.m, axis=1) def test_mean(self): self.methodWithOut('mean', 2.5 * pq.m) self.methodWithOut('mean', [2, 3] * pq.m, axis=0) self.methodWithOut('mean', [1.5, 3.5] * pq.m, axis=1) def test_nanmean(self): import numpy as np q = [[1,2], [3,4], [np.nan,np.nan]] * pq.m self.assertQuantityEqual(q.nanmean(), self.q.mean()) def test_var(self): self.methodWithOut('var', 1.25 * pq.m**2) self.methodWithOut('var', [1, 1] * pq.m**2, axis=0) self.methodWithOut('var', [0.25, 0.25] * pq.m**2, axis=1) def test_std(self): self.methodWithOut('std', 1.1180339887498949 * pq.m) self.methodWithOut('std', [1, 1] * pq.m, axis=0) self.methodWithOut('std', [0.5, 0.5] * pq.m, axis=1) def test_nanstd(self): import numpy as np q0 = [[1,2], [3,4]] * pq.m q1 = [[1,2], [3,4], [np.nan,np.nan]] * pq.m self.assertQuantityEqual(q0.std(), q1.nanstd()) def test_prod(self): self.methodWithOut('prod', 24 * pq.m**4) self.methodWithOut('prod', [3, 8] * pq.m**2, axis=0) self.methodWithOut('prod', [2, 12] * pq.m**2, axis=1) def test_cumprod(self): self.assertRaises(ValueError, self.q.cumprod) self.assertQuantityEqual((self.q/pq.m).cumprod(), [1, 2, 6, 24]) q = self.q/pq.m self.methodWithOut( 'cumprod', [1, 2, 6, 24], q=q, ) self.methodWithOut( 'cumprod', [[1, 2], [3, 8]], q=q, axis=0, ) self.methodWithOut( 'cumprod', [[1, 2], [3, 12]], q=q, axis=1, ) def test_conj(self): self.assertQuantityEqual((self.q*(1+1j)).conj(), self.q*(1-1j)) self.assertQuantityEqual((self.q*(1+1j)).conjugate(), self.q*(1-1j)) def test_real(self): test_q = self.q * (1 + 1j) test_q.real = [[39.3701, 39.3701], [39.3701, 39.3701]] * pq.inch self.assertQuantityEqual(test_q.real, [[1., 1.], [1., 1.]] * pq.m) def test_imag(self): test_q = self.q * (1 + 1j) test_q.imag = [[39.3701, 39.3701], [39.3701, 39.3701]] * pq.inch self.assertQuantityEqual(test_q.imag, [[1., 1.], [1., 1.]] * pq.m) def test_getitem(self): self.assertRaises(IndexError, self.q.__getitem__, (0,10)) self.assertQuantityEqual(self.q[0], [1,2]*pq.m) self.assertQuantityEqual(self.q[1,1], 4*pq.m) def test_setitem (self): self.assertRaises(ValueError, self.q.__setitem__, (0,0), 1) self.assertRaises(ValueError, self.q.__setitem__, (0,0), 1*pq.J) self.assertRaises(ValueError, self.q.__setitem__, 0, 1) self.assertRaises(ValueError, self.q.__setitem__, 0, [1, 2]) self.assertRaises(ValueError, self.q.__setitem__, 0, 1*pq.J) q = self.q.copy() q[0] = 1*pq.m self.assertQuantityEqual(q, [[1,1],[3,4]]*pq.m) q[0] = (1,2)*pq.m self.assertQuantityEqual(q, self.q) q[:] = 1*pq.m self.assertQuantityEqual(q, [[1,1],[1,1]]*pq.m) # check and see that dimensionless numbers work correctly q = [0,1,2,3]*pq.dimensionless q[0] = 1 self.assertQuantityEqual(q, [1,1,2,3]) q[0] = pq.m/pq.mm self.assertQuantityEqual(q, [1000, 1,2,3]) q = [0,1,2,3] * pq.m/pq.mm q[0] = 1 self.assertQuantityEqual(q, [0.001,1,2,3]*pq.m/pq.mm) def test_iterator(self): for q in self.q.flatten(): self.assertQuantityEqual(q.units, pq.m) python-quantities-0.13.0/quantities/tests/test_persistence.py000066400000000000000000000120221417003363700245660ustar00rootroot00000000000000import pickle import copy from .. import units as pq from ..quantity import Quantity from ..uncertainquantity import UncertainQuantity from .. import constants from .common import TestCase class TestPersistence(TestCase): def test_unitquantity_persistence(self): x = pq.m y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) x = pq.CompoundUnit("pc/cm**3") y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_quantity_persistence(self): x = 20*pq.m y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_uncertainquantity_persistence(self): x = UncertainQuantity(20, 'm', 0.2) y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_unitconstant_persistence(self): x = constants.m_e y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_quantity_object_dtype(self): # Regression test for github issue #113 x = Quantity(1,dtype=object) y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_uncertainquantity_object_dtype(self): # Regression test for github issue #113 x = UncertainQuantity(20, 'm', 0.2, dtype=object) y = pickle.loads(pickle.dumps(x)) self.assertQuantityEqual(x, y) def test_backward_compat(self): """ A few pickles collected before fixing #113 just to make sure we remain backwards compatible. """ orig = [ pq.m, 20*pq.m, UncertainQuantity(20, 'm', 0.2), constants.m_e, ] data = [ # generated with protocol=2 b'\x80\x02cquantities.unitquantity\nUnitLength\nq\x00(X\x05\x00\x00\x00meterq\x01NX\x01\x00\x00\x00mq\x02N]q\x03(X\x06\x00\x00\x00metersq\x04X\x05\x00\x00\x00metreq\x05X\x06\x00\x00\x00metresq\x06eNtq\x07Rq\x08K\x01K\x02K\x02\x86q\t\x86q\nb.', b'\x80\x02cquantities.quantity\n_reconstruct_quantity\nq\x00(cquantities.quantity\nQuantity\nq\x01cnumpy\nndarray\nq\x02K\x00\x85q\x03X\x01\x00\x00\x00bq\x04tq\x05Rq\x06(K\x01)cnumpy\ndtype\nq\x07X\x02\x00\x00\x00f8q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00\x00\x00=1.21 raises TypeError self.assertRaises((TypeError, ValueError), np.arctan2, (1*pq.m, 1*pq.m)) def test_hypot(self): self.assertQuantityEqual(np.hypot(3 * pq.m, 4 * pq.m), 5 * pq.m) self.assertRaises(ValueError, np.hypot, 1*pq.m, 2*pq.J) def test_degrees(self): self.assertQuantityEqual( np.degrees(6 * pq.radians), (6 * pq.radians).rescale(pq.degree) ) self.assertRaises(ValueError, np.degrees, 0*pq.degree) def test_radians(self): self.assertQuantityEqual( np.radians(6 * pq.degree), (6 * pq.degree).rescale(pq.radian) ) self.assertRaises(ValueError, np.radians, 0*pq.radians) @unittest.expectedFailure def test_unwrap(self): self.assertQuantityEqual(np.unwrap([0,3*np.pi]*pq.radians), [0,np.pi]) self.assertQuantityEqual(np.unwrap([0,540]*pq.deg), [0,180]*pq.deg) def test_equal(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 1.0) * pq.m self.assertTrue(np.all(np.equal(arr1, arr2))) self.assertFalse(np.all(np.equal(arr1, arr2 * 2))) def test_not_equal(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 1.0) * pq.m self.assertTrue(np.all(np.not_equal(arr1, arr2*2))) self.assertFalse(np.all(np.not_equal(arr1, arr2))) def test_less(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 1.0) * pq.m self.assertTrue(np.all(np.less(arr1, arr2*2))) self.assertFalse(np.all(np.less(arr1*2, arr2))) def test_less_equal(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 2.0) * pq.m self.assertTrue(np.all(np.less_equal(arr1, arr2))) self.assertFalse(np.all(np.less_equal(arr2, arr1))) def test_greater(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 2.0) * pq.m self.assertTrue(np.all(np.greater(arr2*1.01, arr1))) self.assertFalse(np.all(np.greater(arr2, arr1))) def test_greater_equal(self): arr1 = (1, 1) * pq.m arr2 = (1.0, 2.0) * pq.m self.assertTrue(np.all(np.greater_equal(arr2, arr1))) self.assertFalse(np.all(np.greater_equal(arr2*0.99, arr1))) python-quantities-0.13.0/quantities/tests/test_uncertainty.py000066400000000000000000000120771417003363700246210ustar00rootroot00000000000000from .. import units as pq from ..uncertainquantity import UncertainQuantity from .common import TestCase import numpy as np class TestUncertainty(TestCase): def test_creation(self): a = UncertainQuantity(1, pq.m) self.assertQuantityEqual(a, 1*pq.m) self.assertQuantityEqual(a.uncertainty, 0*pq.m) a = UncertainQuantity([1, 1, 1], pq.m) self.assertQuantityEqual(a, [1,1,1]*pq.m) self.assertQuantityEqual(a.uncertainty, [0,0,0]*pq.m) a = UncertainQuantity([1, 1, 1], pq.m, [.1, .1, .1]) self.assertQuantityEqual(a, [1, 1, 1] *pq.m) self.assertQuantityEqual(a.uncertainty, [0.1, 0.1, 0.1] *pq.m) self.assertRaises(ValueError, UncertainQuantity, [1,1,1], pq.m, 1) self.assertRaises(ValueError, UncertainQuantity, [1,1,1], pq.m, [1,1]) def test_rescale(self): a = UncertainQuantity([1, 1, 1], pq.m, [.1, .1, .1]) b = a.rescale(pq.ft) self.assertQuantityEqual( a.rescale('ft'), [3.2808399, 3.2808399, 3.2808399]*pq.ft ) self.assertQuantityEqual( a.rescale('ft').uncertainty, [0.32808399, 0.32808399, 0.32808399]*pq.ft ) def test_set_uncertainty(self): a = UncertainQuantity([1, 2], 'm', [.1, .2]) a.uncertainty = [1., 2.]*pq.m self.assertQuantityEqual(a.uncertainty, [1, 2]*pq.m) def set_u(q, u): q.uncertainty = u self.assertRaises(ValueError, set_u, a, 1) self.assertRaises(ValueError, set_u, a, [1,2]) def test_uncertainquantity_multiply(self): a = UncertainQuantity([1, 2], 'm', [.1, .2]) self.assertQuantityEqual(a*a, [1., 4.]*pq.m**2) self.assertQuantityEqual((a*a).uncertainty, [0.14142,0.56568]*pq.m**2) self.assertQuantityEqual(a*2, [2, 4]*pq.m) self.assertQuantityEqual((a*2).uncertainty, [0.2,0.4]*pq.m) def test_uncertainquantity_negative(self): a = UncertainQuantity([1, 2], 'm', [.1, .2]) self.assertQuantityEqual(-a, [-1., -2.]*pq.m) self.assertQuantityEqual((-a).uncertainty, [0.1, 0.2]*pq.m) self.assertQuantityEqual(-a, a*-1) self.assertQuantityEqual((-a).uncertainty, (a*-1).uncertainty) def test_uncertainquantity_divide(self): a = UncertainQuantity([1, 2], 'm', [.1, .2]) self.assertQuantityEqual(a/a, [1., 1.]) self.assertQuantityEqual((a/a).uncertainty, [0.14142, 0.14142]) self.assertQuantityEqual(a/pq.m, [1., 2.]) self.assertQuantityEqual((a/pq.m).uncertainty, [0.1, 0.2]) self.assertQuantityEqual(a/2, [0.5, 1.]*pq.m) self.assertQuantityEqual((a/2).uncertainty, [0.05, 0.1 ]*pq.m) self.assertQuantityEqual(1/a, [1., 0.5]/pq.m) self.assertQuantityEqual((1/a).uncertainty, [0.1, 0.05]/pq.m) def test_uncertaintity_mean(self): a = UncertainQuantity([1,2], 'm', [.1,.2]) mean0 = np.sum(a)/np.size(a) # calculated traditionally mean1 = a.mean() # calculated using this code self.assertQuantityEqual(mean0, mean1) def test_uncertaintity_nanmean(self): a = UncertainQuantity([1,2], 'm', [.1,.2]) b = UncertainQuantity([1,2,np.nan], 'm', [.1,.2,np.nan]) self.assertQuantityEqual(a.mean(),b.nanmean()) def test_uncertainty_sqrt(self): a = UncertainQuantity([1,2], 'm', [.1,.2]) self.assertQuantityEqual(a**0.5, a.sqrt()) def test_uncertainty_nansum(self): uq = UncertainQuantity([1,2], 'm', [1,1]) uq_nan = UncertainQuantity([1,2,np.nan], 'm', [1,1,np.nan]) self.assertQuantityEqual(np.sum(uq), np.nansum(uq)) self.assertQuantityEqual(np.sum(uq), uq_nan.nansum()) def test_uncertainty_minmax_nan_arg(self): q = [[1, 2], [3, 4]] * pq.m # quantity self.assertQuantityEqual(q.min(), 1*pq.m) # min self.assertQuantityEqual(q.max(), 4*pq.m) # max self.assertQuantityEqual(q.argmin(), 0) # argmin self.assertQuantityEqual(q.argmax(), 3) # argmax # uncertain quantity uq = UncertainQuantity([[1,2],[3,4]], pq.m, [[1,1],[1,1]]) self.assertQuantityEqual(uq.min(), 1*pq.m) # min self.assertQuantityEqual(uq.max(), 4*pq.m) # max self.assertQuantityEqual(uq.argmin(), 0) # argmin self.assertQuantityEqual(uq.argmax(), 3) # argmax # now repeat the above with NaNs nanq = [[1, 2], [3, 4], [np.nan,np.nan]] * pq.m # quantity nanuq = UncertainQuantity([[1,2],[3,4],[np.nan,np.nan]], pq.m, [[1,1],[1,1],[np.nan,np.nan]]) self.assertQuantityEqual(nanq.nanmin(), 1*pq.m) # min self.assertQuantityEqual(nanq.nanmax(), 4*pq.m) # max self.assertQuantityEqual(nanq.nanargmin(), 0) # argmin self.assertQuantityEqual(nanq.nanargmax(), 3) # argmax self.assertQuantityEqual(nanuq.nanmin(), 1*pq.m) # min self.assertQuantityEqual(nanuq.nanmax(), 4*pq.m) # max self.assertQuantityEqual(nanuq.nanargmin(), 0) # argmin self.assertQuantityEqual(nanuq.nanargmax(), 3) # argmax python-quantities-0.13.0/quantities/tests/test_units.py000066400000000000000000000023251417003363700234110ustar00rootroot00000000000000from .. import units as pq from .common import TestCase class TestUnits(TestCase): def test_compound_units(self): pc_per_cc = pq.CompoundUnit("pc/cm**3") self.assertEqual(str(pc_per_cc.dimensionality), "(pc/cm**3)") self.assertEqual(str(pc_per_cc), "1 (pc/cm**3)") temp = pc_per_cc * pq.CompoundUnit('m/m**3') self.assertEqual(str(temp.dimensionality), "(pc/cm**3)*(m/m**3)") self.assertEqual(str(temp), "1.0 (pc/cm**3)*(m/m**3)") def test_units_protected(self): def setunits(u, v): u.units = v def inplace(op, u, val): getattr(u, '__i%s__'%op)(val) self.assertRaises(AttributeError, setunits, pq.m, pq.ft) self.assertRaises(TypeError, inplace, 'add', pq.m, pq.m) self.assertRaises(TypeError, inplace, 'sub', pq.m, pq.m) self.assertRaises(TypeError, inplace, 'mul', pq.m, pq.m) self.assertRaises(TypeError, inplace, 'truediv', pq.m, pq.m) self.assertRaises(TypeError, inplace, 'pow', pq.m, 2) def test_units_copy(self): self.assertQuantityEqual(pq.m.copy(), pq.m) pc_per_cc = pq.CompoundUnit("pc/cm**3") self.assertQuantityEqual(pc_per_cc.copy(), pc_per_cc) python-quantities-0.13.0/quantities/umath.py000066400000000000000000000230771417003363700211730ustar00rootroot00000000000000import numpy as np from .quantity import Quantity from .units import dimensionless, radian, degree from .decorators import with_doc #__all__ = [ # 'exp', 'expm1', 'log', 'log10', 'log1p', 'log2' #] @with_doc(np.prod) def prod(a, axis=None, dtype=None, out=None): return a.prod(axis, dtype, out) @with_doc(np.sum) def sum(a, axis=None, dtype=None, out=None): return a.sum(axis, dtype, out) @with_doc(np.nansum) def nansum(a, axis=None): if not isinstance(a, Quantity): return np.nansum(a, axis) return Quantity( np.nansum(a.magnitude, axis), a.dimensionality, copy=False ) @with_doc(np.cumprod) def cumprod(a, axis=None, dtype=None, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ return a.cumprod(axis, dtype, out) @with_doc(np.cumsum) def cumsum(a,axis=None, dtype=None, out=None): return a.cumsum(axis, dtype, out) diff = np.diff @with_doc(np.ediff1d) def ediff1d(ary, to_end=None, to_begin=None): if not isinstance(ary, Quantity): return np.ediff1d(ary, to_end, to_begin) return Quantity( np.ediff1d(ary.magnitude, to_end, to_begin), ary.dimensionality, copy=False ) @with_doc(np.gradient) def gradient(f, *varargs): # if no sample distances are specified, use dimensionless 1 # this mimics the behavior of np.gradient, but perhaps we should # remove this default behavior # removed for now:: # # if len(varargs) == 0: # varargs = (Quantity(1),) varargsQuantities = [Quantity(i, copy=False) for i in varargs] varargsMag = tuple(i.magnitude for i in varargsQuantities) ret = np.gradient(f.magnitude, *varargsMag) if len(varargs) == 1: # if there was only one sample distance provided, # apply the units in all directions return tuple( Quantity(i, f.units/varargs[0].units) for i in ret) else: #give each output array the units of the input array #divided by the units of the spacing quantity given return tuple( Quantity(i, f.units/j.units) for i,j in zip( ret, varargsQuantities)) @with_doc(np.cross) def cross (a, b , axisa=-1, axisb=-1, axisc=-1, axis=None): if not (isinstance(a, Quantity) and isinstance(b, Quantity)): return np.cross(a, b, axisa, axisb, axisc, axis) if not isinstance(a, Quantity): a = Quantity(a, dimensionless, copy=False) if not isinstance(b, Quantity): b = Quantity(b, dimensionless, copy=False) return Quantity( np.cross(a, b, axisa, axisb, axisc, axis), a._dimensionality*b._dimensionality, copy=False ) @with_doc(np.trapz) def trapz(y, x=None, dx=1.0, axis=-1): # this function has a weird input structure, so it is tricky to wrap it # perhaps there is a simpler way to do this if ( not isinstance(y, Quantity) and not isinstance(x, Quantity) and not isinstance(dx, Quantity) ): return np.trapz(y, x, dx, axis) if not isinstance(y, Quantity): y = Quantity(y, copy = False) if not isinstance(x, Quantity) and not x is None: x = Quantity(x, copy = False) if not isinstance(dx, Quantity): dx = Quantity(dx, copy = False) if x is None: ret = np.trapz(y.magnitude , x, dx.magnitude, axis) return Quantity ( ret, y.units * dx.units) else: ret = np.trapz(y.magnitude , x.magnitude, dx.magnitude, axis) return Quantity ( ret, y.units * x.units) @with_doc(np.sin) def sin(x, out=None): """ Raises a ValueError if input cannot be rescaled to radians. Returns a dimensionless quantity. """ if not isinstance(x, Quantity): return np.sin(x, out) return Quantity(np.sin(x.rescale(radian).magnitude, out), copy=False) @with_doc(np.arcsin) def arcsin(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. Returns a quantity in units of radians. """ if not isinstance(x, Quantity): return np.arcsin(x, out) return Quantity( np.arcsin(x.rescale(dimensionless).magnitude, out), radian, copy=False ) @with_doc(np.cos) def cos(x, out=None): """ Raises a ValueError if input cannot be rescaled to radians. Returns a dimensionless quantity. """ if not isinstance(x, Quantity): return np.cos(x, out) return Quantity(np.cos(x.rescale(radian).magnitude), copy=False) @with_doc(np.arccos) def arccos(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. Returns a quantity in units of radians. """ if not isinstance(x, Quantity): return np.arccos(x, out) return Quantity( np.arccos(x.rescale(dimensionless).magnitude, out), radian, copy=False ) @with_doc(np.tan) def tan(x, out=None): """ Raises a ValueError if input cannot be rescaled to radians. Returns a dimensionless quantity. """ if not isinstance(x, Quantity): return np.tan(x, out) return Quantity(np.tan(x.rescale(radian).magnitude), copy=False) @with_doc(np.arctan) def arctan(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. Returns a quantity in units of radians. """ if not isinstance(x, Quantity): return np.arctan(x, out) return Quantity( np.arctan(x.rescale(dimensionless).magnitude, out), radian, copy=False ) @with_doc(np.arctan2) def arctan2(x1, x2, out=None): """ Raises a ValueError if inputs do not have identical units. Returns a quantity in units of radians. """ if not (isinstance(x1, Quantity) and isinstance(x2, Quantity)): return np.arctan2(x1, x2, out) if not isinstance(x1, Quantity): x1 = Quantity(x1, dimensionless, copy=False) if not isinstance(x2, Quantity): x2 = Quantity(x2, dimensionless, copy=False) if x1._dimensionality.simplified != x2._dimensionality.simplified: raise ValueError( 'x1 and x2 must have identical units, got "%s" and "%s"'\ % (str(x1._dimensionality), str(x2._dimensionality)) ) return Quantity( np.arctan2(x1.magnitude, x2.magnitude, out), radian, copy=False ) @with_doc(np.hypot) def hypot(x1, x2, out = None): """ Raises a ValueError if inputs do not have identical units. """ if not (isinstance(x1, Quantity) and isinstance(x2, Quantity)): return np.hypot(x1, x2, out) if not isinstance(x1, Quantity): x1 = Quantity(x1, dimensionless, copy=False) if not isinstance(x2, Quantity): x2 = Quantity(x2, dimensionless, copy=False) if x1._dimensionality != x2._dimensionality: raise ValueError( 'x1 and x2 must have identical units, got "%s" and "%s"'\ % (str(x1._dimensionality), str(x2._dimensionality)) ) return Quantity( np.hypot(x1.magnitude, x2.magnitude, out), x1.dimensionality, copy = False ) @with_doc(np.unwrap) def unwrap(p, discont=np.pi, axis=-1): if not (isinstance(p, Quantity) and isinstance(discont, Quantity)): return np.unwrap(p, discont, axis) if not isinstance(p, Quantity): p = Quantity(p, copy=False) if not isinstance(discont, Quantity): discont = Quantity(discont, copy=False) discont = discont.rescale(p.units) return Quantity( np.unwrap(p.magnitude, discont.magnitude, axis), p.units ) @with_doc(np.sinh) def sinh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.sinh(x, out) return Quantity( np.sinh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) @with_doc(np.cosh) def cosh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.cosh(x, out) return Quantity( np.cosh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) @with_doc(np.tanh) def tanh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.tanh(x, out) return Quantity( np.tanh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) @with_doc(np.arcsinh) def arcsinh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.arcsinh(x, out) return Quantity( np.arcsinh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) @with_doc(np.arccosh) def arccosh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.arccosh(x, out) return Quantity( np.arccosh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) @with_doc(np.arctanh) def arctanh(x, out=None): """ Raises a ValueError if input cannot be rescaled to a dimensionless quantity. """ if not isinstance(x, Quantity): return np.arctanh(x, out) return Quantity( np.arctanh(x.rescale(dimensionless).magnitude, out), dimensionless, copy=False ) python-quantities-0.13.0/quantities/uncertainquantity.py000066400000000000000000000221171417003363700236360ustar00rootroot00000000000000""" """ import numpy as np from . import markup from .quantity import Quantity, scale_other_units from .registry import unit_registry from .decorators import with_doc class UncertainQuantity(Quantity): # TODO: what is an appropriate value? __array_priority__ = 22 def __new__(cls, data, units='', uncertainty=None, dtype='d', copy=True): ret = Quantity.__new__(cls, data, units, dtype, copy) # _uncertainty initialized to be dimensionless by __array_finalize__: ret._uncertainty._dimensionality = ret._dimensionality if uncertainty is not None: ret.uncertainty = Quantity(uncertainty, ret._dimensionality) elif isinstance(data, UncertainQuantity): if copy or ret._dimensionality != uncertainty._dimensionality: uncertainty = data.uncertainty.rescale(ret.units) ret.uncertainty = uncertainty return ret @Quantity.units.setter def units(self, units): super()._set_units(units) self.uncertainty.units = self._dimensionality @property def _reference(self): ret = super()._reference.view(UncertainQuantity) ret.uncertainty = self.uncertainty._reference return ret @property def simplified(self): ret = super().simplified.view(UncertainQuantity) ret.uncertainty = self.uncertainty.simplified return ret @property def uncertainty(self): return self._uncertainty @uncertainty.setter def uncertainty(self, uncertainty): if not isinstance(uncertainty, Quantity): uncertainty = Quantity(uncertainty, copy=False) try: assert self.shape == uncertainty.shape except AssertionError: raise ValueError('data and uncertainty must have identical shape') if uncertainty._dimensionality != self._dimensionality: uncertainty = uncertainty.rescale(self._dimensionality) self._uncertainty = uncertainty @property def relative_uncertainty(self): return self.uncertainty.magnitude/self.magnitude @with_doc(Quantity.rescale, use_header=False) def rescale(self, units): cls = UncertainQuantity ret = super(cls, self).rescale(units).view(cls) ret.uncertainty = self.uncertainty.rescale(units) return ret def __array_finalize__(self, obj): Quantity.__array_finalize__(self, obj) self._uncertainty = getattr( obj, 'uncertainty', Quantity( np.zeros(self.shape, self.dtype), self._dimensionality, copy=False ) ) @with_doc(Quantity.__add__, use_header=False) @scale_other_units def __add__(self, other): res = super().__add__(other) u = (self.uncertainty**2+other.uncertainty**2)**0.5 return UncertainQuantity(res, uncertainty=u, copy=False) @with_doc(Quantity.__radd__, use_header=False) @scale_other_units def __radd__(self, other): return self.__add__(other) @with_doc(Quantity.__sub__, use_header=False) @scale_other_units def __sub__(self, other): res = super().__sub__(other) u = (self.uncertainty**2+other.uncertainty**2)**0.5 return UncertainQuantity(res, uncertainty=u, copy=False) @with_doc(Quantity.__rsub__, use_header=False) @scale_other_units def __rsub__(self, other): if not isinstance(other, UncertainQuantity): other = UncertainQuantity(other, copy=False) return UncertainQuantity.__sub__(other, self) @with_doc(Quantity.__mul__, use_header=False) def __mul__(self, other): res = super().__mul__(other) try: sru = self.relative_uncertainty oru = other.relative_uncertainty ru = (sru**2+oru**2)**0.5 u = res.view(Quantity) * ru except AttributeError: other = np.array(other, copy=False, subok=True) u = (self.uncertainty**2*other**2)**0.5 res._uncertainty = u return res @with_doc(Quantity.__rmul__, use_header=False) def __rmul__(self, other): return self.__mul__(other) def __neg__(self): return self*-1 @with_doc(Quantity.__truediv__, use_header=False) def __truediv__(self, other): res = super().__truediv__(other) try: sru = self.relative_uncertainty oru = other.relative_uncertainty ru = (sru**2+oru**2)**0.5 u = res.view(Quantity) * ru except AttributeError: other = np.array(other, copy=False, subok=True) u = (self.uncertainty**2/other**2)**0.5 res._uncertainty = u return res @with_doc(Quantity.__rtruediv__, use_header=False) def __rtruediv__(self, other): temp = UncertainQuantity( 1/self.magnitude, self.dimensionality**-1, self.relative_uncertainty/self.magnitude, copy=False ) return other * temp @with_doc(Quantity.__pow__, use_header=False) def __pow__(self, other): res = super().__pow__(other) res.uncertainty = res.view(Quantity) * other * self.relative_uncertainty return res @with_doc(Quantity.__getitem__, use_header=False) def __getitem__(self, key): return UncertainQuantity( self.magnitude[key], self._dimensionality, self.uncertainty[key], copy=False ) @with_doc(Quantity.__repr__, use_header=False) def __repr__(self): return '%s(%s, %s, %s)'%( self.__class__.__name__, repr(self.magnitude), self.dimensionality.string, repr(self.uncertainty.magnitude) ) @with_doc(Quantity.__str__, use_header=False) def __str__(self): if markup.config.use_unicode: dims = self.dimensionality.unicode else: dims = self.dimensionality.string s = '%s %s\n+/-%s (1 sigma)'%( str(self.magnitude), dims, str(self.uncertainty) ) if markup.config.use_unicode: return s.replace('+/-', '±').replace(' sigma', 'σ') return s @with_doc(np.ndarray.sum) def sum(self, axis=None, dtype=None, out=None): return UncertainQuantity( self.magnitude.sum(axis, dtype, out), self.dimensionality, (np.sum(self.uncertainty.magnitude**2, axis))**0.5, copy=False ) @with_doc(np.nansum) def nansum(self, axis=None, dtype=None, out=None): return UncertainQuantity( np.nansum(self.magnitude, axis, dtype, out), self.dimensionality, (np.nansum(self.uncertainty.magnitude**2, axis))**0.5, copy=False ) @with_doc(np.ndarray.mean) def mean(self, axis=None, dtype=None, out=None): return UncertainQuantity( self.magnitude.mean(axis, dtype, out), self.dimensionality, ((1.0/np.size(self,axis))**2 * np.sum(self.uncertainty.magnitude**2, axis))**0.5, copy=False) @with_doc(np.nanmean) def nanmean(self, axis=None, dtype=None, out=None): size = np.sum(~np.isnan(self),axis) return UncertainQuantity( np.nanmean(self.magnitude, axis, dtype, out), self.dimensionality, ((1.0/size)**2 * np.nansum(np.nan_to_num(self.uncertainty.magnitude)**2, axis))**0.5, copy=False) @with_doc(np.sqrt) def sqrt(self, out=None): return self**0.5 @with_doc(np.ndarray.max) def max(self, axis=None, out=None): idx = np.unravel_index(np.argmax(self.magnitude), self.shape) return self[idx] @with_doc(np.nanmax) def nanmax(self, axis=None, out=None): idx = np.unravel_index(np.nanargmax(self.magnitude), self.shape) return self[idx] @with_doc(np.ndarray.min) def min(self, axis=None, out=None): idx = np.unravel_index(np.argmin(self.magnitude), self.shape) return self[idx] @with_doc(np.nanmin) def nanmin(self, axis=None, out=None): idx = np.unravel_index(np.nanargmin(self.magnitude), self.shape) return self[idx] @with_doc(np.ndarray.argmin) def argmin(self,axis=None, out=None): return self.magnitude.argmin() @with_doc(np.ndarray.argmax) def argmax(self,axis=None, out=None): return self.magnitude.argmax() @with_doc(np.nanargmin) def nanargmin(self,axis=None, out=None): return np.nanargmin(self.magnitude) @with_doc(np.nanargmax) def nanargmax(self,axis=None, out=None): return np.nanargmax(self.magnitude) def __setstate__(self, state): ndarray_state = state[:-2] units, sigma = state[-2:] np.ndarray.__setstate__(self, ndarray_state) self._dimensionality = units self._uncertainty = sigma def __reduce__(self): """ Return a tuple for pickling a Quantity. """ reconstruct, reconstruct_args, state = super().__reduce__() state = state + (self._uncertainty,) return reconstruct, reconstruct_args, state python-quantities-0.13.0/quantities/unitquantity.py000066400000000000000000000316361417003363700226330ustar00rootroot00000000000000""" """ import weakref import numpy from .dimensionality import Dimensionality from . import markup from .quantity import Quantity, get_conversion_factor from .registry import unit_registry from .decorators import memoize, with_doc __all__ = [ 'CompoundUnit', 'Dimensionless', 'UnitConstant', 'UnitCurrency', 'UnitCurrent', 'UnitInformation', 'UnitLength', 'UnitLuminousIntensity', 'UnitMass', 'UnitMass', 'UnitQuantity', 'UnitSubstance', 'UnitTemperature', 'UnitTime', 'set_default_units' ] class UnitQuantity(Quantity): _primary_order = 90 _secondary_order = 0 _reference_quantity = None __array_priority__ = 20 def __new__( cls, name, definition=None, symbol=None, u_symbol=None, aliases=[], doc=None ): try: assert isinstance(name, str) except AssertionError: raise TypeError('name must be a string, got %s (not unicode)'%name) try: assert symbol is None or isinstance(symbol, str) except AssertionError: raise TypeError( 'symbol must be a string, ' 'got %s (u_symbol can be unicode)'%symbol ) ret = numpy.array(1, dtype='d').view(cls) ret.flags.writeable = False ret._name = name ret._symbol = symbol ret._u_symbol = u_symbol if doc is not None: ret.__doc__ = doc if definition is not None: if not isinstance(definition, Quantity): definition *= dimensionless ret._definition = definition ret._conv_ref = definition._reference else: ret._definition = None ret._conv_ref = None ret._aliases = aliases ret._format_order = (ret._primary_order, ret._secondary_order) ret.__class__._secondary_order += 1 return ret def __init__( self, name, definition=None, symbol=None, u_symbol=None, aliases=[], doc=None ): unit_registry[name] = self if symbol: unit_registry[symbol] = self for alias in aliases: unit_registry[alias] = self def __array_finalize__(self, obj): pass def __hash__(self): return hash((type(self), self._name)) @property def _reference(self): if self._conv_ref is None: return self else: return self._conv_ref @property def _dimensionality(self): return Dimensionality({self:1}) @property def format_order(self): return self._format_order @property def name(self): return self._name @property def definition(self): if self._definition is None: return self else: return self._definition @property def simplified(self): return self._reference.simplified @property def symbol(self): if self._symbol: return self._symbol else: return self.name @property def u_symbol(self): if self._u_symbol: return self._u_symbol else: return self.symbol @property def units(self): return self @units.setter def units(self, units): raise AttributeError('can not modify protected units') def __repr__(self): ref = self._definition if ref: ref = ', %s * %s'%(str(ref.magnitude), ref.dimensionality.string) else: ref = '' symbol = self._symbol symbol = ', %s'%(repr(symbol)) if symbol else '' if markup.config.use_unicode: u_symbol = self._u_symbol u_symbol = ', %s'%(repr(u_symbol)) if u_symbol else '' else: u_symbol = '' return '%s(%s%s%s%s)'%( self.__class__.__name__, repr(self.name), ref, symbol, u_symbol ) @with_doc(Quantity.__str__, use_header=False) def __str__(self): if self.u_symbol != self.name: if markup.config.use_unicode: s = '1 %s (%s)'%(self.u_symbol, self.name) else: s = '1 %s (%s)'%(self.symbol, self.name) else: s = '1 %s'%self.name return s @with_doc(Quantity.__add__, use_header=False) def __add__(self, other): return self.view(Quantity).__add__(other) @with_doc(Quantity.__radd__, use_header=False) def __radd__(self, other): try: return self.rescale(other.units).__radd__(other) except AttributeError: return self.view(Quantity).__radd__(other) @with_doc(Quantity.__sub__, use_header=False) def __sub__(self, other): return self.view(Quantity).__sub__(other) @with_doc(Quantity.__rsub__, use_header=False) def __rsub__(self, other): try: return self.rescale(other.units).__rsub__(other) except AttributeError: return self.view(Quantity).__rsub__(other) @with_doc(Quantity.__mod__, use_header=False) def __mod__(self, other): return self.view(Quantity).__mod__(other) @with_doc(Quantity.__rsub__, use_header=False) def __rmod__(self, other): try: return self.rescale(other.units).__rmod__(other) except AttributeError: return self.view(Quantity).__rmod__(other) @with_doc(Quantity.__mul__, use_header=False) def __mul__(self, other): return self.view(Quantity).__mul__(other) @with_doc(Quantity.__rmul__, use_header=False) def __rmul__(self, other): return self.view(Quantity).__rmul__(other) @with_doc(Quantity.__truediv__, use_header=False) def __truediv__(self, other): return self.view(Quantity).__truediv__(other) @with_doc(Quantity.__rtruediv__, use_header=False) def __rtruediv__(self, other): return self.view(Quantity).__rtruediv__(other) @with_doc(Quantity.__pow__, use_header=False) def __pow__(self, other): return self.view(Quantity).__pow__(other) @with_doc(Quantity.__rpow__, use_header=False) def __rpow__(self, other): return self.view(Quantity).__rpow__(other) @with_doc(Quantity.__iadd__, use_header=False) def __iadd__(self, other): raise TypeError('can not modify protected units') @with_doc(Quantity.__isub__, use_header=False) def __isub__(self, other): raise TypeError('can not modify protected units') @with_doc(Quantity.__imul__, use_header=False) def __imul__(self, other): raise TypeError('can not modify protected units') @with_doc(Quantity.__itruediv__, use_header=False) def __itruediv__(self, other): raise TypeError('can not modify protected units') @with_doc(Quantity.__ipow__, use_header=False) def __ipow__(self, other): raise TypeError('can not modify protected units') def __getstate__(self): """ Return the internal state of the quantity, for pickling purposes. """ state = (1, self._format_order) return state def __setstate__(self, state): ver, fo = state self._format_order = fo def __reduce__(self): """ Return a tuple for pickling a UnitQuantity. """ return ( type(self), ( self._name, self._definition, self._symbol, self._u_symbol, self._aliases, self.__doc__ ), self.__getstate__() ) def copy(self): return ( type(self)( self._name, self._definition, self._symbol, self._u_symbol, self._aliases, self.__doc__ ) ) unit_registry['UnitQuantity'] = UnitQuantity class IrreducibleUnit(UnitQuantity): _default_unit = None def __init__( self, name, definition=None, symbol=None, u_symbol=None, aliases=[], doc=None ): super().__init__( name, definition, symbol, u_symbol, aliases, doc ) cls = type(self) if cls._default_unit is None: cls._default_unit = self @property def simplified(self): return self.view(Quantity).rescale(self.get_default_unit()) @classmethod def get_default_unit(cls): return cls._default_unit @classmethod def set_default_unit(cls, unit): if unit is None: return if isinstance(unit, str): unit = unit_registry[unit] try: # check that conversions are possible: get_conversion_factor(cls._default_unit, unit) except ValueError: raise TypeError('default unit must be of same type') cls._default_unit = unit class UnitMass(IrreducibleUnit): _primary_order = 1 class UnitLength(IrreducibleUnit): _primary_order = 2 class UnitTime(IrreducibleUnit): _primary_order = 3 class UnitCurrent(IrreducibleUnit): _primary_order = 4 class UnitLuminousIntensity(IrreducibleUnit): _primary_order = 5 class UnitSubstance(IrreducibleUnit): _primary_order = 6 class UnitTemperature(IrreducibleUnit): _primary_order = 7 class UnitInformation(IrreducibleUnit): _primary_order = 8 class UnitCurrency(IrreducibleUnit): _primary_order = 9 class CompoundUnit(UnitQuantity): _primary_order = 99 def __new__(cls, name): return UnitQuantity.__new__(cls, name, unit_registry[name]) def __init__(self, name): # do not register return @with_doc(UnitQuantity.__add__, use_header=False) def __repr__(self): return '1 %s'%self.name @property def name(self): if markup.config.use_unicode: return '(%s)'%(markup.superscript(self._name)) else: return '(%s)'%self._name def __reduce__(self): """ Return a tuple for pickling a UnitQuantity. """ return ( type(self), (self._name, ), self.__getstate__() ) def copy(self): return type(self)(self._name) unit_registry['CompoundUnit'] = CompoundUnit class Dimensionless(UnitQuantity): _primary_order = 100 def __init__(self, name, definition=None): self._name = name if definition is None: definition = self self._definition = definition self._format_order = (self._primary_order, self._secondary_order) self.__class__._secondary_order += 1 unit_registry[name] = self def __reduce__(self): """ Return a tuple for pickling a UnitQuantity. """ return ( type(self), ( self._name, ), self.__getstate__() ) @property def _dimensionality(self): return Dimensionality() dimensionless = Dimensionless('dimensionless') class UnitConstant(UnitQuantity): _primary_order = 0 def __init__( self, name, definition=None, symbol=None, u_symbol=None, aliases=[], doc=None ): # we dont want to register constants in the unit registry return def set_default_units( system=None, currency=None, current=None, information=None, length=None, luminous_intensity=None, mass=None, substance=None, temperature=None, time=None ): """ Set the default units in which simplified quantities will be expressed. system sets the unit system, and can be "SI" or "cgs". All other keyword arguments will accept either a string or a unit quantity. An error will be raised if it is not possible to convert between old and new defaults, so it is not possible to set "kg" as the default unit for time. If both system and individual defaults are given, the system defaults will be applied first, followed by the individual ones. """ if system is not None: system = system.lower() try: assert system in ('si', 'cgs') except AssertionError: raise ValueError('system must be "SI" or "cgs", got "%s"' % system) if system == 'si': UnitCurrent.set_default_unit('A') UnitLength.set_default_unit('m') UnitMass.set_default_unit('kg') elif system == 'cgs': UnitLength.set_default_unit('cm') UnitMass.set_default_unit('g') UnitLuminousIntensity.set_default_unit('cd') UnitSubstance.set_default_unit('mol') UnitTemperature.set_default_unit('degK') UnitTime.set_default_unit('s') UnitCurrency.set_default_unit(currency) UnitCurrent.set_default_unit(current) UnitInformation.set_default_unit(information) UnitLength.set_default_unit(length) UnitLuminousIntensity.set_default_unit(luminous_intensity) UnitMass.set_default_unit(mass) UnitSubstance.set_default_unit(substance) UnitTemperature.set_default_unit(temperature) UnitTime.set_default_unit(time) python-quantities-0.13.0/quantities/units/000077500000000000000000000000001417003363700206345ustar00rootroot00000000000000python-quantities-0.13.0/quantities/units/__init__.py000066400000000000000000000022711417003363700227470ustar00rootroot00000000000000""" """ from . import prefixes from .prefixes import * from . import acceleration from .acceleration import * from . import angle from .angle import * from . import area from .area import * from . import compound from .compound import * from . import concentration from .concentration import * from . import dimensionless from .dimensionless import * from . import electromagnetism from .electromagnetism import * from . import energy from .energy import * from . import force from .force import * from . import frequency from .frequency import * from . import heat from .heat import * from . import information from .information import * from . import length from .length import * from . import mass from .mass import * from . import power from .power import * from . import pressure from .pressure import * from . import radiation from .radiation import * from . import substance from .substance import * from . import temperature from .temperature import * from . import time from .time import * from . import velocity from .velocity import * from . import viscosity from .viscosity import * from . import volume from .volume import * from ..unitquantity import set_default_units python-quantities-0.13.0/quantities/units/acceleration.py000066400000000000000000000005441417003363700236420ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .time import s from .length import m g_0 = g_n = gravity = standard_gravity = gee = force = free_fall = \ standard_free_fall = gp = dynamic = geopotential = UnitQuantity( 'standard_gravity', 9.806650*m/s**2, symbol='g_0', u_symbol='g₀', doc='exact' ) del m, s, UnitQuantity python-quantities-0.13.0/quantities/units/angle.py000066400000000000000000000043531417003363700223010ustar00rootroot00000000000000""" """ from math import pi from ..unitquantity import UnitQuantity, dimensionless rad = radian = radians = UnitQuantity( 'radian', 1*dimensionless, symbol='rad', aliases=['radians'] ) mrad = milliradian = UnitQuantity( 'milliradian', rad/1000, symbol='mrad', aliases=['milliradians'] ) urad = microradian = UnitQuantity( 'microradian', mrad/1000, symbol='urad', u_symbol='µrad', aliases=['microradians'] ) turn = revolution = cycle = turns = circle = circles = UnitQuantity( 'turn', 2*pi*radian, aliases=['turns', 'revolutions', 'circles', 'cycles'] ) deg = degree = degrees = arcdeg = arcdegree = angular_degree = UnitQuantity( 'arcdegree', pi/180*radian, symbol='deg', u_symbol='°', aliases=[ 'degree', 'degrees', 'arc_degree', 'arc_degrees', 'angular_degree', 'angular_degrees', 'arcdegrees', 'arcdeg' ] ) arcminute = arcmin = arc_minute = angular_minute = UnitQuantity( 'arcminute', arcdeg/60, symbol='arcmin', u_symbol='′', aliases=[ 'arcmins', 'arcminutes', 'arc_minute', 'arc_minutes', 'angular_minute', 'angular_minutes' ] ) arcsecond = arcsec = arc_second = angular_second = UnitQuantity( 'arcsecond', arcmin/60, symbol='arcsec', u_symbol='″', aliases=[ 'arcsecs', 'arcseconds', 'arc_second', 'arc_seconds', 'angular_second', 'angular_seconds' ] ) grad = grade = UnitQuantity( 'grad', 0.9*arcdeg, aliases=['grads', 'grade', 'grades', 'gron', 'grons', 'gradian', 'gradians'] ) degrees_north = degrees_N = UnitQuantity( 'degrees_north', arcdeg, symbol='degN', u_symbol='°N', aliases=['degrees_N'] ) degrees_east = degrees_E = UnitQuantity( 'degrees_east', arcdeg, symbol='degE', u_symbol='°E', aliases=['degrees_E'] ) degrees_west = degrees_W = UnitQuantity( 'degrees_west', arcdeg, symbol='degW', u_symbol='°W', aliases=['degrees_W'] ) degrees_true = degrees_T = UnitQuantity( 'degrees_true', arcdeg, symbol='degT', u_symbol='°T', aliases=['degrees_T'] ) sr = steradian = UnitQuantity( 'steradian', radian**2, symbol='sr', aliases=['steradians'] ) del UnitQuantity python-quantities-0.13.0/quantities/units/area.py000066400000000000000000000020201417003363700221100ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .length import m, rod are = ares = UnitQuantity( 'are', 100*m**2, aliases=['ares'] ) b = barn = UnitQuantity( 'barn', 1e-28*m**2, symbol='b', aliases=['barnes'] ) cmil = circular_mil = UnitQuantity( 'circular_mil', 5.067075e-10*m**2, symbol='cmil', aliases=['circular_mils'], doc='conversions approximate, area of a circle with diameter=1 mil' ) D = darcy = UnitQuantity( 'darcy', 9.869233e-13*m**2, symbol='D' ) mD = millidarcy = UnitQuantity( 'millidarcy', D/1000, symbol='mD' ) ha = hectare = UnitQuantity( 'hectare', 10000*m**2, symbol='ha', aliases=['hectares'] ) acre = international_acre = UnitQuantity( 'acre', 4046.8564224*m**2, aliases=['acres', 'international_acre', 'international_acres'], doc="exact. http://en.wikipedia.org/wiki/Acre" ) US_survey_acre = UnitQuantity( 'US_survey_acre', 160*rod**2, aliases=['US_survey_acres'], ) del UnitQuantity, m, rod python-quantities-0.13.0/quantities/units/compound.py000066400000000000000000000001271417003363700230320ustar00rootroot00000000000000""" """ from ..unitquantity import CompoundUnit pc_per_cc = CompoundUnit("pc/cm**3") python-quantities-0.13.0/quantities/units/concentration.py000066400000000000000000000005761417003363700240640ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .substance import mol from .volume import L M = molar = UnitQuantity( 'molar', mol / L, symbol='M', aliases=['Molar'] ) mM = millimolar = UnitQuantity( 'millimolar', molar / 1000, symbol='mM' ) uM = micromolar = UnitQuantity( 'micromolar', mM / 1000, symbol='uM', u_symbol='µM' ) python-quantities-0.13.0/quantities/units/dimensionless.py000066400000000000000000000006051417003363700240630ustar00rootroot00000000000000""" """ from ..unitquantity import dimensionless, UnitQuantity percent = UnitQuantity( 'percent', .01*dimensionless, symbol='%' ) count = counts = UnitQuantity( 'count', 1*dimensionless, symbol='ct', aliases=['cts', 'counts'] ) lsb = UnitQuantity( 'least_significant_bit', 1*dimensionless, symbol='lsb', aliases=['lsbs'] ) del UnitQuantity python-quantities-0.13.0/quantities/units/electromagnetism.py000066400000000000000000000136521417003363700245570ustar00rootroot00000000000000""" """ from ..unitquantity import UnitCurrent, UnitLuminousIntensity, UnitQuantity from .time import s from .length import cm, m from .energy import J, erg from .velocity import c from .force import N from math import pi A = amp = amps = ampere = amperes = UnitCurrent( 'ampere', symbol='A', aliases=['amp', 'amps', 'amperes'] ) mA = milliamp = milliampere = UnitCurrent( 'milliampere', A/1000, symbol='mA', aliases=['milliamp', 'milliamps', 'milliamperes'] ) uA = microampere = UnitCurrent( 'microampere', mA/1000, symbol='uA', u_symbol='µA', aliases=['microamp', 'microamps', 'microamperes']) nA = nanoamp = nanoampere = UnitCurrent( 'nanoampere', uA/1000, symbol='nA', aliases=['nanoamp', 'nanoamps', 'nanoamperes'] ) pA = picoamp = picoampere = UnitCurrent( 'picoampere', nA/1000, symbol='pA', aliases=['picoamp', 'picoamps', 'picoamperes'] ) aA = abampere = biot = UnitCurrent( 'abampere', 10*A, symbol='aA', aliases=['abamperes', 'biot', 'biots'] ) esu = statcoulomb = statC = franklin = Fr = UnitQuantity( 'statcoulomb', 1 * erg**0.5 * cm**0.5, symbol='esu', aliases=['statcoulombs', 'statC', 'franklin', 'franklins', 'Fr'] ) esu_per_second = statampere = UnitCurrent( 'statampere', esu/s, symbol='(esu/s)', aliases=['statamperes'] ) ampere_turn = UnitQuantity( 'ampere_turn', 1*A ) Gi = gilbert = UnitQuantity( 'gilbert', 10/(4*pi)*ampere_turn, symbol='Gi' ) C = coulomb = UnitQuantity( 'coulomb', A*s, symbol='C' ) mC = millicoulomb = UnitQuantity( 'millicoulomb', 1e-3*C, symbol='mC' ) uC = microcoulomb = UnitQuantity( 'microcoulomb', 1e-6*C, symbol='uC', u_symbol='μC' ) V = volt = UnitQuantity( 'volt', J/C, symbol='V', aliases=['volts'] ) kV = kilovolt = UnitQuantity( 'kilovolt', 1000*V, symbol='kV', aliases=['kilovolts'] ) mV = millivolt = UnitQuantity( 'millivolt', V/1000, symbol='mV', aliases=['millivolts'] ) uV = microvolt = UnitQuantity( 'microvolt', V/1e6, symbol='uV', u_symbol='μV', aliases=['microvolts'] ) F = farad = UnitQuantity( 'farad', C/V, symbol='F', aliases=['farads'] ) mF = UnitQuantity( 'millifarad', F/1000, symbol='mF' ) uF = UnitQuantity( 'microfarad', mF/1000, symbol='uF', u_symbol='μF' ) nF = UnitQuantity( 'nanofarad', uF/1000, symbol='nF' ) pF = UnitQuantity( 'picofarad', nF/1000, symbol='pF' ) ohm = Ohm = UnitQuantity( 'ohm', V/A, u_symbol='Ω', aliases=['ohms', 'Ohm'] ) kOhm = UnitQuantity( 'kiloohm', ohm*1000, u_symbol='kΩ', aliases=['kOhm', 'kohm', 'kiloohms'] ) MOhm = UnitQuantity( 'megaohm', kOhm*1000, u_symbol='MΩ', aliases=['MOhm', 'Mohm', 'megaohms'] ) S = siemens = UnitQuantity( 'siemens', A/V, symbol='S' ) mS = millisiemens = UnitQuantity( 'millisiemens', S/1000, symbol='mS' ) uS = microsiemens = UnitQuantity( 'microsiemens', mS/1000, symbol='uS', u_symbol='μS' ) nS = nanosiemens = UnitQuantity( 'nanosiemens', uS/1000, symbol='nS' ) pS = picosiemens = UnitQuantity( 'picosiemens', nS/1000, symbol='pS' ) Wb = weber = UnitQuantity( 'weber', V*s, symbol='Wb', aliases=['webers'] ) T = tesla = UnitQuantity( 'tesla', Wb/m**2, symbol='T', aliases=['teslas'] ) H = henry = UnitQuantity( 'henry', Wb/A, symbol='H' ) abfarad = UnitQuantity( 'abfarad', 1e9*farad, aliases=['abfarads'] ) abhenry = UnitQuantity( 'abhenry', 1e-9*henry ) abmho = UnitQuantity( 'abmho', 1e9*S ) abohm = UnitQuantity( 'abohm', 1e-9*ohm ) abvolt = UnitQuantity( 'abvolt', 1e-8*V, aliases=['abvolts'] ) e = elementary_charge = UnitQuantity( 'elementary_charge', 1.602176487e-19*C, symbol='e', doc='relative uncertainty = 6.64e-8' ) chemical_faraday = UnitQuantity( 'chemical_faraday', 9.64957e4*C ) physical_faraday = UnitQuantity( 'physical_faraday', 9.65219e4*C ) faraday = C12_faraday = UnitQuantity( 'faraday', 96485.3399*C, aliases=['faradays'], doc='The symbol F is reserved for the farad' ) gamma = UnitQuantity( 'gamma', 1e-9*T ) gauss = UnitQuantity( 'gauss', 1e-4*T, symbol='G' ) maxwell = UnitQuantity( 'maxwell', 1e-8*Wb, symbol='Mx', aliases=['maxwells'] ) Oe = oersted = UnitQuantity( 'oersted', 1000/(4*pi)*A/m, symbol='Oe', aliases=['aliases'] ) statfarad = statF = stF = UnitQuantity( 'statfarad', 1.112650e-12*F, symbol='stF', aliases=['statfarads', 'statF'] ) stathenry = statH = stH = UnitQuantity( 'stathenry', 8.987554e11*H, symbol='stH', aliases=['statH'] ) statmho = statS = stS = UnitQuantity( 'statmho', 1.112650e-12*S, symbol='stS' ) statohm = UnitQuantity( 'statohm', 8.987554e11*ohm, u_symbol='stΩ', aliases=['statohms'] ) statvolt = statV = stV = UnitQuantity( 'statvolt', 2.997925e2*V, symbol='stV', aliases=['statvolts', 'statV'] ) unit_pole = UnitQuantity( 'unit_pole', 1.256637e-7*Wb ) vacuum_permeability = mu_0 = magnetic_constant = UnitQuantity( 'magnetic_constant', 4*pi*10**-7*N/A**2, symbol='mu_0', u_symbol='μ₀', aliases=['vacuum_permeability'] ) vacuum_permittivity = epsilon_0 = electric_constant = UnitQuantity( 'electric_constant', 1/(mu_0*c**2), symbol='epsilon_0', u_symbol='ε₀', aliases=['vacuum_permittivity'] ) Z_0 = impedence_of_free_space = characteristic_impedance_of_vacuum = \ UnitQuantity( 'characteristic_impedance_of_vacuum', mu_0*c, symbol='Z_0', u_symbol='Z₀', aliases=['impedence_of_free_space'] ) cd = candle = candela = UnitLuminousIntensity( 'candela', symbol='cd', aliases=['candle', 'candles', 'candelas'] ) del UnitQuantity, s, m, J, c python-quantities-0.13.0/quantities/units/energy.py000066400000000000000000000042401417003363700224770ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .force import dyne, N from .length import cm, m from .time import s, h J = joule = UnitQuantity( 'joule', N*m, symbol='J', aliases=['joules'] ) erg = UnitQuantity( 'erg', dyne*cm ) btu = Btu = BTU = british_thermal_unit = UnitQuantity( 'British_thermal_unit', J*1.05505585262e3, symbol='BTU' ) eV = electron_volt = UnitQuantity( 'electron_volt', J*1.60217653e-19, symbol='eV', aliases=['electron_volts'] ) meV = UnitQuantity( 'meV', eV/1000 ) keV = UnitQuantity( 'keV', 1000*eV ) MeV = UnitQuantity( 'MeV', 1000*keV ) bev = GeV = UnitQuantity( 'GeV', 1000*MeV ) thm = therm = EC_therm = UnitQuantity( 'EC_therm', 100000*BTU, symbol='thm' ) cal = calorie = thermochemical_calorie = UnitQuantity( 'thermochemical_calorie', 4.184*J, symbol='cal', aliases=['calorie', 'calories', 'thermochemical_calories'] ) international_steam_table_calorie = UnitQuantity( 'international_steam_table_calorie', J*4.1868, symbol='cal_IT', aliases=['international_steam_table_calories'] ) ton_TNT = UnitQuantity( 'ton_TNT', 4.184e9*J, symbol='tTNT' ) US_therm = UnitQuantity( 'US_therm', 1.054804e8*J, aliases=['US_therms'] ) Wh = watthour = watt_hour = UnitQuantity( 'watt_hour', J/s*h, symbol='Wh', aliases=['watthour', 'watthours', 'watt_hours'] ) kWh = kilowatthour = kilowatt_hour = UnitQuantity( 'kilowatt_hour', 1000*Wh, symbol='kWh', aliases=['kilowatthour', 'kilowatthours', 'kilowatt_hours'] ) MWh = megawatthour = megawatt_hour = UnitQuantity( 'megawatt_hour', 1000*kWh, symbol='MWh', aliases=['megawatthour', 'megawatthours', 'megawatt_hours'] ) GWh = gigawatthour = gigawatt_hour = UnitQuantity( 'gigawatt_hour', 1000*MWh, symbol='GWh', aliases=['gigawatthour', 'gigawatthours', 'gigawatt_hours'] ) E_h = hartree = hartree_energy = UnitQuantity( 'hartree', 4.35974394e-18*J, symbol='E_h', aliases=['hartrees', 'hartree_energy', 'Hartree_energy'], doc='relative uncertainty = 2.1e-6' ) del UnitQuantity, dyne, N, cm, m, s, h python-quantities-0.13.0/quantities/units/force.py000066400000000000000000000023451417003363700223100ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .mass import gram, kg, ounce, lb from .length import cm, m, ft from .time import s from .acceleration import g_0 N = newton = UnitQuantity( 'newton', kg*m/s**2, symbol='N', aliases=['newtons'] ) dyne = UnitQuantity( 'dyne', gram*cm/s**2, symbol='dyn', aliases=['dynes'] ) pond = UnitQuantity( 'pond', g_0*kg, symbol='p', aliases=['ponds'] ) kgf = force_kilogram = kilogram_force = UnitQuantity( 'kilogram_force', kg*g_0, symbol='kgf', aliases=['force_kilogram'] ) ozf = force_ounce = ounce_force = UnitQuantity( 'ounce_force', ounce*g_0, symbol='ozf', aliases=['force_ounce'] ) lbf = force_pound = pound_force = UnitQuantity( 'pound_force', lb*g_0, symbol='lbf', aliases=['force_pound'] ) poundal = UnitQuantity( 'poundal', lb*ft/s**2, symbol='pdl', aliases=['poundals'] ) gf = gram_force = force_gram = UnitQuantity( 'gram_force', gram*g_0, symbol='gf', aliases=['force_gram'] ) force_ton = ton_force = UnitQuantity( 'ton_force', 2000*force_pound, aliases=['force_ton']) kip = UnitQuantity( 'kip', 1000*lbf ) del UnitQuantity, gram, kg, cm, m, s, g_0 python-quantities-0.13.0/quantities/units/frequency.py000066400000000000000000000012221417003363700232040ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .angle import revolution from .time import s, min from .dimensionless import count Hz = hertz = rps = UnitQuantity( 'hertz', s**-1, symbol='Hz' ) kHz = kilohertz = UnitQuantity( 'kilohertz', Hz*1000, symbol='kHz' ) MHz = megahertz = UnitQuantity( 'megahertz', kHz*1000, symbol='MHz' ) GHz = gigahertz = UnitQuantity( 'gigahertz', MHz*1000, symbol='GHz' ) rpm = revolutions_per_minute = UnitQuantity( 'revolutions_per_minute', revolution/min, symbol='rpm' ) cps = UnitQuantity( 'counts_per_second', count/s ) del UnitQuantity, s, min python-quantities-0.13.0/quantities/units/heat.py000066400000000000000000000007241417003363700221320ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .temperature import K, degF from .length import m, ft from .power import W from .energy import BTU from .time import h RSI = UnitQuantity( 'RSI', K*m**2/W, doc='R-value in SI' ) clo = clos = UnitQuantity( 'clo', 0.155*RSI, aliases=['clos'] ) R_value = UnitQuantity( 'R_value', ft**2*degF*h/BTU, doc='American customary units' ) del UnitQuantity, K, degF, m, ft, W, BTU, h python-quantities-0.13.0/quantities/units/information.py000066400000000000000000000053301417003363700235340ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity, UnitInformation, dimensionless from .time import s bit = UnitInformation( 'bit', aliases=['bits'] ) B = byte = o = octet = UnitInformation( 'byte', 8*bit, symbol='B', aliases=['bytes', 'o', 'octet', 'octets'] ) kB = kilobyte = ko = UnitInformation( 'kilobyte', 1000 * byte, symbol='kB', aliases=['kilobytes', 'kilooctet', 'kilooctets'] ) MB = megabyte = Mo = UnitInformation( 'megabyte', 1000 * kilobyte, symbol='MB', aliases=['megabytes', 'megaoctet', 'megaoctets'] ) GB = gigabyte = Go = UnitInformation( 'gigabyte', 1000 * megabyte, symbol='GB', aliases=['gigabytes', 'gigaoctet', 'gigaoctets'] ) TB = terabyte = To = UnitInformation( 'terabyte', 1000 * gigabyte, symbol='TB', aliases=['terabytes', 'teraoctet', 'teraoctets'] ) PB = petabyte = Po = UnitInformation( 'petabyte', 1000 * terabyte, symbol='PB', aliases=['petabytes', 'petaoctet', 'petaoctets'] ) EB = exabyte = Eo = UnitInformation( 'exabyte', 1000 * petabyte, symbol='EB', aliases=['exabytes', 'exaoctet', 'exaoctets'] ) ZB = zettabyte = Zo = UnitInformation( 'zettabyte', 1000 * exabyte, symbol='ZB', aliases=['zettabytes', 'zettaoctet', 'zettaoctets'] ) YB = yottabyte = Yo = UnitInformation( 'yottabyte', 1000 * zettabyte, symbol='YB', aliases=['yottabytes', 'yottaoctet', 'yottaoctets'] ) Bd = baud = bps = UnitQuantity( 'baud', bit/s, symbol='Bd', ) # IEC KiB = kibibyte = Kio = UnitInformation( 'kibibyte', 1024 * byte, symbol='KiB', aliases=['kibibytes', 'kibioctet', 'kibioctets'] ) MiB = mebibyte = Mio = UnitInformation( 'mebibyte', 1024 * kibibyte, symbol='MiB', aliases=['mebibytes', 'mebioctet', 'mebioctets'] ) GiB = gibibyte = Gio = UnitInformation( 'gibibyte', 1024 * mebibyte, symbol='GiB', aliases=['gibibytes', 'gibioctet', 'gibioctets'] ) TiB = tebibyte = Tio = UnitInformation( 'tebibyte', 1024 * gibibyte, symbol='TiB', aliases=['tebibytes', 'tebioctet', 'tebioctets'] ) PiB = pebibyte = Pio = UnitInformation( 'pebibyte', 1024 * tebibyte, symbol='PiB', aliases=['pebibytes', 'pebioctet', 'pebioctets'] ) EiB = exbibyte = Eio = UnitInformation( 'exbibyte', 1024 * pebibyte, symbol='EiB', aliases=['exbibytes', 'exbioctet', 'exbioctets'] ) ZiB = zebibyte = Zio = UnitInformation( 'zebibyte', 1024 * exbibyte, symbol='ZiB', aliases=['zebibytes', 'zebioctet', 'zebioctets'] ) YiB = yobibyte = Yio = UnitInformation( 'yobibyte', 1024 * zebibyte, symbol='YiB', aliases=['yobibytes', 'yobioctet', 'yobioctets'] ) del UnitQuantity, s, dimensionless python-quantities-0.13.0/quantities/units/length.py000066400000000000000000000102431417003363700224670ustar00rootroot00000000000000""" """ from ..unitquantity import UnitLength, UnitQuantity m = meter = metre = UnitLength( 'meter', symbol='m', aliases=['meters', 'metre', 'metres'] ) km = kilometer = kilometre = UnitLength( 'kilometer', 1000*m, symbol='km', aliases=['kilometers', 'kilometre', 'kilometres'] ) cm = centimeter = centimetre = UnitLength( 'centimeter', m/100, 'cm', aliases=['centimeters', 'centimetre', 'centimetres'] ) mm = millimeter = millimetre = UnitLength( 'millimeter', m/1000, symbol='mm', aliases=['millimeters', 'millimetre', 'millimetres'] ) um = micrometer = micrometre = micron = UnitLength( 'micrometer', mm/1000, symbol='um', u_symbol='µm', aliases=[ 'micron', 'microns', 'micrometers', 'micrometre', 'micrometres' ] ) nm = nanometer = nanometre = UnitLength( 'nanometer', um/1000, symbol='nm', aliases=['nanometers', 'nanometre', 'nanometres'] ) pm = picometer = picometre = UnitLength( 'picometer', nm/1000, symbol='pm', aliases=['picometers', 'picometre', 'picometres'] ) angstrom = UnitLength( 'angstrom', nm/10, u_symbol='Å', aliases=['angstroms'] ) fm = femtometer = femtometre = fermi = UnitLength( 'femtometer', pm/1000, symbol='fm', aliases=['femtometers', 'femtometre', 'femtometres', 'fermi', 'fermis'] ) inch = international_inch = UnitLength( 'inch', 2.54*cm, symbol='in', aliases=['inches', 'international_inch', 'international_inches'] ) ft = foot = international_foot = UnitLength( 'foot', 12*inch, symbol='ft', aliases=['feet', 'international_foot' 'international_feet'] ) mi = mile = international_mile = UnitLength( 'mile', 5280*ft, symbol='mi', aliases=['miles', 'international_mile', 'international_miles'] ) yd = yard = international_yard = UnitLength( 'yard', 3*ft, symbol='yd', aliases=['yards', 'international_yard', 'international_yards'] ) mil = thou = UnitLength( 'mil', inch/1000, aliases=['mils', 'thou', 'thous'] ) pc = parsec = UnitLength( 'parsec', 3.08568025e16*m, symbol='pc', aliases=['parsecs'], doc='approximate' ) ly = light_year = UnitLength( 'light_year', 9460730472580.8*km, symbol='ly', aliases=['light_years'] ) au = astronomical_unit = UnitLength( 'astronomical_unit', 149597870691*m, symbol='au', aliases=['astronomical_units'], doc=''' An astronomical unit (abbreviated as AU, au, a.u., or sometimes ua) is a unit of length roughly equal to the mean distance between the Earth and the Sun. It is approximately 150 million kilometres (93 million miles). uncertainty ± 30 m http://en.wikipedia.org/wiki/Astronomical_unit ''' ) nmi = nautical_mile = UnitLength( 'nautical_mile', 1.852e3*m, symbol='nmi', aliases=['nmile', 'nmiles', 'nautical_miles'] ) pt = printers_point = point = UnitLength( 'printers_point', 127*mm/360, symbol='point', aliases=['printers_points', 'points'], doc='pt is reserved for pint' ) pica = UnitLength( 'pica', 12*printers_point, aliases=['picas', 'printers_pica', 'printers_picas'] ) US_survey_foot = UnitLength( 'US_survey_foot', 1200*m/3937, aliases=['US_survey_feet'] ) US_survey_yard = UnitLength( 'US_survey_yard', 3*US_survey_foot, aliases=['US_survey_yards'] ) US_survey_mile = US_statute_mile = UnitLength( 'US_survey_mile', 5280*US_survey_foot, aliases=['US_survey_miles', 'US_statute_mile', 'US_statute_miles'] ) rod = pole = perch = UnitLength( 'rod', 16.5*US_survey_foot, aliases=['rods', 'pole', 'poles', 'perch', 'perches'] ) furlong = UnitLength( 'furlong', 660*US_survey_foot, aliases=['furlongs'] ) fathom = UnitLength( 'fathom', 6*US_survey_foot, aliases=['fathoms'] ) chain = UnitLength( 'chain', 66*US_survey_foot, aliases=['chains'] ) barleycorn = UnitLength( 'barleycorn', inch/3, aliases=['barleycorns'] ) arpentlin = UnitLength( 'arpentlin', 191.835*ft ) kayser = wavenumber = UnitQuantity( 'kayser', 1/cm, aliases=['kaysers', 'wavenumber', 'wavenumbers'] ) del UnitQuantity python-quantities-0.13.0/quantities/units/mass.py000066400000000000000000000064301417003363700221540ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity, UnitMass from .length import m kg = kilogram = UnitMass( 'kilogram', symbol='kg', aliases=['kilograms'] ) g = gram = UnitMass( 'gram', kg/1000, symbol='g', aliases=['grams'] ) mg = milligram = UnitMass( 'milligram', gram/1000, symbol='mg', aliases=['milligrams'] ) oz = ounce = avoirdupois_ounce = UnitMass( 'ounce', 28.349523125*g, symbol='oz', aliases=['ounces','avoirdupois_ounce', 'avoirdupois_ounces'], doc='exact' ) lb = pound = avoirdupois_pound = UnitMass( 'pound', 0.45359237*kg, symbol='lb', aliases=['pounds', 'avoirdupois_pound', 'avoirdupois_pounds'], doc='exact' ) st = stone = UnitMass( 'stone', 14*lb, symbol='st', doc='As defined in the UK, 1 stone = 14 avoirdupois pounds' ) carat = UnitMass( 'carat', 200*mg, aliases=['carats'] ) gr = grain = UnitMass( 'grain', 64.79891*mg, symbol='gr', aliases=['grains'] ) long_hundredweight = UnitMass( 'long_hundredweight', 112*lb, aliases=['long_hundredweights'] ) short_hundredweight = UnitMass( 'short_hundredweight', 100*lb, aliases=['short_hundredweights'] ) # cwt is used for both short and long hundredweight, so we wont use it t = metric_ton = tonne = UnitMass( 'tonne', 1000*kg, symbol='t', aliases=['tonnes'] ) dwt = pennyweight = UnitMass( 'pennyweight', 24*gr, symbol='dwt', aliases=['pennyweights'] ) slug = slugs = UnitMass( 'slug', 14.59390*kg, aliases=['slugs'] ) toz = troy_ounce = apounce = apothecary_ounce = UnitMass( 'troy_ounce', 480*gr, symbol='toz', u_symbol='℥', aliases=[ 'apounce', 'apounces', 'apothecary_ounce', 'apothecary_ounces', 'troy_ounces' ] ) troy_pound = appound = apothecary_pound = UnitMass( 'troy_pound', 12*toz, symbol='tlb', u_symbol='℔', aliases=[ 'troy_pounds', 'appound', 'appounds', 'apothecary_pound', 'apothecary_pounds' ] ) u = amu = atomic_mass_unit = dalton = Da = UnitMass( 'atomic_mass_unit', 1.660538782e-27*kg, symbol='u', aliases=['amu', 'Da', 'dalton'], doc='relative uncertainty = 5e-8' ) scruple = UnitMass( 'scruple', 20*gr, u_symbol='℈', aliases=['scruples'] ) dr = dram = UnitMass( 'dram', oz/16, symbol='dr', aliases=['drams'], doc='avoirdupois dram' ) drachm = apdram = UnitMass( 'drachm', 60*gr, u_symbol=' ', aliases=['drachms', 'apdram', 'apdrams'], doc='also known as the apothecary dram' ) bag = UnitMass( 'bag', 94*lb, aliases=['bags'] ) ton = short_ton = UnitMass( 'short_ton', 2000*lb, aliases=['short_tons'] ) long_ton = UnitMass( 'long_ton', 2240*lb, aliases=['long_tons'] ) # both long and short tons are referred to as "ton" so we wont use it ############################################################ ## Mass per unit length ## ############################################################ denier = UnitQuantity( 'denier', g/(9000*m), aliases=['deniers'] ) tex = UnitQuantity( 'tex', g/(1000*m), aliases=['texs'] ) dtex = UnitQuantity( 'dtex', g/(10000*m), aliases=['dtexs'] ) del UnitQuantity, m python-quantities-0.13.0/quantities/units/power.py000066400000000000000000000024641417003363700223500ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .energy import Btu, J from .time import s, h, min from .electromagnetism import A, V from .length import ft from .force import lbf W = watt = volt_ampere = UnitQuantity( 'watt', J/s, symbol='W', aliases=['watts', 'volt_ampere', 'volt_amperes', 'VA'] ) mW = milliwatt = UnitQuantity( 'milliwatt', W/1000, symbol='mW', aliases=['milliwatts'] ) kW = kilowatt = UnitQuantity( 'kilowatt', 1000*W, symbol='kW', aliases=['kilowatts'] ) MW = megawatt = UnitQuantity( 'megawatt', 1000*kW, symbol='MW', aliases=['megawatts'] ) hp = horsepower = UK_horsepower = British_horsepower = UnitQuantity( 'horsepower', 33000*ft*lbf/min, symbol='hp', aliases=['UK_horsepower', 'British_horsepower'] ) boiler_horsepower = UnitQuantity( 'boiler_horsepower', 33475*Btu/h ) metric_horsepower = UnitQuantity( 'metric_horsepower', 0.73549875*kW, doc='exact' ) electric_horsepower = UnitQuantity( 'electric_horsepower', 746*W ) water_horsepower = UnitQuantity( 'water_horsepower', 746.043*W, doc='exact' ) refrigeration_ton = ton_of_refrigeration = UnitQuantity( 'refrigeration_ton', 12000*Btu/h, aliases=['ton_of_refrigeration'] ) del UnitQuantity, Btu, J, s, h, A, V python-quantities-0.13.0/quantities/units/prefixes.py000066400000000000000000000005611417003363700230350ustar00rootroot00000000000000#SI prefixes yotta = 1e24 zetta = 1e21 exa = 1e18 peta = 1e15 tera = 1e12 giga = 1e9 mega = 1e6 kilo = 1e3 hecto = 1e2 deka = 1e1 deci = 1e-1 centi = 1e-2 milli = 1e-3 micro = 1e-6 nano = 1e-9 pico = 1e-12 femto = 1e-15 atto = 1e-18 zepto = 1e-21 #binary prefixes kibi = 2**10 mebi = 2**20 gibi = 2**30 tebi = 2**40 pebi = 2**50 exbi = 2**60 zebi = 2**70 yobi = 2**80 python-quantities-0.13.0/quantities/units/pressure.py000066400000000000000000000070411417003363700230600ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .acceleration import gravity from .mass import g, kg, pound from .length import m, mm, cm, inch, ft from .force import N, kip Hg = mercury = conventional_mercury = UnitQuantity( 'conventional_mercury', gravity*13.59510*g/cm**3 ) mercury_60F = UnitQuantity('mercury_60F', gravity*13556.8*kg/m**3) H2O = h2o = water = conventional_water = UnitQuantity('H2O', gravity*1000*kg/m**3) water_4C = water_39F = UnitQuantity('water_4C', gravity*999.972*kg/m**3) water_60F = UnitQuantity('water_60F', gravity*999.001*kg/m**3) Pa = pascal = UnitQuantity( 'pascal', N/m**2, symbol='Pa', aliases=['pascals'] ) hPa = hectopascal = UnitQuantity( 'hectopascal', 100*Pa, symbol='hPa', ) kPa = kilopascal = UnitQuantity( 'kilopascal', 1000*Pa, symbol='kPa', aliases=['kilopascals'] ) MPa = megapascal = UnitQuantity( 'megapascal', 1000*kPa, symbol='MPa', aliases=['megapascals'] ) GPa = gigapascal = UnitQuantity( 'gigapascal', 1000*MPa, symbol='GPa', aliases=['gigapascals'] ) bar = UnitQuantity( 'bar', 100000*pascal, aliases=['bars'] ) mb = mbar = millibar = UnitQuantity( 'millibar', 0.001*bar, symbol='mb', aliases=['mbar'] ) kbar = kilobar = UnitQuantity( 'kilobar', 1000*bar, symbol='kbar', aliases=['kilobars'] ) Mbar = megabar = UnitQuantity( 'megabar', 1000*kbar, symbol='Mbar', aliases=['megabars'] ) Gbar = gigabar = UnitQuantity( 'gigabar', 1000*Mbar, symbol='Gbar', aliases=['gigabars'] ) atm = atmosphere = standard_atmosphere = UnitQuantity( 'standard_atmosphere', 101325*pascal, symbol='atm', aliases=['atmosphere', 'atmospheres', 'standard_atmospheres'] ) at = technical_atmosphere = UnitQuantity( 'technical_atmosphere', kg*gravity/cm**2, symbol='at', aliases=['technical_atmospheres'] ) torr = UnitQuantity( 'torr', atm/760 ) psi = pound_force_per_square_inch = UnitQuantity( 'pound_force_per_square_inch', pound*gravity/inch**2, symbol='psi' ) ksi = kip_per_square_inch = UnitQuantity( 'kip_per_square_inch', kip/inch**2, symbol='ksi' ) barye = barie = barad = barad = barrie = baryd = UnitQuantity( 'barye', 0.1*N/m**2, symbol='Ba', aliases=[ 'barie', 'baries', 'baryes', 'barad', 'barads', 'barrie', 'baryd', 'baryed' ] ) mmHg = mm_Hg = millimeter_Hg = millimeter_Hg_0C = UnitQuantity( 'millimeter_Hg', mm*mercury, symbol='mmHg', aliases=['mm_Hg', 'millimeter_Hg_0C'], doc=""" The pressure exerted at the base of a column of fluid exactly 1 mm high, when the density of the fluid is exactly 13.5951 g/cm^3, at a place where the acceleration of gravity is exactly 9.80665 m/s^2. http://en.wikipedia.org/wiki/Conventional_millimeter_of_mercury """ ) cmHg = cm_Hg = centimeter_Hg = UnitQuantity( 'cmHg', cm*Hg, aliases=['cm_Hg', 'centimeter_Hg'] ) inHg = in_Hg = inch_Hg = inch_Hg_32F = UnitQuantity( 'inHg', inch*Hg, aliases=['in_Hg', 'inch_Hg', 'inch_Hg_32F'] ) inch_Hg_60F = UnitQuantity( 'inch_Hg_60F', inch*mercury_60F ) inch_H2O_39F = UnitQuantity( 'inch_H2O_39F', inch*water_39F ) inch_H2O_60F = UnitQuantity( 'inch_H2O_60F', inch*water_60F ) footH2O = UnitQuantity( 'footH2O', ft*water ) cmH2O = UnitQuantity( 'cmH2O', cm*water ) foot_H2O = ftH2O = UnitQuantity( 'foot_H2O', ft*water, aliases=['ftH2O'] ) del UnitQuantity, gravity, kg, pound, m, mm, cm, inch, ft, N, kip python-quantities-0.13.0/quantities/units/radiation.py000066400000000000000000000020111417003363700231520ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .time import s from .mass import kg from .energy import J from .electromagnetism import coulomb Bq = becquerel = UnitQuantity( 'becquerel', 1/s, symbol='Bq', aliases=['becquerels'] ) Ci = curie = UnitQuantity( 'curie', 3.7e10*becquerel, symbol='Ci', aliases=['curies'] ) rd = rutherford = UnitQuantity( 'rutherford', 1e6*Bq, symbol='Rd', aliases=['rutherfords'], doc='this unit is obsolete, in favor of 1e6 Bq' ) Gy = gray = Sv = sievert = UnitQuantity( 'gray', J/kg, symbol='Gy', aliases=['grays', 'Sv', 'sievert', 'sieverts'] ) rem = UnitQuantity( 'rem', 1e-2*sievert, aliases=['rems'] ) rads = UnitQuantity( 'rads', 1e-2*gray, doc=''' rad is commonly used symbol for radian. rads unit of radiation is deprecated. ''' ) R = roentgen = UnitQuantity( 'roentgen', 2.58e-4*coulomb/kg, symbol='R', aliases=['roentgens'] ) del UnitQuantity, s, kg, J, coulomb python-quantities-0.13.0/quantities/units/substance.py000066400000000000000000000004271417003363700232000ustar00rootroot00000000000000""" """ from ..unitquantity import UnitSubstance mol = mole = UnitSubstance( 'mole', symbol='mol' ) mmol = UnitSubstance( 'millimole', mol/1000, symbol='mmol' ) umol = UnitSubstance( 'micromole', mmol/1000, symbol='umol', u_symbol='µmol' ) python-quantities-0.13.0/quantities/units/temperature.py000066400000000000000000000031371417003363700235470ustar00rootroot00000000000000""" """ from ..unitquantity import UnitTemperature K = degK = kelvin = Kelvin = UnitTemperature( 'Kelvin', symbol='K', aliases=['degK', 'kelvin'] ) for prefix, symbolprefix, magnitude in ( ('yotta', 'Y', 1e24), ('zetta', 'Z', 1e21), ('exa', 'E', 1e18), ('peta', 'P', 1e15), ('tera', 'T', 1e12), ('giga', 'G', 1e9), ('mega', 'M', 1e6), ('kilo', 'k', 1e3), ('hecto', 'h', 1e2), ('deka', 'da', 1e1), ('deci', 'd', 1e-1), ('centi', 'c', 1e-2), ('milli', 'm', 1e-3), ('micro', 'u', 1e-6), ('nano', 'n', 1e-9), ('pico', 'p', 1e-12), ('femto', 'f', 1e-15), ('atto', 'a', 1e-18), ('zepto', 'z', 1e-21), ('yocto', 'y', 1e-24), ): symbol = symbolprefix +'K' globals()[symbol] = UnitTemperature( prefix + 'kelvin', K*magnitude, symbol=symbol ) degR = rankine = Rankine = UnitTemperature( 'Rankine', K/1.8, symbol='degR', u_symbol='°R', aliases=['rankine'] ) degC = celsius = Celsius = UnitTemperature( 'Celsius', K, symbol='degC', u_symbol='°C', aliases=['celsius'], doc=''' Unicode has special compatibility characters for ℃, but its use is discouraged by the unicode consortium. ''' ) degF = fahrenheit = Fahrenheit = UnitTemperature( 'Fahrenheit', degR, symbol='degF', u_symbol='°F', aliases=['fahrenheit'], doc=''' Unicode has special compatibility characters for ℉, but its use is discouraged by the unicode consortium. ''' ) python-quantities-0.13.0/quantities/units/time.py000066400000000000000000000071521417003363700221510ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity, UnitTime s = sec = second = UnitTime( 'second', symbol='s', aliases=['sec', 'seconds'] ) ks = kilosecond = UnitTime( 'kilosecond', s*1000, 'ks', aliases=['kiloseconds'] ) Ms = megasecond = UnitTime( 'megasecond', ks*1000, 'Ms', aliases=['megaseconds'] ) ms = millisecond = UnitTime( 'millisecond', s/1000, 'ms', aliases=['milliseconds'] ) us = microsecond = UnitTime( 'microsecond', ms/1000, symbol='us', u_symbol='µs', aliases=['microseconds'] ) ns = nanosecond = UnitTime( 'nanosecond', us/1000, symbol='ns', aliases=['nanoseconds'] ) ps = picosecond = UnitTime( 'picosecond', ns/1000, symbol='ps', aliases=['picoseconds'] ) fs = femtosecond = UnitTime( 'femtosecond', ps/1000, symbol='fs', aliases=['femtoseconds'] ) attosecond = UnitTime( 'attosecond', fs/1000, symbol='as', aliases=['attoseconds'] ) # as is a keyword in python2.6 min = minute = UnitTime( 'minute', 60*s, symbol='min', aliases=['minutes'] ) h = hr = hour = UnitTime( 'hour', 60*min, symbol='h', aliases=['hr', 'hours'] ) d = day = UnitTime( 'day', 24*hr, symbol='d', aliases=['days'] ) week = UnitTime( 'week', 7*day, aliases=['weeks'] ) fortnight = UnitTime( 'fortnight', 2*week, aliases=['fortnights'] ) yr = year = tropical_year = a = UnitTime( 'year', 31556925.9747*s, symbol='yr', aliases=['a', 'years', 'tropical_year', 'tropical_years'], doc='a is an acceptable alias for year, short for anno' ) month = UnitTime( 'month', yr/12, aliases=['months'] ) shake = UnitTime( 'shake', 1e-8*s, aliases=['shakes'] ) sidereal_day = UnitTime( 'sidereal_day', day/1.00273790935079524, aliases=['sidereal_days'], doc=''' approximate. http://en.wikipedia.org/wiki/Sidereal_time ''' ) sidereal_hour = UnitTime( 'sidereal_hour', sidereal_day/24, aliases=['sidereal_hours'] ) sidereal_minute = UnitTime( 'sidereal_minute', sidereal_hour/60, aliases=['sidereal_minutes'] ) sidereal_second = UnitTime( 'sidereal_second', sidereal_minute/60, aliases=['sidereal_seconds'] ) sidereal_year = UnitTime( 'sidereal_year', 366.25636042*sidereal_day, aliases=['sidereal_years'], doc='http://en.wikipedia.org/wiki/Sidereal_year' ) sidereal_month = UnitTime( 'sidereal_month', 27.321661*day, aliases=['sidereal_months'], doc='http://en.wikipedia.org/wiki/Month#Sidereal_month' ) tropical_month = UnitTime( 'tropical_month', 27.321582*day, aliases=['tropical_months'] ) synodic_month = lunar_month = UnitTime( 'synodic_month', 29.530589*day, aliases=['synodic_months', 'lunar_month', 'lunar_months'], doc=''' long-term average. http://en.wikipedia.org/wiki/Month#Synodic_month ''' ) common_year = UnitTime( 'common_year', 365*day, aliases=['common_years'] ) leap_year = UnitTime( 'leap_year', 366*day, aliases=['leap_years'] ) Julian_year = UnitTime( 'Julian_year', 365.25*day, aliases=['Julian_years'] ) Gregorian_year = UnitTime( 'Gregorian_year', 365.2425*day, aliases=['Gregorian_years'] ) millenium = UnitTime( 'millenium', 1000*year, aliases=['millenia'] ) eon = UnitTime( 'eon', 1e9*year, aliases=['eons'] ) work_year = UnitQuantity( 'work_year', 2056*hour, aliases=['work_years'] ) work_month = UnitQuantity( 'work_month', work_year/12, aliases=['work_months'] ) del UnitQuantity python-quantities-0.13.0/quantities/units/velocity.py000066400000000000000000000006761417003363700230550ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .length import m, nmi from .time import s, h c = speed_of_light = UnitQuantity( 'speed_of_light', 299792458*m/s, symbol='c', doc='exact' ) kt = knot = knot_international = international_knot = UnitQuantity( 'nautical_miles_per_hour', nmi/h, symbol='kt', aliases=['knot', 'knots', 'knot_international', 'international_knot'] ) del UnitQuantity, m, nmi, s, h python-quantities-0.13.0/quantities/units/viscosity.py000066400000000000000000000006441417003363700232460ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .time import s from .length import m from .pressure import Pa P = poise = UnitQuantity( 'poise', 1e-1*Pa*s, symbol='P' ) cP = centipoise = UnitQuantity( 'centipoise', P/100, symbol='cP' ) St = stokes = UnitQuantity( 'stokes', 1e-4*m**2/s, symbol='St' ) rhe = UnitQuantity( 'rhe', 10/(Pa*s) ) del UnitQuantity, s, m, Pa python-quantities-0.13.0/quantities/units/volume.py000066400000000000000000000111641417003363700225200ustar00rootroot00000000000000""" """ from ..unitquantity import UnitQuantity from .length import cm, m, foot, inch from .area import acre l = L = liter = litre = UnitQuantity( 'liter', 1e-3*m**3, symbol='L', aliases=['l', 'liters', 'litre', 'litres'] ) mL = milliliter = millilitre = UnitQuantity( 'milliliter', liter/1000, symbol='mL', aliases=['ml', 'milliliters', 'millilitre', 'millilitres'] ) kL = kiloliter = kilolitre = UnitQuantity( 'kiloliter', liter*1000, symbol='kL', aliases=['kl', 'kiloliters', 'kilolitre', 'kilolitres'] ) ML = megaliter = megalitre = UnitQuantity( 'megaliter', kiloliter*1000, symbol='ML', aliases=['Ml', 'megaliters', 'megalitre', 'megalitres'] ) GL = gigaliter = gigalitre = UnitQuantity( 'gigaliter', megaliter*1000, symbol='GL', aliases=['Gl', 'gigaliters', 'gigalitre', 'gigalitres'] ) cc = cubic_centimeter = milliliter = UnitQuantity( 'cubic_centimeter', cm**3, symbol='cc', aliases=['cubic_centimeters'] ) stere = UnitQuantity( 'stere', m**3, aliases=['steres'] ) gross_register_ton = register_ton = UnitQuantity( 'gross_register_ton', 100*foot**3, symbol='GRT', aliases=['gross_register_tons', 'register_ton', 'register_tons'] ) acre_foot = UnitQuantity( 'acre_foot', acre*foot, aliases=['acre_feet'] ) board_foot = UnitQuantity( 'board_foot', foot**2*inch, symbol='FBM', aliases=['board_feet']) bu = bushel = US_bushel = UnitQuantity( 'US_bushel', 2150.42*inch**3, symbol='bu' ) US_dry_gallon = UnitQuantity( 'US_dry_gallon', bushel/8, ) gallon = liquid_gallon = US_liquid_gallon = UnitQuantity( 'US_liquid_gallon', 231*inch**3, aliases=[ 'gallon', 'gallons', 'liquid_gallon', 'liquid_gallons', 'US_liquid_gallons' ], ) dry_quart = US_dry_quart = UnitQuantity( 'US_dry_quart', US_dry_gallon/4, aliases=['dry_quart', 'dry_quarts', 'US_dry_quarts'] ) dry_pint = US_dry_pint = UnitQuantity( 'US_dry_pint', US_dry_quart/2, aliases=['dry_pint', 'dry_pints', 'US_dry_pints'] ) quart = liquid_quart = US_liquid_quart = UnitQuantity( 'US_liquid_quart', US_liquid_gallon/4, symbol='quart', aliases=['quarts', 'liquid_quart', 'liquid_quarts', 'US_liquid_quarts'] ) pt = pint = liquid_pint = US_liquid_pint = UnitQuantity( 'US_liquid_pint', US_liquid_quart/2, symbol='pt', aliases=[ 'pint', 'pints', 'liquid_pint', 'liquid_pints', 'US_liquid_pints' ], ) cup = US_liquid_cup = UnitQuantity( 'cup', US_liquid_pint/2, aliases=['cups', 'US_liquid_cup', 'US_liquid_cups'] ) gill = US_liquid_gill = UnitQuantity( 'US_liquid_gill', US_liquid_cup/2, symbol='gill', aliases=['gills', 'US_liquid_gills'] ) floz = fluid_ounce = US_fluid_ounce = US_liquid_ounce = UnitQuantity( 'US_fluid_ounce', US_liquid_gill/4, symbol='fl_oz', aliases=[ 'fluid_ounce', 'fluid_ounces', 'US_fluid_ounces', 'US_liquid_ounce', 'US_liquid_ounces' ] ) Imperial_bushel = UnitQuantity( 'Imperial_bushel', 36.36872*liter, doc='exact' ) UK_liquid_gallon = Canadian_liquid_gallon = UnitQuantity( 'UK_liquid_gallon', 4.54609*liter, aliases=[ 'UK_liquid_gallons', 'Canadian_liquid_gallon', 'Canadian_liquid_gallons' ], doc='exact' ) UK_liquid_quart = UnitQuantity( 'UK_liquid_quart', UK_liquid_gallon/4, aliases=['UK_liquid_quarts'] ) UK_liquid_pint = UnitQuantity( 'UK_liquid_pint', UK_liquid_quart/2, aliases=['UK_liquid_pints'] ) UK_liquid_cup = UnitQuantity( 'UK_liquid_cup', UK_liquid_pint/2, aliases=['UK_liquid_cups'] ) UK_liquid_gill = UnitQuantity( 'UK_liquid_gill', UK_liquid_cup/2, aliases=['UK_liquid_gills'] ) UK_fluid_ounce = UK_liquid_ounce = UnitQuantity( 'UK_fluid_ounce', UK_liquid_gill/5, # not a mistake aliases=['UK_fluid_ounces', 'UK_liquid_ounce', 'UK_liquid_ounces'] ) bbl = barrel = UnitQuantity( 'barrel', 42*US_liquid_gallon, symbol='bbl' ) tbsp = Tbsp = Tblsp = tblsp = tbs = Tbl = tablespoon = UnitQuantity( 'tablespoon', US_fluid_ounce/2, symbol='tbsp', aliases=['Tbsp', 'Tblsp', 'Tbl', 'tblsp', 'tbs', 'tablespoons'] ) tsp = teaspoon = UnitQuantity( 'teaspoon', tablespoon/3, symbol='tsp', aliases=['teaspoons'] ) pk = peck = UnitQuantity( 'peck', bushel/4, symbol='pk', aliases=['pecks'] ) fldr = fluid_dram = fluidram = UnitQuantity( 'fluid_dram', floz/8, symbol='fldr', aliases=['fluid_drams', 'fluidram', 'fluidrams'] ) firkin = UnitQuantity( 'firkin', barrel/4 ) del UnitQuantity, cm, m python-quantities-0.13.0/setup.cfg000066400000000000000000000002521417003363700171240ustar00rootroot00000000000000[versioneer] VCS = git style = pep440 versionfile_source = quantities/_version.py versionfile_build = quantities/_version.py tag_prefix = v parentdir_prefix = quantities-python-quantities-0.13.0/setup.py000077500000000000000000000105751417003363700170310ustar00rootroot00000000000000from distutils.cmd import Command from distutils.core import setup from distutils.command.build import build as _build import os import sys import versioneer TEST_RESULT = None cmdclass = versioneer.get_cmdclass() _sdist = cmdclass['sdist'] class data(Command): description = "Convert the NIST databas of constants" user_options = [] boolean_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): with open('quantities/constants/NIST_codata.txt') as f: data = f.read() data = data.split('\n')[10:-1] with open('quantities/constants/_codata.py', 'w') as f: f.write('# THIS FILE IS AUTOMATICALLY GENERATED\n') f.write('# ANY CHANGES MADE HERE WILL BE LOST\n\n') f.write('physical_constants = {}\n\n') for line in data: name = line[:55].rstrip().replace('mag.','magnetic') name = name.replace('mom.', 'moment') val = line[55:77].replace(' ','').replace('...','') prec = line[77:99].replace(' ','').replace('(exact)', '0') unit = line[99:].rstrip().replace(' ', '*').replace('^', '**') d = "{'value': %s, 'precision': %s, 'units': '%s'}" \ %(val, prec, unit) f.write("physical_constants['%s'] = %s\n"%(name, d)) cmdclass['data'] = data class sdist(_sdist): def run(self): self.run_command('data') _sdist.run(self) cmdclass['sdist'] = sdist class build(_build): def run(self): self.run_command('data') _build.run(self) cmdclass['build'] = build class test(Command): """Run the test suite.""" description = "Run the test suite" user_options = [('verbosity=', 'V', 'set test report verbosity')] def initialize_options(self): self.verbosity = 0 def finalize_options(self): try: self.verbosity = int(self.verbosity) except ValueError: raise ValueError('verbosity must be an integer.') def run(self): import sys import unittest suite = unittest.TestLoader().discover('.') global TEST_RESULT TEST_RESULT = unittest.TextTestRunner(verbosity=self.verbosity+1).run(suite) cmdclass['test'] = test packages = [] for dirpath, dirnames, filenames in os.walk('quantities'): if '__init__.py' in filenames: packages.append('.'.join(dirpath.split(os.sep))) else: del(dirnames[:]) setup( author = 'Darren Dale', author_email = 'dsdale24@gmail.com', # classifiers = """Development Status :: 4 - Beta # Environment :: Console # Intended Audience :: Developers # Intended Audience :: Education # Intended Audience :: End Users/Desktop # Intended Audience :: Science/Research # License :: OSI Approved :: BSD License # Operating System :: OS Independent # Programming Language :: Python # Topic :: Education # Topic :: Scientific/Engineering # """, cmdclass = cmdclass, description = "Support for physical quantities with units, based on numpy", download_url = "http://pypi.python.org/pypi/quantities", keywords = ['quantities', 'units', 'physical', 'constants'], license = 'BSD', long_description = """Quantities is designed to handle arithmetic and conversions of physical quantities, which have a magnitude, dimensionality specified by various units, and possibly an uncertainty. See the tutorial_ for examples. Quantities builds on the popular numpy library and is designed to work with numpy ufuncs, many of which are already supported. Quantities is actively developed, and while the current features and API are stable, test coverage is incomplete so the package is not suggested for mission-critical applications. .. _tutorial: http://python-quantities.readthedocs.io/en/latest/user/tutorial.html """, name = 'quantities', packages = packages, platforms = 'Any', requires = [ 'python (>=3.7)', 'numpy (>=1.16)', ], url = 'http://python-quantities.readthedocs.io/', version = versioneer.get_version(), ) if __name__ == '__main__': if TEST_RESULT is not None: if len(TEST_RESULT.errors) > 0: # failing test -> Set non-success exit-code sys.exit(os.EX_OK+1) python-quantities-0.13.0/versioneer.py000066400000000000000000002342541417003363700200510ustar00rootroot00000000000000 # Version: 0.21 """The Versioneer - like a rocketeer, but for versions. The Versioneer ============== * like a rocketeer, but for versions! * https://github.com/python-versioneer/python-versioneer * Brian Warner * License: Public Domain * Compatible with: Python 3.6, 3.7, 3.8, 3.9 and pypy3 * [![Latest Version][pypi-image]][pypi-url] * [![Build Status][travis-image]][travis-url] This is a tool for managing a recorded version number in distutils-based python projects. The goal is to remove the tedious and error-prone "update the embedded version string" step from your release process. Making a new release should be as easy as recording a new tag in your version-control system, and maybe making new tarballs. ## Quick Install * `pip install versioneer` to somewhere in your $PATH * add a `[versioneer]` section to your setup.cfg (see [Install](INSTALL.md)) * run `versioneer install` in your source tree, commit the results * Verify version information with `python setup.py version` ## Version Identifiers Source trees come from a variety of places: * a version-control system checkout (mostly used by developers) * a nightly tarball, produced by build automation * a snapshot tarball, produced by a web-based VCS browser, like github's "tarball from tag" feature * a release tarball, produced by "setup.py sdist", distributed through PyPI Within each source tree, the version identifier (either a string or a number, this tool is format-agnostic) can come from a variety of places: * ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows about recent "tags" and an absolute revision-id * the name of the directory into which the tarball was unpacked * an expanded VCS keyword ($Id$, etc) * a `_version.py` created by some earlier build step For released software, the version identifier is closely related to a VCS tag. Some projects use tag names that include more than just the version string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool needs to strip the tag prefix to extract the version identifier. For unreleased software (between tags), the version identifier should provide enough information to help developers recreate the same tree, while also giving them an idea of roughly how old the tree is (after version 1.2, before version 1.3). Many VCS systems can report a description that captures this, for example `git describe --tags --dirty --always` reports things like "0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the 0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has uncommitted changes). The version identifier is used for multiple purposes: * to allow the module to self-identify its version: `myproject.__version__` * to choose a name and prefix for a 'setup.py sdist' tarball ## Theory of Operation Versioneer works by adding a special `_version.py` file into your source tree, where your `__init__.py` can import it. This `_version.py` knows how to dynamically ask the VCS tool for version information at import time. `_version.py` also contains `$Revision$` markers, and the installation process marks `_version.py` to have this marker rewritten with a tag name during the `git archive` command. As a result, generated tarballs will contain enough information to get the proper version. To allow `setup.py` to compute a version too, a `versioneer.py` is added to the top level of your source tree, next to `setup.py` and the `setup.cfg` that configures it. This overrides several distutils/setuptools commands to compute the version when invoked, and changes `setup.py build` and `setup.py sdist` to replace `_version.py` with a small static file that contains just the generated version data. ## Installation See [INSTALL.md](./INSTALL.md) for detailed installation instructions. ## Version-String Flavors Code which uses Versioneer can learn about its version string at runtime by importing `_version` from your main `__init__.py` file and running the `get_versions()` function. From the "outside" (e.g. in `setup.py`), you can import the top-level `versioneer.py` and run `get_versions()`. Both functions return a dictionary with different flavors of version information: * `['version']`: A condensed version string, rendered using the selected style. This is the most commonly used value for the project's version string. The default "pep440" style yields strings like `0.11`, `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section below for alternative styles. * `['full-revisionid']`: detailed revision identifier. For Git, this is the full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". * `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the commit date in ISO 8601 format. This will be None if the date is not available. * `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that this is only accurate if run in a VCS checkout, otherwise it is likely to be False or None * `['error']`: if the version string could not be computed, this will be set to a string describing the problem, otherwise it will be None. It may be useful to throw an exception in setup.py if this is set, to avoid e.g. creating tarballs with a version string of "unknown". Some variants are more useful than others. Including `full-revisionid` in a bug report should allow developers to reconstruct the exact code being tested (or indicate the presence of local changes that should be shared with the developers). `version` is suitable for display in an "about" box or a CLI `--version` output: it can be easily compared against release notes and lists of bugs fixed in various releases. The installer adds the following text to your `__init__.py` to place a basic version in `YOURPROJECT.__version__`: from ._version import get_versions __version__ = get_versions()['version'] del get_versions ## Styles The setup.cfg `style=` configuration controls how the VCS information is rendered into a version string. The default style, "pep440", produces a PEP440-compliant string, equal to the un-prefixed tag name for actual releases, and containing an additional "local version" section with more detail for in-between builds. For Git, this is TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags --dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and that this commit is two revisions ("+2") beyond the "0.11" tag. For released software (exactly equal to a known tag), the identifier will only contain the stripped tag, e.g. "0.11". Other styles are available. See [details.md](details.md) in the Versioneer source tree for descriptions. ## Debugging Versioneer tries to avoid fatal errors: if something goes wrong, it will tend to return a version of "0+unknown". To investigate the problem, run `setup.py version`, which will run the version-lookup code in a verbose mode, and will display the full contents of `get_versions()` (including the `error` string, which may help identify what went wrong). ## Known Limitations Some situations are known to cause problems for Versioneer. This details the most significant ones. More can be found on Github [issues page](https://github.com/python-versioneer/python-versioneer/issues). ### Subprojects Versioneer has limited support for source trees in which `setup.py` is not in the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are two common reasons why `setup.py` might not be in the root: * Source trees which contain multiple subprojects, such as [Buildbot](https://github.com/buildbot/buildbot), which contains both "master" and "slave" subprojects, each with their own `setup.py`, `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI distributions (and upload multiple independently-installable tarballs). * Source trees whose main purpose is to contain a C library, but which also provide bindings to Python (and perhaps other languages) in subdirectories. Versioneer will look for `.git` in parent directories, and most operations should get the right version string. However `pip` and `setuptools` have bugs and implementation details which frequently cause `pip install .` from a subproject directory to fail to find a correct version string (so it usually defaults to `0+unknown`). `pip install --editable .` should work correctly. `setup.py install` might work too. Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in some later version. [Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking this issue. The discussion in [PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the issue from the Versioneer side in more detail. [pip PR#3176](https://github.com/pypa/pip/pull/3176) and [pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve pip to let Versioneer work correctly. Versioneer-0.16 and earlier only looked for a `.git` directory next to the `setup.cfg`, so subprojects were completely unsupported with those releases. ### Editable installs with setuptools <= 18.5 `setup.py develop` and `pip install --editable .` allow you to install a project into a virtualenv once, then continue editing the source code (and test) without re-installing after every change. "Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a convenient way to specify executable scripts that should be installed along with the python package. These both work as expected when using modern setuptools. When using setuptools-18.5 or earlier, however, certain operations will cause `pkg_resources.DistributionNotFound` errors when running the entrypoint script, which must be resolved by re-installing the package. This happens when the install happens with one version, then the egg_info data is regenerated while a different version is checked out. Many setup.py commands cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into a different virtualenv), so this can be surprising. [Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes this one, but upgrading to a newer version of setuptools should probably resolve it. ## Updating Versioneer To upgrade your project to a new release of Versioneer, do the following: * install the new Versioneer (`pip install -U versioneer` or equivalent) * edit `setup.cfg`, if necessary, to include any new configuration settings indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. * re-run `versioneer install` in your source tree, to replace `SRC/_version.py` * commit any changed files ## Future Directions This tool is designed to make it easily extended to other version-control systems: all VCS-specific components are in separate directories like src/git/ . The top-level `versioneer.py` script is assembled from these components by running make-versioneer.py . In the future, make-versioneer.py will take a VCS name as an argument, and will construct a version of `versioneer.py` that is specific to the given VCS. It might also take the configuration arguments that are currently provided manually during installation by editing setup.py . Alternatively, it might go the other direction and include code from all supported VCS systems, reducing the number of intermediate scripts. ## Similar projects * [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time dependency * [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of versioneer * [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools plugin ## License To make Versioneer easier to embed, all its code is dedicated to the public domain. The `_version.py` that it creates is also in the public domain. Specifically, both are released under the Creative Commons "Public Domain Dedication" license (CC0-1.0), as described in https://creativecommons.org/publicdomain/zero/1.0/ . [pypi-image]: https://img.shields.io/pypi/v/versioneer.svg [pypi-url]: https://pypi.python.org/pypi/versioneer/ [travis-image]: https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg [travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer """ # pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring # pylint:disable=missing-class-docstring,too-many-branches,too-many-statements # pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error # pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with # pylint:disable=attribute-defined-outside-init,too-many-arguments import configparser import errno import json import os import re import subprocess import sys from typing import Callable, Dict class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_root(): """Get the project root directory. We require that all commands are run from the project root, i.e. the directory that contains setup.py, setup.cfg, and versioneer.py . """ root = os.path.realpath(os.path.abspath(os.getcwd())) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): # allow 'python path/to/setup.py COMMAND' root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): err = ("Versioneer was unable to run the project root directory. " "Versioneer requires setup.py to be executed from " "its immediate directory (like 'python setup.py COMMAND'), " "or in a way that lets it use sys.argv[0] to find the root " "(like 'python path/to/setup.py COMMAND').") raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools # tree) execute all dependencies in a single python process, so # "versioneer" may be imported multiple times, and python's shared # module-import table will cache the first one. So we can't use # os.path.dirname(__file__), as that will find whichever # versioneer.py was first imported, even in later projects. my_path = os.path.realpath(os.path.abspath(__file__)) me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir: print("Warning: build in %s is using versioneer.py from %s" % (os.path.dirname(my_path), versioneer_py)) except NameError: pass return root def get_config_from_root(root): """Read the project setup.cfg file to determine Versioneer config.""" # This might raise OSError (if setup.cfg is missing), or # configparser.NoSectionError (if it lacks a [versioneer] section), or # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . setup_cfg = os.path.join(root, "setup.cfg") parser = configparser.ConfigParser() with open(setup_cfg, "r") as cfg_file: parser.read_file(cfg_file) VCS = parser.get("versioneer", "VCS") # mandatory # Dict-like interface for non-mandatory entries section = parser["versioneer"] cfg = VersioneerConfig() cfg.VCS = VCS cfg.style = section.get("style", "") cfg.versionfile_source = section.get("versionfile_source") cfg.versionfile_build = section.get("versionfile_build") cfg.tag_prefix = section.get("tag_prefix") if cfg.tag_prefix in ("''", '""'): cfg.tag_prefix = "" cfg.parentdir_prefix = section.get("parentdir_prefix") cfg.verbose = section.get("verbose") return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" # these dictionaries contain VCS-specific tools LONG_VERSION_PY: Dict[str, str] = {} HANDLERS: Dict[str, Dict[str, Callable]] = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" HANDLERS.setdefault(vcs, {})[method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None for command in commands: try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git process = subprocess.Popen([command] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None)) break except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands,)) return None, None stdout = process.communicate()[0].strip().decode() if process.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, process.returncode return stdout, process.returncode LONG_VERSION_PY['git'] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by # versioneer-0.21 (https://github.com/python-versioneer/python-versioneer) """Git implementation of _version.py.""" import errno import os import re import subprocess import sys from typing import Callable, Dict def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "%(STYLE)s" cfg.tag_prefix = "%(TAG_PREFIX)s" cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY: Dict[str, str] = {} HANDLERS: Dict[str, Dict[str, Callable]] = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None for command in commands: try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git process = subprocess.Popen([command] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None)) break except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %%s" %% dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %%s" %% (commands,)) return None, None stdout = process.communicate()[0].strip().decode() if process.returncode != 0: if verbose: print("unable to run %%s (error)" %% dispcmd) print("stdout was %%s" %% stdout) return None, process.returncode return stdout, process.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %%s but none started with prefix %%s" %% (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: with open(versionfile_abs, "r") as fobj: for line in fobj: if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) except OSError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if "refnames" not in keywords: raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %%d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%%s', no digits" %% ",".join(refs - tags)) if verbose: print("likely tags: %%s" %% ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') if not re.match(r'\d', r): continue if verbose: print("picking %%s" %% r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] TAG_PREFIX_REGEX = "*" if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] TAG_PREFIX_REGEX = r"\*" _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %%s not under git control" %% root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", "%%s%%s" %% (tag_prefix, TAG_PREFIX_REGEX)], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") branch_name = branch_name.strip() if branch_name == "HEAD": # If we aren't exactly on a branch, pick a branch which represents # the current commit. If all else fails, we are on a branchless # commit. branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) # --contains was added in git-1.5.4 if rc != 0 or branches is None: raise NotThisMethod("'git branch --contains' returned error") branches = branches.split("\n") # Remove the first line if we're running detached if "(" in branches[0]: branches.pop(0) # Strip off the leading "* " from the list of branches. branches = [branch[2:] for branch in branches] if "master" in branches: branch_name = "master" elif not branches: branch_name = None else: # Pick the first branch that is returned. Good or bad. branch_name = branches[0] pieces["branch"] = branch_name # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%%s'" %% describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%%s' doesn't start with prefix '%%s'" print(fmt %% (full_tag, tag_prefix)) pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" %% (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_branch(pieces): """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . The ".dev0" means not master branch. Note that .dev0 sorts backwards (a feature branch will appear "older" than the master branch). Exceptions: 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def pep440_split_post(ver): """Split pep440 version string at the post-release segment. Returns the release segments before the post-release and the post-release version number (or -1 if no post-release segment is present). """ vc = str.split(ver, ".post") return vc[0], int(vc[1] or 0) if len(vc) == 2 else None def render_pep440_pre(pieces): """TAG[.postN.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: if pieces["distance"]: # update the post release segment tag_version, post_version = pep440_split_post(pieces["closest-tag"]) rendered = tag_version if post_version is not None: rendered += ".post%%d.dev%%d" %% (post_version+1, pieces["distance"]) else: rendered += ".post0.dev%%d" %% (pieces["distance"]) else: # no commits, use the tag as the version rendered = pieces["closest-tag"] else: # exception #1 rendered = "0.post0.dev%%d" %% pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%%s" %% pieces["short"] else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%%s" %% pieces["short"] return rendered def render_pep440_post_branch(pieces): """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . The ".dev0" means not master branch. Exceptions: 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%%s" %% pieces["short"] if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += "+g%%s" %% pieces["short"] if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-branch": rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-post-branch": rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%%s'" %% style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for _ in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None} try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} ''' @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: with open(versionfile_abs, "r") as fobj: for line in fobj: if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) except OSError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if "refnames" not in keywords: raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') if not re.match(r'\d', r): continue if verbose: print("picking %s" % r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] TAG_PREFIX_REGEX = "*" if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] TAG_PREFIX_REGEX = r"\*" _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", "%s%s" % (tag_prefix, TAG_PREFIX_REGEX)], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") branch_name = branch_name.strip() if branch_name == "HEAD": # If we aren't exactly on a branch, pick a branch which represents # the current commit. If all else fails, we are on a branchless # commit. branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) # --contains was added in git-1.5.4 if rc != 0 or branches is None: raise NotThisMethod("'git branch --contains' returned error") branches = branches.split("\n") # Remove the first line if we're running detached if "(" in branches[0]: branches.pop(0) # Strip off the leading "* " from the list of branches. branches = [branch[2:] for branch in branches] if "master" in branches: branch_name = "master" elif not branches: branch_name = None else: # Pick the first branch that is returned. Good or bad. branch_name = branches[0] pieces["branch"] = branch_name # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%s'" % describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def do_vcs_install(manifest_in, versionfile_source, ipy): """Git-specific installation logic for Versioneer. For Git, this means creating/changing .gitattributes to mark _version.py for export-subst keyword substitution. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] files = [manifest_in, versionfile_source] if ipy: files.append(ipy) try: my_path = __file__ if my_path.endswith(".pyc") or my_path.endswith(".pyo"): my_path = os.path.splitext(my_path)[0] + ".py" versioneer_file = os.path.relpath(my_path) except NameError: versioneer_file = "versioneer.py" files.append(versioneer_file) present = False try: with open(".gitattributes", "r") as fobj: for line in fobj: if line.strip().startswith(versionfile_source): if "export-subst" in line.strip().split()[1:]: present = True break except OSError: pass if not present: with open(".gitattributes", "a+") as fobj: fobj.write(f"{versionfile_source} export-subst\n") files.append(".gitattributes") run_command(GITS, ["add", "--"] + files) def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") SHORT_VERSION_PY = """ # This file was generated by 'versioneer.py' (0.21) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. import json version_json = ''' %s ''' # END VERSION_JSON def get_versions(): return json.loads(version_json) """ def versions_from_file(filename): """Try to determine the version from _version.py if present.""" try: with open(filename) as f: contents = f.read() except OSError: raise NotThisMethod("unable to read _version.py") mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S) if not mo: mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) print("set %s to '%s'" % (filename, versions["version"])) def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_branch(pieces): """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . The ".dev0" means not master branch. Note that .dev0 sorts backwards (a feature branch will appear "older" than the master branch). Exceptions: 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def pep440_split_post(ver): """Split pep440 version string at the post-release segment. Returns the release segments before the post-release and the post-release version number (or -1 if no post-release segment is present). """ vc = str.split(ver, ".post") return vc[0], int(vc[1] or 0) if len(vc) == 2 else None def render_pep440_pre(pieces): """TAG[.postN.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: if pieces["distance"]: # update the post release segment tag_version, post_version = pep440_split_post(pieces["closest-tag"]) rendered = tag_version if post_version is not None: rendered += ".post%d.dev%d" % (post_version+1, pieces["distance"]) else: rendered += ".post0.dev%d" % (pieces["distance"]) else: # no commits, use the tag as the version rendered = pieces["closest-tag"] else: # exception #1 rendered = "0.post0.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_post_branch(pieces): """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . The ".dev0" means not master branch. Exceptions: 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["branch"] != "master": rendered += ".dev0" rendered += "+g%s" % pieces["short"] if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-branch": rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-post-branch": rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} class VersioneerBadRootError(Exception): """The project root directory is unknown or missing key files.""" def get_versions(verbose=False): """Get the project version from whatever source is available. Returns dict with two keys: 'version' and 'full'. """ if "versioneer" in sys.modules: # see the discussion in cmdclass.py:get_cmdclass() del sys.modules["versioneer"] root = get_root() cfg = get_config_from_root(root) assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose assert cfg.versionfile_source is not None, \ "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) # extract version from first of: _version.py, VCS command (e.g. 'git # describe'), parentdir. This is meant to work for developers using a # source checkout, for users of a tarball created by 'setup.py sdist', # and for users of a tarball/zipball created by 'git archive' or github's # download-from-tag feature or the equivalent in other VCSes. get_keywords_f = handlers.get("get_keywords") from_keywords_f = handlers.get("keywords") if get_keywords_f and from_keywords_f: try: keywords = get_keywords_f(versionfile_abs) ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) if verbose: print("got version from expanded keyword %s" % ver) return ver except NotThisMethod: pass try: ver = versions_from_file(versionfile_abs) if verbose: print("got version from file %s %s" % (versionfile_abs, ver)) return ver except NotThisMethod: pass from_vcs_f = handlers.get("pieces_from_vcs") if from_vcs_f: try: pieces = from_vcs_f(cfg.tag_prefix, root, verbose) ver = render(pieces, cfg.style) if verbose: print("got version from VCS %s" % ver) return ver except NotThisMethod: pass try: if cfg.parentdir_prefix: ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) if verbose: print("got version from parentdir %s" % ver) return ver except NotThisMethod: pass if verbose: print("unable to compute version") return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} def get_version(): """Get the short version string for this project.""" return get_versions()["version"] def get_cmdclass(cmdclass=None): """Get the custom setuptools/distutils subclasses used by Versioneer. If the package uses a different cmdclass (e.g. one from numpy), it should be provide as an argument. """ if "versioneer" in sys.modules: del sys.modules["versioneer"] # this fixes the "python setup.py develop" case (also 'install' and # 'easy_install .'), in which subdependencies of the main project are # built (using setup.py bdist_egg) in the same python process. Assume # a main project A and a dependency B, which use different versions # of Versioneer. A's setup.py imports A's Versioneer, leaving it in # sys.modules by the time B's setup.py is executed, causing B to run # with the wrong versioneer. Setuptools wraps the sub-dep builds in a # sandbox that restores sys.modules to it's pre-build state, so the # parent is protected against the child's "import versioneer". By # removing ourselves from sys.modules here, before the child build # happens, we protect the child from the parent's versioneer too. # Also see https://github.com/python-versioneer/python-versioneer/issues/52 cmds = {} if cmdclass is None else cmdclass.copy() # we add "version" to both distutils and setuptools from distutils.core import Command class cmd_version(Command): description = "report generated version string" user_options = [] boolean_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): vers = get_versions(verbose=True) print("Version: %s" % vers["version"]) print(" full-revisionid: %s" % vers.get("full-revisionid")) print(" dirty: %s" % vers.get("dirty")) print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) cmds["version"] = cmd_version # we override "build_py" in both distutils and setuptools # # most invocation pathways end up running build_py: # distutils/build -> build_py # distutils/install -> distutils/build ->.. # setuptools/bdist_wheel -> distutils/install ->.. # setuptools/bdist_egg -> distutils/install_lib -> build_py # setuptools/install -> bdist_egg ->.. # setuptools/develop -> ? # pip install: # copies source tree to a tempdir before running egg_info/etc # if .git isn't copied too, 'git describe' will fail # then does setup.py bdist_wheel, or sometimes setup.py install # setup.py egg_info -> ? # we override different "build_py" commands for both environments if 'build_py' in cmds: _build_py = cmds['build_py'] elif "setuptools" in sys.modules: from setuptools.command.build_py import build_py as _build_py else: from distutils.command.build_py import build_py as _build_py class cmd_build_py(_build_py): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_py.run(self) # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_py"] = cmd_build_py if 'build_ext' in cmds: _build_ext = cmds['build_ext'] elif "setuptools" in sys.modules: from setuptools.command.build_ext import build_ext as _build_ext else: from distutils.command.build_ext import build_ext as _build_ext class cmd_build_ext(_build_ext): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_ext.run(self) if self.inplace: # build_ext --inplace will only build extensions in # build/lib<..> dir with no _version.py to write to. # As in place builds will already have a _version.py # in the module dir, we do not need to write one. return # now locate _version.py in the new build/ directory and replace # it with an updated value target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_ext"] = cmd_build_ext if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION # "product_version": versioneer.get_version(), # ... class cmd_build_exe(_build_exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _build_exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) cmds["build_exe"] = cmd_build_exe del cmds["build_py"] if 'py2exe' in sys.modules: # py2exe enabled? from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _py2exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) cmds["py2exe"] = cmd_py2exe # we override different "sdist" commands for both environments if 'sdist' in cmds: _sdist = cmds['sdist'] elif "setuptools" in sys.modules: from setuptools.command.sdist import sdist as _sdist else: from distutils.command.sdist import sdist as _sdist class cmd_sdist(_sdist): def run(self): versions = get_versions() self._versioneer_generated_versions = versions # unless we update this, the command will keep using the old # version self.distribution.metadata.version = versions["version"] return _sdist.run(self) def make_release_tree(self, base_dir, files): root = get_root() cfg = get_config_from_root(root) _sdist.make_release_tree(self, base_dir, files) # now locate _version.py in the new base_dir directory # (remembering that it may be a hardlink) and replace it with an # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, self._versioneer_generated_versions) cmds["sdist"] = cmd_sdist return cmds CONFIG_ERROR = """ setup.cfg is missing the necessary Versioneer configuration. You need a section like: [versioneer] VCS = git style = pep440 versionfile_source = src/myproject/_version.py versionfile_build = myproject/_version.py tag_prefix = parentdir_prefix = myproject- You will also need to edit your setup.py to use the results: import versioneer setup(version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), ...) Please read the docstring in ./versioneer.py for configuration instructions, edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. """ SAMPLE_CONFIG = """ # See the docstring in versioneer.py for instructions. Note that you must # re-run 'versioneer.py setup' after changing this section, and commit the # resulting files. [versioneer] #VCS = git #style = pep440 #versionfile_source = #versionfile_build = #tag_prefix = #parentdir_prefix = """ OLD_SNIPPET = """ from ._version import get_versions __version__ = get_versions()['version'] del get_versions """ INIT_PY_SNIPPET = """ from . import {0} __version__ = {0}.get_versions()['version'] """ def do_setup(): """Do main VCS-independent setup function for installing Versioneer.""" root = get_root() try: cfg = get_config_from_root(root) except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: if isinstance(e, (OSError, configparser.NoSectionError)): print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) return 1 print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write(LONG % {"DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, }) ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: old = f.read() except OSError: old = "" module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] snippet = INIT_PY_SNIPPET.format(module) if OLD_SNIPPET in old: print(" replacing boilerplate in %s" % ipy) with open(ipy, "w") as f: f.write(old.replace(OLD_SNIPPET, snippet)) elif snippet not in old: print(" appending to %s" % ipy) with open(ipy, "a") as f: f.write(snippet) else: print(" %s unmodified" % ipy) else: print(" %s doesn't exist, ok" % ipy) ipy = None # Make sure both the top-level "versioneer.py" and versionfile_source # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so # they'll be copied into source distributions. Pip won't be able to # install the package without this. manifest_in = os.path.join(root, "MANIFEST.in") simple_includes = set() try: with open(manifest_in, "r") as f: for line in f: if line.startswith("include "): for include in line.split()[1:]: simple_includes.add(include) except OSError: pass # That doesn't cover everything MANIFEST.in can do # (http://docs.python.org/2/distutils/sourcedist.html#commands), so # it might give some false negatives. Appending redundant 'include' # lines is safe, though. if "versioneer.py" not in simple_includes: print(" appending 'versioneer.py' to MANIFEST.in") with open(manifest_in, "a") as f: f.write("include versioneer.py\n") else: print(" 'versioneer.py' already in MANIFEST.in") if cfg.versionfile_source not in simple_includes: print(" appending versionfile_source ('%s') to MANIFEST.in" % cfg.versionfile_source) with open(manifest_in, "a") as f: f.write("include %s\n" % cfg.versionfile_source) else: print(" versionfile_source already in MANIFEST.in") # Make VCS-specific changes. For git, this means creating/changing # .gitattributes to mark _version.py for export-subst keyword # substitution. do_vcs_install(manifest_in, cfg.versionfile_source, ipy) return 0 def scan_setup_py(): """Validate the contents of setup.py against Versioneer's expectations.""" found = set() setters = False errors = 0 with open("setup.py", "r") as f: for line in f.readlines(): if "import versioneer" in line: found.add("import") if "versioneer.get_cmdclass()" in line: found.add("cmdclass") if "versioneer.get_version()" in line: found.add("get_version") if "versioneer.VCS" in line: setters = True if "versioneer.versionfile_source" in line: setters = True if len(found) != 3: print("") print("Your setup.py appears to be missing some important items") print("(but I might be wrong). Please make sure it has something") print("roughly like the following:") print("") print(" import versioneer") print(" setup( version=versioneer.get_version(),") print(" cmdclass=versioneer.get_cmdclass(), ...)") print("") errors += 1 if setters: print("You should remove lines like 'versioneer.VCS = ' and") print("'versioneer.versionfile_source = ' . This configuration") print("now lives in setup.cfg, and should be removed from setup.py") print("") errors += 1 return errors if __name__ == "__main__": cmd = sys.argv[1] if cmd == "setup": errors = do_setup() errors += scan_setup_py() if errors: sys.exit(1)