rowan-python 3.0.4__tar.gz → 3.0.5__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 (128) hide show
  1. {rowan_python-3.0.4 → rowan_python-3.0.5}/PKG-INFO +1 -1
  2. rowan_python-3.0.5/examples/data/Al_FCC.xyz +3 -0
  3. rowan_python-3.0.5/examples/periodic_dft.py +58 -0
  4. rowan_python-3.0.5/examples/pka.py +69 -0
  5. {rowan_python-3.0.4 → rowan_python-3.0.5}/pixi.lock +28 -28
  6. {rowan_python-3.0.4 → rowan_python-3.0.5}/pyproject.toml +1 -1
  7. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/__init__.py +8 -0
  8. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/molecule.py +31 -0
  9. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/analogue_docking.py +9 -0
  10. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/basic_calculation.py +18 -0
  11. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/pka.py +32 -17
  12. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/strain.py +15 -7
  13. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/tautomer_search.py +16 -6
  14. rowan_python-3.0.4/examples/pka.py +0 -43
  15. {rowan_python-3.0.4 → rowan_python-3.0.5}/.envrc +0 -0
  16. {rowan_python-3.0.4 → rowan_python-3.0.5}/.github/workflows/build-and-deploy-docs.yml +0 -0
  17. {rowan_python-3.0.4 → rowan_python-3.0.5}/.github/workflows/python-publish.yml +0 -0
  18. {rowan_python-3.0.4 → rowan_python-3.0.5}/.github/workflows/test.yml +0 -0
  19. {rowan_python-3.0.4 → rowan_python-3.0.5}/.gitignore +0 -0
  20. {rowan_python-3.0.4 → rowan_python-3.0.5}/.pre-commit-config.yaml +0 -0
  21. {rowan_python-3.0.4 → rowan_python-3.0.5}/LICENSE +0 -0
  22. {rowan_python-3.0.4 → rowan_python-3.0.5}/README.md +0 -0
  23. {rowan_python-3.0.4 → rowan_python-3.0.5}/docs/images/deciduous-tree-favicon.png +0 -0
  24. {rowan_python-3.0.4 → rowan_python-3.0.5}/docs/index.md +0 -0
  25. {rowan_python-3.0.4 → rowan_python-3.0.5}/docs/rowan_rdkit.md +0 -0
  26. {rowan_python-3.0.4 → rowan_python-3.0.5}/docs/stylesheets/colors.css +0 -0
  27. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/PROTAC_solubility.py +0 -0
  28. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/admet.py +0 -0
  29. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/analogue_docking.py +0 -0
  30. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/aqueous_solubility.py +0 -0
  31. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/basic_calculation.py +0 -0
  32. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/basic_calculation_from_json.py +0 -0
  33. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/basic_calculation_with_constraint.py +0 -0
  34. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/basic_calculation_with_solvent.py +0 -0
  35. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/batch_docking.py +0 -0
  36. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/bde.py +0 -0
  37. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/boltz_paired_msa.py +0 -0
  38. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/boltz_single_msa.py +0 -0
  39. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/chai_paired_msa.py +0 -0
  40. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/chai_single_msa.py +0 -0
  41. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/cofolding_screen.py +0 -0
  42. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/colabfold_paired_msa.py +0 -0
  43. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/colabfold_single_msa.py +0 -0
  44. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/conformer_dependent_redox.py +0 -0
  45. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/conformers.py +0 -0
  46. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/data/1iep_receptorH.pdb +0 -0
  47. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/data/citalopram_1iep.xyz +0 -0
  48. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/data/tyk2_ligands.sdf +0 -0
  49. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/data/tyk2_structure.pdb +0 -0
  50. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/data/workflow_example.json +0 -0
  51. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/dcd_download.py +0 -0
  52. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/descriptors.py +0 -0
  53. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/docking_screen.py +0 -0
  54. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/double_ended_ts_search.py +0 -0
  55. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/electronic_properties.py +0 -0
  56. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/estimate_workflow.py +0 -0
  57. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/fukui_index.py +0 -0
  58. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/hydrogen_bond_basicity.py +0 -0
  59. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/interaction_energy_decomposition.py +0 -0
  60. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/ion_mobility.py +0 -0
  61. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/irc.py +0 -0
  62. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/macropka.py +0 -0
  63. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/membrane_permeability.py +0 -0
  64. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/multistage_optimization.py +0 -0
  65. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/nmr.py +0 -0
  66. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/optimization.py +0 -0
  67. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/pdb_download.py +0 -0
  68. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/phenol_pka.py +0 -0
  69. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/pose_analysis_md.py +0 -0
  70. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/protein_binder_design.py +0 -0
  71. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/protein_cofolding.py +0 -0
  72. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/protein_md.py +0 -0
  73. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/rbfe_graph.py +0 -0
  74. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/redox_potential.py +0 -0
  75. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/relative_binding_free_energy_perturbation.py +0 -0
  76. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/retrieve_workflow.py +0 -0
  77. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/scan.py +0 -0
  78. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/solvent_dependent_conformers.py +0 -0
  79. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/spin_states.py +0 -0
  80. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/strain.py +0 -0
  81. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/tautomer.py +0 -0
  82. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/template.py +0 -0
  83. {rowan_python-3.0.4 → rowan_python-3.0.5}/examples/webhook.py +0 -0
  84. {rowan_python-3.0.4 → rowan_python-3.0.5}/mkdocs.yml +0 -0
  85. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/calculation.py +0 -0
  86. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/config.py +0 -0
  87. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/constants.py +0 -0
  88. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/folder.py +0 -0
  89. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/project.py +0 -0
  90. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/protein.py +0 -0
  91. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/py.typed +0 -0
  92. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/rowan_rdkit/__init__.py +0 -0
  93. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/rowan_rdkit/chem_utils.py +0 -0
  94. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/types.py +0 -0
  95. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/user.py +0 -0
  96. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/utils.py +0 -0
  97. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/__init__.py +0 -0
  98. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/admet.py +0 -0
  99. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/base.py +0 -0
  100. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/batch_docking.py +0 -0
  101. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/bde.py +0 -0
  102. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/conformer_search.py +0 -0
  103. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/constants.py +0 -0
  104. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/descriptors.py +0 -0
  105. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/docking.py +0 -0
  106. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/double_ended_ts_search.py +0 -0
  107. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/electronic_properties.py +0 -0
  108. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/fukui.py +0 -0
  109. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/hydrogen_bond_donor_acceptor_strength.py +0 -0
  110. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/interaction_energy_decomposition.py +0 -0
  111. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/ion_mobility.py +0 -0
  112. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/irc.py +0 -0
  113. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/macropka.py +0 -0
  114. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/membrane_permeability.py +0 -0
  115. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/msa.py +0 -0
  116. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/multistage_optimization.py +0 -0
  117. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/nmr.py +0 -0
  118. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/pose_analysis_md.py +0 -0
  119. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/protein_binder_design.py +0 -0
  120. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/protein_cofolding.py +0 -0
  121. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/protein_md.py +0 -0
  122. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/rbfe_graph.py +0 -0
  123. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/redox_potential.py +0 -0
  124. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/relative_binding_free_energy_perturbation.py +0 -0
  125. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/scan.py +0 -0
  126. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/solubility.py +0 -0
  127. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/solvent_dependent_conformers.py +0 -0
  128. {rowan_python-3.0.4 → rowan_python-3.0.5}/rowan/workflows/spin_states.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rowan-python
