Skip to main content

A package to calculate isotopic composition of (custom) Elements, Molecules and Mixtures.

Project description

isoVec

Description

isoVec is a framework to build complex mixtures, get atomic or weight percentages of each of its substances down to the isotopic composition (the isotopce vector, hence the name). The information on atomic weight, as well as abundance of those isotopes in natural occuring elements, is from "Atomic Weights and Isotopic Compositions" by the NIST Physical Measurement Laboratory [1]. This information is given in the form of Isotope and Element classes. The user can create custom elements and specify the isotopic composition manually. Elements make up Molecules and Elements and Molecules can make up a Mixture. A thorough example is given in Section Example.

Installation

The source code of the most recent development version is hosted on GitHub. The binary installers and the source code of stable releases is available on the project site on the Python Package Index (PyPI) and can be simply installed from the repository via

pip install isovec

There are no additional dependencies other than core Python packages of Python 3.9.

Example

The composition of the atmosphere of the Earth may serve as an example how to use isoVec. The constituents and their atomic (mole) fractions are taken from the respective Wikipedia article and are as of April 2022:

Constituent Atomic Fraction
Nitrogen (N2) 78.084 %
Oxygen (O2) 20.946 %
Argon (Ar) 0.9340 %
Carbon dioxide (CO2) 417 ppm
Neon (Ne) 18.18 ppm
Helium (He) 5.24 ppm
Methane (CH4) 1.87 ppm
Krypton (Kr) 1.14 ppm

Let's assume for the following that you import isoVec with the following (shorter) alias. Keep in mind, that all content is packed inside the given namespace.

import isovec as iso

Element

Natural occuring elements are already implemented and can be accessed via its symbol and "_nat". Nitrogen for example is called with N_nat. For the sake of this tutorial, we will define nitrogen again by ourselfs. Each isotope is acessed via the elements symbol, an underscore "_" and its mass number (that is protons + neutrons). Nitrogen-14 is therefore called via N_14. Naturally, an Element can only be composed of its respective isotopes, that is Isotope objects with the same atomic number. We can now create a custom Element with a name to identify and the composition as a dictionary:

nitrogen = iso.Element("nitrogen", {
    iso.N_14: 9.963600E-01,
    iso.N_15: 3.640000E-03
})

Whenever you supply a composition, positive values refer to a atomic fraction (as done before), while negative values refer to a weight fraction. Use whatever information is available or more convencient, but you cannot mix atomic and weight fractions inside one composition dictionary. Also, the composition doesn't necessarily need to add up to one. Instead, each fraction is normalised by the total sum of given fractions.

Molecule

Straightforward, the composition for a molecule is the number of atoms per element. Therefore, only positive values for the compoosition are reasonable here. The atomic weight of a molecule is calculated automatically, but could be overwritten when supplying the kwargs key-value pair atomic_wt=value in the constructor. However, this class isn't strictly limited to molecules, but can be used for crystalline or amorphous structures with a stochiometric distribution. Using the implemented natural elements, the Molecule for carbon dioxide is given by a name identifier and the atomic composition:

carbon_dioxide = iso.Molecule("carbon dioxide", {
    iso.C_nat: 1,
    iso.O_nat: 2
})

Likewise we generate the other molecules:

methane = iso.Molecule("methane", {
    iso.C_nat: 1,
    iso.H_nat: 4
})
nitrogen2 = iso.Molecule("molecular nitrogen", { iso.N_nat: 2})
oxygen2 = iso.Molecule("molecular oxygen", { iso.O_nat: 2})

Mixture

