rowan-python 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl

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.
rowan/__init__.py CHANGED
@@ -1,10 +1,8 @@
1
1
  # ruff: noqa
2
-
3
- from . import utils
4
-
5
2
  from . import constants
6
3
 
7
4
  from .folder import *
8
5
  from .workflow import *
9
6
  from .protein import *
10
7
  from .user import *
8
+ from .utils import *
@@ -97,24 +97,24 @@ apply_nest_asyncio()
97
97
  def _get_rdkit_mol_from_uuid(calculation_uuid: str) -> RdkitMol:
98
98
  stjames_mol_dict = rowan.retrieve_calculation_molecules(calculation_uuid)[-1]
99
99
 
100
- return Chem.MolFromXYZBlock(stjames.Molecule(**stjames_mol_dict).to_xyz()) # type: ignore [attr-defined]
100
+ return Chem.MolFromXYZBlock(stjames.Molecule(**stjames_mol_dict).to_xyz())
101
101
 
102
102
 
103
103
  def _embed_rdkit_mol(rdkm: RdkitMol) -> RdkitMol:
104
104
  try:
105
- AllChem.SanitizeMol(rdkm)
105
+ AllChem.SanitizeMol(rdkm) # type: ignore [attr-defined]
106
106
  except Exception as e:
107
107
  raise ValueError("Molecule could not be generated -- invalid chemistry!") from e
108
108
 
109
- rdkm = AllChem.AddHs(rdkm)
109
+ rdkm = AllChem.AddHs(rdkm) # type: ignore [attr-defined]
110
110
  try:
111
- assert AllChem.EmbedMolecule(rdkm, maxAttempts=200) >= 0
111
+ assert AllChem.EmbedMolecule(rdkm, maxAttempts=200) >= 0 # type: ignore [attr-defined]
112
112
  except AssertionError as e:
113
- status1 = AllChem.EmbedMolecule(rdkm, maxAttempts=200, useRandomCoords=True)
113
+ status1 = AllChem.EmbedMolecule(rdkm, maxAttempts=200, useRandomCoords=True) # type: ignore [attr-defined]
114
114
  if status1 < 0:
115
115
  raise ValueError("Cannot embed molecule!") from e
116
116
  try:
117
- assert AllChem.MMFFOptimizeMolecule(rdkm, maxIters=200) >= 0 # type: ignore [call-arg]
117
+ assert AllChem.MMFFOptimizeMolecule(rdkm, maxIters=200) >= 0 # type: ignore [attr-defined]
118
118
  except AssertionError:
119
119
  pass
120
120
 