3
- Version: 3.0.4
3
+ Version: 3.0.5
4
4
  Summary: Rowan Python Library
5
5
  Project-URL: Homepage, https://github.com/rowansci/rowan-client
6
6
  Project-URL: Bug Tracker, https://github.com/rowansci/rowan-client/issues
@@ -0,0 +1,3 @@
1
+ 1
2
+ Lattice="0.0 2.0230 2.0230 2.0230 0.0 2.0230 2.0230 2.0230 0.0" Properties=species:S:1:pos:R:3
3
+ Al 0.00000000 0.00000000 0.00000000
@@ -0,0 +1,58 @@
1
+ """
2
+ Run a periodic DFT energy calculation on bulk aluminium using Quantum ESPRESSO.
3
+
4
+ Key settings for PBC calculations:
5
+ - ``pw_cutoff``: plane-wave kinetic-energy cutoff in Hartree (higher = more accurate/slower)
6
+ - ``kpoints``: Monkhorst–Pack k-point grid (denser = more accurate/slower)
7
+ - ``smearing``: occupation smearing type — recommended for metals to aid SCF convergence
8
+ - ``degauss``: smearing width in Hartree (typical range: 0.005–0.02)
9
+
10
+ Periodic molecules are constructed from atomic positions + lattice vectors.
11
+ See documentation at: https://docs.rowansci.com/science/workflows/basic-calculation
12
+ """
13
+
14
+ import rowan
15
+
16
+ # Set your API key or use the ROWAN_API_KEY environment variable
17
+ # rowan.api_key = "rowan-sk..."
18
+ folder = rowan.get_folder("examples/periodic_dft")
19
+
20
+ # Build bulk Al FCC primitive cell.
21
+ # Lattice vectors in Angstrom; Al has 13 electrons so multiplicity=2.
22
+ cell = rowan.PeriodicCell(
23
+ lattice_vectors=(
24
+ (0.0, 2.0230, 2.0230),
25
+ (2.0230, 0.0, 2.0230),
26
+ (2.0230, 2.0230, 0.0),
27
+ )
28
+ )
29
+ al_fcc = rowan.Molecule.from_atoms(
30
+ atoms=[rowan.Atom(atomic_number=13, position=(0.0, 0.0, 0.0))],
31
+ charge=0,
32
+ multiplicity=2,
33
+ cell=cell,
34
+ )
35
+
36
+ # Marzari–Vanderbilt cold smearing is recommended for metals.
37
+ pbc_settings = rowan.PBCDFTSettings(
38
+ pw_cutoff=7.5, # Hartree; SSSP efficiency recommends ~7–9 Ha for Al
39
+ kpoints=(4, 4, 4), # Monkhorst–Pack grid; increase for production runs
40
+ smearing=rowan.PBCDFTSmearing.MV,
41
+ degauss=0.01, # Hartree smearing width
42
+ )
43
+
44
+ workflow = rowan.submit_basic_calculation_workflow(
45
+ initial_molecule=al_fcc,
46
+ tasks=["energy"],
47
+ method="PBE",
48
+ basis_set="SSSP_efficiency",
49
+ pbc_dft_settings=pbc_settings,
50
+ name="Al FCC bulk energy",
51
+ folder=folder,
52
+ )
53
+
54
+ print(f"View workflow privately at: https://labs.rowansci.com/calculation/{workflow.uuid}")
55
+ result = workflow.result()
56
+ print(result)
57
+ # e.g. <BasicCalculationResult energy=-19.725 H>
58
+ print(f"Al FCC energy: {result.energy:.6f} Hartree")
@@ -0,0 +1,69 @@
1
+ """
2
+ Calculate the pKa of phenol using the Rowan API.
3
+
4
+ Experimental value ≈ 9.99
5
+
6
+ Four methods are available:
7
+ - aimnet2_wagen2024: AIMNet2-based; requires 3D structure; water only.
8
+ - gxtb_wagen2026: g-xTB-based; requires 3D structure; water only; full periodic table.
9
+ - chemprop_nevolianis2025: Chemprop-based; requires SMILES; several solvents supported.
10
+ - starling: SMILES-based; water only.
11
+
12
+ See documentation at: https://docs.rowansci.com/science/workflows/pka
13
+ """
14
+
15
+ import rowan
16
+
17
+ # Set your API key or use the ROWAN_API_KEY environment variable
18
+ # rowan.api_key = "rowan-sk..."
19
+ folder = rowan.get_folder("examples/pka")
20
+
21
+ # 3D structure-based methods — pass a Molecule with coordinates
22
+ mol = rowan.Molecule.from_smiles("c1ccccc1O")
23
+
24
+ workflow = rowan.submit_pka_workflow(
25
+ initial_molecule=mol,
26
+ method="aimnet2_wagen2024",
27
+ name="Phenol pKa (aimnet2_wagen2024)",
28
+ folder=folder,
29
+ )
30
+ print(f"View at: https://labs.rowansci.com/pka/{workflow.uuid}")
31
+ result = workflow.result()
32
+ print(result)
33
+ # e.g. <pKaResult acid=9.87>
34
+
35
+ workflow2 = rowan.submit_pka_workflow(
36
+ initial_molecule=mol,
37
+ method="gxtb_wagen2026",
38
+ name="Phenol pKa (gxtb_wagen2026)",
39
+ folder=folder,
40
+ )
41
+ print(f"View at: https://labs.rowansci.com/pka/{workflow2.uuid}")
42
+ result2 = workflow2.result()
43
+ print(result2)
44
+ # e.g. <pKaResult acid=9.92>
45
+
46
+ # SMILES-based methods — pass a SMILES string directly
47
+ smiles = "c1ccccc1O"
48
+
49
+ workflow3 = rowan.submit_pka_workflow(
50
+ initial_molecule=smiles,
51
+ method="chemprop_nevolianis2025",
52
+ name="Phenol pKa (chemprop_nevolianis2025)",
53
+ folder=folder,
54
+ )
55
+ print(f"View at: https://labs.rowansci.com/pka/{workflow3.uuid}")
56
+ result3 = workflow3.result()
57
+ print(result3)
58
+ # e.g. <pKaResult acid=9.75>
59
+
60
+ workflow4 = rowan.submit_pka_workflow(
61
+ initial_molecule=smiles,
62
+ method="starling",
63
+ name="Phenol pKa (starling)",
64
+ folder=folder,
65
+ )
66
+ print(f"View at: https://labs.rowansci.com/pka/{workflow4.uuid}")
67
+ result4 = workflow4.result()
68
+ print(result4)
69
+ # e.g. <pKaResult acid=9.81>
@@ -44,8 +44,8 @@ environments:
44
44
  - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl
