OEDepict Examples

Generating 2D Coordinates

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2004-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Generates 2D coordinates
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigurePrepareDepictionOptions(itf, OEPrepareDepictionSetup_SuppressHydrogens |
                                       OEPrepareDepictionSetup_DepictOrientation)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-in")
    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    ofs = oemolostream(".sdf")
    if itf.HasString("-out"):
        oname = itf.GetString("-out")
        if not ofs.open(oname):
            OEThrow.Fatal("Cannot open output file!")
        if not OEIs2DFormat(ofs.GetFormat()):
            OEThrow.Fatal("Invalid output format for 2D coordinates")

    if itf.HasString("-ringdict"):
        rdfname = itf.GetString("-ringdict")
        if not OEInit2DRingDictionary(rdfname):
            OEThrow.Warning("Cannot use user-defined ring dictionary!")

    popts = OEPrepareDepictionOptions()
    OESetupPrepareDepictionOptions(popts, itf)
    popts.SetClearCoords(True)

    for mol in ifs.GetOEGraphMols():
        OEPrepareDepiction(mol, popts)
        OEWriteMolecule(ofs, mol)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = """
!BRIEF [-in] <input> [-out] <output> [-ringdict] <rd file>

!CATEGORY "input/output options :"

  !PARAMETER -in
    !ALIAS -i
    !TYPE string
    !REQUIRED true
    !KEYLESS 1
    !VISIBILITY simple
    !BRIEF Input filename
  !END

  !PARAMETER -out
    !ALIAS -o
    !TYPE string
    !REQUIRED false
    !KEYLESS 2
    !VISIBILITY simple
    !BRIEF Output filename
  !END

  !PARAMETER -ringdict
    !ALIAS -rd
    !TYPE string
    !REQUIRED false
    !VISIBILITY simple
    !BRIEF User-defined 2D ring dictionary
    !DETAIL
        2D ring dictionaries can be generated by the following OEChem examples:
        C++    - createringdict.cpp
        Python - createringdict.py
        Java   - CreateRingDict.java
        C#     - CreateRingDict.cs
  !END

!END
"""

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting Substructure Search Match

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Depict a molecule and highlight the substructure specified by
# the given SMARTS pattern
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureImageOptions(itf)
    OEConfigurePrepareDepictionOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)
    OEConfigureHighlightParams(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-in")
    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredImageFile(ext):
        OEThrow.Fatal("Unknown image type!")

    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    mol = OEGraphMol()
    if not OEReadMolecule(ifs, mol):
        OEThrow.Fatal("Cannot read input file!")

    smarts = itf.GetString("-smarts")

    ss = OESubSearch()
    if not ss.Init(smarts):
        OEThrow.Fatal("Cannot parse smarts: %s" % smarts)

    popts = OEPrepareDepictionOptions()
    OESetupPrepareDepictionOptions(popts, itf)
    OEPrepareDepiction(mol, popts)

    width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
    dopts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
    OESetup2DMolDisplayOptions(dopts, itf)
    dopts.SetMargins(10.0)

    disp = OE2DMolDisplay(mol, dopts)

    hstyle = OEGetHighlightStyle(itf)
    hcolor = OEGetHighlightColor(itf)

    OEPrepareSearch(mol, ss)

    unique = True
    for match in ss.Match(mol, unique):
        OEAddHighlighting(disp, hcolor, hstyle, match)

    OERenderMolecule(ofs, ext, disp)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-in] <input> [-smarts] <smarts> [-out] <output image>

