molformula 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- molformula-0.1.0/LICENSE +11 -0
- molformula-0.1.0/PKG-INFO +373 -0
- molformula-0.1.0/README.md +345 -0
- molformula-0.1.0/examples/acetaminophen_fragmentation.py +43 -0
- molformula-0.1.0/examples/lipid_adduct_ions.py +99 -0
- molformula-0.1.0/examples/peptide_msms.py +95 -0
- molformula-0.1.0/pyproject.toml +66 -0
- molformula-0.1.0/pyproject.toml.orig +65 -0
- molformula-0.1.0/src/molformula/__init__.py +49 -0
- molformula-0.1.0/src/molformula/_core.py +759 -0
- molformula-0.1.0/src/molformula/_error.py +206 -0
- molformula-0.1.0/src/molformula/_hill.py +100 -0
- molformula-0.1.0/src/molformula/_parser.py +232 -0
- molformula-0.1.0/src/molformula/py.typed +0 -0
- molformula-0.1.0/tests/test_formula_changes.py +205 -0
- molformula-0.1.0/tests/test_hill_format.py +169 -0
- molformula-0.1.0/tests/test_ion_creation.py +158 -0
- molformula-0.1.0/tests/test_mass.py +250 -0
- molformula-0.1.0/tests/test_parser_examples.py +244 -0
- molformula-0.1.0/tests/test_public_api.py +121 -0
molformula-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2026 Hiroshi Nakayama and RIKEN (The Institute of Physical and Chemical Research)
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
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 HOLDER 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.
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: molformula
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple chemical formula processor for analyzing mass spectrometry data
|
|
5
|
+
Keywords: chemical formula,molecular formula,mass spectrometry,exact mass,isotopic mass,isotope,mz,proteomics,lipidomics,metabolomics,cheminformatics,bioinformatics
|
|
6
|
+
Author: Hiroshi Nakayama, RIKEN (The Institute of Physical and Chemical Research)
|
|
7
|
+
Author-email: Hiroshi Nakayama <64342563+benkeicrab@users.noreply.github.com>
|
|
8
|
+
License-Expression: BSD-3-Clause
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Project-URL: Repository, https://github.com/benkeicrab/molformula.git
|
|
26
|
+
Project-URL: Issues, https://github.com/benkeicrab/molformula/issues
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# molformula
|
|
30
|
+
|
|
31
|
+
A simple, dependency-free Python library for safe chemical-formula manipulation and mass-spectrometry-oriented calculations.
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
This library handles molecular formulas and simple condensed formulas (See Supported formula syntax), arithmetic processing of these formulas, ionization, and exact mass and m/z calculations with enforced formula invariants.
|
|
36
|
+
The API is designed to support a functional style, using immutable formula values and composable, non-mutating operations.
|
|
37
|
+
It is intended as a foundation for mass spectrometry data processing.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
### Python version
|
|
43
|
+
|
|
44
|
+
Supports Python >=3.10
|
|
45
|
+
|
|
46
|
+
### Dependency
|
|
47
|
+
|
|
48
|
+
No third-party library is required for using the library. `pytest` for developers / contributors.
|
|
49
|
+
|
|
50
|
+
### Installation / uninstallation
|
|
51
|
+
|
|
52
|
+
```Bash
|
|
53
|
+
# installation
|
|
54
|
+
pip install molformula
|
|
55
|
+
|
|
56
|
+
# uninstallation
|
|
57
|
+
pip uninstall molformula
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
### Import
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
>>> import molformula as mf
|
|
66
|
+
```
|
|
67
|
+
or more explicitly (and thus more preferable)
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
>>> from molformula import Formula, IonFormula, apply_formula_change, deprotonated, exact_mass, ion_mz, make_formula_change, protonated, sum_formulas, to_str
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Creating and showing canonical formulas
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
>>> # molecular formula and simple condensed formulas are supported.
|
|
78
|
+
>>> glucose = Formula("CH2OH(CHOH)4CHO")
|
|
79
|
+
>>> # Output is canonicalized to Hill-system order [1].
|
|
80
|
+
>>> to_str(glucose)
|
|
81
|
+
'C6H12O6'
|
|
82
|
+
>>> # A symbol for explicit isotope must be written with a bracket in a formula.
|
|
83
|
+
>>> labeled_glucose = Formula("[13C]H2OH(CHOH)4CHO")
|
|
84
|
+
>>> # Labeled positions in a condensed formula are not preserved.
|
|
85
|
+
>>> # this package's additional rule: the ordinary symbol first, then explicit isotopes in increasing mass-number order.
|
|
86
|
+
>>> to_str(labeled_glucose)
|
|
87
|
+
'C5[13C]H12O6'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Formula arithmetic
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
>>> H2O = Formula('H2O')
|
|
94
|
+
>>> apply_formula_change(glucose, losses=(H2O,))
|
|
95
|
+
Formula('C6H10O5')
|
|
96
|
+
>>> C, C13 = Formula('C'), Formula('[13C]')
|
|
97
|
+
>>> apply_formula_change(glucose, gains=(C13,), losses=(C,))
|
|
98
|
+
Formula('C5[13C]H12O6')
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Reusable formula changes
|
|
102
|
+
|
|
103
|
+
Repeating application of a chemical change is supported.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
>>> # Define a specific formula change such as dehydration.
|
|
107
|
+
>>> dehydrated = make_formula_change(losses=(H2O,))
|
|
108
|
+
>>> dehydrated(glucose)
|
|
109
|
+
Formula('C6H10O5')
|
|
110
|
+
>>> C13_labeled = make_formula_change(gains=(C13,), losses=(C,))
|
|
111
|
+
>>> C13_labeled(glucose)
|
|
112
|
+
Formula('C5[13C]H12O6')
|
|
113
|
+
>>> C13_labeled(C13_labeled(glucose))
|
|
114
|
+
Formula('C4[13C]2H12O6')
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Ionization
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
>>> protonated_glucose = protonated(glucose, 1)
|
|
121
|
+
>>> protonated_glucose
|
|
122
|
+
IonFormula(formula=Formula('C6H13O6'), z=1)
|
|
123
|
+
>>> deprotonated_glucose = deprotonated(glucose, 1)
|
|
124
|
+
>>> deprotonated_glucose
|
|
125
|
+
IonFormula(formula=Formula('C6H11O6'), z=-1)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Exact mass and m/z
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
>>> exact_mass(glucose)
|
|
132
|
+
180.06338810418
|
|
133
|
+
>>> ion_mz(deprotonated_glucose)
|
|
134
|
+
179.05611165185906
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Exact mass and m/z are calculated using atomic mass values from NIST Physical Measurement Laboratory [2] and electron mass from 2022 CODATA recommended value [3]
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
### Application in peptide MS/MS
|
|
141
|
+
|
|
142
|
+
The following example constructs b- and y-ion series from amino-acid residue formulas for peptide AGSK.
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
>>> def b_y_ion_series(seq, z):
|
|
146
|
+
... water = Formula('H2O')
|
|
147
|
+
... b_ions, y_ions = [], []
|
|
148
|
+
... l = len(seq)
|
|
149
|
+
... for i in range(l):
|
|
150
|
+
... b_neutral = sum_formulas(*seq[: i+1])
|
|
151
|
+
... b_ion = protonated(b_neutral, z)
|
|
152
|
+
... b_ions.append(b_ion)
|
|
153
|
+
...
|
|
154
|
+
... y_neutral = sum_formulas(water, *seq[l-1-i: ])
|
|
155
|
+
... y_ion = protonated(y_neutral, z)
|
|
156
|
+
... y_ions.append(y_ion)
|
|
157
|
+
...
|
|
158
|
+
... return b_ions, y_ions
|
|
159
|
+
...
|
|
160
|
+
>>> gly = Formula('HNCH2CO')
|
|
161
|
+
>>> ser = Formula('HNCH(CH2OH)CO')
|
|
162
|
+
>>> ala = Formula('HNCH(CH3)CO')
|
|
163
|
+
>>> lys = Formula('HNCH(CH2CH2CH2CH2NH2)CO')
|
|
164
|
+
>>> pep_seq = [ala, gly, ser, lys]
|
|
165
|
+
|
|
166
|
+
>>> b_ions, y_ions = b_y_ion_series(pep_seq, 1)
|
|
167
|
+
>>> [ion_mz(ion) for ion in b_ions]
|
|
168
|
+
[72.04439023747095, 129.06585395816097, 216.09788236288097, 344.19284537807096]
|
|
169
|
+
>>> [ion_mz(ion) for ion in y_ions]
|
|
170
|
+
[147.11280415154096, 234.14483255626095, 291.16629627695096, 362.20341006210094]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The example includes full-length prefix and suffix compositions for completeness; these entries do not correspond to distinct backbone cleavage sites.
|
|
174
|
+
|
|
175
|
+
For phosphorylation of Ser and H3PO4-loss of phospho-Ser,
|
|
176
|
+
see examples/peptide_msms.py.
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
## Supported formula syntax
|
|
180
|
+
|
|
181
|
+
### Supported notation
|
|
182
|
+
|
|
183
|
+
- 'C6H12O6' # Molecular formula
|
|
184
|
+
- 'C5[13C]H12O6' # Molecular formula with explicit isotope
|
|
185
|
+
- 'CH4O' # Count 1 can be omitted.
|
|
186
|
+
- 'CH3OH' # Simple condensed formula
|
|
187
|
+
- '(CH3)2CHOH' # Condensed formula with parentheses and multipliers
|
|
188
|
+
- '[ 13 C] 6H12O6' # Whitespace is allowed between tokens but not within lexical tokens such as elemental symbols or integer counts.
|
|
189
|
+
|
|
190
|
+
### Unsupported notation
|
|
191
|
+
|
|
192
|
+
- '2H2O' # leading stoichiometric coefficient
|
|
193
|
+
- 'CuSO4.H2O' # component separator / hydrate notation
|
|
194
|
+
- '[CH3COO]-' # Charged formula
|
|
195
|
+
- 'K3[Fe(CN)6]' # Complex
|
|
196
|
+
- 'CH3-OH' # Bond representation with '-' and/or '='
|
|
197
|
+
|
|
198
|
+
- Formulas with unsupported atom species (See Limitations below)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## API overview
|
|
202
|
+
|
|
203
|
+
The library has immutable types: Formula and IonFormula, as well as functions for manipulating these types.
|
|
204
|
+
|
|
205
|
+
### Types
|
|
206
|
+
|
|
207
|
+
#### `Formula`:
|
|
208
|
+
|
|
209
|
+
- Representation of non-negative atom-species counts.
|
|
210
|
+
|
|
211
|
+
- Must contain at least one atom.
|
|
212
|
+
|
|
213
|
+
- Does not encode charge, bonding, valence, or molecular structure.
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
#### `IonFormula`:
|
|
217
|
+
|
|
218
|
+
- Combines a Formula with a non-zero charge (z).
|
|
219
|
+
|
|
220
|
+
- Cannot be constructed directly; use ionization functions below.
|
|
221
|
+
|
|
222
|
+
- Ionization functions treat their Formula argument as a neutral
|
|
223
|
+
precursor.
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
### Operations to the types
|
|
227
|
+
|
|
228
|
+
#### Parsing and formatting
|
|
229
|
+
|
|
230
|
+
- `Formula()`: Construct formula object.
|
|
231
|
+
|
|
232
|
+
- `to_str()`: Output a canonical representation of formula in Hill-system order [1]. Structural information in the original notation is not preserved.
|
|
233
|
+
|
|
234
|
+
- `atom_species_counts()`: Return atom-species counts as a new dictionary.
|
|
235
|
+
|
|
236
|
+
#### Arithmetic operation between Formula
|
|
237
|
+
|
|
238
|
+
The library offers high-level API of arithmetic operations between Formulas.
|
|
239
|
+
|
|
240
|
+
Intermediates can have negative atom counts; however, the resulting Formula must have non-negative counts and contain at least one atom.
|
|
241
|
+
|
|
242
|
+
- `apply_formula_change()`:
|
|
243
|
+
Apply atom-count gains and losses to a target Formula.
|
|
244
|
+
|
|
245
|
+
- `make_formula_change()`:
|
|
246
|
+
The atom-count gains and losses are baked into the return function.
|
|
247
|
+
The function applies gains/losses to a target Formula.
|
|
248
|
+
|
|
249
|
+
- `sum_formulas()`:
|
|
250
|
+
Sum up multiple Formulas.
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
#### Ionization
|
|
254
|
+
|
|
255
|
+
Ionization functions manipulate atom counts and charges. Currently, three types of ionization are supported.
|
|
256
|
+
|
|
257
|
+
- `protonated()`:
|
|
258
|
+
Adds n hydrogen atoms and sets charge to +n.
|
|
259
|
+
|
|
260
|
+
- `deprotonated()`:
|
|
261
|
+
Removes n hydrogen atoms and sets charge to -n.
|
|
262
|
+
|
|
263
|
+
- `deelectronated()`:
|
|
264
|
+
Leaves atom counts unchanged and sets charge to +1.
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
#### Mass calculation
|
|
268
|
+
|
|
269
|
+
`exact_mass()` calculates the exact mass of a `Formula`, and `ion_mz()`
|
|
270
|
+
calculates the m/z of an `IonFormula`.
|
|
271
|
+
The mass and m/z values are calculated with the atomic/isotopic masses [2] and electron mass [3].
|
|
272
|
+
No explicit decimal rounding is applied to the calculated mass or m/z values.
|
|
273
|
+
|
|
274
|
+
- `exact_mass()`:
|
|
275
|
+
Calculates exact mass of Formula. No electron-mass correction is applied.
|
|
276
|
+
|
|
277
|
+
- `ion_mz()`:
|
|
278
|
+
Calculates an ion m/z from an instance of IonFormula
|
|
279
|
+
The m/z value of ion: IonFormula is calculated as
|
|
280
|
+
|
|
281
|
+
(exact_mass(ion.formula) - ion.z * electron_mass) / abs(ion.z)
|
|
282
|
+
|
|
283
|
+
so positive charge removes electron mass and negative charge adds it.
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
#### Exceptions
|
|
287
|
+
|
|
288
|
+
The class hierarchy is as shown below:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
TypeError # Error in Python types
|
|
292
|
+
ValueError
|
|
293
|
+
└── ChemicalFormulaError # Base class for domain-value errors.
|
|
294
|
+
├── FormulaChangeError # Change producing invalid Formula.
|
|
295
|
+
├── IonizationError
|
|
296
|
+
│ ├── InvalidProtonCountError
|
|
297
|
+
│ ├── InsufficientHydrogenError
|
|
298
|
+
│ └── EmptyIonFormulaError
|
|
299
|
+
└── FormulaParseError
|
|
300
|
+
├── EmptyParenthesisError
|
|
301
|
+
├── UnmatchedParenthesesError
|
|
302
|
+
├── InvalidBracketError
|
|
303
|
+
├── EmptyFormulaError
|
|
304
|
+
├── InvalidFormulaError
|
|
305
|
+
├── UnsupportedAtomSpeciesError
|
|
306
|
+
└── InvalidCountError
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
- The `position` attribute in `FormulaParseError` is a zero-based offset into the original input string. It may equal `len(input)` when expected input is missing at the end of the string.
|
|
310
|
+
|
|
311
|
+
- When raised by this package, the `deficits` attribute in `FormulaChangeError` is a dictionary mapping each atom species that would have a negative count to the positive number of missing atoms.
|
|
312
|
+
|
|
313
|
+
- The `zero_result` attribute in `FormulaChangeError` is True only when the formula change would remove all atoms exactly, without producing any negative counts.
|
|
314
|
+
|
|
315
|
+
- See the API documentation for details.
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
## Limitations
|
|
319
|
+
|
|
320
|
+
- Supported atom species: C, 13C, H, 2H, N, 15N, O, 18O, P, S, Se, F, Cl, 37Cl, Br, 81Br, I, Si, Li, Na, K, Mg, Ca, Fe;
|
|
321
|
+
The principal isotope of each element is represented by the ordinary elemental symbol. Other supported isotopes use mass-number-prefixed atom-species symbols, which are written in brackets in formula strings (e.g. 13C as [13C]).
|
|
322
|
+
|
|
323
|
+
- Complexes, hydrates, SMILES, and condensed-formula syntax other than the supported forms shown above are not supported.
|
|
324
|
+
|
|
325
|
+
- Formula validates atom-species counts, but does not validate chemical valence, bonding, structural plausibility, or electrical neutrality.
|
|
326
|
+
|
|
327
|
+
- Arithmetic operations on IonFormula are not allowed; ion reactions are expressed by arithmetic operations on Formula followed by ionization.
|
|
328
|
+
|
|
329
|
+
- Radical character and spin state are not represented.
|
|
330
|
+
|
|
331
|
+
- `to_str()` returns a canonical formula in Hill-system order, losing input order, grouping, etc.
|
|
332
|
+
|
|
333
|
+
- Adduct ions are not supported as a dedicated model. Existing formula-change and ionization operations can be composed to construct many adduct compositions, for example:
|
|
334
|
+
|
|
335
|
+
```Python
|
|
336
|
+
>>> glycine = Formula('C2H5NO2')
|
|
337
|
+
>>> ammonium_adduct = make_formula_change(gains=(Formula('NH3'),))
|
|
338
|
+
>>> ammonium_adducted = protonated(ammonium_adduct(glycine), 1)
|
|
339
|
+
>>> ammonium_adducted
|
|
340
|
+
IonFormula(formula=Formula('C2H9N2O2'), z=1)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
See examples/lipid_adduct_ions.py for more details.
|
|
344
|
+
|
|
345
|
+
However, molformula does not determine whether such ions are chemically plausible or experimentally observable.
|
|
346
|
+
|
|
347
|
+
- `deprotonated()` strictly removes ordinary hydrogen (1H) atoms. It does not remove deuterium (2H) or tritium. To model deuterated loss, use `apply_formula_change()` with an explicit deuterium Formula('[2H]') as a loss.
|
|
348
|
+
```Python
|
|
349
|
+
>>> deuterium = Formula('[2H]')
|
|
350
|
+
>>> deuterated_glycine = Formula('C2H8[2H]N2O2')
|
|
351
|
+
>>> to_str(apply_formula_change(deuterated_glycine, losses=(deuterium,)))
|
|
352
|
+
'C2H8N2O2'
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
- Exact masses are calculated from the configured principal or explicitly specified isotopic masses. Isotopic abundance distributions, fine structure, and peak centroiding are not supported.
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
This project is licensed under the 3-clause BSD License. See LICENSE for details.
|
|
361
|
+
|
|
362
|
+
## Contributing
|
|
363
|
+
|
|
364
|
+
Bug reports and suggestions are welcome through GitHub Issues.
|
|
365
|
+
Contribution guidelines will be added as the project develops.
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
## References
|
|
369
|
+
1. Hill, E. A., JACS (1900) 22 (8): 478–494. https://doi.org/10.1021/ja02046a005
|
|
370
|
+
|
|
371
|
+
2. Atomic mass from NIST Physical Measurement Laboratory https://physics.nist.gov/cgi-bin/Compositions/stand_alone.pl
|
|
372
|
+
|
|
373
|
+
3. 2022 CODATA recommended value https://physics.nist.gov/cgi-bin/cuu/Value?eqmeu|search_for=electron+mass
|