4

I would like to create a ChemDraw .cdx file from an InChI with Python. This answer gives a solution for cdx --> InChI.

The minimal example below cdx_to_inchi works fine, but I could not figure out how I can get inchi_to_cdx to work.

import comtypes.client as w32

def cdx_to_inchi(cdx):
    ChemDraw = w32.CreateObject("ChemDraw.Application")
    ChemDraw.Visible = False
    Compound = ChemDraw.Documents.Open(cdx)            # opens existing file
    inchi = Compound.Objects.Data("chemical/x-inchi")
    print(inchi)
    ChemDraw.Quit()

def inchi_to_cdx(inchi):
    ChemDraw = w32.CreateObject("ChemDraw.Application")
    ChemDraw.Visible = False

    Compound = ChemDraw.Documents.Open("Emtpy.cdx")   # opens existing file
    # ChemDraw.Documents.New("NewFile.cdx")           # How to create a new file?

    # Compound.Objects.SetData(inchi)                 # How to paste InChi data?
    # ChemDraw.Documents.Save()                       # How to save?
    # ChemDraw.Documents.SaveAs("MyMolecule.cdx")     # How to save under different name?
    ChemDraw.Quit()

cdx = r'C:\Data\Test.cdx'
inchi = '1S/C6H6/c1-2-4-6-5-3-1/h1-6H'

cdx_to_inchi(cdx)
inchi_to_cdx(inchi)
theozh
  • 22,244
  • 5
  • 28
  • 72
  • You need to uncomment the lines which save the file I would presume. – l'L'l Jan 08 '20 at 22:55
  • well, I commented theses lines because otherwise the program will not terminate and stop at these lines.These lines are so far just for "illustration". – theozh Jan 09 '20 at 05:24

1 Answers1

0

The following is at least a somehow working solution. It basically "mimics" a human user with keypresses. It is adapted from here. The drawbacks are:

  1. it seems to be Windows specific
  2. ChemDraw has to be the active application, i.e. will not work in the background
  3. additional delays slow down the whole procedure. a few 10'000 molecules would take about a day (well, better than by hand ;-)

These questions remain:

  1. How to make it platform independent?
  2. How to let it work in the background?
  3. How to avoid additional delays or how short can the delays be made that it still works reliably?

Code:

### create a ChemDraw .cdx file from an InChI string
import win32com.client as win32
import win32clipboard
import time

def sleep():
    time.sleep(0.5)   # wait for 0.5 seconds that script is not too fast for ChemDraw

def sleep_short():
    time.sleep(0.25)  # wait for 0.25 seconds between key presses

# initialize windows shell (so we can send keyboard commands)
shell = win32.Dispatch("WScript.Shell")

def hit_keys(keys): # function to wait, then send a keypress signal
    sleep_short()
    shell.SendKeys(keys,1)

# initialize ChemDraw
chemdraw = win32.gencache.EnsureDispatch('ChemDraw.Application') # connect to ChemDraw
chemdraw.Visible = True  # window needs to be visible otherwise keypresses will not work
sleep()

doc = chemdraw.Documents.Add()    # create a new document
doc.Activate()
sleep()

# ChemDraw must be the active application, so it can receive keyboard commands
shell.AppActivate("ChemDraw Prime") # name of the ChemDraw window bar
sleep()

inchi = 'InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H'
# set clipboard data
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(inchi)
win32clipboard.CloseClipboard()
sleep()     # not sure whether a delay is needed here

hit_keys("%e") # edit
hit_keys("s")  # paste special
hit_keys("i")  # pase as inchi
sleep()

ffname = r'C:\Users\Test\Scripts\MyMolecule.cdx'  # full filename
doc.SaveAs(ffname)   # save the file
doc.Close()
chemdraw.Quit()    # close ChemDraw
### end of code
theozh
  • 22,244
  • 5
  • 28
  • 72