Nanny7 commited on
Commit
51b4bcc
·
1 Parent(s): 63c87ea

Fix reaction visualization to properly parse SMILES and show correct molecular structures

Browse files
Files changed (1) hide show
  1. app.py +76 -42
app.py CHANGED
@@ -190,47 +190,70 @@ def smiles_to_name(smiles: str) -> str:
190
  def reaction_smiles_to_svg(reaction_smiles: str) -> str:
191
  """Convert reaction SMILES to SVG image"""
192
  try:
193
- # Parse the reaction SMILES - try ReactionFromSmarts first, fallback to manual parsing
194
- try:
195
- reaction = rdChemReactions.ReactionFromSmarts(reaction_smiles)
196
- except:
197
- # If ReactionFromSmarts fails, try to parse manually
198
- if ">>" not in reaction_smiles:
199
- raise gr.Error("Reaction SMILES must contain '>>' to separate reactants from products")
200
-
201
- parts = reaction_smiles.split(">>")
202
- if len(parts) != 2:
203
- raise gr.Error("Reaction SMILES must have exactly one '>>' separator")
204
-
205
- reactant_smiles = parts[0].strip()
206
- product_smiles = parts[1].strip()
207
-
208
- # Create reaction from individual molecules
209
- reactant_mols = []
210
- for smi in reactant_smiles.split('.'):
211
- smi = smi.strip()
212
- if smi:
213
- mol = Chem.MolFromSmiles(smi)
214
- if mol is None:
215
- raise gr.Error(f"Invalid SMILES in reactants: {smi}")
216
- reactant_mols.append(mol)
217
-
218
- product_mols = []
219
- for smi in product_smiles.split('.'):
 
 
 
 
 
 
 
 
 
 
 
220
  smi = smi.strip()
221
  if smi:
222
  mol = Chem.MolFromSmiles(smi)
223
  if mol is None:
224
- raise gr.Error(f"Invalid SMILES in products: {smi}")
225
- product_mols.append(mol)
226
-
227
- reaction = rdChemReactions.ChemicalReaction()
228
- for mol in reactant_mols:
229
- reaction.AddReactantTemplate(mol)
230
- for mol in product_mols:
231
- reaction.AddProductTemplate(mol)
232
-
233
- # Draw the reaction as image
 
 
 
 
 
 
 
 
 
 
 
 
234
  image = Draw.ReactionToImage(reaction, subImgSize=(200, 200), useSVG=False, drawOptions=None, returnPNG=False)
235
 
236
  # Convert PIL image to base64 for HTML display
@@ -243,6 +266,17 @@ def reaction_smiles_to_svg(reaction_smiles: str) -> str:
243
  # Return as HTML img tag
244
  return f'<img src="data:image/png;base64,{img_str}" alt="Reaction" style="max-width:100%; height:auto;">'
245
 
 
 
 
 
 
 
 
 
 
 
 
246
  except gr.Error:
247
  raise
248
  except Exception as e:
@@ -1346,17 +1380,17 @@ reaction_interface = gr.Interface(
1346
  fn=reaction_smiles_to_svg,
1347
  inputs=gr.Textbox(
1348
  label="Reaction SMILES",
1349
- placeholder="CCO.O=C=O>>CC(=O)O.O=C=O (Esterification reaction)",
1350
- info="Use '>>' to separate reactants from products"
1351
  ),
1352
  outputs=gr.HTML(label="Reaction Visualization"),
1353
  title="Reaction Visualizer",
1354
- description="Visualize chemical reactions from SMILES notation.",
1355
  api_name="reaction_visualizer",
1356
  examples=[
 
1357
  ["CC(=O)O.CO>>CC(=O)OC.O"],
1358
- ["c1ccccc1.ClCl>>c1ccccc1Cl.Cl"],
1359
- ["Cl.[Na+].[OH-]>>[Na+].[Cl-].O"]
1360
  ],
1361
  )
1362
 
 
190
  def reaction_smiles_to_svg(reaction_smiles: str) -> str:
191
  """Convert reaction SMILES to SVG image"""
192
  try:
193
+ # Parse the reaction SMILES properly
194
+ if ">>" not in reaction_smiles:
195
+ raise gr.Error("Reaction SMILES must contain '>>' to separate reactants from products")
196
+
197
+ # Split by '>>' to get reactants and products
198
+ parts = reaction_smiles.split(">>")
199
+ if len(parts) != 2:
200
+ raise gr.Error("Reaction SMILES must have exactly one '>>' separator")
201
+
202
+ # Handle optional reagents/conditions (e.g., "reactants>reagents>products")
203
+ reactant_part = parts[0].strip()
204
+ product_part = parts[1].strip()
205
+
206
+ # Check if there are reagents (format: reactants>reagents>products)
207
+ if ">" in reactant_part:
208
+ reactant_smiles, reagent_smiles = reactant_part.split(">", 1)
209
+ reactant_smiles = reactant_smiles.strip()
210
+ reagent_smiles = reagent_smiles.strip()
211
+ else:
212
+ reactant_smiles = reactant_part
213
+ reagent_smiles = ""
214
+
215
+ product_smiles = product_part
216
+
217
+ # Create reaction from individual molecules using MolFromSmiles (not SMARTS)
218
+ reactant_mols = []
219
+ for smi in reactant_smiles.split('.'):
220
+ smi = smi.strip()
221
+ if smi:
222
+ mol = Chem.MolFromSmiles(smi)
223
+ if mol is None:
224
+ raise gr.Error(f"Invalid SMILES in reactants: {smi}")
225
+ reactant_mols.append(mol)
226
+
227
+ # Parse reagents/catalysts if present
228
+ reagent_mols = []
229
+ if reagent_smiles:
230
+ for smi in reagent_smiles.split('.'):
231
  smi = smi.strip()
232
  if smi:
233
  mol = Chem.MolFromSmiles(smi)
234
  if mol is None:
235
+ raise gr.Error(f"Invalid SMILES in reagents: {smi}")
236
+ reagent_mols.append(mol)
237
+
238
+ product_mols = []
239
+ for smi in product_smiles.split('.'):
240
+ smi = smi.strip()
241
+ if smi:
242
+ mol = Chem.MolFromSmiles(smi)
243
+ if mol is None:
244
+ raise gr.Error(f"Invalid SMILES in products: {smi}")
245
+ product_mols.append(mol)
246
+
247
+ # Build the reaction object
248
+ reaction = rdChemReactions.ChemicalReaction()
249
+ for mol in reactant_mols:
250
+ reaction.AddReactantTemplate(mol)
251
+ for mol in reagent_mols:
252
+ reaction.AddAgentTemplate(mol)
253
+ for mol in product_mols:
254
+ reaction.AddProductTemplate(mol)
255
+
256
+ # Draw the reaction as image with proper parameters
257
  image = Draw.ReactionToImage(reaction, subImgSize=(200, 200), useSVG=False, drawOptions=None, returnPNG=False)
258
 
259
  # Convert PIL image to base64 for HTML display
 
266
  # Return as HTML img tag
267
  return f'<img src="data:image/png;base64,{img_str}" alt="Reaction" style="max-width:100%; height:auto;">'
268
 
269
+
270
+ # Convert PIL image to base64 for HTML display
271
+ import io
272
+ import base64
273
+ buffer = io.BytesIO()
274
+ image.save(buffer, format='PNG')
275
+ img_str = base64.b64encode(buffer.getvalue()).decode()
276
+
277
+ # Return as HTML img tag
278
+ return f'<img src="data:image/png;base64,{img_str}" alt="Reaction" style="max-width:100%; height:auto;">'
279
+
280
  except gr.Error:
281
  raise
282
  except Exception as e:
 
1380
  fn=reaction_smiles_to_svg,
1381
  inputs=gr.Textbox(
1382
  label="Reaction SMILES",
1383
+ placeholder="CC=O.CC=O>[OH-]>CC(O)CC=O (Aldol condensation)",
1384
+ info="Format: reactants>reagents>products or reactants>>products"
1385
  ),
1386
  outputs=gr.HTML(label="Reaction Visualization"),
1387
  title="Reaction Visualizer",
1388
+ description="Visualize chemical reactions from SMILES notation. Use 'reactants>reagents>products' or 'reactants>>products' format.",
1389
  api_name="reaction_visualizer",
1390
  examples=[
1391
+ ["CC=O.CC=O>[OH-]>CC(O)CC=O"],
1392
  ["CC(=O)O.CO>>CC(=O)OC.O"],
1393
+ ["c1ccccc1.ClCl>>c1ccccc1Cl.Cl"]
 
1394
  ],
1395
  )
1396