rdkit-dof 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.
@@ -0,0 +1,78 @@
1
+ name: Build, Test, and Deploy
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ release:
11
+ types: [published]
12
+
13
+ jobs:
14
+ # ===========================================================================
15
+ # 1. 构建与测试 (Matrix 测试多系统多版本)
16
+ # ===========================================================================
17
+ build-and-test:
18
+ name: Test on ${{ matrix.os }} (Py ${{ matrix.python-version }})
19
+ runs-on: ${{ matrix.os }}
20
+ strategy:
21
+ fail-fast: false # 如果一个版本失败,不要立即取消其他测试
22
+ matrix:
23
+ os: [ubuntu-latest, macos-latest, windows-latest]
24
+ python-version: ["3.9", "3.10", "3.11"]
25
+
26
+ steps:
27
+ - name: Checkout code
28
+ uses: actions/checkout@v4
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v3
32
+ with:
33
+ enable-cache: true
34
+ cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
35
+
36
+ - name: Set up Python ${{ matrix.python-version }}
37
+ run: uv python install ${{ matrix.python-version }}
38
+
39
+ - name: Install dependencies
40
+ run: uv sync --all-extras --dev
41
+
42
+ - name: Run tests
43
+ run: uv run pytest
44
+
45
+ # ===========================================================================
46
+ # 2. 部署到 PyPI (仅在 Release 发布时运行)
47
+ # ===========================================================================
48
+ deploy:
49
+ name: Deploy to PyPI
50
+ runs-on: ubuntu-latest
51
+ needs: build-and-test
52
+ if: github.event_name == 'release' && github.event.action == 'published'
53
+
54
+ environment:
55
+ name: pypi
56
+ url: https://pypi.org/p/rdkit-dof
57
+
58
+ permissions:
59
+ id-token: write
60
+ contents: write
61
+
62
+ steps:
63
+ - name: Checkout code
64
+ uses: actions/checkout@v4
65
+
66
+ - name: Install uv
67
+ uses: astral-sh/setup-uv@v3
68
+
69
+ - name: Build distributions
70
+ run: uv build
71
+
72
+ - name: Publish to PyPI
73
+ run: uv publish
74
+
75
+ - name: Upload artifacts to GitHub Release
76
+ uses: softprops/action-gh-release@v2
77
+ with:
78
+ files: dist/*
@@ -0,0 +1,273 @@
1
+ # ---> JupyterNotebooks
2
+ # gitignore template for Jupyter Notebooks
3
+ # website: http://jupyter.org/
4
+
5
+ .ipynb_checkpoints
6
+ */.ipynb_checkpoints/*
7
+
8
+ # IPython
9
+ profile_default/
10
+ ipython_config.py
11
+
12
+ # Remove previous ipynb_checkpoints
13
+ # git rm -r .ipynb_checkpoints/
14
+
15
+ # ---> Python
16
+ # Byte-compiled / optimized / DLL files
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+
21
+ # C extensions
22
+ *.so
23
+
24
+ # Distribution / packaging
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ downloads/
30
+ eggs/
31
+ .eggs/
32
+ lib/
33
+ lib64/
34
+ parts/
35
+ sdist/
36
+ var/
37
+ wheels/
38
+ share/python-wheels/
39
+ *.egg-info/
40
+ .installed.cfg
41
+ *.egg
42
+ MANIFEST
43
+
44
+ # PyInstaller
45
+ # Usually these files are written by a python script from a template
46
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
47
+ *.manifest
48
+ *.spec
49
+
50
+ # Installer logs
51
+ pip-log.txt
52
+ pip-delete-this-directory.txt
53
+
54
+ # Unit test / coverage reports
55
+ htmlcov/
56
+ .tox/
57
+ .nox/
58
+ .coverage
59
+ .coverage.*
60
+ .cache
61
+ nosetests.xml
62
+ coverage.xml
63
+ *.cover
64
+ *.py,cover
65
+ .hypothesis/
66
+ .pytest_cache/
67
+ cover/
68
+
69
+ # Translations
70
+ *.mo
71
+ *.pot
72
+
73
+ # Django stuff:
74
+ *.log
75
+ local_settings.py
76
+ db.sqlite3
77
+ db.sqlite3-journal
78
+
79
+ # Flask stuff:
80
+ instance/
81
+ .webassets-cache
82
+
83
+ # Scrapy stuff:
84
+ .scrapy
85
+
86
+ # Sphinx documentation
87
+ docs/_build/
88
+
89
+ # PyBuilder
90
+ .pybuilder/
91
+ target/
92
+
93
+ # Jupyter Notebook
94
+ .ipynb_checkpoints
95
+
96
+ # IPython
97
+ profile_default/
98
+ ipython_config.py
99
+
100
+ # pyenv
101
+ # For a library or package, you might want to ignore these files since the code is
102
+ # intended to run in multiple environments; otherwise, check them in:
103
+ # .python-version
104
+
105
+ # pipenv
106
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
107
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
108
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
109
+ # install all needed dependencies.
110
+ #Pipfile.lock
111
+
112
+ # UV
113
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
114
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
115
+ # commonly ignored for libraries.
116
+ #uv.lock
117
+
118
+ # poetry
119
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
120
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
121
+ # commonly ignored for libraries.
122
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
123
+ #poetry.lock
124
+
125
+ # pdm
126
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
127
+ #pdm.lock
128
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
129
+ # in version control.
130
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
131
+ .pdm.toml
132
+ .pdm-python
133
+ .pdm-build/
134
+
135
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
136
+ __pypackages__/
137
+
138
+ # Celery stuff
139
+ celerybeat-schedule
140
+ celerybeat.pid
141
+
142
+ # SageMath parsed files
143
+ *.sage.py
144
+
145
+ # Environments
146
+ .env
147
+ .venv
148
+ env/
149
+ venv/
150
+ ENV/
151
+ env.bak/
152
+ venv.bak/
153
+
154
+ # Spyder project settings
155
+ .spyderproject
156
+ .spyproject
157
+
158
+ # Rope project settings
159
+ .ropeproject
160
+
161
+ # mkdocs documentation
162
+ /site
163
+
164
+ # mypy
165
+ .mypy_cache/
166
+ .dmypy.json
167
+ dmypy.json
168
+
169
+ # Pyre type checker
170
+ .pyre/
171
+
172
+ # pytype static type analyzer
173
+ .pytype/
174
+
175
+ # Cython debug symbols
176
+ cython_debug/
177
+
178
+ # PyCharm
179
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
180
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
181
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
182
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
183
+ #.idea/
184
+
185
+ # Ruff stuff:
186
+ .ruff_cache/
187
+
188
+ # PyPI configuration file
189
+ .pypirc
190
+
191
+ # ---> VisualStudioCode
192
+ .vscode/*
193
+ !.vscode/settings.json
194
+ !.vscode/tasks.json
195
+ !.vscode/launch.json
196
+ !.vscode/extensions.json
197
+ !.vscode/*.code-snippets
198
+
199
+ # Local History for Visual Studio Code
200
+ .history/
201
+
202
+ # Built Visual Studio Code Extensions
203
+ *.vsix
204
+
205
+ # ---> Windows
206
+ # Windows thumbnail cache files
207
+ Thumbs.db
208
+ Thumbs.db:encryptable
209
+ ehthumbs.db
210
+ ehthumbs_vista.db
211
+
212
+ # Dump file
213
+ *.stackdump
214
+
215
+ # Folder config file
216
+ [Dd]esktop.ini
217
+
218
+ # Recycle Bin used on file shares
219
+ $RECYCLE.BIN/
220
+
221
+ # Windows Installer files
222
+ *.cab
223
+ *.msi
224
+ *.msix
225
+ *.msm
226
+ *.msp
227
+
228
+ # Windows shortcuts
229
+ *.lnk
230
+
231
+ # ---> Linux
232
+ *~
233
+
234
+ # temporary files which can be created if a process still has a handle open of a deleted file
235
+ .fuse_hidden*
236
+
237
+ # KDE directory preferences
238
+ .directory
239
+
240
+ # Linux trash folder which might appear on any partition or disk
241
+ .Trash-*
242
+
243
+ # .nfs files are created when an open file is removed but is still being accessed
244
+ .nfs*
245
+
246
+ # ---> macOS
247
+ # General
248
+ .DS_Store
249
+ .AppleDouble
250
+ .LSOverride
251
+
252
+ # Icon must end with two \r
253
+ Icon
254
+
255
+ # Thumbnails
256
+ ._*
257
+
258
+ # Files that might appear in the root of a volume
259
+ .DocumentRevisions-V100
260
+ .fseventsd
261
+ .Spotlight-V100
262
+ .TemporaryItems
263
+ .Trashes
264
+ .VolumeIcon.icns
265
+ .com.apple.timemachine.donotpresent
266
+
267
+ # Directories potentially created on remote AFP share
268
+ .AppleDB
269
+ .AppleDesktop
270
+ Network Trash Folder
271
+ Temporary Items
272
+ .apdisk
273
+
@@ -0,0 +1 @@
1
+ 3.9
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tmj
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.4
2
+ Name: rdkit-dof
3
+ Version: 0.1.0
4
+ Summary: RDKit molecule drawing with Depth of Field (DOF) effects.
5
+ Project-URL: Homepage, https://github.com/gentle1999/rdkit-dof
6
+ Project-URL: Bug Tracker, https://github.com/gentle1999/rdkit-dof/issues
7
+ Project-URL: Repository, https://github.com/gentle1999/rdkit-dof.git
8
+ Author-email: Miao-Jiong Tang <mj_t@zju.edu.cn>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: DOF,cheminformatics,chemistry,drawing,molecule,rdkit,visualization
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
22
+ Classifier: Topic :: Scientific/Engineering :: Visualization
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: pydantic-settings>=2.11.0
26
+ Requires-Dist: pydantic>=2.12.5
27
+ Requires-Dist: rdkit>=2023.9.6
28
+ Description-Content-Type: text/markdown
29
+
30
+ # rdkit-dof
31
+
32
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
33
+
34
+ [简体中文](README_zh.md)
35
+
36
+ `rdkit-dof` is a Python toolkit that uses RDKit to generate beautiful 2D images of molecules with a "Depth of Field" (DOF) or "fog" effect. Based on the molecule's 3D conformation, atoms and bonds farther from the viewer are drawn with higher transparency and lower saturation, creating a sense of visual depth in the 2D image.
37
+
38
+ ## Comparison
39
+
40
+ To better showcase the effect of `rdkit-dof`, we have compared it with RDKit's default drawing function.
41
+
42
+ ### Single Molecule Comparison
43
+
44
+ | Default RDKit | rdkit-dof Effect |
45
+ | :---------------------------------------------------------: | :-------------------------------------------------: |
46
+ | ![Paclitaxel Default](assets/comparison_single_default.svg) | ![Paclitaxel DOF](assets/comparison_single_dof.svg) |
47
+
48
+ ### Grid Mode Comparison
49
+
50
+ | Default RDKit | rdkit-dof Effect |
51
+ | :-------------------------------------------------: | :-----------------------------------------: |
52
+ | ![Grid Default](assets/comparison_grid_default.svg) | ![Grid DOF](assets/comparison_grid_dof.svg) |
53
+
54
+ ## Tech Stack
55
+
56
+ - **Core:** Python 3.9+
57
+ - **Cheminformatics:** RDKit
58
+ - **Image Processing:** Pillow
59
+ - **Configuration:** Pydantic
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install rdkit-dof
65
+ ```
66
+
67
+ ## Usage
68
+
69
+ Here is a basic example of how to generate an image with a depth-of-field effect for a molecule.
70
+
71
+ ```python
72
+ from rdkit import Chem
73
+ from rdkit.Chem.rdDistGeom import EmbedMolecule
74
+ from rdkit.Chem.rdForceFieldHelpers import MMFFOptimizeMolecule
75
+ from rdkit_dof import MolToDofImage, dofconfig
76
+
77
+ # 1. Create an RDKit molecule object and generate a 3D conformation
78
+ smiles = "CC1=C2[C@@]([C@]([C@H]([C@@H]3[C@]4([C@H](OC4)C[C@@H]([C@]3(C(=O)[C@@H]2OC(=O)C)C)O)OC(=O)C)OC(=O)c5ccccc5)(C[C@@H]1OC(=O)[C@H](O)[C@@H](NC(=O)c6ccccc6)c7ccccc7)C)C"
79
+ mol = Chem.MolFromSmiles(smiles)
80
+ mol = Chem.AddHs(mol)
81
+ EmbedMolecule(mol, randomSeed=42)
82
+ MMFFOptimizeMolecule(mol)
83
+
84
+ # 2. (Optional) Switch to a preset theme
85
+ dofconfig.use_style("default")
86
+
87
+ # 3. Call the core function to generate the image (returns SVG text)
88
+ svg_data = MolToDofImage(
89
+ mol,
90
+ size=(1000, 800),
91
+ legend="Paclitaxel (Taxol)",
92
+ use_svg=True,
93
+ return_image=False, # Set to False to get raw data (str or bytes)
94
+ )
95
+
96
+ # 4. Save to a file
97
+ with open("paclitaxel.svg", "w") as f:
98
+ f.write(svg_data)
99
+
100
+ print("Image saved to paclitaxel.svg")
101
+
102
+ # 5. (Optional) Display the image (in a Jupyter Notebook)
103
+ svg_img = MolToDofImage(
104
+ mol,
105
+ size=(1000, 800),
106
+ legend="Paclitaxel (Taxol)",
107
+ use_svg=True,
108
+ return_image=True, # Set to True to get an IPython/Pillow image object
109
+ )
110
+ svg_img # Display the image
111
+ ```
112
+
113
+ ## API
114
+
115
+ This toolkit provides two core drawing functions:
116
+
117
+ ### `MolToDofImage`
118
+
119
+ Generates a DOF image for a single molecule.
120
+
121
+ ```python
122
+ MolToDofImage(
123
+ mol: Chem.Mol,
124
+ size: Optional[tuple[int, int]] = None,
125
+ legend: str = "",
126
+ use_svg: bool = True,
127
+ return_image: bool = True,
128
+ *,
129
+ settings: Optional[DofDrawSettings] = None,
130
+ **kwargs: Any,
131
+ ) -> Union["SVG", str, Image.Image, bytes]
132
+ ```
133
+
134
+ - **`mol`**: RDKit molecule object, which must contain a 3D conformation.
135
+ - **`size`**: Image dimensions `(width, height)`.
136
+ - **`legend`**: Legend text below the image.
137
+ - **`use_svg`**: `True` returns SVG, `False` returns PNG.
138
+ - **`return_image`**: `True` returns an IPython/Pillow image object, `False` returns raw data (string for SVG, bytes for PNG).
139
+ - **`settings`**: A `DofDrawSettings` instance for local configuration.
140
+ - **`**kwargs`**: Other RDKit `MolDrawOptions` parameters.
141
+
142
+ ### `MolGridToDofImage`
143
+
144
+ Generates a DOF image for a grid of molecules, with parameters similar to RDKit's `MolsToGridImage`.
145
+
146
+ ```python
147
+ MolGridToDofImage(
148
+ mols: Sequence[Union[Chem.Mol, Chem.RWMol, None]],
149
+ molsPerRow: int = 3,
150
+ subImgSize: tuple[int, int] = (300, 300),
151
+ legends: Optional[Sequence[Union[str, None]]] = None,
152
+ use_svg: bool = True,
153
+ return_image: bool = True,
154
+ *,
155
+ settings: Optional[DofDrawSettings] = None,
156
+ **kwargs: Any,
157
+ ) -> Union["SVG", str, Image.Image, bytes]
158
+ ```
159
+
160
+ ## Configuration
161
+
162
+ You can customize the drawing style via a global `dofconfig` object or environment variables (`.env`).
163
+
164
+ ### Global Config Object
165
+
166
+ Modify the properties of the `rdkit_dof.dofconfig` object directly in your code.
167
+
168
+ ```python
169
+ from rdkit_dof import dofconfig
170
+
171
+ # Use a preset style
172
+ dofconfig.use_style("nature") # Options: 'default', 'nature', 'jacs', 'dark'
173
+
174
+ # Customize colors and effects
175
+ dofconfig.fog_color = (0.1, 0.1, 0.1) # Background fog color (RGB, 0-1)
176
+ dofconfig.min_alpha = 0.3 # Minimum alpha for the farthest atoms
177
+ dofconfig.default_size = (500, 500) # Default image size
178
+
179
+ # Override colors for specific atoms (atomic number -> RGB)
180
+ dofconfig.atom_colors[8] = (1.0, 0.2, 0.2) # Set Oxygen to bright red
181
+ ```
182
+
183
+ ### Environment Variables
184
+
185
+ You can also customize the drawing style by setting environment variables. All configuration properties have a corresponding environment variable, named `MOL_DOF_` plus the property name (in upper snake case).
186
+
187
+ For example, to set `fog_color` to dark gray (RGB 0.1, 0.1, 0.1) and `min_alpha` to 0.2, you can add this to your `.env` file:
188
+
189
+ ```env
190
+ # Set fog color to dark gray
191
+ MOL_DOF_FOG_COLOR=[0.1, 0.1, 0.1]
192
+ # Adjust minimum alpha
193
+ MOL_DOF_MIN_ALPHA=0.2
194
+ ```
195
+
196
+ ### Main Configuration Properties
197
+
198
+ | Property | Description | Default (Light Theme) |
199
+ | ---------------- | -------------------------------------------------------- | ----------------------- |
200
+ | `preset_style` | Name of the preset style | `"default"` |
201
+ | `fog_color` | Fog/background color (RGB, 0-1) | `(0.95, 0.95, 0.95)` |
202
+ | `min_alpha` | Minimum alpha for the farthest atoms | `0.4` |
203
+ | `default_size` | Default image size `(width, height)` for `MolToDofImage` | `(800, 800)` |
204
+ | `enable_ipython` | Whether to enable IPython image display | `True` |
205
+ | `atom_colors` | Atom color map `(dict[int, tuple])` | Based on `preset_style` |
206
+
207
+ ## Running the Examples
208
+
209
+ The script `scripts/_generate_comparison_images.py` is a complete example for generating all the images in this document. You can run it to reproduce them:
210
+
211
+ ```bash
212
+ # Generate comparison images
213
+ python scripts/_generate_comparison_images.py
214
+ ```
215
+
216
+ ## Compatibility
217
+
218
+ - **OS:** This project is OS-independent and runs on Linux, macOS, and Windows.
219
+ - **Python Version:** Requires Python 3.9 or higher.
220
+ - **RDKit Version:** Recommended to use `2023.09` or higher.
221
+
222
+ ## Contribution Guide
223
+
224
+ Contributions of any kind are welcome!
225
+
226
+ 1. Fork the repository.
227
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`).
228
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`).
229
+ 4. Push to the branch (`git push origin feature/AmazingFeature`).
230
+ 5. Open a Pull Request.
231
+
232
+ ## License
233
+
234
+ This project is distributed under the MIT License. See the [LICENSE](LICENSE) file for details.