The air is now a mixture of several molecules and pure elements, as stated in the table from the introduction. This Mixture is given by a name identifier and the composition, in this case atomic (which again doesn't necessarily need to add up). In the following definition, we also utilise helper functions for conversion (an extensive list ca be found in the documentation):

air = iso.Mixture("air", {
    nitrogen2:                 78.084E-02,  # Molecule
    oxygen2:        iso.percent(20.946),    # Molecule
    iso.Ar_nat:     iso.percent( 0.9340),   # Element
    carbon_dioxide:            417.0E-06,   # Molecule
    iso.Ne_nat:        iso.ppm( 18.18),     # Element
    iso.He_nat:        iso.ppm(  5.24),     # Element
    methane:           iso.ppm(  1.87),     # Molecule
    iso.Kr_nat:        iso.ppm(  1.14)      # Element
})

A printed overview of all subcomponents can be obtained by invoking print_overview() ony any substance we want to inspect:

air.print_overview(True)

which yields the following (excerpt of the) output:

________________________________________________________________

 Mixture "air"
  100.0000 at.%  |  100.0000 wt.%

----------------------------------------------------------------
1. Molecule "molecular nitrogen": 28.0134 g/mol
     78.0775 at.%  |   75.5097 wt.%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1.1. Element "natural nitrogen": 14.0067 g/mol
       78.0775 at.%  |   75.5097 wt.%

1.1.1.    N-14:    77.7933 at.%  |   75.2154 wt.%
1.1.2.    N-15:     0.2842 at.%  |    0.2943 wt.%
----------------------------------------------------------------
2. Molecule "molecular oxygen": 31.9988 g/mol
     20.9443 at.%  |   23.1372 wt.%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2.1. Element "natural oxygen": 15.9994 g/mol
       20.9443 at.%  |   23.1372 wt.%

2.1.1.    O-16:    20.8934 at.%  |   23.0744 wt.%
2.1.2.    O-17:     0.0080 at.%  |    0.0093 wt.%
2.1.3.    O-18:     0.0429 at.%  |    0.0534 wt.%
----------------------------------------------------------------
3. Element "natural argon": 39.9478 g/mol
      0.9339 at.%  |    1.2880 wt.%

3.1.      Ar-36:    0.0031 at.%  |    0.0039 wt.%
3.2.      Ar-38:    0.0006 at.%  |    0.0008 wt.%
3.3.      Ar-40:    0.9302 at.%  |    1.2834 wt.%
----------------------------------------------------------------
4. Molecule "carbon dioxide": 44.0095 g/mol
      0.0417 at.%  |    0.0634 wt.%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.1. Element "natural carbon": 12.0107 g/mol
        0.0139 at.%  |    0.0173 wt.%

4.1.1.    C-12:     0.0138 at.%  |    0.0171 wt.%
4.1.2.    C-13:     0.0001 at.%  |    0.0002 wt.%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.2. Element "natural oxygen": 15.9994 g/mol
        0.0278 at.%  |    0.0461 wt.%

4.2.1.    O-16:     0.0277 at.%  |    0.0459 wt.%
4.2.2.    O-17:     0.0000 at.%  |    0.0000 wt.%
4.2.3.    O-18:     0.0001 at.%  |    0.0001 wt.%
----------------------------------------------------------------
   [...]

The overview splits up all subcomponents in a layered manner and gives their atomic and weight fractions, down to the isotopic composition. This function has an optional flag to scale the subcomponents, that is False by default. If scaled, it will yield the fraction of the subcomponent compared to the top-level component, where the function was invoked on. In other words, the fractions are multiplicative downwards. If not scaled, the fractions will only sum up on their respective layer, for example 4.1 and 4.2 would add up to 100 %.

Isotope Composition

As can be seen above, this doesn't sum up the fractions for the single isotopes, something we might be interested in. The method get_isotopes() can be called upon every component and yields an ordered dictionary with the isotopes and their respective summed atomic fractions. For our mixture of air, the following code

isotope_vector = air.get_isotopes()
for isotope, at_frac in isotope_vector.items():
    print(f"{isotope.name:>6}: {at_frac:.4E}")

yields the final isotope vector:

   H-1: 1.4957E-06
   H-2: 1.7203E-10
  He-3: 7.0210E-12
  He-4: 5.2396E-06
  C-12: 1.3787E-04
  C-13: 1.4912E-06
  N-14: 7.7793E-01
  N-15: 2.8420E-03
  O-16: 2.0921E-01
  O-17: 7.9694E-05
  O-18: 4.2993E-04
   [...]

Changelog

For a history of changes, refer to the file CHANGELOG.md in the source code distributions or directly on the GitHub repository.

References

  1. Coursey, J.S., Schwab, D.J., Tsai, J.J., and Dragoset, R.A. (2015), Atomic Weights and Isotopic Compositions (version 4.1). [Online] Available: http://physics.nist.gov/Comp [Accessed 23 November 2022]. National Institute of Standards and Technology, Gaithersburg, MD.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

isovec-1.0.2.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

isovec-1.0.2-py3-none-any.whl (27.3 kB view details)

Uploaded Python 3

File details

Details for the file isovec-1.0.2.tar.gz.

File metadata

  • Download URL: isovec-1.0.2.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for isovec-1.0.2.tar.gz
Algorithm Hash digest
SHA256 cb36fe5212f062d00ce56343f41b0309b0749bcfd0eff3102a2e246f81d2b5eb
MD5 4b1bfc9c8d5e55839fed9710c3969721
BLAKE2b-256 53ba1690e2a99908f4be73f35264c62f61c69247d25b5c875a8507e3b964575c

See more details on using hashes here.

File details

Details for the file isovec-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: isovec-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 27.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for isovec-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b7f0e1f4fe7278fdce0aff23a0d3db6be55b5b2d0c7a04ccfd7e9bb313382372
MD5 5385db2766fdd6a48863132b3659ac94
BLAKE2b-256 cb7f033560064f28a59182dd5fd152bafcbd50350b064d71d20fe9c9a21ea1f3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page