@@ -477,9 +477,9 @@ async def _single_energy(
477
477
  get_api_key()
478
478
  method = stjames.Method(method)
479
479
 
480
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
480
+ if mol.GetNumConformers() == 0:
481
481
  mol = _embed_rdkit_mol(mol)
482
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
482
+ if mol.GetNumConformers() == 0:
483
483
  raise NoConformersError("This molecule has no conformers")
484
484
 
485
485
  if method not in FAST_METHODS:
@@ -489,7 +489,7 @@ async def _single_energy(
489
489
 
490
490
  workflow_uuids = []
491
491
  for conformer in mol.GetConformers():
492
- cid = conformer.GetId() # type: ignore [call-arg]
492
+ cid = conformer.GetId()
493
493
  stjames_mol = _rdkit_to_stjames(mol, cid)
494
494
  post = rowan.submit_workflow(
495
495
  name=name,
@@ -623,9 +623,9 @@ async def _single_optimize(
623
623
  get_api_key()
624
624
  method = stjames.Method(method)
625
625
 
626
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
626
+ if mol.GetNumConformers() == 0:
627
627
  mol = _embed_rdkit_mol(mol)
628
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
628
+ if mol.GetNumConformers() == 0:
629
629
  raise NoConformersError("This molecule has no conformers")
630
630
 
631
631
  if method not in FAST_METHODS:
@@ -637,7 +637,7 @@ async def _single_optimize(
637
637
 
638
638
  workflow_uuids = []
639
639
  for conformer in mol.GetConformers():
640
- cid = conformer.GetId() # type: ignore [call-arg]
640
+ cid = conformer.GetId()
641
641
  stjames_mol = _rdkit_to_stjames(mol, cid)
642
642
 
643
643
  post = rowan.submit_workflow(
@@ -677,7 +677,7 @@ async def _single_optimize(
677
677
  energies = [cacluation[-1]["energy"] for cacluation in calculations]
678
678
 
679
679
  for i, conformer in enumerate(optimized_mol.GetConformers()):
680
- conformer.SetPositions(np.array(optimized_positions[i])) # type: ignore [attr-defined]
680
+ conformer.SetPositions(np.array(optimized_positions[i]))
681
681
 
682
682
  return {
683
683
  "molecule": mol,
@@ -796,9 +796,9 @@ async def _single_conformers(
796
796
  get_api_key()
797
797
  method = stjames.Method(method)
798
798
 
799
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
799
+ if mol.GetNumConformers() == 0:
800
800
  mol = _embed_rdkit_mol(mol)
801
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
801
+ if mol.GetNumConformers() == 0:
802
802
  raise NoConformersError("This molecule has no conformers")
803
803
 
804
804
  if method not in FAST_METHODS:
@@ -858,12 +858,12 @@ async def _single_conformers(
858
858
  lowest_n_uuids = [item[1][0] for item in sorted_data[:num_conformers]]
859
859
  lowest_energies = [item[0] for item in sorted_data[:num_conformers]]
860
860
 
861
- AllChem.EmbedMultipleConfs(mol, numConfs=num_conformers)
861
+ AllChem.EmbedMultipleConfs(mol, numConfs=num_conformers) # type: ignore [attr-defined]
862
862
 
863
863
  for i, conformer in enumerate(mol.GetConformers()):
864
864
  atoms = rowan.retrieve_calculation_molecules(lowest_n_uuids[i])[-1]["atoms"]
865
865
  pos = [atom["position"] for atom in atoms]
866
- conformer.SetPositions(np.array(pos)) # type: ignore [attr-defined]
866
+ conformer.SetPositions(np.array(pos))
867
867
 
868
868
  return {
869
869
  "molecule": mol,
@@ -959,9 +959,9 @@ async def _single_charges(
959
959
  get_api_key()
960
960
  method = stjames.Method(method)
961
961
 
962
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
962
+ if mol.GetNumConformers() == 0:
963
963
  mol = _embed_rdkit_mol(mol)
964
- if mol.GetNumConformers() == 0: # type: ignore [call-arg]
964
+ if mol.GetNumConformers() == 0:
965
965
  raise NoConformersError("This molecule has no conformers")
966
966
 
967
967
  if method not in FAST_METHODS:
@@ -971,7 +971,7 @@ async def _single_charges(
971
971
 
972
972
  workflow_uuids = []
973
973
  for conformer in mol.GetConformers():
974
- cid = conformer.GetId() # type: ignore [call-arg]
974
+ cid = conformer.GetId()
975
975
 
976
976
  post = rowan.submit_workflow(
977
977
  name=name,
rowan/workflow.py CHANGED
@@ -68,7 +68,7 @@ class Workflow(BaseModel):
68
68
  """
69
69
  Loads workflow data from the database and updates the current instance.
70
70
 
71
- :param in_place: Whether to update the current instance in-place.
71
+ :param in_place: Whether to update the current instance in-place.
72
72
  :return: The updated instance (self).
73
73
  :raises HTTPError: If the API request fails.
74
74
  """
@@ -217,7 +217,7 @@ class Workflow(BaseModel):
217
217
 
218
218
 
219
219
  def submit_workflow(
220
- workflow_type: str,
220
+ workflow_type: stjames.WORKFLOW_NAME,
221
221
  workflow_data: dict[str, Any] | None = None,
222
222
  initial_molecule: dict[str, Any] | StJamesMolecule | RdkitMol | None = None,
223
223
  initial_smiles: str | None = None,
@@ -241,6 +241,11 @@ def submit_workflow(
241
241
  :raises ValueError: If neither `initial_smiles` nor a valid `initial_molecule` is provided.
242
242
  :raises HTTPError: If the API request fails.
243
243
  """
244
+ if workflow_type not in stjames.WORKFLOW_MAPPING:
245
+ raise ValueError(
246
+ "Invalid workflow type. Must be one of:\n " + "\n ".join(stjames.WORKFLOW_MAPPING)
247
+ )
248
+
244
249
  data = {
245
250
  "name": name,
246
251
  "folder_uuid": folder_uuid,
@@ -300,7 +305,7 @@ def list_workflows(
300
305
  public: bool | None = None,
301
306
  starred: bool | None = None,
302
307
  status: int | None = None,
303
- workflow_type: str | None = None,
308
+ workflow_type: stjames.WORKFLOW_NAME | None = None,
304
309
  page: int = 0,
305
310
  size: int = 10,
306
311
  ) -> list[Workflow]:
@@ -411,7 +416,7 @@ def submit_conformer_search_workflow(
411
416
  conf_gen_mode: str = "rapid",
412
417
  final_method: stjames.Method | str = "aimnet2_wb97md3",
413
418
  solvent: str | None = None,
414
- transistion_state: bool = False,
419
+ transition_state: bool = False,
415
420
  name: str = "Conformer Search Workflow",
416
421
  folder_uuid: str | None = None,
417
422
  max_credits: int | None = None,
@@ -428,7 +433,7 @@ def submit_conformer_search_workflow(
428
433
  for options.
429
434
  :param solvent: The solvent to use for the final optimization. See [the list of available solvents](https://github.com/rowansci/stjames-public/blob/master/stjames/solvent.py)
430
435
  for valid values. Be aware that not all methods support solvents.
431
- :param transistion_state: Whether to optimize the transition state.
436
+ :param transition_state: Whether to optimize the transition state.
432
437
  :param name: The name of the workflow.
433
438
  :param folder_uuid: The UUID of the folder to place the workflow in.
434
439
  :param max_credits: The maximum number of credits to use for the workflow.
@@ -452,7 +457,7 @@ def submit_conformer_search_workflow(
452
457
  tasks=["optimize"],
453
458
  mode=stjames.Mode.AUTO,
454
459
  solvent_settings={"solvent": solvent, "model": solvent_model} if solvent else None,
455
- opt_settings={"transition_state": transistion_state, "constraints": []},
460
+ opt_settings={"transition_state": transition_state, "constraints": []},
456
461
  )
457
462
 
458
463
  msos = stjames.MultiStageOptSettings(
@@ -466,7 +471,7 @@ def submit_conformer_search_workflow(
466
471
  "conf_gen_mode": conf_gen_mode,
467
472
  "mso_mode": "manual",
468
473
  "solvent": solvent,
469
- "transistion_state": transistion_state,
474
+ "transition_state": transition_state,
470
475
  }
471
476
 
472
477
  data = {
@@ -639,7 +644,7 @@ def submit_fukui_workflow(
639
644
  optimization_method: str = "gfn2_xtb",
640
645
  fukui_method: str = "gfn1_xtb",
641
646
  solvent_settings: dict[str, str] | None = None,
642
- name: str = "Redox Potential Workflow",
647
+ name: str = "Fukui Workflow",
643
648
  folder_uuid: str | None = None,
644
649
  max_credits: int | None = None,
645
650
  ) -> Workflow:
@@ -647,9 +652,9 @@ def submit_fukui_workflow(
647
652
  Submits a fukui workflow to the API.
648
653
 
649
654
  :param initial_molecule: The molecule to calculate the fukui indices of.
650
- :optimization_method: The method to use for the optimization.
651
- :fukui_method: The method to use for the fukui calculation.
652
- :solvent_settings: The solvent settings to use for the fukui calculation.
655
+ :param optimization_method: The method to use for the optimization.
656
+ :param fukui_method: The method to use for the fukui calculation.
657
+ :param solvent_settings: The solvent settings to use for the fukui calculation.
653
658
  :param name: The name of the workflow.
654
659
  :param folder_uuid: The UUID of the folder to place the workflow in.
655
660
  :param max_credits: The maximum number of credits to use for the workflow.
@@ -665,9 +670,9 @@ def submit_fukui_workflow(
665
670
  fukui_settings = stjames.Settings(method=fukui_method, solvent_settings=solvent_settings)
666
671
 
667
672
  workflow_data = {
668
- "opt_settings": optimization_settings,
673
+ "opt_settings": optimization_settings.model_dump(),
669
674
  "opt_engine": stjames.Method(optimization_method).default_engine(),
670
- "fukui_settings": fukui_settings,
675
+ "fukui_settings": fukui_settings.model_dump(),
671
676
  "fukui_engine": stjames.Method(fukui_method).default_engine(),
672
677
  }
673
678
 
@@ -828,6 +833,56 @@ def submit_scan_workflow(
828
833
  return Workflow(**response.json())
829
834
 
830
835
 
836
+ def submit_macropka_workflow(
837
+ initial_smiles: str,
838
+ min_pH: int = 0,
839
+ max_pH: int = 14,
840
+ min_charge: int = -2,
841
+ max_charge: int = 2,
842
+ compute_solvation_energy: bool = True,
843
+ name: str = "Macropka Workflow",
844
+ folder_uuid: str | None = None,
845
+ max_credits: int | None = None,
846
+ ) -> Workflow:
847
+ """
848
+ Submits a macropka workflow to the API.
849
+
850
+ :param initial_smiles: The molecule used in the macropka workflow.
851
+ :param min_pH: The minimum pH to use in the macropka workflow.
852
+ :param max_pH: The maximum pH to use in the macropka workflow.
853
+ :param min_charge: The minimum charge to use in the macropka workflow.
854
+ :param max_charge: The maximum charge to use in the macropka workflow.
855
+ :param compute_solvation_energy: Whether to compute the solvation energy.
856
+ :param name: The name of the workflow.
857
+ :param folder_uuid: The UUID of the folder to store the workflow in.
858
+ :param max_credits: The maximum number of credits to use for the workflow.
859
+ :return: A Workflow object representing the submitted workflow.
860
+ :raises requests.HTTPError: if the request to the API fails.
861
+ """
862
+
863
+ workflow_data = {
864
+ "min_pH": min_pH,
865
+ "max_pH": max_pH,
866
+ "min_charge": min_charge,
867
+ "max_charge": max_charge,
868
+ "compute_solvation_energy": compute_solvation_energy,
869
+ }
870
+
871
+ data = {
872
+ "name": name,
873
+ "folder_uuid": folder_uuid,
874
+ "workflow_type": "macropka",
875
+ "workflow_data": workflow_data,
876
+ "initial_smiles": initial_smiles,
877
+ "max_credits": max_credits,
878
+ }
879
+
880
+ with api_client() as client:
881
+ response = client.post("/workflow", json=data)
882
+ response.raise_for_status()
883
+ return Workflow(**response.json())
884
+
885
+
831
886
  def submit_irc_workflow(
832
887
  initial_molecule: dict[str, Any] | StJamesMolecule | RdkitMol | None = None,
833
888
  method: stjames.Method | str = "uma_m_omol",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rowan-python
3
- Version: 2.0.0
3
+ Version: 2.0.2
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
@@ -1,14 +1,14 @@
1
- rowan/__init__.py,sha256=KiUTRLxIjUZ__oJLeOzS28SfNPFLe5Y9PBIydjSkZFI,149
1
+ rowan/__init__.py,sha256=KWt0ConmoDkmFZUk1lKO7eXFwRbaVU0oLLnYvOafLVc,148
2
2
  rowan/constants.py,sha256=ZZvv3L0b2y3dMGlWGeaRmx40J5tBrpxNxvJgjP1TNjg,37
3
3
  rowan/folder.py,sha256=n9WkjHMweQLtVcWUvCttOrmezvUdbFxam_eDEMzLF_A,6791
4
4
  rowan/protein.py,sha256=TOCsN50RaYh3Ja4GBxzH6R7qUk-Y9Xv7y1WU3buPFis,7778
5
5
  rowan/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  rowan/user.py,sha256=Dl--NPUPATKCs2VmILsW8HnLiunG0Lxr0n6mKuHm21U,3891
7
7
  rowan/utils.py,sha256=SyKvrvlgZ2BKZKRKziZdVZvV_Y4Hld77Bris0lerA9o,3296
8
- rowan/workflow.py,sha256=Iq6ySvOxOJf30gIH9RtQMSRux9wgEVR0ctpMtjjgI8s,37488
8
+ rowan/workflow.py,sha256=4BKDQJLVZsn65cM5SMfbub9M1GYOjF12GbdADhqaa1k,39496
9
9
  rowan/rowan_rdkit/__init__.py,sha256=EATX2VRzywzKxqkpCUMTf7RNQLkWsfi5VcCNDW6EIiw,503
10
- rowan/rowan_rdkit/chem_utils.py,sha256=1WAczzwNzIlghgP7eT2l2LhWW4yUpND5XC475q2lXaA,35044
11
- rowan_python-2.0.0.dist-info/METADATA,sha256=JdaZgAaitRmoHQ0Gl-jR7XyIGdXrw0-ktUNsKCw4ITA,1598
12
- rowan_python-2.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- rowan_python-2.0.0.dist-info/licenses/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
14
- rowan_python-2.0.0.dist-info/RECORD,,
10
+ rowan/rowan_rdkit/chem_utils.py,sha256=i7-EmAcmvHYtc9NiZblLY_k2DoQKofAZo5KT2qtkUCI,34775
11
+ rowan_python-2.0.2.dist-info/METADATA,sha256=dnQGAYLRXOsMxaKdBt5NjQBd6osWMXCDtNoTkwRjDIQ,1598
12
+ rowan_python-2.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ rowan_python-2.0.2.dist-info/licenses/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
14
+ rowan_python-2.0.2.dist-info/RECORD,,