!CATEGORY "input/output options :"

    !PARAMETER -in
      !ALIAS -i
      !TYPE string
      !REQUIRED true
      !KEYLESS 1
      !VISIBILITY simple
      !BRIEF Input filename
    !END

    !PARAMETER -smarts
      !TYPE string
      !REQUIRED true
      !KEYLESS 2
      !VISIBILITY simple
      !BRIEF SMARTS pattern
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !KEYLESS 3
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Aligning Molecules Based on MCS

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Aligns the fit molecule(s) based on their maximum common substructure
# with the reference molecule.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    rname = itf.GetString("-ref")
    fname = itf.GetString("-fit")
    oname = itf.GetString("-out")

    rifs = oemolistream()
    if not rifs.open(rname):
        OEThrow.Fatal("Cannot open reference molecule file!")

    refmol = OEGraphMol()
    if not OEReadMolecule(rifs, refmol):
        OEThrow.Fatal("Cannot read reference molecule!")

    fifs = oemolistream()
    if not fifs.open(fname):
        OEThrow.Fatal("Cannot open align molecule file!")

    ofs = oemolostream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")
    if not OEIs2DFormat(ofs.GetFormat()):
        OEThrow.Fatal("Invalid output format for 2D coordinates")

    OEPrepareDepiction(refmol)

    mcss = OEMCSSearch(OEMCSType_Approximate)
    atomexpr = OEExprOpts_DefaultAtoms
    bondexpr = OEExprOpts_DefaultBonds
    mcss.Init(refmol, atomexpr, bondexpr)
    mcss.SetMCSFunc(OEMCSMaxBondsCompleteCycles())

    OEWriteConstMolecule(ofs, refmol)

    for fitmol in fifs.GetOEGraphMols():
        alignres = OEPrepareAlignedDepiction(fitmol, mcss)
        if alignres.IsValid():
            OEThrow.Info("%s  mcs size: %d" % (fitmol.GetTitle(), alignres.NumAtoms()))
            OEWriteMolecule(ofs, fitmol)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-ref] <input> [-fit] <input> [-out] <output>

!CATEGORY "input/output options :"

    !PARAMETER -ref
      !ALIAS -r
      !TYPE string
      !REQUIRED true
      !KEYLESS 1
      !VISIBILITY simple
      !BRIEF Ref filename
    !END

    !PARAMETER -fit
      !ALIAS -f
      !TYPE string
      !REQUIRED true
      !KEYLESS 2
      !VISIBILITY simple
      !BRIEF Align filename
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !KEYLESS 3
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting MDL Query

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts an MDL query structure into an image file.
# The output file format depends on its file extension.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureImageOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-in")
    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredImageFile(ext):
        OEThrow.Fatal("Unknown image type!")

    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    if ifs.GetFormat() != OEFormat_MDL:
        OEThrow.Fatal("Input file is not an MDL query file")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    mol = OEGraphMol()
    if not OEReadMDLQueryFile(ifs, mol):
        OEThrow.Fatal("Cannot read mdl query input file!")

    clearcoords, suppressH = False, False
    OEPrepareDepiction(mol, clearcoords, suppressH)

    width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
    opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
    OESetup2DMolDisplayOptions(opts, itf)

    disp = OE2DMolDisplay(mol, opts)
    OERenderMolecule(ofs, ext, disp)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-in] <input> [-out] <output image>

!CATEGORY "input/output options :"

    !PARAMETER -in
      !ALIAS -i
      !TYPE string
      !REQUIRED true
      !KEYLESS 1
      !VISIBILITY simple
      !BRIEF Input filename
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !KEYLESS 2
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting MDL Reaction

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts an MDL reaction into an image file.
# The output file format is depends on its file extension.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface()
    OEConfigure(itf, InterfaceData)
    OEConfigureImageOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-in")
    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredImageFile(ext):
        OEThrow.Fatal("Unknown image type!")

    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    mol = OEGraphMol()
    if not OEReadMDLReactionQueryFile(ifs, mol):
        OEThrow.Fatal("Cannot read mdl reaction!")

    clearcoords, suppressH = False, False
    OEPrepareDepiction(mol, clearcoords, suppressH)

    width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
    opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
    OESetup2DMolDisplayOptions(opts, itf)

    disp = OE2DMolDisplay(mol, opts)
    OERenderMolecule(ofs, ext, disp)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-in] <input> [-out] <output image>

