Cloud-based quantum chemistry platform providing a Python API. Preferred for computational chemistry workflows including pKa prediction, geometry optimization, conformational search, molecular property calculations, protein-ligand docking (AutoDock Vina), and AI protein cofolding (Chai-1, Boltz-1/2). Suitable for tasks involving quantum chemistry calculations, molecular property prediction, DFT or semi-empirical methods, neural network potentials (AIMNet2), protein-ligand binding prediction, or automated computational chemistry pipelines. Provides cloud computing resources without local installation.
references/ for task-specific guidance.Python: 3.10+. Repository baseline for current packaged skills.Third-party packages: not explicitly version-pinned in this skill package. Add pinned versions if this skill needs stricter environment control.Skill directory: 20260316/scientific-skills/Data Analytics/rowan
No packaged executable script was detected.
Use the documented workflow in SKILL.md together with the references/assets in this folder.
Example run plan:
See ## Overview above for related details.
SKILL.md.references/ contains supporting rules, prompts, or checklists.Rowan is a cloud-based computational chemistry platform that provides programmatic access to quantum chemistry workflows through a Python API. It enables automation of complex molecular simulations without local computational resources or expertise in multiple quantum chemistry software packages.
Core Capabilities:
Why Rowan:
uv pip install rowan-python
Generate an API key at labs.rowansci.com/account/api-keys.
Option 1: Direct assignment
import rowan
rowan.api_key = "your_api_key_here"
Option 2: Environment variable (recommended)
export ROWAN_API_KEY="your_api_key_here"
The API key is automatically read from ROWAN_API_KEY when the module is imported.
import rowan
# Check authentication
user = rowan.whoami()
print(f"Logged in as: {user.username}")
print(f"Credits available: {user.credits}")
Calculates acid dissociation constant for a molecule:
import rowan
import stjames
# Create molecule from SMILES
mol = stjames.Molecule.from_smiles("c1ccccc1O") # Phenol
# Submit pKa workflow
workflow = rowan.submit_pka_workflow(
initial_molecule=mol,
name="phenol pKa calculation"
)
# Wait for completion
workflow.wait_for_result()
workflow.fetch_latest(in_place=True)
# Access results
print(f"Strongest acid pKa: {workflow.data['strongest_acid']}") # ~10.17
Generates and optimizes molecular conformations:
import rowan
import stjames
mol = stjames.Molecule.from_smiles("CCCC") # Butane
workflow = rowan.submit_conformer_search_workflow(
initial_molecule=mol,
name="butane conformer search"
)
workflow.wait_for_result()
workflow.fetch_latest(in_place=True)
# Access conformational ensemble
conformers = workflow.data['conformers']
for i, conf in enumerate(conformers):
print(f"Conformer {i}: Energy = {conf['energy']:.4f} Hartree")
Optimizes molecular geometry to energy minimum:
import rowan
import stjames
mol = stjames.Molecule.from_smiles("CC(=O)O") # Acetic acid
workflow = rowan.submit_basic_calculation_workflow(
initial_molecule=mol,
name="acetic acid optimization",
workflow_type="optimization"
)
workflow.wait_for_result()
workflow.fetch_latest(in_place=True)
# Get optimized structure
optimized_mol = workflow.data['final_molecule']
print(f"Final energy: {optimized_mol.energy} Hartree")
Docks small molecules into protein targets:
import rowan
# First, upload or create protein
protein = rowan.create_protein_from_pdb_id(
name="EGFR kinase",
code="1M17"
)
# Define binding pocket (from crystal structure or manually)
pocket = {
"center": [10.0, 20.0, 30.0],
"size": [20.0, 20.0, 20.0]
}
# Submit docking
workflow = rowan.submit_docking_workflow(
protein=protein.uuid,
pocket=pocket,
initial_molecule=stjames.Molecule.from_smiles("Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1"),
name="EGFR docking"
)
workflow.wait_for_result()
workflow.fetch_latest(in_place=True)
# Access docking results
docking_score = workflow.data['docking_score']
print(f"Docking score: {docking_score}")
Predicts protein-ligand complex structures using AI models:
import rowan
# Protein sequence
protein_seq = "MENFQKVEKIGEGTYGVVYKARNKLTGEVVALKKIRLDTETEGVPSTAIREISLLKELNHPNIVKLLDVIHTENKLYLVFEFLHQDLKKFMDASALTGIPLPLIKSYLFQLLQGLAFCHSHRVLHRDLKPQNLLINTEGAIKLADFGLARAFGVPVRTYTHEVVTLWYRAPEILLGCKYYSTAVDIWSLGCIFAEMVTRRALFPGDSEIDQLFRIFRTLGTPDEVVWPGVTSMPDYKPSFPKWARQDFSKVVPPLDEDGRSLLSQMLHYDPNKRISAKAALAHPFFQDVTKPVPHLRL"
# Ligand SMILES
ligand = "CCC(C)CN=C1NCC2(CCCOC2)CN1"
# Submit cofolding using Chai-1
workflow = rowan.submit_protein_cofolding_workflow(
initial_protein_sequences=[protein_seq],
initial_smiles_list=[ligand],
name="kinase-ligand cofolding",
model="chai_1r" # or "boltz_1x", "boltz_2"
)
workflow.wait_for_result()
workflow.fetch_latest(in_place=True)
# Access structure prediction results
print(f"Predicted TM Score: {workflow.data['ptm_score']}")
print(f"Interface pTM: {workflow.data['interface_ptm']}")
For users working with RDKit molecules, Rowan provides a simplified interface:
import rowan
from rdkit import Chem
# Create RDKit molecule
mol = Chem.MolFromSmiles("c1ccccc1O")
# Calculate pKa directly
pka_result = rowan.run_pka(mol)
print(f"pKa: {pka_result.strongest_acid}")
# Batch processing
mols = [Chem.MolFromSmiles(smi) for smi in ["CCO", "CC(=O)O", "c1ccccc1O"]]
results = rowan.batch_pka(mols)
for mol, result in zip(mols, results):
print(f"{Chem.MolToSmiles(mol)}: pKa = {result.strongest_acid}")
Available RDKit-native functions:
run_pka, batch_pka - pKa calculationrun_tautomers, batch_tautomers - Tautomer enumerationrun_conformers, batch_conformers - Conformer generationrun_energy, batch_energy - Single-point energy calculationrun_optimization, batch_optimization - Geometry optimizationSee references/rdkit_native.md for full documentation.
# List recent workflows
workflows = rowan.list_workflows(size=10)
for wf in workflows:
print(f"{wf.name}: {wf.status}")
# Filter by status
pending = rowan.list_workflows(status="running")
# Get specific workflow
workflow = rowan.retrieve_workflow("workflow-uuid")
# Submit multiple workflows
workflows = rowan.batch_submit_workflow(
molecules=[mol1, mol2, mol3],
workflow_type="pka",
workflow_data={}
)
# Poll status of multiple workflows
statuses = rowan.batch_poll_status([wf.uuid for wf in workflows])
# Create folder for project
folder = rowan.create_folder(name="Drug Discovery Project")
# Submit workflow to folder
workflow = rowan.submit_pka_workflow(
initial_molecule=mol,
name="compound pKa",
folder_uuid=folder.uuid
)
# List workflows in folder
folder_workflows = rowan.list_workflows(folder_uuid=folder.uuid)
Rowan supports multiple theoretical levels:
Neural Network Potentials:
Semi-empirical:
Density Functional Theory (DFT):
The system automatically selects methods based on workflow type, or you can explicitly specify them in workflow parameters.
For detailed API documentation, see the following reference files:
references/api_reference.md: Complete API documentation - Workflow class, submission functions, retrieval methodsreferences/workflow_types.md: All 30+ workflow types and parameters - pKa, docking, cofolding, etc.references/rdkit_native.md: RDKit-native API functions for seamless chemoinformatics integrationreferences/molecule_handling.md: stjames.Molecule class - creating molecules from SMILES, XYZ, RDKitreferences/proteins_and_organization.md: Protein upload, folder management, project organizationreferences/results_interpretation.md: Understanding workflow outputs, confidence scores, validationimport rowan
import stjames
smiles_list = ["CCO", "c1ccccc1O", "CC(=O)O"]
# Submit all pKa calculations
workflows = []
for smi in smiles_list:
mol = stjames.Molecule.from_smiles(smi)
wf = rowan.submit_pka_workflow(
initial_molecule=mol,
name=f"pKa: {smi}"
)
workflows.append(wf)
# Wait for all to complete
for wf in workflows:
wf.wait_for_result()
wf.fetch_latest(in_place=True)
print(f"{wf.name}: pKa = {wf.data['strongest_acid']}")
import rowan
# Upload protein once
protein = rowan.upload_protein("target.pdb", name="Drug Target")
protein.sanitize() # Structure cleaning
# Define pocket
pocket = {"center": [x, y, z], "size": [20, 20, 20]}
# Screen compound library
for smiles in compound_library:
mol = stjames.Molecule.from_smiles(smiles)
workflow = rowan.submit_docking_workflow(
protein=protein.uuid,
pocket=pocket,
initial_molecule=mol,
name=f"Dock: {smiles[:20]}"
)
import rowan
import stjames
mol = stjames.Molecule.from_smiles("complex_molecule_smiles")
# Generate conformers
conf_wf = rowan.submit_conformer_search_workflow(
initial_molecule=mol,
name="conformer search"
)
conf_wf.wait_for_result()
conf_wf.fetch_latest(in_place=True)
# Analyze lowest energy conformers
conformers = sorted(conf_wf.data['conformers'], key=lambda x: x['energy'])
print(f"Found {len(conformers)} unique conformers")
print(f"Energy range: {conformers[0]['energy']:.4f} to {conformers[-1]['energy']:.4f} Hartree")
rowan.whoami().creditsimport rowan