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.4.0-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 82f9e214dc6e63a9e3c7d04b4f16dbf71caa603d34ee9cb246559bac484a222a |
|
MD5 | 82e4874c33a15cf855a5108b04e1ba40 |
|
BLAKE2b-256 | 6a698a23fd2046efeb23ec3aa865536e8f26d0eaa3f97ce138c858210ee9b5f1 |
Hashes for PyPartMC-0.4.0-cp311-cp311-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7aba921618162c15d930c6222e4e6ce100f8a368f52ae69b2ca2260897774806 |
|
MD5 | 39b4f0892a4095ce51e143f250d1bc7f |
|
BLAKE2b-256 | dfddacbc55d6b917ffed32120351e4f06a6f99a3f23f1bbd3a898d3d7bff9291 |
Hashes for PyPartMC-0.4.0-cp311-cp311-macosx_12_0_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 52a621e77954b303b92db00b622f64db5027b9749949d9ae823e9a9e3fbfb1f3 |
|
MD5 | 285cb301be09f33d601afcb19f71b7d7 |
|
BLAKE2b-256 | 4b2e3386eb74391e55931aa380e23af7d7e6d9832e84818d86c888c2b2584dba |
Hashes for PyPartMC-0.4.0-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c8484833638b05314139a72c5f8926cd4654c3172be1fe39c07f6637860a6f0b |
|
MD5 | 3f5870fe86e87d2ed9204880a268adb9 |
|
BLAKE2b-256 | e1ad28fcb61d27d87c1f284ee374e65d3e63aee7c6fff93be74bbef350430879 |
Hashes for PyPartMC-0.4.0-cp310-cp310-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ba0648df513f153d32d5fa1e77facb74ab612bba7255b3a0b2b7e5be101aaff8 |
|
MD5 | 2a0335b57cd03c47454df3ced1a7b8e1 |
|
BLAKE2b-256 | b5fc728581249d8b634d6dc7c7f70230a31059ba3b6be7cab5f06143810819db |
Hashes for PyPartMC-0.4.0-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 576b69887c79e7c31d02185f2be40e42b7d1efdf216eceab55f0929518fd0423 |
|
MD5 | 228335a64525250afb826f9f4943c3d5 |
|
BLAKE2b-256 | 6a102c39d7f1a1b62d42bf838ca3523dbebe14182e548abbb45935263b944241 |
Hashes for PyPartMC-0.4.0-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ced078f2196f31efc8a1f6e072dc5e3614a9d775c861f4ebf040d4eb52f3d3a6 |
|
MD5 | 2b661eb363faf733e07ac96564e06227 |
|
BLAKE2b-256 | b5ed7c5ec71031deaab265dd84434dc03ed63993e6566721244efeab604b0be7 |
Hashes for PyPartMC-0.4.0-cp39-cp39-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0f1b48abb5d4df7dc7b0c239a32089201601a73175705786518cebf917f648d1 |
|
MD5 | 161e4ec9f82b30b9763a6bfaff641c09 |
|
BLAKE2b-256 | e57273992f0be3662491d99af9469a5df808973751023f23a5cd1bebd1e92858 |
Hashes for PyPartMC-0.4.0-cp39-cp39-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ebafbaac4091d22e196cec1ba4efd93c8926e786fa3791e1cc9711bd1c32c321 |
|
MD5 | ee2cae01999093f4d8a006b1ae8dfbc0 |
|
BLAKE2b-256 | 5870731fba3638866d81f6b223d81c3529d45c5cfd585c50ddb7899174bf8c4e |
Hashes for PyPartMC-0.4.0-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c492a8315b698cb724053a88be816ae2dbaf3c0b91648dd04e9fe8dfb1372ec2 |
|
MD5 | aa7bc9c2747129ccb76988ad6d10e087 |
|
BLAKE2b-256 | 0b214eb30f247cd932961617e31ba25ca69da142a31eb108249f54da88a5bb81 |
Hashes for PyPartMC-0.4.0-cp38-cp38-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d88030e4a12624ee3cb92e8c6a0667ca2e2a3ef9e45c4cf5868e8adcf55bbb58 |
|
MD5 | 3b6406cbdd39b5ee6a4050ec912f1cd0 |
|
BLAKE2b-256 | da1c4195f6a50cbf61f3fcbb56db650e5c5db83c4f0c6f0556ff6371da272a17 |
Hashes for PyPartMC-0.4.0-cp38-cp38-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1e43b74803ffb7b2a7839d71336383211b1574cd5c5fcc44b34271947d2b0ae1 |
|
MD5 | 2bb7409fd87cf90bc962221b2266b036 |
|
BLAKE2b-256 | 240a21186b7a798a63fbaf2aca565510dfe5114f6d9c1b1d44f570ac5bcef081 |
Hashes for PyPartMC-0.4.0-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5c14b42a07011fb6de85b46d712c3ba75cae939ce7aeb3363b57d519f6832022 |
|
MD5 | d8177a4dab0b61fec2f234638b875729 |
|
BLAKE2b-256 | db2c24295a5e33d833000af0dcafe33607bc2b21341186ca0f2116ce86d8daf2 |
Hashes for PyPartMC-0.4.0-cp37-cp37m-manylinux_2_24_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fbb549bda66285b1fcb7b3b386b8cecf54ea33083ad116d24dd76f083470289c |
|
MD5 | be40e3431d06fe76924c29605137d177 |
|
BLAKE2b-256 | b7dfa4cafe4777caa9b9e2000579516da8b12b770179bbf735818140cb496d3c |
Hashes for PyPartMC-0.4.0-cp37-cp37m-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 24a30c8b55205b2f5a80f30634148e06f8f615afdaec2e9bbdab9d644212e665 |
|
MD5 | 777830d083122cac37fbadb06c9320c2 |
|
BLAKE2b-256 | cb4ef720001422174ad0437689eda96b05363e2c6e2b56d0e21414eff16dab66 |