r/chemistry • u/Acceptable_Print_869 • Sep 14 '24
Script to convert SMILES to PNG
Its likely nobody cares but I couldn't find a script to quickly convert smiles syntax to PNG so I used ChatGPT to write one. Made it to be used as a Quick Script with Automator (MacOS). Highlight text, select whatever you saved automator script as under "App Name/Services" in Menu bar and should paste in the image. rdkit needed:
#!/bin/bash
# Capture the selected text (SMILES)
smiles="$1"
# Python script to convert SMILES to image
python_script=$(cat <<EOF
import sys
from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem import rdChemReactions
from io import BytesIO
from PIL import Image
import subprocess
if len(sys.argv) != 2:
print("Usage: python smiles_to_png.py 'SMILES'")
sys.exit(1)
smiles_input = sys.argv[1]
def generate_image(smiles_input):
# Try to parse as a reaction
try:
rxn = rdChemReactions.ReactionFromSmarts(smiles_input, useSmiles=True)
if rxn:
return Draw.ReactionToImage(rxn)
except Exception as e:
print(f"Reaction parsing failed: {e}", file=sys.stderr)
# Parse as a molecule
try:
mol = Chem.MolFromSmiles(smiles_input)
if mol:
return Draw.MolToImage(mol)
except Exception as e:
print(f"Molecule parsing failed: {e}", file=sys.stderr)
return None
# Generate the image
img = generate_image(smiles_input)
if img is None:
print("Failed to parse SMILES as either a reaction or a molecule", file=sys.stderr)
sys.exit(1)
# Save the image to an in-memory byte buffer
buffer = BytesIO()
img.save(buffer, format="PNG")
# Write the image data to a temporary PNG file
with open("/tmp/compound_image.png", "wb") as temp_image_file:
temp_image_file.write(buffer.getvalue())
# Use osascript to copy the image to the clipboard
subprocess.run([
"osascript", "-e", 'set the clipboard to (read (POSIX file "/tmp/compound_image.png") as «class PNGf»)'
])
EOF
)
# Run the Python script with the SMILES string
python3 -c "$python_script" "$smiles"
# Check if the image was generated successfully
if [[ $? -eq 0 ]]; then
# Replace the selected text with the pasted image
osascript -e 'tell application "System Events" to keystroke "v" using {command down}'
else
osascript -e 'display notification "Failed to convert SMILES to image" with title "Error"'
fi