Python interface to PartMC
Project description
PyPartMC
PyPartMC is a Python interface to PartMC, a particle-resolved Monte-Carlo code for atmospheric aerosol simulation. PyPartMC is implemented in C++ and it also constitutes a C++ API to the PartMC Fortran internals. The Python API can facilitate using PartMC from other environments - see, e.g., Julia example below.
TL;DR (try in a Jupyter notebook)
! pip install PyPartMC
import PyPartMC
Jupyter notebooks with examples
- Urban plum scenario demo (as in PartMC):
- Dry-Wet Particle Size Equilibration with PartMC and PySDM:
Features
- works on Linux, macOS and Windows (compatibility assured with CI builds)
- hassle-free installation using
pip
(prior PartMC installation not needed) - works out of the box on mybinder.org, Google Colab and alike
- ships with a set of examples maintained in a form of Jupyter notebooks
- Pythonic API (but retaining PartMC jargon) incl. Python GC deallocation of Fortran objects
- specification of parameters using native Python datatypes (lists, dicts) in place of PartMC spec files
- code snippets in README depicting how to use PyPartMC from Julia (also executed on CI)
- auto-generated API docs on the web
- support for [de]serialization of selected wrapped structures using JSON
- based on unmodified PartMC code
- does not use or require shell or any pre-installed libraries
- aiming at 100% unit test coverage
Usage examples
example object instantiation in Python
import PyPartMC as ppmc
print(ppmc.__version__)
gas_data = ppmc.GasData(("H2SO4", "HNO3", "HCl", "NH3", "NO", "NO2"))
example object instantiation in Julia
using Pkg
Pkg.add("PyCall")
using PyCall
ppmc = pyimport("PyPartMC")
print(ppmc.__version__)
gas_data = ppmc.GasData(("H2SO4", "HNO3", "HCl", "NH3", "NO", "NO2"))
usage in other projects
PyPartMC is used within the test workflow of the PySDM project.
Implementation outline
- PyPartMC is written in C++, Fortran and uses pybind11 and CMake.
- JSON support is handled with nlohmann::json and pybind11_json
- PartMC and selected parts of SUNDIALS are statically linked (and compiled in during
pip install
orpython -m build
) - C (SUNDIALS, netCDF), C++ (pybind11, ...) and Fortran (PartMC, CAMP, netCDF-fortran) dependencies are linked through git submodules
- MOSAIC dependency is optionally linked through setting the environmental variable
MOSAIC_HOME
- a drop-in replacement of the PartMC spec file routines is used for i/o from/to JSON
Implementation architecture
flowchart TD
subgraph J ["Julia"]
julia_user_code["Julia user code"] --> PyCall.jl
end
subgraph P ["Python"]
PyCall.jl --> PyPartMC
python_user_code -.-> NumPy
python_user_code["Python user code"] ---> PyPartMC["pubind11-generated PyPartMC module"]
end
subgraph Cpp ["C++"]
cpp_user_code["C++ user code"] ----> ppmc_cpp
PyPartMC --> ppmc_cpp["PyPartMC-C++"]
ppmc_cpp --> pybind11_json
pybind11_json ---> nlohmann::JSON
fake_spec_file_cpp --> nlohmann::JSON
end
subgraph C ["C"]
fake_spec_file_c --> fake_spec_file_cpp["SpecFile-C++"]
ppmc_cpp --> ppmc_c["PyPartMC-C"]
netCDF-C
SUNDIALS
camp_c["CAMP C code"]
end
subgraph Fortran ["Fortran"]
PartMC -....-> MOSAIC
ppmc_c --> ppmc_f["PyPartMC-F"]
ppmc_f ---> PartMC
PartMC --> netCDF-F
netCDF-F --> netCDF-C
PartMC --> SUNDIALS
PartMC ---> camp_f
camp_f["CAMP"] --> camp_c
PartMC ----> fake_spec_file_f[SpecFile-F]
fake_spec_file_f --> fake_spec_file_c["SpecFile-C"]
end
style PartMC fill:#7ae7ff,stroke-width:2px,color:#2B2B2B
Troubleshooting
Common installation issues
error: [Errno 2] No such file or directory: 'cmake'
Try rerunning after installing CMake, e.g., using apt-get install cmake
(Ubuntu/Debian), brew install cmake
(homebrew on macOS) or using MSYS2 on Windows.
No CMAKE_Fortran_COMPILER could be found.
Try installing a Fortran compiler (e.g., brew reinstall gcc
with Homebrew on macOS or using MSYS2 on Windows).
Could not find NC_M4 using the following names: m4, m4.exe
Try installing m4
(e.g., using MSYS2 on Windows).
Notes for developers
How to debug
git clone --recursive git+https://github.com/open-atmos/PyPartMC.git
cd PyPartMC
DEBUG=1 VERBOSE=1 pip --verbose install -e .
gdb python
(gdb) run -m pytest -s -vv -We -p no:unraisableexception tests
Pre-commit hooks
PyPartMC codebase benefits from Pylint, Black and isort code analysis (which are all part of the CI workflows where we also use pre-commit hooks. The pre-commit hooks can be run locally, and then the resultant changes need to be staged before committing. To set up the hooks locally, install pre-commit via pip install pre-commit
and set up the git hooks via pre-commit install
(this needs to be done every time you clone the project). To run all pre-commit hooks, run pre-commit run --all-files
. The .pre-commit-config.yaml
file can be modified in case new hooks are to be added or existing ones need to be altered.
Credits
PyPartMC:
authors: PyPartMC developers
funding: US Department of Energy Atmospheric System Research programme
copyright: University of Illinois at Urbana-Champaign
licence: GPL v3
PartMC:
authors: Nicole Riemer, Matthew West, Jeff Curtis et al.
licence: GPL v2 or later
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for PyPartMC-0.3.0-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e6ef7a7f37d426dfa633f0181cc3846aa0ca6b94586a85aeeed1edd92b612691 |
|
MD5 | c2a8cf8bb8f49434043436be7484fcb6 |
|
BLAKE2b-256 | 4c755b4e34342e5e3d248a4ab860fc4b65b813a3dfc4105e0e3a41f3ba23e3a1 |
Hashes for PyPartMC-0.3.0-cp311-cp311-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d0602b3c14077e7a882137474cf30b7ccb91728d27631189b6667d17eeac80fd |
|
MD5 | c436ea789f50b5d35f0843f7b9b14766 |
|
BLAKE2b-256 | 00e1bedb4b9a773c56fab04b936edd7fbc3cdb433a277d6253dce46a25a92115 |
Hashes for PyPartMC-0.3.0-cp311-cp311-macosx_12_0_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cdcffa529087df653f56d5694205e2280ae0a8887098dfcff98659b992db10c4 |
|
MD5 | 59e946859beda42b2291a6cf79e9b0e2 |
|
BLAKE2b-256 | d847a7e9dcca4878c8c138585a5cb17a21c51b1c0ffb698030953f4d5409c775 |
Hashes for PyPartMC-0.3.0-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 423565964d1e25a764a994d786be4b1fe975daa4366fea5fa2652c9deb740fef |
|
MD5 | cd795fbf47d81345c59f01379ced157f |
|
BLAKE2b-256 | dae707dc0aa52cd11b068851bd0d6dfa87f716bd77f6cbb8c58a326d6cb34664 |
Hashes for PyPartMC-0.3.0-cp310-cp310-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | df16cdaea33fc8f72987d8dcf7b872a70b1fb3f6b52800e644f86ffe5268744c |
|
MD5 | 0784b03056ba0ede068118be2b42b188 |
|
BLAKE2b-256 | eae705f4f64140e7d3df5bbf3617d9e3024cc271300e376de18d1b97a258d7b0 |
Hashes for PyPartMC-0.3.0-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d05924b28a2084bb88c9dedd9151cb5f19ba5c75edbce7b0e021a1f842cbbd57 |
|
MD5 | 9d11491cca1edbb86afb0dc5d43cfe60 |
|
BLAKE2b-256 | 22d2b5d2e27725d015cb94ac4fb6b11b08b9161df97de278843e5032e8f2e9a9 |
Hashes for PyPartMC-0.3.0-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5ad6721206b5c03a844819e09a8bd3fa693db2ad1f44bd159ac2d53bcac29921 |
|
MD5 | cb83b3cfd9caa8d0957f745d55d57e13 |
|
BLAKE2b-256 | 61b415333e9b4537a6092bf62f22d4910ccc16afa280f5843de3f8bea31cbf61 |
Hashes for PyPartMC-0.3.0-cp39-cp39-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3497b31830a474be2f4a09f03b8b801b4837e883f80cf0a3b85faf3368e36e74 |
|
MD5 | 8f5f7aea3e1559940d7b58594cbbcb45 |
|
BLAKE2b-256 | df16cb667de2c410ee97090135906190e31ef267b5e972d309d0af6039059476 |
Hashes for PyPartMC-0.3.0-cp39-cp39-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 015f2d602828566875378bfa1afb9f815fcbaa7d45e9acaf6f768a51696b71e7 |
|
MD5 | 4b67b33da3ad28e92f30fb77d7770da3 |
|
BLAKE2b-256 | ab62d04c3f13e752f54cb0fffd8b6b2cf5e179f35a61e17e18aa573f00801f27 |
Hashes for PyPartMC-0.3.0-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c9905dfe6d836078c0defbe5e1f71576d01aae096972c24456acb9c01ced847a |
|
MD5 | ad341ffdb35de8cf72abbefec9bc708e |
|
BLAKE2b-256 | 294ec748d59eb4ff0bac507b5d838e0e3d667458177312012865977717035d37 |
Hashes for PyPartMC-0.3.0-cp38-cp38-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c02e989480629d5f8ff46b8551e6e8ba2c829f4499d5fe21a122085fdfcb0458 |
|
MD5 | fce52e48390e22a26d597e935672431e |
|
BLAKE2b-256 | 2259aabe80e31e291fb010b3df8743b0ea9c078f570445ab9e8be6dd3b468781 |
Hashes for PyPartMC-0.3.0-cp38-cp38-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 947de073dfa56fc5ddc7bebdcb3781f6e2bef0aa26eadabe448509e4a7f9255e |
|
MD5 | 5c6e21ab9546a2df74c354c0acb5c448 |
|
BLAKE2b-256 | 8d1cecc2512fa9497f438db99eb4753861da2b2c3eebb51eead8300e2fabdebd |
Hashes for PyPartMC-0.3.0-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e7a32f5ca1cb368dbb44199d24b9158168b730fcecb9db030ece2a37ef01810a |
|
MD5 | 6d5531c5172bc652448d5199ced84e30 |
|
BLAKE2b-256 | 69529b47fb98d2416672fec4486f34abc8a6474df843579ca44e41ad78ed0669 |
Hashes for PyPartMC-0.3.0-cp37-cp37m-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3c85476a0c46bfd98644c4ac9a26aea006bd6edbf6543d7ad09e402f11d51e2d |
|
MD5 | 077224b0812a6da4099dd974665f80cb |
|
BLAKE2b-256 | 1c56be27f8692357154c5f38e9ae7303f4eaffff695121917773340bac75bb62 |
Hashes for PyPartMC-0.3.0-cp37-cp37m-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f3d0eab0d2672f5c3a6964931cdc680cb230c6dc517bd3634fcb08466a2dc7c5 |
|
MD5 | bd0524e02fc72f09112d0e3b22222bb4 |
|
BLAKE2b-256 | 2e595e9900408f47c06d5397ca530791665fcb9ac111a1809b4d4b58170b91ad |