scripts/ro5_screen.py
scripts/ro5_screen.pyBrowse 4 files
664 tokens
2,034 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1#!/usr/bin/env python32"""3ro5_screen.py — Batch Lipinski Ro5 + Veber screening via PubChem API.4Usage: python3 ro5_screen.py aspirin ibuprofen paracetamol5No external dependencies beyond stdlib.6"""7import sys, json, time8import urllib.request, urllib.parse9 10BASE = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name"11PROPS = "MolecularWeight,XLogP,HBondDonorCount,HBondAcceptorCount,RotatableBondCount,TPSA"12 13def fetch(name):14 url = f"{BASE}/{urllib.parse.quote(name)}/property/{PROPS}/JSON"15 try:16 with urllib.request.urlopen(url, timeout=10) as r:17 return json.loads(r.read())["PropertyTable"]["Properties"][0]18 except Exception:19 return None20 21def check(p):22 mw,logp,hbd,hba,rot,tpsa = float(p.get("MolecularWeight",0)),float(p.get("XLogP",0)),int(p.get("HBondDonorCount",0)),int(p.get("HBondAcceptorCount",0)),int(p.get("RotatableBondCount",0)),float(p.get("TPSA",0))23 v = sum([mw>500,logp>5,hbd>5,hba>10])24 return dict(mw=mw,logp=logp,hbd=hbd,hba=hba,rot=rot,tpsa=tpsa,violations=v,ro5=v<=1,veber=tpsa<=140 and rot<=10,ok=v<=1 and tpsa<=140 and rot<=10)25 26def report(name, r):27 if not r: print(f"✗ {name:30s} — not found"); return28 s = "✓ PASS" if r["ok"] else "✗ FAIL"29 flags = (f" [Ro5 violations:{r['violations']}]" if not r["ro5"] else "") + (" [Veber fail]" if not r["veber"] else "")30 print(f"{s} {name:28s} MW={r['mw']:.0f} LogP={r['logp']:.2f} HBD={r['hbd']} HBA={r['hba']} TPSA={r['tpsa']:.0f} RotB={r['rot']}{flags}")31 32def main():33 compounds = sys.stdin.read().splitlines() if len(sys.argv)<2 or sys.argv[1]=="-" else sys.argv[1:]34 print(f"\n{'Status':<8} {'Compound':<30} Properties\n" + "-"*85)35 passed = 036 for name in compounds:37 props = fetch(name.strip())38 result = check(props) if props else None39 report(name.strip(), result)40 if result and result["ok"]: passed += 141 time.sleep(0.3)42 print(f"\nSummary: {passed}/{len(compounds)} passed Ro5 + Veber.\n")43 44if __name__ == "__main__": main()45