!CATEGORY "input/output options :"

    !PARAMETER -in
      !ALIAS -i
      !TYPE string
      !REQUIRED true
      !KEYLESS 1
      !VISIBILITY simple
      !BRIEF Input filename
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !KEYLESS 2
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting a Single Molecule

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts a molecule structure into an image file.
# The output file format depends on its file extension.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureImageOptions(itf)
    OEConfigurePrepareDepictionOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-in")
    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredImageFile(ext):
        OEThrow.Fatal("Unknown image type!")

    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    mol = OEGraphMol()
    if not OEReadMolecule(ifs, mol):
        OEThrow.Fatal("Cannot read input file!")

    if itf.HasString("-ringdict"):
        rdfname = itf.GetString("-ringdict")
        if not OEInit2DRingDictionary(rdfname):
            OEThrow.Warning("Cannot use user-defined ring dictionary!")

    popts = OEPrepareDepictionOptions()
    OESetupPrepareDepictionOptions(popts, itf)

    OEPrepareDepiction(mol, popts)

    width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
    dopts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
    OESetup2DMolDisplayOptions(dopts, itf)

    disp = OE2DMolDisplay(mol, dopts)
    OERenderMolecule(ofs, ext, disp)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = """
!BRIEF [-in] <input> [-out] <output image> [-ringdict] <rd file>

!CATEGORY "input/output options :"

  !PARAMETER -in
    !ALIAS -i
    !TYPE string
    !REQUIRED true
    !KEYLESS 1
    !VISIBILITY simple
    !BRIEF Input filename
  !END

  !PARAMETER -out
    !ALIAS -o
    !TYPE string
    !REQUIRED true
    !KEYLESS 2
    !VISIBILITY simple
    !BRIEF Output filename
  !END

  !PARAMETER -ringdict
    !ALIAS -rd
    !TYPE string
    !REQUIRED false
    !VISIBILITY simple
    !BRIEF User-defined 2D ring dictionary
    !DETAIL
        2D ring dictionaries can be generated by the following OEChem examples:
        C++    - createringdict.cpp
        Python - createringdict.py
        Java   - CreateRingDict.java
        C#     - CreateRingDict.cs
    !END

!END
"""

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting Molecules in Multi-Page

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts molecules into a multi-page PDF document.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureReportOptions(itf)
    OEConfigurePrepareDepictionOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)

    if not OEParseCommandLine(itf, argv):
        return 1

    iname = itf.GetString("-in")
    ifs = oemolistream()
    if not ifs.open(iname):
        OEThrow.Fatal("Cannot open input file!")

    oname = itf.GetString("-out")
    ext = OEGetFileExtension(oname)
    if ext != "pdf":
        OEThrow.Fatal("Output must be PDF format.")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    if itf.HasString("-ringdict"):
        rdfname = itf.GetString("-ringdict")
        if not OEInit2DRingDictionary(rdfname):
            OEThrow.Warning("Cannot use user-defined ring dictionary!")

    ropts = OEReportOptions()
    OESetupReportOptions(ropts, itf)
    ropts.SetFooterHeight(25.0)
    report = OEReport(ropts)

    popts = OEPrepareDepictionOptions()
    OESetupPrepareDepictionOptions(popts, itf)

    dopts = OE2DMolDisplayOptions()
    OESetup2DMolDisplayOptions(dopts, itf)
    dopts.SetDimensions(report.GetCellWidth(), report.GetCellHeight(), OEScale_AutoScale)

    for mol in ifs.GetOEGraphMols():
        cell = report.NewCell()
        OEPrepareDepiction(mol, popts)
        disp = OE2DMolDisplay(mol, dopts)
        OERenderMolecule(cell, disp)

    font = OEFont(OEFontFamily_Default, OEFontStyle_Bold, 12, OEAlignment_Center, OEBlack)
    for pagenum, footer in enumerate(report.GetFooters()):
        text = "Page %d of %d" % (pagenum + 1, report.NumPages())
        OEDrawTextToCenter(footer, text, font)

    OEWriteReport(ofs, ext, report)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-in] <input> [-out] <output pdf> [-ringdict] <rd file>

!CATEGORY "input/output options :"

  !PARAMETER -in
    !ALIAS -i
    !TYPE string
    !REQUIRED true
    !KEYLESS 1
    !VISIBILITY simple
    !BRIEF Input filename
  !END

  !PARAMETER -out
    !ALIAS -o
    !TYPE string
    !REQUIRED true
    !KEYLESS 2
    !VISIBILITY simple
    !BRIEF Output filename
  !END

  !PARAMETER -ringdict
    !ALIAS -rd
    !TYPE string
    !REQUIRED false
    !VISIBILITY simple
    !BRIEF User-defined 2D ring dictionary
    !DETAIL
        2D ring dictionaries can be generated by the following OEChem examples:
        C++    - createringdict.cpp
        Python - createringdict.py
        Java   - CreateRingDict.java
        C#     - CreateRingDict.cs
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting Molecules In a Grid

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts molecules into an image with grid layout.
# The output file format depends on its file extension.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface()
    OEConfigure(itf, InterfaceData)
    OEConfigureImageWidth(itf, 400.0)
    OEConfigureImageHeight(itf, 400.0)
    OEConfigureImageGridParams(itf)
    OEConfigurePrepareDepictionOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredImageFile(ext):
        OEThrow.Fatal("Unknown image type!")

    ofs = oeofstream()
    if not ofs.open(oname):
        OEThrow.Fatal("Cannot open output file!")

    width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
    image = OEImage(width, height)

    rows = OEGetImageGridNumRows(itf)
    cols = OEGetImageGridNumColumns(itf)
    grid = OEImageGrid(image, rows, cols)

    popts = OEPrepareDepictionOptions()
    OESetupPrepareDepictionOptions(popts, itf)

    dopts = OE2DMolDisplayOptions()
    OESetup2DMolDisplayOptions(dopts, itf)
    dopts.SetDimensions(grid.GetCellWidth(), grid.GetCellHeight(), OEScale_AutoScale)

    celliter = grid.GetCells()
    for iname in itf.GetStringList("-in"):
        ifs = oemolistream()
        if not ifs.open(iname):
            OEThrow.Warning("Cannot open %s input file!" % iname)
            continue

        for mol in ifs.GetOEGraphMols():
            if not celliter.IsValid():
                break

            OEPrepareDepiction(mol, popts)
            disp = OE2DMolDisplay(mol, dopts)
            OERenderMolecule(celliter.Target(), disp)
            celliter.Next()

    OEWriteImage(ofs, ext, image)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF -in <input1> [ <input2> .. ] -out <output image>

!CATEGORY "input/output options :"

    !PARAMETER -in
      !ALIAS -i
      !TYPE string
      !LIST true
      !REQUIRED true
      !VISIBILITY simple
      !BRIEF Input filename(s)
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Generating 2D Ring Dictionary Report

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2015 OpenEye Scientific Software, Inc.
#############################################################################
# Converts a ring dictionary into a multi-page PDF document.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureReportOptions(itf)

    if not OEParseCommandLine(itf, argv):
        OEThrow.Fatal("Unable to interpret command line!")

    ifname = itf.GetString("-ringdict")
    ofname = itf.GetString("-out")

    if not OEIsValid2DRingDictionary(ifname):
        OEThrow.Fatal("Invalid ring dictionary file!")

    ringdict = OE2DRingDictionary(ifname)

    ropts = OEReportOptions()
    OESetupReportOptions(ropts, itf)

    OEWrite2DRingDictionaryReport(ofname, ringdict, ropts)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = """
!BRIEF [-ringdict] <input ringdict> [-out] <output pdf>

!CATEGORY "input/output options :"

    !PARAMETER -ringdict
      !ALIAS -rd
      !TYPE string
      !REQUIRED true
      !KEYLESS 1
      !VISIBILITY simple
      !BRIEF Input ring dictionary filename
      !DETAIL
        2D ring dictionaries can be generated by the following OEChem examples:
        C++    - createringdict.cpp
        Python - createringdict.py
        Java   - CreateRingDict.java
        C#     - CreateRingDict.cs
    !END

    !PARAMETER -out
      !ALIAS -o
      !TYPE string
      !REQUIRED true
      !KEYLESS 2
      !VISIBILITY simple
      !BRIEF Output filename
    !END

!END
"""

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Depicting MDL Query Substructure Search Hits

#!/usr/bin/env python
#############################################################################
# Copyright (C) 2011-2015 OpenEye Scientific Software, Inc.
#############################################################################
# Performs substructure search on a molecule using a MDL query and
# generates an image file depicting one match per molecule.
# The output file format depends on its file extension.
#############################################################################

import sys
from openeye.oechem import *
from openeye.oedepict import *


def main(argv=[__name__]):

    itf = OEInterface(InterfaceData)
    OEConfigureReportOptions(itf)
    OEConfigure2DMolDisplayOptions(itf)
    OEConfigureHighlightParams(itf)

    if not OEParseCommandLine(itf, argv):
        return 1

    qname = itf.GetString("-query")
    tname = itf.GetString("-target")
    oname = itf.GetString("-out")

    ext = OEGetFileExtension(oname)
    if not OEIsRegisteredMultiPageImageFile(ext):
        OEThrow.Fatal("Unknown multipage image type!")

    qfile = oemolistream()
    if not qfile.open(qname):
        OEThrow.Fatal("Cannot open mdl query file!")
    if qfile.GetFormat() != OEFormat_MDL and qfile.GetFormat() != OEFormat_SDF:
        OEThrow.Fatal("Query file has to be an MDL file!")

    ifs = oemolistream()
    if not ifs.open(tname):
        OEThrow.Fatal("Cannot open target input file!")

    depictquery = OEGraphMol()
    if not OEReadMDLQueryFile(qfile, depictquery):
        OEThrow.Fatal("Cannot read query molecule!")
    OEPrepareDepiction(depictquery)
    queryopts = OEMDLQueryOpts_Default | OEMDLQueryOpts_SuppressExplicitH
    qmol = OEQMol()
    OEBuildMDLQueryExpressions(qmol, depictquery, queryopts)

    ss = OESubSearch()
    if not ss.Init(qmol):
        OEThrow.Fatal("Cannot initialize substructure search!")

    hstyle = OEGetHighlightStyle(itf)
    hcolor = OEGetHighlightColor(itf)
    align = itf.GetBool("-align")

    ropts = OEReportOptions()
    OESetupReportOptions(ropts, itf)
    ropts.SetHeaderHeight(140.0)
    report = OEReport(ropts)

    dopts = OE2DMolDisplayOptions()
    OESetup2DMolDisplayOptions(dopts, itf)
    cellwidth, cellheight = report.GetCellWidth(), report.GetCellHeight()
    dopts.SetDimensions(cellwidth, cellheight, OEScale_AutoScale)

    unique = True
    for mol in ifs.GetOEGraphMols():
        OEPrepareSearch(mol, ss)
        miter = ss.Match(mol, unique)
        if not miter.IsValid():
            continue  # no match

        match = miter.Target()
        if align:
            OEPrepareAlignedDepiction(mol, ss.GetPattern(), match)
        else:
            OEPrepareDepiction(mol)

        cell = report.NewCell()
        disp = OE2DMolDisplay(mol, dopts)
        OEAddHighlighting(disp, hcolor, hstyle, match)
        OERenderMolecule(cell, disp)
        OEDrawBorder(cell, OELightGreyPen)

    # render query structure in each header
    headwidth, headheight = report.GetHeaderWidth(), report.GetHeaderHeight()
    dopts.SetDimensions(headwidth, headheight, OEScale_AutoScale)
    disp = OE2DMolDisplay(depictquery, dopts)
    for header in report.GetHeaders():
        OERenderMolecule(header, disp)
        OEDrawBorder(header, OELightGreyPen)

    OEWriteReport(oname, report)

    return 0


#############################################################################
# INTERFACE
#############################################################################

InterfaceData = '''
!BRIEF [-query] <input> [-target] <input> [-out] <output multipage image> [-align]

!CATEGORY "input/output options :"

  !PARAMETER -query
    !ALIAS -q
    !TYPE string
    !REQUIRED true
    !KEYLESS 1
    !VISIBILITY simple
    !BRIEF Input query filename
  !END

  !PARAMETER -target
    !ALIAS -t
    !TYPE string
    !REQUIRED true
    !KEYLESS 2
    !VISIBILITY simple
    !BRIEF Input target filename
  !END

  !PARAMETER -out
    !ALIAS -o
    !TYPE string
    !REQUIRED true
    !KEYLESS 3
    !VISIBILITY simple
    !BRIEF Output image filename
  !END

!END

!CATEGORY "general options :"

  !PARAMETER -align
    !TYPE bool
    !REQUIRED false
    !DEFAULT true
    !VISIBILITY simple
    !BRIEF Align hits to query
  !END

!END
'''

if __name__ == "__main__":
    sys.exit(main(sys.argv))