pdbrust 0.7.1__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.
Files changed (207) hide show
  1. pdbrust-0.7.1/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
  2. pdbrust-0.7.1/.github/ISSUE_TEMPLATE/feature_request.md +41 -0
  3. pdbrust-0.7.1/.github/dependabot.yml +22 -0
  4. pdbrust-0.7.1/.github/workflows/python-publish.yml +211 -0
  5. pdbrust-0.7.1/.github/workflows/rust.yml +217 -0
  6. pdbrust-0.7.1/.gitignore +21 -0
  7. pdbrust-0.7.1/.zenodo.json +53 -0
  8. pdbrust-0.7.1/CHANGELOG.md +366 -0
  9. pdbrust-0.7.1/CITATION.cff +37 -0
  10. pdbrust-0.7.1/CLAUDE.md +858 -0
  11. pdbrust-0.7.1/CONTRIBUTORS.md +7 -0
  12. pdbrust-0.7.1/Cargo.lock +2534 -0
  13. pdbrust-0.7.1/Cargo.toml +88 -0
  14. pdbrust-0.7.1/LICENSE +21 -0
  15. pdbrust-0.7.1/PKG-INFO +390 -0
  16. pdbrust-0.7.1/README.md +677 -0
  17. pdbrust-0.7.1/ROADMAP.md +339 -0
  18. pdbrust-0.7.1/SECURITY.md +30 -0
  19. pdbrust-0.7.1/assets/banner.png +0 -0
  20. pdbrust-0.7.1/benches/parsing_benchmark.rs +136 -0
  21. pdbrust-0.7.1/benchmark_results/benchmark_report.txt +60 -0
  22. pdbrust-0.7.1/benchmark_results/failures.tsv +1 -0
  23. pdbrust-0.7.1/benchmark_results/timing_histogram.txt +15 -0
  24. pdbrust-0.7.1/benchmarks/python_benchmark.py +123 -0
  25. pdbrust-0.7.1/benchmarks/rust_benchmark.rs +137 -0
  26. pdbrust-0.7.1/codecov.yml +11 -0
  27. pdbrust-0.7.1/docs/GETTING_STARTED.md +470 -0
  28. pdbrust-0.7.1/examples/analysis_workflow.rs +151 -0
  29. pdbrust-0.7.1/examples/async_download_demo.rs +269 -0
  30. pdbrust-0.7.1/examples/atom_interactive.rs +101 -0
  31. pdbrust-0.7.1/examples/b_factor_demo.rs +222 -0
  32. pdbrust-0.7.1/examples/basic_usage.rs +73 -0
  33. pdbrust-0.7.1/examples/batch_processing.rs +197 -0
  34. pdbrust-0.7.1/examples/dockq_demo.rs +193 -0
  35. pdbrust-0.7.1/examples/dockq_detailed_comparison.rs +319 -0
  36. pdbrust-0.7.1/examples/dockq_validation.rs +262 -0
  37. pdbrust-0.7.1/examples/filtering_demo.rs +155 -0
  38. pdbrust-0.7.1/examples/full_pdb_benchmark.rs +806 -0
  39. pdbrust-0.7.1/examples/geometry_demo.rs +167 -0
  40. pdbrust-0.7.1/examples/lddt_demo.rs +220 -0
  41. pdbrust-0.7.1/examples/ligand_quality_demo.rs +292 -0
  42. pdbrust-0.7.1/examples/pdb_files/1CRN.cif +1654 -0
  43. pdbrust-0.7.1/examples/pdb_files/1HSG.pdb +2075 -0
  44. pdbrust-0.7.1/examples/pdb_files/1L2Y.pdb +11842 -0
  45. pdbrust-0.7.1/examples/pdb_files/1UBQ.pdb +970 -0
  46. pdbrust-0.7.1/examples/pdb_files/2GB1.cif +2173 -0
  47. pdbrust-0.7.1/examples/pdb_files/5HH6.cif +7466 -0
  48. pdbrust-0.7.1/examples/pdb_files/8HM2.pdb +1698 -0
  49. pdbrust-0.7.1/examples/pdb_files/AF-P62987-F1.pdb +1089 -0
  50. pdbrust-0.7.1/examples/pdb_files/multi_model.pdb +19 -0
  51. pdbrust-0.7.1/examples/pdb_files/test.pdb +24 -0
  52. pdbrust-0.7.1/examples/rcsb_workflow.rs +202 -0
  53. pdbrust-0.7.1/examples/read_pdb.rs +76 -0
  54. pdbrust-0.7.1/examples/rust_benchmark.rs +169 -0
  55. pdbrust-0.7.1/examples/secondary_structure_demo.rs +244 -0
  56. pdbrust-0.7.1/examples/selection_demo.rs +198 -0
  57. pdbrust-0.7.1/examples/validate_new_files.rs +325 -0
  58. pdbrust-0.7.1/examples/write_pdb.rs +149 -0
  59. pdbrust-0.7.1/pdbrust-python/Cargo.toml +42 -0
  60. pdbrust-0.7.1/pdbrust-python/README.md +358 -0
  61. pdbrust-0.7.1/pdbrust-python/examples/advanced_filtering.py +347 -0
  62. pdbrust-0.7.1/pdbrust-python/examples/alphafold_analysis.py +203 -0
  63. pdbrust-0.7.1/pdbrust-python/examples/b_factor_analysis.py +240 -0
  64. pdbrust-0.7.1/pdbrust-python/examples/basic_usage.py +162 -0
  65. pdbrust-0.7.1/pdbrust-python/examples/batch_processing.py +295 -0
  66. pdbrust-0.7.1/pdbrust-python/examples/dockq_demo.py +109 -0
  67. pdbrust-0.7.1/pdbrust-python/examples/geometry_rmsd.py +154 -0
  68. pdbrust-0.7.1/pdbrust-python/examples/lddt_demo.py +159 -0
  69. pdbrust-0.7.1/pdbrust-python/examples/ligand_interactions.py +266 -0
  70. pdbrust-0.7.1/pdbrust-python/examples/numpy_integration.py +171 -0
  71. pdbrust-0.7.1/pdbrust-python/examples/quality_and_summary.py +277 -0
  72. pdbrust-0.7.1/pdbrust-python/examples/ramachandran_analysis.py +235 -0
  73. pdbrust-0.7.1/pdbrust-python/examples/rcsb_search.py +229 -0
  74. pdbrust-0.7.1/pdbrust-python/examples/secondary_structure.py +256 -0
  75. pdbrust-0.7.1/pdbrust-python/examples/selection_language.py +239 -0
  76. pdbrust-0.7.1/pdbrust-python/examples/writing_files.py +146 -0
  77. pdbrust-0.7.1/pdbrust-python/src/atom.rs +218 -0
  78. pdbrust-0.7.1/pdbrust-python/src/descriptors.rs +1318 -0
  79. pdbrust-0.7.1/pdbrust-python/src/dockq.rs +465 -0
  80. pdbrust-0.7.1/pdbrust-python/src/dssp.rs +385 -0
  81. pdbrust-0.7.1/pdbrust-python/src/error.rs +91 -0
  82. pdbrust-0.7.1/pdbrust-python/src/geometry.rs +413 -0
  83. pdbrust-0.7.1/pdbrust-python/src/inventory.rs +267 -0
  84. pdbrust-0.7.1/pdbrust-python/src/lib.rs +183 -0
  85. pdbrust-0.7.1/pdbrust-python/src/ligand_quality.rs +282 -0
  86. pdbrust-0.7.1/pdbrust-python/src/numpy_support.rs +117 -0
  87. pdbrust-0.7.1/pdbrust-python/src/parsing.rs +225 -0
  88. pdbrust-0.7.1/pdbrust-python/src/quality.rs +187 -0
  89. pdbrust-0.7.1/pdbrust-python/src/rcsb.rs +564 -0
  90. pdbrust-0.7.1/pdbrust-python/src/records.rs +309 -0
  91. pdbrust-0.7.1/pdbrust-python/src/structure.rs +1535 -0
  92. pdbrust-0.7.1/pdbrust-python/src/summary.rs +268 -0
  93. pdbrust-0.7.1/pdbrust-python/tests/test_paths_and_errors.py +77 -0
  94. pdbrust-0.7.1/pdbrust-python/tests/test_rcsb.py +60 -0
  95. pdbrust-0.7.1/pdbrust-python/tests/test_writer_interop.py +124 -0
  96. pdbrust-0.7.1/pyproject.toml +44 -0
  97. pdbrust-0.7.1/python/pdbrust/__init__.py +212 -0
  98. pdbrust-0.7.1/python/pdbrust/py.typed +1 -0
  99. pdbrust-0.7.1/src/classify.rs +165 -0
  100. pdbrust-0.7.1/src/core/mmcif.rs +314 -0
  101. pdbrust-0.7.1/src/core/mmcif_converter.rs +594 -0
  102. pdbrust-0.7.1/src/core/mod.rs +64 -0
  103. pdbrust-0.7.1/src/core/pdb.rs +612 -0
  104. pdbrust-0.7.1/src/descriptors/alphafold.rs +583 -0
  105. pdbrust-0.7.1/src/descriptors/bfactor.rs +625 -0
  106. pdbrust-0.7.1/src/descriptors/composition.rs +444 -0
  107. pdbrust-0.7.1/src/descriptors/dihedrals.rs +650 -0
  108. pdbrust-0.7.1/src/descriptors/distance.rs +509 -0
  109. pdbrust-0.7.1/src/descriptors/geometry.rs +570 -0
  110. pdbrust-0.7.1/src/descriptors/hbonds.rs +472 -0
  111. pdbrust-0.7.1/src/descriptors/interactions.rs +754 -0
  112. pdbrust-0.7.1/src/descriptors/mod.rs +180 -0
  113. pdbrust-0.7.1/src/dockq/chain_mapping.rs +366 -0
  114. pdbrust-0.7.1/src/dockq/contacts.rs +315 -0
  115. pdbrust-0.7.1/src/dockq/metrics.rs +280 -0
  116. pdbrust-0.7.1/src/dockq/mod.rs +645 -0
  117. pdbrust-0.7.1/src/dockq/sequence_align.rs +244 -0
  118. pdbrust-0.7.1/src/dssp/assignment.rs +372 -0
  119. pdbrust-0.7.1/src/dssp/dihedral.rs +281 -0
  120. pdbrust-0.7.1/src/dssp/hbond.rs +390 -0
  121. pdbrust-0.7.1/src/dssp/mod.rs +338 -0
  122. pdbrust-0.7.1/src/dssp/patterns.rs +539 -0
  123. pdbrust-0.7.1/src/dssp/types.rs +382 -0
  124. pdbrust-0.7.1/src/error.rs +72 -0
  125. pdbrust-0.7.1/src/filter/cleaning.rs +480 -0
  126. pdbrust-0.7.1/src/filter/extraction.rs +677 -0
  127. pdbrust-0.7.1/src/filter/mod.rs +78 -0
  128. pdbrust-0.7.1/src/filter/selection/ast.rs +106 -0
  129. pdbrust-0.7.1/src/filter/selection/error.rs +112 -0
  130. pdbrust-0.7.1/src/filter/selection/evaluator.rs +316 -0
  131. pdbrust-0.7.1/src/filter/selection/lexer.rs +436 -0
  132. pdbrust-0.7.1/src/filter/selection/mod.rs +213 -0
  133. pdbrust-0.7.1/src/filter/selection/parser.rs +446 -0
  134. pdbrust-0.7.1/src/geometry/lddt.rs +736 -0
  135. pdbrust-0.7.1/src/geometry/mod.rs +593 -0
  136. pdbrust-0.7.1/src/geometry/rmsd.rs +284 -0
  137. pdbrust-0.7.1/src/geometry/superposition.rs +595 -0
  138. pdbrust-0.7.1/src/geometry/transform.rs +324 -0
  139. pdbrust-0.7.1/src/guide.rs +881 -0
  140. pdbrust-0.7.1/src/inventory.rs +462 -0
  141. pdbrust-0.7.1/src/lib.rs +350 -0
  142. pdbrust-0.7.1/src/ligand_quality/clash.rs +359 -0
  143. pdbrust-0.7.1/src/ligand_quality/mod.rs +370 -0
  144. pdbrust-0.7.1/src/ligand_quality/overlap.rs +348 -0
  145. pdbrust-0.7.1/src/ligand_quality/radii.rs +339 -0
  146. pdbrust-0.7.1/src/ligand_quality/report.rs +452 -0
  147. pdbrust-0.7.1/src/models.rs +26 -0
  148. pdbrust-0.7.1/src/parser/gzip.rs +232 -0
  149. pdbrust-0.7.1/src/parser/mmcif/mod.rs +21 -0
  150. pdbrust-0.7.1/src/parser/mmcif/parser.rs +347 -0
  151. pdbrust-0.7.1/src/parser/mod.rs +47 -0
  152. pdbrust-0.7.1/src/parser/pdb/mod.rs +3 -0
  153. pdbrust-0.7.1/src/parser/pdb/parser.rs +424 -0
  154. pdbrust-0.7.1/src/quality/mod.rs +617 -0
  155. pdbrust-0.7.1/src/rcsb/async_download.rs +644 -0
  156. pdbrust-0.7.1/src/rcsb/download.rs +330 -0
  157. pdbrust-0.7.1/src/rcsb/mod.rs +104 -0
  158. pdbrust-0.7.1/src/rcsb/search.rs +588 -0
  159. pdbrust-0.7.1/src/records/atom.rs +529 -0
  160. pdbrust-0.7.1/src/records/bonds.rs +30 -0
  161. pdbrust-0.7.1/src/records/chain.rs +256 -0
  162. pdbrust-0.7.1/src/records/conect.rs +16 -0
  163. pdbrust-0.7.1/src/records/mod.rs +20 -0
  164. pdbrust-0.7.1/src/records/model.rs +16 -0
  165. pdbrust-0.7.1/src/records/remark.rs +12 -0
  166. pdbrust-0.7.1/src/records/residue.rs +252 -0
  167. pdbrust-0.7.1/src/records/seqres.rs +193 -0
  168. pdbrust-0.7.1/src/records/ssbond.rs +32 -0
  169. pdbrust-0.7.1/src/summary/mod.rs +507 -0
  170. pdbrust-0.7.1/src/utils.rs +190 -0
  171. pdbrust-0.7.1/src/writer/mod.rs +714 -0
  172. pdbrust-0.7.1/tests/alphafold_tests.rs +236 -0
  173. pdbrust-0.7.1/tests/descriptors_tests.rs +892 -0
  174. pdbrust-0.7.1/tests/dihedral_tests.rs +159 -0
  175. pdbrust-0.7.1/tests/dockq_tests.rs +684 -0
  176. pdbrust-0.7.1/tests/dockq_validation/1A2K.dockq +43 -0
  177. pdbrust-0.7.1/tests/dockq_validation/1A2K_model.pdb +7103 -0
  178. pdbrust-0.7.1/tests/dockq_validation/1A2K_native.pdb +3560 -0
  179. pdbrust-0.7.1/tests/dockq_validation/1EXB.dockq +17 -0
  180. pdbrust-0.7.1/tests/dockq_validation/1EXB_model.pdb +28373 -0
  181. pdbrust-0.7.1/tests/dockq_validation/1EXB_native.pdb +13256 -0
  182. pdbrust-0.7.1/tests/dockq_validation/dimer_dimer.dockq +5 -0
  183. pdbrust-0.7.1/tests/dockq_validation/dimer_model.pdb +6972 -0
  184. pdbrust-0.7.1/tests/dockq_validation/dimer_native.pdb +6972 -0
  185. pdbrust-0.7.1/tests/dockq_validation/model.dockq +25 -0
  186. pdbrust-0.7.1/tests/dockq_validation/model.pdb +4888 -0
  187. pdbrust-0.7.1/tests/dockq_validation/native.pdb +4889 -0
  188. pdbrust-0.7.1/tests/dssp_tests.rs +511 -0
  189. pdbrust-0.7.1/tests/filter_tests.rs +415 -0
  190. pdbrust-0.7.1/tests/geometry_tests.rs +408 -0
  191. pdbrust-0.7.1/tests/hbond_api_tests.rs +155 -0
  192. pdbrust-0.7.1/tests/interaction_tests.rs +259 -0
  193. pdbrust-0.7.1/tests/lddt_tests.rs +458 -0
  194. pdbrust-0.7.1/tests/ligand_quality_tests.rs +542 -0
  195. pdbrust-0.7.1/tests/mmcif_metadata_tests.rs +140 -0
  196. pdbrust-0.7.1/tests/mmcif_tests.rs +896 -0
  197. pdbrust-0.7.1/tests/parsing_tests.rs +664 -0
  198. pdbrust-0.7.1/tests/pdb_parser_robustness_tests.proptest-regressions +7 -0
  199. pdbrust-0.7.1/tests/pdb_parser_robustness_tests.rs +232 -0
  200. pdbrust-0.7.1/tests/property_tests.proptest-regressions +8 -0
  201. pdbrust-0.7.1/tests/property_tests.rs +266 -0
  202. pdbrust-0.7.1/tests/quality_tests.rs +306 -0
  203. pdbrust-0.7.1/tests/rcsb_async_tests.rs +312 -0
  204. pdbrust-0.7.1/tests/rcsb_tests.rs +306 -0
  205. pdbrust-0.7.1/tests/selection_tests.rs +443 -0
  206. pdbrust-0.7.1/tests/summary_tests.rs +322 -0
  207. pdbrust-0.7.1/tests/writer_tests.rs +430 -0
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: 'bug'
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Load a PDB file with '...'
16
+ 2. Call function '....'
17
+ 3. See error
18
+
19
+ **Expected behavior**
20
+ A clear and concise description of what you expected to happen.
21
+
22
+ **PDB File**
23
+ If applicable, please share the relevant PDB file or a minimal example that reproduces the issue.
24
+
25
+ **Environment:**
26
+ - OS: [e.g. Ubuntu 22.04]
27
+ - Rust version: [e.g. 1.70.0]
28
+ - PDBRust version: [e.g. 0.1.0]
29
+ - Features enabled: [e.g. parallel, geometry]
30
+
31
+ **Additional context**
32
+ Add any other context about the problem here.
33
+
34
+ **Error message**
35
+ If applicable, please share the complete error message.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest an idea for this project
4
+ title: '[FEATURE] '
5
+ labels: enhancement
6
+ assignees: ''
7
+ ---
8
+
9
+ **Is your feature request related to a problem? Please describe.**
10
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11
+
12
+ **Describe the solution you'd like**
13
+ A clear and concise description of what you want to happen.
14
+
15
+ **Describe alternatives you've considered**
16
+ A clear and concise description of any alternative solutions or features you've considered.
17
+
18
+ **Implementation Details**
19
+ If you have a specific implementation in mind, please describe it here.
20
+
21
+ **Additional context**
22
+ Add any other context or screenshots about the feature request here.
23
+
24
+ **Technical Considerations**
25
+ - [ ] Does this feature require changes to the public API?
26
+ - [ ] Does this feature require changes to the data structures?
27
+ - [ ] Does this feature require changes to the documentation?
28
+ - [ ] Does this feature require new dependencies?
29
+
30
+ **Priority**
31
+ Please indicate the priority of this feature:
32
+ - [ ] High (Critical for project success)
33
+ - [ ] Medium (Important but not blocking)
34
+ - [ ] Low (Nice to have)
35
+
36
+ **Impact**
37
+ Please describe the impact this feature will have on:
38
+ - Performance
39
+ - User experience
40
+ - Code maintainability
41
+ - Other aspects of the project
@@ -0,0 +1,22 @@
1
+ version: 2
2
+ updates:
3
+ # Enable version updates for Rust
4
+ - package-ecosystem: "cargo"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ day: "monday"
9
+ open-pull-requests-limit: 10
10
+ labels:
11
+ - "dependencies"
12
+ commit-message:
13
+ prefix: "chore"
14
+ include: "scope"
15
+ groups:
16
+ dependencies:
17
+ patterns:
18
+ - "*"
19
+ ignore:
20
+ # Ignore major version updates for now
21
+ - dependency-name: "*"
22
+ update-types: ["version-update:semver-major"]
@@ -0,0 +1,211 @@
1
+ name: Python Wheels
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ pull_request:
8
+ paths:
9
+ - 'pdbrust-python/**'
10
+ - '.github/workflows/python-publish.yml'
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ # Build wheels for Linux
18
+ linux:
19
+ runs-on: ${{ matrix.runner }}
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ include:
24
+ - target: x86_64
25
+ runner: ubuntu-latest
26
+ # Built natively: the manylinux2014 cross-compiler for aarch64 cannot
27
+ # assemble ring's ARM code (needed for rustls).
28
+ - target: aarch64
29
+ runner: ubuntu-24.04-arm
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+
33
+ - uses: actions/setup-python@v5
34
+ with:
35
+ python-version: '3.12'
36
+
37
+ - name: Build wheels
38
+ uses: PyO3/maturin-action@v1
39
+ with:
40
+ target: ${{ matrix.target }}
41
+ args: --release --out dist -i 3.10 3.11 3.12 3.13 3.14 --manifest-path pdbrust-python/Cargo.toml --features full
42
+ sccache: 'true'
43
+ manylinux: auto
44
+
45
+ # Wheels must install only the pdbrust package (no stray top-level files
46
+ # in site-packages).
47
+ - name: Check wheel contents
48
+ shell: bash
49
+ run: |
50
+ python - <<'EOF'
51
+ import glob, sys, zipfile
52
+ wheels = glob.glob("dist/*.whl")
53
+ if not wheels:
54
+ sys.exit("no wheels found in dist/")
55
+ for wheel in wheels:
56
+ names = zipfile.ZipFile(wheel).namelist()
57
+ stray = [n for n in names if not n.startswith(("pdbrust/", "pdbrust-"))]
58
+ if stray:
59
+ sys.exit(f"{wheel} installs files outside the pdbrust package: {stray}")
60
+ print(f"{len(wheels)} wheel(s) contain only the pdbrust package")
61
+ EOF
62
+
63
+ - name: Upload wheels
64
+ uses: actions/upload-artifact@v4
65
+ with:
66
+ name: wheels-linux-${{ matrix.target }}
67
+ path: dist
68
+
69
+ # Build wheels for macOS (full features including RCSB)
70
+ macos:
71
+ runs-on: macos-latest
72
+ strategy:
73
+ matrix:
74
+ target: [x86_64, aarch64]
75
+ steps:
76
+ - uses: actions/checkout@v4
77
+
78
+ - uses: actions/setup-python@v5
79
+ with:
80
+ python-version: '3.12'
81
+
82
+ - name: Build wheels
83
+ uses: PyO3/maturin-action@v1
84
+ with:
85
+ target: ${{ matrix.target }}
86
+ args: --release --out dist -i 3.10 3.11 3.12 3.13 3.14 --manifest-path pdbrust-python/Cargo.toml --features full
87
+ sccache: 'true'
88
+
89
+ # Wheels must install only the pdbrust package (no stray top-level files
90
+ # in site-packages).
91
+ - name: Check wheel contents
92
+ shell: bash
93
+ run: |
94
+ python - <<'EOF'
95
+ import glob, sys, zipfile
96
+ wheels = glob.glob("dist/*.whl")
97
+ if not wheels:
98
+ sys.exit("no wheels found in dist/")
99
+ for wheel in wheels:
100
+ names = zipfile.ZipFile(wheel).namelist()
101
+ stray = [n for n in names if not n.startswith(("pdbrust/", "pdbrust-"))]
102
+ if stray:
103
+ sys.exit(f"{wheel} installs files outside the pdbrust package: {stray}")
104
+ print(f"{len(wheels)} wheel(s) contain only the pdbrust package")
105
+ EOF
106
+
107
+ - name: Upload wheels
108
+ uses: actions/upload-artifact@v4
109
+ with:
110
+ name: wheels-macos-${{ matrix.target }}
111
+ path: dist
112
+
113
+ # Build wheels for Windows (full features including RCSB)
114
+ windows:
115
+ runs-on: windows-latest
116
+ strategy:
117
+ matrix:
118
+ target: [x64]
119
+ steps:
120
+ - uses: actions/checkout@v4
121
+
122
+ - uses: actions/setup-python@v5
123
+ with:
124
+ python-version: '3.12'
125
+ architecture: ${{ matrix.target }}
126
+
127
+ - name: Build wheels
128
+ uses: PyO3/maturin-action@v1
129
+ with:
130
+ target: ${{ matrix.target }}
131
+ args: --release --out dist -i 3.10 3.11 3.12 3.13 3.14 --manifest-path pdbrust-python/Cargo.toml --features full
132
+ sccache: 'true'
133
+
134
+ # Wheels must install only the pdbrust package (no stray top-level files
135
+ # in site-packages).
136
+ - name: Check wheel contents
137
+ shell: bash
138
+ run: |
139
+ python - <<'EOF'
140
+ import glob, sys, zipfile
141
+ wheels = glob.glob("dist/*.whl")
142
+ if not wheels:
143
+ sys.exit("no wheels found in dist/")
144
+ for wheel in wheels:
145
+ names = zipfile.ZipFile(wheel).namelist()
146
+ stray = [n for n in names if not n.startswith(("pdbrust/", "pdbrust-"))]
147
+ if stray:
148
+ sys.exit(f"{wheel} installs files outside the pdbrust package: {stray}")
149
+ print(f"{len(wheels)} wheel(s) contain only the pdbrust package")
150
+ EOF
151
+
152
+ - name: Upload wheels
153
+ uses: actions/upload-artifact@v4
154
+ with:
155
+ name: wheels-windows-${{ matrix.target }}
156
+ path: dist
157
+
158
+ # Build source distribution
159
+ sdist:
160
+ runs-on: ubuntu-latest
161
+ steps:
162
+ - uses: actions/checkout@v4
163
+
164
+ - name: Build sdist
165
+ uses: PyO3/maturin-action@v1
166
+ with:
167
+ command: sdist
168
+ args: --out dist --manifest-path pdbrust-python/Cargo.toml
169
+
170
+ # Users on platforms without a pre-built wheel install from the sdist,
171
+ # so make sure it builds and imports.
172
+ - uses: actions/setup-python@v5
173
+ with:
174
+ python-version: '3.12'
175
+
176
+ - name: Install from the sdist and smoke-test
177
+ run: |
178
+ python -m pip install dist/*.tar.gz
179
+ python -c "import pdbrust; s = pdbrust.parse_pdb_file('examples/pdb_files/1UBQ.pdb'); assert s.num_atoms == 660; print('sdist OK:', s.num_atoms, 'atoms')"
180
+
181
+ - name: Upload sdist
182
+ uses: actions/upload-artifact@v4
183
+ with:
184
+ name: wheels-sdist
185
+ path: dist
186
+ if: success()
187
+
188
+ # Publish to PyPI on tag push
189
+ publish:
190
+ name: Publish to PyPI
191
+ runs-on: ubuntu-latest
192
+ if: startsWith(github.ref, 'refs/tags/v')
193
+ # Wait for the sdist too, so it is always uploaded together with the wheels.
194
+ needs: [linux, macos, windows, sdist]
195
+ permissions:
196
+ id-token: write # For trusted publishing
197
+ steps:
198
+ - name: Download all wheels
199
+ uses: actions/download-artifact@v4
200
+ with:
201
+ pattern: wheels-*
202
+ path: dist
203
+ merge-multiple: true
204
+
205
+ - name: List wheels
206
+ run: ls -la dist/
207
+
208
+ - name: Publish to PyPI
209
+ uses: pypa/gh-action-pypi-publish@release/v1
210
+ with:
211
+ verbose: true
@@ -0,0 +1,217 @@
1
+ name: Rust CI/CD
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+
9
+ env:
10
+ CARGO_TERM_COLOR: always
11
+ RUSTFLAGS: "-D warnings"
12
+
13
+ jobs:
14
+ test:
15
+ name: Test
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ # Let every OS/toolchain combination finish so one failure (or a flaky
19
+ # runner) doesn't hide the results of the others.
20
+ fail-fast: false
21
+ matrix:
22
+ os: [ubuntu-latest, windows-latest, macos-latest]
23
+ rust: [stable, 1.85.0] # Test on both stable and MSRV
24
+ include:
25
+ - os: ubuntu-latest
26
+ rust: stable
27
+ run-coverage: true
28
+ steps:
29
+ - uses: actions/checkout@v5
30
+
31
+ - name: Install Rust toolchain
32
+ uses: dtolnay/rust-toolchain@master
33
+ with:
34
+ toolchain: ${{ matrix.rust }}
35
+
36
+ - name: Cache dependencies
37
+ uses: actions/cache@v5
38
+ with:
39
+ path: |
40
+ ~/.cargo/registry
41
+ ~/.cargo/git
42
+ target
43
+ key: ${{ runner.os }}-cargo-${{ matrix.rust }}-${{ hashFiles('**/Cargo.lock') }}
44
+
45
+ - name: Run tests
46
+ run: cargo test --lib --tests --verbose --package pdbrust
47
+
48
+ - name: Run tests with all features
49
+ run: cargo test --all-features --verbose --package pdbrust
50
+
51
+ lint:
52
+ name: Lint
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/checkout@v5
56
+
57
+ - name: Install Rust toolchain
58
+ uses: dtolnay/rust-toolchain@stable
59
+ with:
60
+ components: clippy, rustfmt
61
+
62
+ - name: Cache dependencies
63
+ uses: actions/cache@v5
64
+ with:
65
+ path: |
66
+ ~/.cargo/registry
67
+ ~/.cargo/git
68
+ target
69
+ key: ${{ runner.os }}-cargo-lint-${{ hashFiles('**/Cargo.lock') }}
70
+
71
+ - name: Clippy check
72
+ run: cargo clippy --all-targets --all-features --package pdbrust
73
+
74
+ - name: Check formatting
75
+ run: cargo fmt --all -- --check
76
+
77
+ features:
78
+ name: Feature combinations
79
+ runs-on: ubuntu-latest
80
+ steps:
81
+ - uses: actions/checkout@v5
82
+
83
+ - name: Install Rust toolchain
84
+ uses: dtolnay/rust-toolchain@stable
85
+
86
+ - name: Install cargo-hack
87
+ uses: taiki-e/install-action@cargo-hack
88
+
89
+ # Users often enable a single feature (e.g. `features = ["geometry"]`);
90
+ # make sure each one compiles on its own without warnings.
91
+ - name: Check each feature individually
92
+ run: cargo hack check --each-feature --package pdbrust
93
+
94
+ python:
95
+ name: Python bindings (${{ matrix.python-version }})
96
+ runs-on: ubuntu-latest
97
+ strategy:
98
+ fail-fast: false
99
+ matrix:
100
+ # Oldest and newest supported Python versions
101
+ python-version: ["3.10", "3.14"]
102
+ env:
103
+ # Build the bindings the same way the release wheels are built
104
+ # (python-publish.yml does not use -D warnings).
105
+ RUSTFLAGS: ""
106
+ steps:
107
+ - uses: actions/checkout@v5
108
+
109
+ - uses: actions/setup-python@v6
110
+ with:
111
+ python-version: ${{ matrix.python-version }}
112
+
113
+ - name: Install Rust toolchain
114
+ uses: dtolnay/rust-toolchain@stable
115
+
116
+ - name: Compile-check all binding features
117
+ run: cargo check --package pdbrust-python --all-features
118
+
119
+ # Same features as the Linux release wheels (see python-publish.yml).
120
+ - name: Build and install the Python package
121
+ run: |
122
+ python -m pip install --upgrade pip maturin
123
+ maturin build --manifest-path pdbrust-python/Cargo.toml --interpreter python --features full --out dist
124
+ python -m pip install dist/*.whl numpy
125
+
126
+ - name: Smoke-test the Python package
127
+ run: |
128
+ python - <<'EOF'
129
+ import pdbrust
130
+
131
+ pdb = pdbrust.parse_pdb_file("examples/pdb_files/1UBQ.pdb")
132
+ cif = pdbrust.parse_mmcif_file("examples/pdb_files/1CRN.cif")
133
+ for s in (pdb, cif):
134
+ assert s.num_atoms > 0
135
+ assert s.get_coords_array().shape == (s.num_atoms, 3)
136
+
137
+ print(f"1UBQ: {pdb.num_atoms} atoms, {pdb.num_chains} chain(s)")
138
+ print(f"1CRN: {cif.num_atoms} atoms")
139
+ print(f"Radius of gyration: {pdb.radius_of_gyration():.2f}")
140
+ print(f"Secondary structure: {pdb.secondary_structure_string()[:40]}")
141
+ EOF
142
+
143
+ # Includes checks that files written by pdbrust are read correctly by gemmi.
144
+ - name: Run the Python tests
145
+ run: |
146
+ python -m pip install pytest gemmi==0.7.5
147
+ python -m pytest pdbrust-python/tests -q
148
+
149
+ coverage:
150
+ name: Code coverage
151
+ runs-on: ubuntu-latest
152
+ steps:
153
+ - uses: actions/checkout@v5
154
+
155
+ - name: Install Rust toolchain
156
+ uses: dtolnay/rust-toolchain@stable
157
+ with:
158
+ components: llvm-tools-preview
159
+
160
+ - name: Install cargo-llvm-cov
161
+ uses: taiki-e/install-action@cargo-llvm-cov
162
+
163
+ - name: Generate code coverage
164
+ run: cargo llvm-cov --all-features --package pdbrust --lcov --output-path lcov.info
165
+
166
+ - name: Upload coverage to Codecov
167
+ uses: codecov/codecov-action@v6
168
+ with:
169
+ token: ${{ secrets.CODECOV_TOKEN }}
170
+ files: lcov.info
171
+ # Dependabot and fork PRs have no access to the token; an upload
172
+ # failure there says nothing about the code, so don't fail CI on it.
173
+ fail_ci_if_error: false
174
+
175
+ doc:
176
+ name: Documentation
177
+ runs-on: ubuntu-latest
178
+ steps:
179
+ - uses: actions/checkout@v5
180
+
181
+ - name: Install Rust toolchain
182
+ uses: dtolnay/rust-toolchain@stable
183
+
184
+ - name: Check documentation
185
+ env:
186
+ RUSTDOCFLAGS: "-D warnings"
187
+ run: cargo doc --no-deps --all-features --package pdbrust
188
+
189
+ security:
190
+ name: Security
191
+ runs-on: ubuntu-latest
192
+ steps:
193
+ - uses: actions/checkout@v5
194
+
195
+ - name: Install Rust toolchain
196
+ uses: dtolnay/rust-toolchain@stable
197
+
198
+ - name: Install cargo-audit
199
+ run: cargo install cargo-audit
200
+
201
+ - name: Run security audit
202
+ run: cargo audit
203
+ continue-on-error: true # Advisory - don't block on security for now
204
+
205
+ release:
206
+ name: Release
207
+ needs: [test, lint, security]
208
+ runs-on: ubuntu-latest
209
+ if: startsWith(github.ref, 'refs/tags/')
210
+ steps:
211
+ - uses: actions/checkout@v5
212
+
213
+ - name: Install Rust toolchain
214
+ uses: dtolnay/rust-toolchain@stable
215
+
216
+ - name: Publish to crates.io
217
+ run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }}
@@ -0,0 +1,21 @@
1
+ /target
2
+ **/*.rs.bk
3
+ .idea/
4
+ .vscode/
5
+ *.swp
6
+ *.swo
7
+ libraryPDB/
8
+
9
+ # Paper sources are kept private until a preprint is posted
10
+ /docs/paper/
11
+ /docs/*overleaf*.zip
12
+
13
+ # Python
14
+ __pycache__/
15
+ *.py[cod]
16
+ *.so
17
+ *.egg-info/
18
+ dist/
19
+ build/
20
+ .eggs/
21
+ .venv/
@@ -0,0 +1,53 @@
1
+ {
2
+ "title": "PDBRust: A High-Performance Rust Library for PDB/mmCIF Parsing and Analysis",
3
+ "description": "<p>PDBRust is a fast Rust library for parsing and analyzing Protein Data Bank (PDB) and mmCIF protein structure files. It provides comprehensive support for molecular structure data with robust error handling, structural analysis, quality assessment, and RCSB PDB integration.</p><p>Key features:</p><ul><li>Dual format support: PDB and mmCIF with automatic format detection</li><li>40-260x faster than equivalent Python implementations</li><li>Validated against the entire PDB archive (230,655 structures, 100% success rate)</li><li>Python bindings available via PyPI</li><li>Feature-gated modules for minimal compile times</li></ul>",
4
+ "creators": [
5
+ {
6
+ "name": "Fooladi, Hosein",
7
+ "orcid": "0000-0002-3124-2761",
8
+ "affiliation": "Department of Pharmaceutical Sciences, Division of Pharmaceutical Chemistry, Faculty of Life Sciences, University of Vienna, Josef-Holaubek-Platz 2, 1090 Vienna, Austria"
9
+ }
10
+ ],
11
+ "keywords": [
12
+ "bioinformatics",
13
+ "protein structure",
14
+ "PDB",
15
+ "mmCIF",
16
+ "structural biology",
17
+ "Rust",
18
+ "Python",
19
+ "molecular structure",
20
+ "protein analysis",
21
+ "computational biology"
22
+ ],
23
+ "license": "MIT",
24
+ "upload_type": "software",
25
+ "access_right": "open",
26
+ "programming_language": ["Rust", "Python"],
27
+ "related_identifiers": [
28
+ {
29
+ "identifier": "https://github.com/HFooladi/pdbrust",
30
+ "relation": "isSupplementTo",
31
+ "resource_type": "software",
32
+ "scheme": "url"
33
+ },
34
+ {
35
+ "identifier": "https://crates.io/crates/pdbrust",
36
+ "relation": "isIdenticalTo",
37
+ "resource_type": "software",
38
+ "scheme": "url"
39
+ },
40
+ {
41
+ "identifier": "https://pypi.org/project/pdbrust/",
42
+ "relation": "isIdenticalTo",
43
+ "resource_type": "software",
44
+ "scheme": "url"
45
+ },
46
+ {
47
+ "identifier": "https://docs.rs/pdbrust",
48
+ "relation": "isDocumentedBy",
49
+ "resource_type": "publication-other",
50
+ "scheme": "url"
51
+ }
52
+ ]
53
+ }