rowan-mcp 1.0.2__py3-none-any.whl → 2.0.1__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.
Potentially problematic release.
This version of rowan-mcp might be problematic. Click here for more details.
- rowan_mcp/__init__.py +1 -1
- rowan_mcp/__main__.py +3 -5
- rowan_mcp/functions/admet.py +0 -5
- rowan_mcp/functions/bde.py +1 -8
- rowan_mcp/functions/conformers.py +1 -4
- rowan_mcp/functions/descriptors.py +1 -4
- rowan_mcp/functions/docking.py +6 -56
- rowan_mcp/functions/electronic_properties.py +1 -4
- rowan_mcp/functions/folder_management.py +1 -8
- rowan_mcp/functions/fukui.py +1 -4
- rowan_mcp/functions/hydrogen_bond_basicity.py +1 -8
- rowan_mcp/functions/multistage_opt.py +1 -4
- rowan_mcp/functions/pka.py +1 -8
- rowan_mcp/functions/redox_potential.py +2 -5
- rowan_mcp/functions/system_management.py +1 -8
- rowan_mcp/functions/tautomers.py +1 -4
- rowan_mcp/functions_v2/BENCHMARK.md +86 -0
- rowan_mcp/functions_v2/molecule_lookup.py +232 -0
- rowan_mcp/functions_v2/protein_management.py +141 -0
- rowan_mcp/functions_v2/submit_basic_calculation_workflow.py +195 -0
- rowan_mcp/functions_v2/submit_conformer_search_workflow.py +158 -0
- rowan_mcp/functions_v2/submit_descriptors_workflow.py +52 -0
- rowan_mcp/functions_v2/submit_docking_workflow.py +244 -0
- rowan_mcp/functions_v2/submit_fukui_workflow.py +114 -0
- rowan_mcp/functions_v2/submit_irc_workflow.py +58 -0
- rowan_mcp/functions_v2/submit_macropka_workflow.py +99 -0
- rowan_mcp/functions_v2/submit_pka_workflow.py +72 -0
- rowan_mcp/functions_v2/submit_protein_cofolding_workflow.py +88 -0
- rowan_mcp/functions_v2/submit_redox_potential_workflow.py +55 -0
- rowan_mcp/functions_v2/submit_scan_workflow.py +82 -0
- rowan_mcp/functions_v2/submit_solubility_workflow.py +157 -0
- rowan_mcp/functions_v2/submit_tautomer_search_workflow.py +51 -0
- rowan_mcp/functions_v2/workflow_management_v2.py +382 -0
- rowan_mcp/server.py +109 -144
- rowan_mcp/tests/basic_calculation_from_json.py +0 -0
- rowan_mcp/tests/basic_calculation_with_constraint.py +33 -0
- rowan_mcp/tests/basic_calculation_with_solvent.py +0 -0
- rowan_mcp/tests/bde.py +37 -0
- rowan_mcp/tests/benchmark_queries.md +120 -0
- rowan_mcp/tests/cofolding_screen.py +131 -0
- rowan_mcp/tests/conformer_dependent_redox.py +37 -0
- rowan_mcp/tests/conformers.py +31 -0
- rowan_mcp/tests/data.json +189 -0
- rowan_mcp/tests/docking_screen.py +157 -0
- rowan_mcp/tests/irc.py +24 -0
- rowan_mcp/tests/macropka.py +13 -0
- rowan_mcp/tests/multistage_opt.py +13 -0
- rowan_mcp/tests/optimization.py +21 -0
- rowan_mcp/tests/phenol_pka.py +36 -0
- rowan_mcp/tests/pka.py +36 -0
- rowan_mcp/tests/protein_cofolding.py +17 -0
- rowan_mcp/tests/scan.py +28 -0
- {rowan_mcp-1.0.2.dist-info → rowan_mcp-2.0.1.dist-info}/METADATA +38 -45
- rowan_mcp-2.0.1.dist-info/RECORD +69 -0
- rowan_mcp-1.0.2.dist-info/RECORD +0 -34
- {rowan_mcp-1.0.2.dist-info → rowan_mcp-2.0.1.dist-info}/WHEEL +0 -0
- {rowan_mcp-1.0.2.dist-info → rowan_mcp-2.0.1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rowan v2 API: Redox Potential Workflow
|
|
3
|
+
Calculate reduction and oxidation potentials for molecules.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
import rowan
|
|
8
|
+
import stjames
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def submit_redox_potential_workflow(
|
|
12
|
+
initial_molecule: Annotated[str, "SMILES string for redox potential calculation"],
|
|
13
|
+
reduction: Annotated[bool, "Whether to calculate reduction potential (gaining electron)"] = False,
|
|
14
|
+
oxidization: Annotated[bool, "Whether to calculate oxidation potential (losing electron)"] = True,
|
|
15
|
+
mode: Annotated[str, "Calculation mode: 'rapid' (fast), 'careful' (balanced), or 'meticulous' (thorough)"] = "rapid",
|
|
16
|
+
name: Annotated[str, "Workflow name for identification and tracking"] = "Redox Potential Workflow",
|
|
17
|
+
folder_uuid: Annotated[str, "UUID of folder to organize this workflow. Empty string uses default folder"] = "",
|
|
18
|
+
max_credits: Annotated[int, "Maximum credits to spend on this calculation. 0 for no limit"] = 0
|
|
19
|
+
):
|
|
20
|
+
"""Submit a redox potential calculation workflow using Rowan v2 API.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
initial_molecule: SMILES string for redox potential calculation
|
|
24
|
+
reduction: Whether to calculate reduction potential (gaining electron)
|
|
25
|
+
oxidization: Whether to calculate oxidation potential (losing electron)
|
|
26
|
+
mode: Calculation mode: 'rapid' (fast), 'careful' (balanced), or 'meticulous' (thorough)
|
|
27
|
+
name: Workflow name for identification and tracking
|
|
28
|
+
folder_uuid: UUID of folder to organize this workflow. Empty string uses default folder.
|
|
29
|
+
max_credits: Maximum credits to spend on this calculation. 0 for no limit.
|
|
30
|
+
|
|
31
|
+
Calculates reduction and/or oxidation potentials for a molecule using
|
|
32
|
+
quantum chemistry methods.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Workflow object representing the submitted workflow
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
# Simple redox potential from SMILES
|
|
39
|
+
result = submit_redox_potential_workflow(
|
|
40
|
+
initial_molecule="Cc1ccccc1", # Toluene
|
|
41
|
+
reduction=True,
|
|
42
|
+
oxidization=True,
|
|
43
|
+
name="Toluene Redox Potential"
|
|
44
|
+
)
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
return rowan.submit_redox_potential_workflow(
|
|
48
|
+
initial_molecule=stjames.Molecule.from_smiles(initial_molecule),
|
|
49
|
+
reduction=reduction,
|
|
50
|
+
oxidization=oxidization,
|
|
51
|
+
mode=mode,
|
|
52
|
+
name=name,
|
|
53
|
+
folder_uuid=folder_uuid if folder_uuid else None,
|
|
54
|
+
max_credits=max_credits if max_credits > 0 else None
|
|
55
|
+
)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rowan v2 API: Scan Workflow
|
|
3
|
+
Perform potential energy surface scans along molecular coordinates.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Dict, Any, Annotated
|
|
7
|
+
import rowan
|
|
8
|
+
import stjames
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
def submit_scan_workflow(
|
|
12
|
+
initial_molecule: Annotated[str, "SMILES string to scan"],
|
|
13
|
+
scan_settings: Annotated[str, "JSON string of scan parameters: '{\"type\": \"dihedral\"/\"bond\"/\"angle\", \"atoms\": [1-indexed], \"start\": value, \"stop\": value, \"num\": points}'"] = "",
|
|
14
|
+
calculation_engine: Annotated[str, "Computational engine: 'omol25', 'xtb', 'psi4'"] = "omol25",
|
|
15
|
+
calculation_method: Annotated[str, "Computational method (e.g., 'uma_m_omol', 'gfn2-xtb', 'b3lyp-d3bj')"] = "uma_m_omol",
|
|
16
|
+
wavefront_propagation: Annotated[bool, "Whether to use wavefront propagation for scan"] = True,
|
|
17
|
+
name: Annotated[str, "Workflow name for identification and tracking"] = "Scan Workflow",
|
|
18
|
+
folder_uuid: Annotated[str, "UUID of folder to organize this workflow. Empty string uses default folder"] = "",
|
|
19
|
+
max_credits: Annotated[int, "Maximum credits to spend on this calculation. 0 for no limit"] = 0
|
|
20
|
+
):
|
|
21
|
+
"""Submit a potential energy surface scan workflow using Rowan v2 API.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
initial_molecule: SMILES string to scan
|
|
25
|
+
scan_settings: JSON string of scan parameters: '{"type": "dihedral"/"bond"/"angle", "atoms": [1-indexed], "start": value, "stop": value, "num": points}'
|
|
26
|
+
calculation_engine: Computational engine: 'omol25', 'xtb', or 'psi4'
|
|
27
|
+
calculation_method: Calculation method (depends on engine): 'uma_m_omol', 'gfn2_xtb', 'r2scan_3c'
|
|
28
|
+
wavefront_propagation: Use previous scan point geometries as starting points for faster convergence
|
|
29
|
+
name: Workflow name for identification and tracking
|
|
30
|
+
folder_uuid: UUID of folder to organize this workflow. Empty string uses default folder.
|
|
31
|
+
max_credits: Maximum credits to spend on this calculation. 0 for no limit.
|
|
32
|
+
|
|
33
|
+
Performs systematic scans along specified molecular coordinates (bonds, angles,
|
|
34
|
+
or dihedrals) to map the potential energy surface.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Workflow object representing the submitted workflow
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
# Water angle scan
|
|
41
|
+
result = submit_scan_workflow(
|
|
42
|
+
initial_molecule="O", # Water SMILES
|
|
43
|
+
name="Water Angle scan",
|
|
44
|
+
scan_settings='{"type": "angle", "atoms": [2, 1, 3], "start": 100, "stop": 110, "num": 5}',
|
|
45
|
+
calculation_method="GFN2-xTB",
|
|
46
|
+
calculation_engine="xtb"
|
|
47
|
+
)
|
|
48
|
+
"""
|
|
49
|
+
# Parse scan_settings if provided
|
|
50
|
+
parsed_scan_settings = None
|
|
51
|
+
if scan_settings:
|
|
52
|
+
try:
|
|
53
|
+
parsed_scan_settings = json.loads(scan_settings)
|
|
54
|
+
except (json.JSONDecodeError, ValueError) as e:
|
|
55
|
+
raise ValueError(f"Invalid scan_settings format: {e}")
|
|
56
|
+
|
|
57
|
+
# Validate and convert scan_settings
|
|
58
|
+
if parsed_scan_settings is not None:
|
|
59
|
+
# Convert step to num if step is provided instead of num
|
|
60
|
+
if 'step' in parsed_scan_settings and 'num' not in parsed_scan_settings:
|
|
61
|
+
start = parsed_scan_settings.get('start', 0)
|
|
62
|
+
stop = parsed_scan_settings.get('stop', 360)
|
|
63
|
+
step = parsed_scan_settings['step']
|
|
64
|
+
parsed_scan_settings['num'] = int((stop - start) / step) + 1
|
|
65
|
+
del parsed_scan_settings['step'] # Remove step as API doesn't accept it
|
|
66
|
+
|
|
67
|
+
# Validate required fields
|
|
68
|
+
required_fields = ['type', 'atoms', 'start', 'stop', 'num']
|
|
69
|
+
missing_fields = [field for field in required_fields if field not in parsed_scan_settings]
|
|
70
|
+
if missing_fields:
|
|
71
|
+
raise ValueError(f"Missing required fields in scan_settings: {missing_fields}")
|
|
72
|
+
|
|
73
|
+
return rowan.submit_scan_workflow(
|
|
74
|
+
initial_molecule=stjames.Molecule.from_smiles(initial_molecule),
|
|
75
|
+
scan_settings=parsed_scan_settings,
|
|
76
|
+
calculation_engine=calculation_engine,
|
|
77
|
+
calculation_method=calculation_method,
|
|
78
|
+
wavefront_propagation=wavefront_propagation,
|
|
79
|
+
name=name,
|
|
80
|
+
folder_uuid=folder_uuid if folder_uuid else None,
|
|
81
|
+
max_credits=max_credits if max_credits > 0 else None
|
|
82
|
+
)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rowan v2 API: Solubility Workflow
|
|
3
|
+
Predict molecular solubility in various solvents at different temperatures.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import List, Annotated
|
|
7
|
+
import rowan
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def submit_solubility_workflow(
|
|
12
|
+
initial_smiles: Annotated[str, "SMILES string of the molecule for solubility prediction"],
|
|
13
|
+
solvents: Annotated[str, "JSON string list of solvents as SMILES or names (e.g., '[\"water\", \"ethanol\", \"CCO\"]'). Empty string uses defaults"] = "",
|
|
14
|
+
temperatures: Annotated[str, "JSON string list of temperatures in Kelvin (e.g., '[298.15, 310.15]'). Empty string uses default range"] = "",
|
|
15
|
+
name: Annotated[str, "Workflow name for identification and tracking"] = "Solubility Workflow",
|
|
16
|
+
folder_uuid: Annotated[str, "UUID of folder to organize this workflow. Empty string uses default folder"] = "",
|
|
17
|
+
max_credits: Annotated[int, "Maximum credits to spend on this calculation. 0 for no limit"] = 0
|
|
18
|
+
):
|
|
19
|
+
"""Submit a solubility prediction workflow using Rowan v2 API.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
initial_smiles: SMILES string of the molecule for solubility prediction
|
|
23
|
+
solvents: JSON string list of solvents as SMILES or names (e.g., '["water", "ethanol", "CCO"]'). Empty string uses defaults
|
|
24
|
+
temperatures: JSON string list of temperatures in Kelvin (e.g., '[298.15, 310.15]'). Empty string uses default range
|
|
25
|
+
name: Workflow name for identification and tracking
|
|
26
|
+
folder_uuid: UUID of folder to organize this workflow. Empty string uses default folder.
|
|
27
|
+
max_credits: Maximum credits to spend on this calculation. 0 for no limit.
|
|
28
|
+
|
|
29
|
+
Predicts solubility (log S) of a molecule in multiple solvents at various temperatures
|
|
30
|
+
using machine learning models.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Workflow object representing the submitted workflow
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
# Basic solubility prediction
|
|
37
|
+
result = submit_solubility_workflow(
|
|
38
|
+
initial_smiles="CC(=O)Nc1ccc(O)cc1",
|
|
39
|
+
solvents='["water", "ethanol"]',
|
|
40
|
+
temperatures='[298.15, 310.15]'
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# With SMILES solvents
|
|
44
|
+
result = submit_solubility_workflow(
|
|
45
|
+
initial_smiles="CC(=O)O",
|
|
46
|
+
solvents='["O", "CCO", "CCCCCC"]',
|
|
47
|
+
temperatures='[273.15, 298.15, 323.15]'
|
|
48
|
+
)
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
# Parse solvents parameter - handle string input
|
|
52
|
+
parsed_solvents = None
|
|
53
|
+
if solvents:
|
|
54
|
+
# Handle various string formats
|
|
55
|
+
solvents = solvents.strip()
|
|
56
|
+
if solvents.startswith('[') and solvents.endswith(']'):
|
|
57
|
+
# JSON array format like '["water", "ethanol"]'
|
|
58
|
+
try:
|
|
59
|
+
parsed_solvents = json.loads(solvents)
|
|
60
|
+
except (json.JSONDecodeError, ValueError):
|
|
61
|
+
# Failed to parse as JSON, try as comma-separated
|
|
62
|
+
solvents = solvents.strip('[]').replace('"', '').replace("'", "")
|
|
63
|
+
parsed_solvents = [s.strip() for s in solvents.split(',') if s.strip()]
|
|
64
|
+
elif ',' in solvents:
|
|
65
|
+
# Comma-separated format like 'water, ethanol'
|
|
66
|
+
parsed_solvents = [s.strip() for s in solvents.split(',') if s.strip()]
|
|
67
|
+
else:
|
|
68
|
+
# Single solvent as string like 'water'
|
|
69
|
+
parsed_solvents = [solvents]
|
|
70
|
+
|
|
71
|
+
# Convert solvent names to SMILES if needed
|
|
72
|
+
solvent_name_to_smiles = {
|
|
73
|
+
'water': 'O',
|
|
74
|
+
'ethanol': 'CCO',
|
|
75
|
+
'dmso': 'CS(=O)C',
|
|
76
|
+
'acetone': 'CC(=O)C',
|
|
77
|
+
'methanol': 'CO',
|
|
78
|
+
'chloroform': 'C(Cl)(Cl)Cl',
|
|
79
|
+
'dichloromethane': 'C(Cl)Cl',
|
|
80
|
+
'toluene': 'Cc1ccccc1',
|
|
81
|
+
'benzene': 'c1ccccc1',
|
|
82
|
+
'hexane': 'CCCCCC',
|
|
83
|
+
'ether': 'CCOCC',
|
|
84
|
+
'diethyl ether': 'CCOCC',
|
|
85
|
+
'thf': 'C1CCOC1',
|
|
86
|
+
'tetrahydrofuran': 'C1CCOC1',
|
|
87
|
+
'dioxane': 'C1COCCO1',
|
|
88
|
+
'acetonitrile': 'CC#N',
|
|
89
|
+
'pyridine': 'c1ccncc1'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
converted_solvents = []
|
|
93
|
+
for solvent in parsed_solvents:
|
|
94
|
+
solvent_lower = solvent.lower().strip()
|
|
95
|
+
if solvent_lower in solvent_name_to_smiles:
|
|
96
|
+
converted_solvents.append(solvent_name_to_smiles[solvent_lower])
|
|
97
|
+
else:
|
|
98
|
+
# Assume it's already a SMILES string or use as-is
|
|
99
|
+
converted_solvents.append(solvent)
|
|
100
|
+
parsed_solvents = converted_solvents
|
|
101
|
+
|
|
102
|
+
# Validate the final solvent SMILES to catch issues early
|
|
103
|
+
try:
|
|
104
|
+
from rdkit import Chem
|
|
105
|
+
for i, solvent_smiles in enumerate(parsed_solvents):
|
|
106
|
+
mol = Chem.MolFromSmiles(solvent_smiles)
|
|
107
|
+
if mol is None:
|
|
108
|
+
raise ValueError(f"Invalid solvent SMILES: '{solvent_smiles}' at position {i}")
|
|
109
|
+
except ImportError:
|
|
110
|
+
# RDKit not available for validation, proceed anyway
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
# Parse temperatures parameter - handle string input
|
|
114
|
+
parsed_temperatures = None
|
|
115
|
+
if temperatures:
|
|
116
|
+
# Handle various string formats
|
|
117
|
+
temperatures = temperatures.strip()
|
|
118
|
+
if temperatures.startswith('[') and temperatures.endswith(']'):
|
|
119
|
+
# JSON array format like '[298.15, 310.15]'
|
|
120
|
+
try:
|
|
121
|
+
parsed_temperatures = json.loads(temperatures)
|
|
122
|
+
except (json.JSONDecodeError, ValueError):
|
|
123
|
+
# Failed to parse as JSON, try as comma-separated
|
|
124
|
+
temperatures = temperatures.strip('[]').replace('"', '').replace("'", "")
|
|
125
|
+
parsed_temperatures = [float(t.strip()) for t in temperatures.split(',') if t.strip()]
|
|
126
|
+
elif ',' in temperatures:
|
|
127
|
+
# Comma-separated format like '298.15, 310.15'
|
|
128
|
+
parsed_temperatures = [float(t.strip()) for t in temperatures.split(',') if t.strip()]
|
|
129
|
+
else:
|
|
130
|
+
# Single temperature as string like '298.15'
|
|
131
|
+
parsed_temperatures = [float(temperatures)]
|
|
132
|
+
|
|
133
|
+
# Validate the main SMILES string early to catch issues
|
|
134
|
+
try:
|
|
135
|
+
from rdkit import Chem
|
|
136
|
+
mol = Chem.MolFromSmiles(initial_smiles)
|
|
137
|
+
if mol is None:
|
|
138
|
+
raise ValueError(f"Invalid initial SMILES: '{initial_smiles}'")
|
|
139
|
+
except ImportError:
|
|
140
|
+
# RDKit not available for validation, proceed anyway
|
|
141
|
+
pass
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
result = rowan.submit_solubility_workflow(
|
|
145
|
+
initial_smiles=initial_smiles,
|
|
146
|
+
solvents=parsed_solvents,
|
|
147
|
+
temperatures=parsed_temperatures,
|
|
148
|
+
name=name,
|
|
149
|
+
folder_uuid=folder_uuid if folder_uuid else None,
|
|
150
|
+
max_credits=max_credits if max_credits > 0 else None
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return result
|
|
154
|
+
|
|
155
|
+
except Exception as e:
|
|
156
|
+
# Re-raise the exception so MCP can handle it
|
|
157
|
+
raise
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rowan v2 API: Tautomer Search Workflow
|
|
3
|
+
Search for tautomeric forms of molecules.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
import rowan
|
|
8
|
+
import stjames
|
|
9
|
+
|
|
10
|
+
def submit_tautomer_search_workflow(
|
|
11
|
+
initial_molecule: Annotated[str, "SMILES string to search for tautomers"],
|
|
12
|
+
mode: Annotated[str, "Search mode: 'rapid' (fast), 'careful' (balanced), or 'meticulous' (thorough)"] = "careful",
|
|
13
|
+
name: Annotated[str, "Workflow name for identification and tracking"] = "Tautomer Search Workflow",
|
|
14
|
+
folder_uuid: Annotated[str, "UUID of folder to organize this workflow. Empty string uses default folder"] = "",
|
|
15
|
+
max_credits: Annotated[int, "Maximum credits to spend on this calculation. 0 for no limit"] = 0
|
|
16
|
+
):
|
|
17
|
+
"""Submit a tautomer search workflow using Rowan v2 API.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
initial_molecule: SMILES string to search for tautomers
|
|
21
|
+
mode: Search mode: 'rapid' (fast), 'careful' (balanced), or 'meticulous' (thorough)
|
|
22
|
+
name: Workflow name for identification and tracking
|
|
23
|
+
folder_uuid: UUID of folder to organize this workflow. Empty string uses default folder.
|
|
24
|
+
max_credits: Maximum credits to spend on this calculation. 0 for no limit.
|
|
25
|
+
|
|
26
|
+
Searches for different tautomeric forms of a molecule and evaluates their
|
|
27
|
+
relative stabilities. Tautomers are structural isomers that readily interconvert.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Workflow object representing the submitted workflow
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
# Basic tautomer search
|
|
34
|
+
result = submit_tautomer_search_workflow(
|
|
35
|
+
initial_molecule="CC(=O)CC(=O)C"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Meticulous search for complex molecule
|
|
39
|
+
result = submit_tautomer_search_workflow(
|
|
40
|
+
initial_molecule="c1ccc2c(c1)ncc(=O)[nH]2",
|
|
41
|
+
mode="meticulous"
|
|
42
|
+
)
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
return rowan.submit_tautomer_search_workflow(
|
|
46
|
+
initial_molecule=stjames.Molecule.from_smiles(initial_molecule),
|
|
47
|
+
mode=mode,
|
|
48
|
+
name=name,
|
|
49
|
+
folder_uuid=folder_uuid if folder_uuid else None,
|
|
50
|
+
max_credits=max_credits if max_credits > 0 else None
|
|
51
|
+
)
|