45
45
  - pypi: https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
46
46
  - pypi: https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
47
- - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
48
- - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
47
+ - pypi: https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl
48
+ - pypi: https://files.pythonhosted.org/packages/cb/e4/566101a561492ce8454f0844ca29c3b675a6b3a7b3ff577db85ed05c8c50/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
49
49
  - pypi: https://files.pythonhosted.org/packages/27/60/41cf00319d2a01946854e634f9a5791b0370c08bffbe4d094b0743213f6c/rdkit-2026.3.1-cp314-cp314-manylinux_2_28_x86_64.whl
50
50
  - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl
51
51
  - pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl
@@ -83,8 +83,8 @@ environments:
83
83
  - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl
84
84
  - pypi: https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl
85
85
  - pypi: https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl
86
- - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
87
- - pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl
86
+ - pypi: https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl
87
+ - pypi: https://files.pythonhosted.org/packages/35/95/3a0c6f65e231709fb3463e32943c69d10285cb50203a2130a4732053a06d/pydantic_core-2.46.0-cp314-cp314-macosx_11_0_arm64.whl
88
88
  - pypi: https://files.pythonhosted.org/packages/6a/a4/c05a31806eaf366af246903230fe441cef8b7949cc4592656025ac8975e6/rdkit-2026.3.1-cp314-cp314-macosx_11_0_arm64.whl
89
89
  - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl
90
90
  - pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl
@@ -166,7 +166,7 @@ environments:
166
166
  - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl
167
167
  - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl
168
168
  - pypi: https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl
169
- - pypi: https://files.pythonhosted.org/packages/6b/8d/93491ff7b79419edc7eabf95cb3b3f7490e2e574b2855c7c7e7394ff933f/mypy-1.20.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
169
+ - pypi: https://files.pythonhosted.org/packages/d7/aa/a19d884a8d28fcd3c065776323029f204dbc774e70ec9c85eba228b680de/mypy-1.20.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
170
170
  - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl
171
171
  - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl
172
172
  - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl
@@ -183,8 +183,8 @@ environments:
183
183
  - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl
184
184
  - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl
185
185
  - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl
186
- - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
187
- - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
186
+ - pypi: https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl
187
+ - pypi: https://files.pythonhosted.org/packages/cb/e4/566101a561492ce8454f0844ca29c3b675a6b3a7b3ff577db85ed05c8c50/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
188
188
  - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
189
189
  - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl
190
190
  - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl
@@ -268,7 +268,7 @@ environments:
268
268
  - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl
269
269
  - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl
270
270
  - pypi: https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl
271
- - pypi: https://files.pythonhosted.org/packages/7d/c5/5fe9d8a729dd9605064691816243ae6c49fde0bd28f6e5e17f6a24203c43/mypy-1.20.0-cp314-cp314-macosx_11_0_arm64.whl
271
+ - pypi: https://files.pythonhosted.org/packages/d5/82/74e62e7097fa67da328ac8ece8de09133448c04d20ddeaeba251a3000f01/mypy-1.20.1-cp314-cp314-macosx_11_0_arm64.whl
272
272
  - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl
273
273
  - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl
274
274
  - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl
@@ -285,8 +285,8 @@ environments:
285
285
  - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl
286
286
  - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl
287
287
  - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl
288
- - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
289
- - pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl
288
+ - pypi: https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl
289
+ - pypi: https://files.pythonhosted.org/packages/35/95/3a0c6f65e231709fb3463e32943c69d10285cb50203a2130a4732053a06d/pydantic_core-2.46.0-cp314-cp314-macosx_11_0_arm64.whl
290
290
  - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
291
291
  - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl
292
292
  - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl
@@ -1039,10 +1039,10 @@ packages:
1039
1039
  version: 11.0.2
1040
1040
  sha256: 6e35b35f818b01f691643c6c611bc0902f2e92b46c18fffa77ae1e7c46e912e4
1041
1041
  requires_python: '>=3.10'
1042
- - pypi: https://files.pythonhosted.org/packages/6b/8d/93491ff7b79419edc7eabf95cb3b3f7490e2e574b2855c7c7e7394ff933f/mypy-1.20.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
1042
+ - pypi: https://files.pythonhosted.org/packages/d5/82/74e62e7097fa67da328ac8ece8de09133448c04d20ddeaeba251a3000f01/mypy-1.20.1-cp314-cp314-macosx_11_0_arm64.whl
1043
1043
  name: mypy
1044
- version: 1.20.0
1045
- sha256: 7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83
1044
+ version: 1.20.1
1045
+ sha256: 752507dd481e958b2c08fc966d3806c962af5a9433b5bf8f3bdd7175c20e34fe
1046
1046
  requires_dist:
1047
1047
  - typing-extensions>=4.6.0
1048
1048
  - mypy-extensions>=1.0.0
@@ -1056,10 +1056,10 @@ packages:
1056
1056
  - orjson ; extra == 'faster-cache'
1057
1057
  - ast-serialize>=0.1.1,<1.0.0 ; extra == 'native-parser'
1058
1058
  requires_python: '>=3.10'
1059
- - pypi: https://files.pythonhosted.org/packages/7d/c5/5fe9d8a729dd9605064691816243ae6c49fde0bd28f6e5e17f6a24203c43/mypy-1.20.0-cp314-cp314-macosx_11_0_arm64.whl
1059
+ - pypi: https://files.pythonhosted.org/packages/d7/aa/a19d884a8d28fcd3c065776323029f204dbc774e70ec9c85eba228b680de/mypy-1.20.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
1060
1060
  name: mypy
1061
- version: 1.20.0
1062
- sha256: 31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5
1061
+ version: 1.20.1
1062
+ sha256: 2c3f6221a76f34d5100c6d35b3ef6b947054123c3f8d6938a4ba00b1308aa572
1063
1063
  requires_dist:
1064
1064
  - typing-extensions>=4.6.0
1065
1065
  - mypy-extensions>=1.0.0
@@ -1289,29 +1289,29 @@ packages:
1289
1289
  sha256: 1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0
1290
1290
  requires_dist:
1291
1291
  - pytest ; extra == 'tests'
1292
- - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
1292
+ - pypi: https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl
1293
1293
  name: pydantic
1294
- version: 2.12.5
1295
- sha256: e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d
1294
+ version: 2.13.0
1295
+ sha256: ab0078b90da5f3e2fd2e71e3d9b457ddcb35d0350854fbda93b451e28d56baaf
1296
1296
  requires_dist:
1297
1297
  - annotated-types>=0.6.0
1298
- - pydantic-core==2.41.5
1298
+ - pydantic-core==2.46.0
1299
1299
  - typing-extensions>=4.14.1
1300
1300
  - typing-inspection>=0.4.2
1301
1301
  - email-validator>=2.0.0 ; extra == 'email'
1302
1302
  - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone'
1303
1303
  requires_python: '>=3.9'
1304
- - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
1304
+ - pypi: https://files.pythonhosted.org/packages/35/95/3a0c6f65e231709fb3463e32943c69d10285cb50203a2130a4732053a06d/pydantic_core-2.46.0-cp314-cp314-macosx_11_0_arm64.whl
1305
1305
  name: pydantic-core
1306
- version: 2.41.5
1307
- sha256: 22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375
1306
+ version: 2.46.0
1307
+ sha256: 0a36f2cc88170cc177930afcc633a8c15907ea68b59ac16bd180c2999d714940
1308
1308
  requires_dist:
1309
1309
  - typing-extensions>=4.14.1
1310
1310
  requires_python: '>=3.9'
1311
- - pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl
1311
+ - pypi: https://files.pythonhosted.org/packages/cb/e4/566101a561492ce8454f0844ca29c3b675a6b3a7b3ff577db85ed05c8c50/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
1312
1312
  name: pydantic-core
1313
- version: 2.41.5
1314
- sha256: 1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14
1313
+ version: 2.46.0
1314
+ sha256: 67e2c2e171b78db8154da602de72ffdc473c6ee51de8a9d80c0f1cd4051abfc7
1315
1315
  requires_dist:
1316
1316
  - typing-extensions>=4.14.1
1317
1317
  requires_python: '>=3.9'
@@ -1531,8 +1531,8 @@ packages:
1531
1531
  requires_python: '>=3.10'
1532
1532
  - pypi: ./
1533
1533
  name: rowan-python
1534
- version: 3.0.4
1535
- sha256: 68bb5250327c5075096e931e0f397030cdb0a64fec9cb12c901fc97caba6f01d
1534
+ version: 3.0.5
1535
+ sha256: 0edb360654d940882164004a70b7a68baea296fd2ab32bd1e2ddab8a3e84fcf9
1536
1536
  requires_dist:
1537
1537
  - httpx
1538
1538
  - stjames>=0.0.174
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "rowan-python"
3
- version = "3.0.4"
3
+ version = "3.0.5"
4
4
  description = "Rowan Python Library"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -1,17 +1,25 @@
1
1
  # ruff: noqa
2
2
  from . import constants
3
3
  from stjames import (
4
+ Atom,
4
5
  Constraint,
5
6
  ConstraintType,
7
+ ConformerGenSettingsUnion,
6
8
  Correction,
7
9
  Engine,
10
+ ETKDGSettings,
11
+ iMTDSettings,
8
12
  Method,
9
13
  Mode,
14
+ MultiStageOptSettings,
10
15
  OptimizationSettings,
16
+ PBCDFTSettings,
17
+ PeriodicCell,
11
18
  Settings,
12
19
  SolventSettings,
13
20
  Task,
14
21
  )
22
+ from stjames.pbc_dft_settings import PBCDFTSmearing
15
23
  from stjames.optimization.freezing_string_method import (
16
24
  FSMInterpolation,
17
25
  FSMOptimizationCoordinates,
@@ -87,6 +87,32 @@ class Molecule(BaseModel):
87
87
  """
88
88
  return cls(_stjames=stj)
89
89
 
90
+ @classmethod
91
+ def from_atoms(
92
+ cls,
93
+ atoms: list[stjames.Atom],
94
+ charge: int = 0,
95
+ multiplicity: int = 1,
96
+ cell: stjames.PeriodicCell | None = None,
97
+ ) -> Self:
98
+ """
99
+ Create molecule from a list of atoms.
100
+
101
+ :param atoms: List of Atom objects.
102
+ :param charge: Molecular charge (default 0).
103
+ :param multiplicity: Spin multiplicity (default 1).
104
+ :param cell: PeriodicCell for periodic boundary conditions.
105
+ :returns: Molecule instance.
106
+ """
107
+ return cls(
108
+ _stjames=stjames.Molecule(
109
+ atoms=atoms,
110
+ charge=charge,
111
+ multiplicity=multiplicity,
112
+ cell=cell,
113
+ )
114
+ )
115
+
90
116
  def to_xyz(self) -> str:
91
117
  """Convert to XYZ format string."""
92
118
  return self._stjames.to_xyz()
@@ -184,6 +210,11 @@ class Molecule(BaseModel):
184
210
  """Thermal correction to Gibbs free energy (Hartree)."""
185
211
  return self._stjames.thermal_free_energy_corr
186
212
 
213
+ @property
214
+ def cell(self) -> stjames.PeriodicCell | None:
215
+ """Unit cell for periodic boundary conditions."""
216
+ return self._stjames.cell
217
+
187
218
  @property
188
219
  def gradient(self) -> list[tuple[float, float, float]] | None:
189
220
  """Nuclear gradient (Hartree/Bohr)."""
@@ -162,6 +162,9 @@ def submit_analogue_docking_workflow(
162
162
  executable: str = "vina",
163
163
  scoring_function: str = "vinardo",
164
164
  exhaustiveness: float = 8,
165
+ num_conformers_per_analogue: int = 100,
166
+ require_posebusters: bool = False,
167
+ run_local_optimization: bool = False,
165
168
  name: str = "Analogue Docking Workflow",
166
169
  folder_uuid: str | None = None,
167
170
  folder: Folder | None = None,
@@ -178,6 +181,9 @@ def submit_analogue_docking_workflow(
178
181
  :param executable: Which docking implementation to use.
179
182
  :param scoring_function: Which docking scoring function to use.
180
183
  :param exhaustiveness: Which exhaustiveness to employ.
184
+ :param num_conformers_per_analogue: Maximum number of conformers to generate per analogue.
185
+ :param require_posebusters: Filter conformers based on PoseBusters validity before docking.
186
+ :param run_local_optimization: Whether to run a local opt in docking pocket or just score.
181
187
  :param name: Name of the workflow.
182
188
  :param folder_uuid: UUID of the folder to place the workflow in.
183
189
  :param folder: Folder object to store the workflow in.
@@ -207,6 +213,9 @@ def submit_analogue_docking_workflow(
207
213
  initial_molecule=initial_molecule,
208
214
  protein=protein,
209
215
  docking_settings=docking_settings,
216
+ num_conformers_per_analogue=num_conformers_per_analogue,
217
+ require_posebusters=require_posebusters,
218
+ run_local_optimization=run_local_optimization,
210
219
  )
211
220
 
212
221
  data = {
@@ -9,6 +9,7 @@ from stjames import (
9
9
  Engine,
10
10
  Method,
11
11
  OptimizationSettings,
12
+ PBCDFTSettings,
12
13
  Settings,
13
14
  SolventSettings,
14
15
  )
@@ -159,6 +160,7 @@ def submit_basic_calculation_workflow(
159
160
  corrections: list[str] | None = None,
160
161
  solvent_settings: SolventSettings | dict[str, Any] | None = None,
161
162
  opt_settings: OptimizationSettings | dict[str, Any] | None = None,
163
+ pbc_dft_settings: PBCDFTSettings | dict[str, Any] | None = None,
162
164
  preset: PresetName | None = None,
163
165
  name: str = "Basic Calculation Workflow",
164
166
  folder_uuid: str | None = None,
@@ -179,6 +181,10 @@ def submit_basic_calculation_workflow(
179
181
  :param corrections: Dispersion corrections, see `Correction`.
180
182
  :param solvent_settings: Solvent settings as a dict or `SolventSettings`.
181
183
  :param opt_settings: Optimization settings as a dict or `OptimizationSettings`.
184
+ :param pbc_dft_settings: Periodic boundary condition DFT settings as a dict or
185
+ `PBCDFTSettings`. Specifies the plane-wave cutoff (Hartree), Monkhorst–Pack
186
+ k-point grid, and optional smearing. When set, the engine is automatically
187
+ set to Quantum ESPRESSO unless ``engine`` is explicitly provided.
182
188
  :param preset: Named preset, mutually exclusive with method/engine/basis_set/corrections.
183
189
  - `general_nnp` — omol25_conserving_s on omol25
184
190
  - `organic_nnp` — aimnet2_wb97md3 on aimnet2
@@ -203,6 +209,9 @@ def submit_basic_calculation_workflow(
203
209
  if folder:
204
210
  folder_uuid = folder.uuid
205
211
 
212
+ if isinstance(pbc_dft_settings, dict):
213
+ pbc_dft_settings = PBCDFTSettings(**pbc_dft_settings)
214
+
206
215
  if preset is not None:
207
216
  if any(x is not None for x in [method, engine, corrections, basis_set]):
208
217
  raise ValueError(
@@ -214,6 +223,7 @@ def submit_basic_calculation_workflow(
214
223
  mode=mode,
215
224
  solvent_settings=solvent_settings,
216
225
  **({"opt_settings": opt_settings} if opt_settings else {}),
226
+ **({"pbc_dft_settings": pbc_dft_settings} if pbc_dft_settings else {}),
217
227
  )
218
228
  else:
219
229
  if method is None:
@@ -228,6 +238,10 @@ def submit_basic_calculation_workflow(
228
238
  if isinstance(opt_settings, dict):
229
239
  opt_settings = stjames.OptimizationSettings(**opt_settings)
230
240
 
241
+ # pbc_dft_settings implies Quantum ESPRESSO; override engine unless explicitly set
242
+ if pbc_dft_settings is not None and engine is None:
243
+ engine = Engine.QUANTUM_ESPRESSO
244
+
231
245
  settings_kwargs: dict[str, Any] = {
232
246
  "method": method,
233
247
  "basis_set": basis_set,
@@ -236,8 +250,12 @@ def submit_basic_calculation_workflow(
236
250
  "corrections": corrections or [],
237
251
  "solvent_settings": solvent_settings,
238
252
  }
253
+ if engine is not None:
254
+ settings_kwargs["engine"] = engine
239
255
  if opt_settings is not None:
240
256
  settings_kwargs["opt_settings"] = opt_settings
257
+ if pbc_dft_settings is not None:
258
+ settings_kwargs["pbc_dft_settings"] = pbc_dft_settings
241
259
  settings = stjames.Settings(**settings_kwargs)
242
260
 
243
261
  initial_molecule = molecule_to_dict(initial_molecule)
@@ -23,13 +23,15 @@ class pKaMicrostate:
23
23
  """
24
24
  Microstate from a pKa calculation.
25
25
 
26
- Available fields depend on the pKa method used:
27
- aimnet2_wagen2024 provides delta_g; chemprop_nevolianis2025 provides smiles and uncertainty.
26
+ Available fields depend on the pKa method used. 3D structure-based methods
27
+ (aimnet2_wagen2024, gxtb_wagen2026) populate delta_g. SMILES-based methods
28
+ (chemprop_nevolianis2025, starling) populate smiles; chemprop_nevolianis2025
29
+ also populates uncertainty.
28
30
 
29
31
  :param atom_index: Index of the protonation site atom.
30
32
  :param pka: Predicted pKa value.
31
- :param smiles: SMILES of the microstate (chemprop_nevolianis2025 only).
32
- :param delta_g: Free energy of (de)protonation in kcal/mol (aimnet2_wagen2024 only).
33
+ :param smiles: SMILES of the microstate (SMILES-based methods only).
34
+ :param delta_g: Free energy of (de)protonation in kcal/mol (3D structure-based methods only).
33
35
  :param uncertainty: Prediction uncertainty (chemprop_nevolianis2025 only).
34
36
  """
35
37
 
@@ -40,6 +42,12 @@ class pKaMicrostate:
40
42
  uncertainty: float | None = None
41
43
 
42
44
 
45
+ # Methods grouped by input type and solvent support
46
+ _PKA_3D_METHODS = {"aimnet2_wagen2024", "gxtb_wagen2026"}
47
+ _PKA_SMILES_METHODS = {"chemprop_nevolianis2025", "starling"}
48
+ _PKA_WATER_ONLY_METHODS = {"aimnet2_wagen2024", "gxtb_wagen2026", "starling"}
49
+
50
+
43
51
  @register_result("pka")
44
52
  class pKaResult(WorkflowResult):
45
53
  """Result from a pKa workflow."""
@@ -95,19 +103,19 @@ class pKaResult(WorkflowResult):
95
103
  """
96
104
  Optimized structure calculations (lazily fetched).
97
105
 
98
- Only available for aimnet2_wagen2024 method (3D structure-based).
106
+ Only available for 3D structure-based methods (aimnet2_wagen2024, gxtb_wagen2026).
99
107
 
100
108
  .. note::
101
109
  Makes one API call per structure on first access.
102
110
  Results are cached. Call clear_cache() to refresh.
103
111
 
104
- :raises ValueError: If method is chemprop_nevolianis2025 (no structures).
112
+ :raises ValueError: If method is SMILES-based (chemprop_nevolianis2025, starling).
105
113
  """
106
114
  method = self._workflow.microscopic_pka_method
107
- if method == "chemprop_nevolianis2025":
115
+ if method in _PKA_SMILES_METHODS:
108
116
  raise ValueError(
109
- "chemprop_nevolianis2025 is SMILES-based and does not produce structures. "
110
- "Use aimnet2_wagen2024 for 3D structure calculations."
117
+ f"{method} is SMILES-based and does not produce structures. "
118
+ "Use aimnet2_wagen2024 or gxtb_wagen2026 for 3D structure calculations."
111
119
  )
112
120
  if "structures" not in self._cache:
113
121
  uuids = self._get_structure_uuids()
@@ -118,7 +126,9 @@ class pKaResult(WorkflowResult):
118
126
  def submit_pka_workflow(
119
127
  initial_molecule: MoleculeInput | str,
120
128
  pka_range: tuple[int, int] = (2, 12),
121
- method: Literal["aimnet2_wagen2024", "chemprop_nevolianis2025"] = "aimnet2_wagen2024",
129
+ method: Literal[
130
+ "aimnet2_wagen2024", "gxtb_wagen2026", "chemprop_nevolianis2025", "starling"
131
+ ] = "aimnet2_wagen2024",
122
132
  solvent: SolventInput = "water",
123
133
  deprotonate_elements: list[int] | None = None,
124
134
  protonate_elements: list[int] | None = None,
@@ -136,7 +146,11 @@ def submit_pka_workflow(
136
146
  :param initial_molecule: Molecule to calculate pKa for.
137
147
  Accepts Molecule, stjames.Molecule, RDKit Mol, dict, or SMILES string.
138
148
  :param pka_range: Range of pKa values to calculate.
139
- :param method: Algorithm used to compute pKa values.
149
+ :param method: Algorithm used to compute pKa values:
150
+ - ``aimnet2_wagen2024``: AIMNet2-based; requires 3D structure; water only.
151
+ - ``gxtb_wagen2026``: g-xTB-based; requires 3D structure; water only; full periodic table.
152
+ - ``chemprop_nevolianis2025``: Chemprop-based; requires SMILES; several solvents supported.
153
+ - ``starling``: SMILES-based; water only.
140
154
  :param solvent: Solvent in which pKa values will be computed.
141
155
  :param deprotonate_elements: Elements to deprotonate (atomic numbers).
142
156
  :param protonate_elements: Elements to protonate (atomic numbers).
@@ -148,7 +162,7 @@ def submit_pka_workflow(
148
162
  :param webhook_url: URL that Rowan will POST to when the workflow completes.
149
163
  :param is_draft: If True, submit the workflow as a draft without starting execution.
150
164
  :returns: Workflow object representing the submitted workflow.
151
- :raises ValueError: If method and input type don't match.
165
+ :raises ValueError: If method and input type don't match, or solvent is unsupported.
152
166
  :raises requests.HTTPError: if the request to the API fails.
153
167
  """
154
168
  if folder and folder_uuid:
@@ -163,16 +177,17 @@ def submit_pka_workflow(
163
177
  else:
164
178
  mol_dict = molecule_to_dict(initial_molecule)
165
179
 
166
- # Validate method/input compatibility
167
- if method == "aimnet2_wagen2024" and not mol_dict:
180
+ if method in _PKA_3D_METHODS and not mol_dict:
168
181
  raise ValueError(
169
- "aimnet2_wagen2024 requires a 3D structure. Provide a Molecule, not a SMILES string."
182
+ f"{method} requires a 3D structure. Provide a Molecule, not a SMILES string."
170
183
  )
171
- if method == "chemprop_nevolianis2025" and not initial_smiles:
184
+ if method in _PKA_SMILES_METHODS and not initial_smiles:
172
185
  raise ValueError(
173
- "chemprop_nevolianis2025 requires a SMILES string. "
186
+ f"{method} requires a SMILES string. "
174
187
  "Provide a SMILES string, not a 3D structure."
175
188
  )
189
+ if method in _PKA_WATER_ONLY_METHODS and solvent != "water":
190
+ raise ValueError(f"{method} only supports water as solvent.")
176
191
 
177
192
  protonate_elements = protonate_elements or [7]
178
193
  deprotonate_elements = deprotonate_elements or [7, 8, 16]
@@ -1,6 +1,7 @@
1
1
  """Strain workflow - calculate molecular strain energy."""
2
2
 
3
3
  import math
4
+ from typing import Any
4
5
 
5
6
  import stjames
6
7
 
@@ -113,6 +114,7 @@ def submit_strain_workflow(
113
114
  harmonic_constraint_spring_constant: float = 5.0,
114
115
  constrain_hydrogens: bool = False,
115
116
  conf_gen_settings: stjames.ConformerGenSettingsUnion | None = None,
117
+ multistage_opt_settings: stjames.MultiStageOptSettings | None = None,
116
118
  name: str = "Strain Workflow",
117
119
  folder_uuid: str | None = None,
118
120
  folder: Folder | None = None,
@@ -128,7 +130,9 @@ def submit_strain_workflow(
128
130
  constraints (kcal/mol/A). Default 5.0.
129
131
  :param constrain_hydrogens: Whether to constrain hydrogen positions. Default False.
130
132
  :param conf_gen_settings: Conformer generation settings. Defaults to ETKDG with
131
- max 50 conformers.
133
+ max 200 conformers.
134
+ :param multistage_opt_settings: Optimization settings for conformer ranking.
135
+ Defaults to AIMNet2/wB97M-D3 optimization with CPCMx singlepoint.
132
136
  :param name: Name of the workflow.
133
137
  :param folder_uuid: UUID of the folder to store the workflow in.
134
138
  :param folder: Folder object to store the workflow in.
@@ -144,12 +148,16 @@ def submit_strain_workflow(
144
148
  folder_uuid = folder.uuid
145
149
  initial_molecule = molecule_to_dict(initial_molecule)
146
150
 
147
- workflow = stjames.StrainWorkflow(
148
- initial_molecule=initial_molecule,
149
- harmonic_constraint_spring_constant=harmonic_constraint_spring_constant,
150
- constrain_hydrogens=constrain_hydrogens,
151
- conf_gen_settings=conf_gen_settings or stjames.ETKDGSettings(max_confs=50),
152
- )
151
+ workflow_kwargs: dict[str, Any] = {
152
+ "initial_molecule": initial_molecule,
153
+ "harmonic_constraint_spring_constant": harmonic_constraint_spring_constant,
154
+ "constrain_hydrogens": constrain_hydrogens,
155
+ "conf_gen_settings": conf_gen_settings or stjames.ETKDGSettings(max_confs=200),
156
+ }
157
+ if multistage_opt_settings is not None:
158
+ workflow_kwargs["multistage_opt_settings"] = multistage_opt_settings
159
+
160
+ workflow = stjames.StrainWorkflow(**workflow_kwargs)
153
161
 
154
162
  data = {
155
163
  "workflow_type": "strain",
@@ -1,6 +1,7 @@
1
1
  """Tautomer-search workflow - find tautomeric forms of molecules."""
2
2
 
3
3
  from dataclasses import dataclass
4
+ from typing import Any
4
5
 
5
6
  import stjames
6
7
 
@@ -105,6 +106,8 @@ class TautomerResult(WorkflowResult):
105
106
  def submit_tautomer_search_workflow(
106
107
  initial_molecule: MoleculeInput,
107
108
  mode: Mode = Mode.CAREFUL,
109
+ conf_gen_settings: stjames.ConformerGenSettingsUnion | None = None,
110
+ multistage_opt_settings: stjames.MultiStageOptSettings | None = None,
108
111
  name: str = "Tautomer Search Workflow",
109
112
  folder_uuid: str | None = None,
110
113
  folder: Folder | None = None,
@@ -116,7 +119,11 @@ def submit_tautomer_search_workflow(
116
119
  Submits a tautomer-search workflow to the API.
117
120
 
118
121
  :param initial_molecule: Molecule to find tautomers for.
119
- :param mode: Mode to run the calculation in (reckless, rapid, careful).
122
+ :param mode: *Deprecated.*
123
+ :param conf_gen_settings: Conformer generation settings. Defaults to ETKDG with
124
+ 250 initial conformers, 20 max conformers, and 15 kcal/mol MMFF energy cutoff.
125
+ :param multistage_opt_settings: Optimization settings for tautomer ranking.
126
+ Defaults to AIMNet2/wB97M-D3 optimization with CPCMx singlepoint.
120
127
  :param name: Name of the workflow.
121
128
  :param folder_uuid: UUID of the folder to place the workflow in.
122
129
  :param folder: Folder object to store the workflow in.
@@ -132,14 +139,17 @@ def submit_tautomer_search_workflow(
132
139
  folder_uuid = folder.uuid
133
140
  initial_molecule = molecule_to_dict(initial_molecule)
134
141
 
135
- workflow = stjames.TautomerWorkflow(
136
- initial_molecule=initial_molecule,
137
- mode=mode,
138
- )
142
+ workflow_kwargs: dict[str, Any] = {"initial_molecule": initial_molecule, "mode": mode}
143
+ if conf_gen_settings is not None:
144
+ workflow_kwargs["conf_gen_settings"] = conf_gen_settings
145
+ if multistage_opt_settings is not None:
146
+ workflow_kwargs["multistage_opt_settings"] = multistage_opt_settings
147
+
148
+ workflow = stjames.TautomerWorkflow(**workflow_kwargs)
139
149
 
140
150
  data = {
141
151
  "workflow_type": "tautomers",
142
- "workflow_data": workflow.model_dump(mode="json"),
152
+ "workflow_data": workflow.model_dump(serialize_as_any=True, mode="json"),
143
153
  "initial_molecule": initial_molecule,
144
154
  "name": name,
145
155
  "folder_uuid": folder_uuid,
@@ -1,43 +0,0 @@
1
- """
2
- Calculate the pKa of the conjugate acid of pyridine using the Rowan API.
3
-
4
- Experimental value ≈5.23
5
-
6
- See documentiation at: https://docs.rowansci.com/science/workflows/pka
7
- and preprint at: https://rowansci.com/publications/pka-prediction
8
- """
9
-
10
- import rowan
11
-
12
- # Set your API key or use the ROWAN_API_KEY environment variable
13
- # rowan.api_key = "rowan-sk..."
14
- folder = rowan.get_folder("examples/pka")
15
-
16
- workflow = rowan.submit_pka_workflow(
17
- initial_molecule=rowan.Molecule.from_smiles("c1ccccc1O"),
18
- method="aimnet2_wagen2024",
19
- mode="reckless",
20
- name="Pyridine pKa",
21
- folder=folder,
22
- )
23
-
24
- print(
25
- f"View pKa with aimnet2_wagen2024 privately at: https://labs.rowansci.com/pka/{workflow.uuid}"
26
- )
27
- result = workflow.result()
28
- print(result)
29
- # e.g. <pKaResult acid=4.75>
30
-
31
- workflow2 = rowan.submit_pka_workflow(
32
- initial_molecule="c1ccccc1O",
33
- method="chemprop_nevolianis2025",
34
- name="Pyridine pKa (ML)",
35
- folder=folder,
36
- )
37
-
38
- print(
39
- f"View pKa with chemprop_nevolianis2025 privately at: https://labs.rowansci.com/pka/{workflow2.uuid}"
40
- )
41
- result2 = workflow2.result()
42
- print(result2)
43
- # e.g. <pKaResult acid=4.75>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes