#!/usr/bin/env python
# (C) 2017 OpenEye Scientific Software Inc. All rights reserved.
#
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of OpenEye products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. OpenEye claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.

import sys
from openeye import oechem

# **************************************************************
# USED TO GENERATE CODE SNIPPETS FOR THE OECHEM DOCUMENTATION
# *************************************************************/


# @ <SNIPPET>
# @ <SNIPPET-OERMSD-ARRAY>
def OERMSD_Array(refcrds, fitcrds, size):
    oechem.OERMSD(refcrds, fitcrds, size)

    overlay = True
    oechem.OERMSD(refcrds, fitcrds, size, overlay)

    rotmat = oechem.OEDoubleArray(9)
    oechem.OERMSD(refcrds, fitcrds, size, overlay, rotmat)

    transvec = oechem.OEDoubleArray(3)
    oechem.OERMSD(refcrds, fitcrds, size, overlay, rotmat, transvec)
# @ </SNIPPET-OERMSD-ARRAY>


# @ <SNIPPET-OERMSD-FULLMOL>
def OERMSD_Full_MolBase(ref, fit):
    oechem.OERMSD(ref, fit)

    automorf = True
    oechem.OERMSD(ref, fit, automorf)

    heavyOnly = True
    oechem.OERMSD(ref, fit, automorf, heavyOnly)

    overlay = False
    oechem.OERMSD(ref, fit, automorf, heavyOnly, overlay)

    rotmat = oechem.OEDoubleArray(9)
    oechem.OERMSD(ref, fit, automorf, heavyOnly, overlay, rotmat)

    transvec = oechem.OEDoubleArray(3)
    oechem.OERMSD(ref, fit, automorf, heavyOnly, overlay, rotmat, transvec)


def OERMSD_Full_MCMolBase(ref, fit):
    nConfs = fit.GetMaxConfIdx()
    vecRmsd = oechem.OEDoubleArray(nConfs)
    oechem.OERMSD(ref, fit, vecRmsd)

    automorf = True
    oechem.OERMSD(ref, fit, vecRmsd, automorf)

    heavyOnly = True
    oechem.OERMSD(ref, fit, vecRmsd, automorf, heavyOnly)

    overlay = True
    oechem.OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay)

    rotmat = oechem.OEDoubleArray(9*nConfs)
    oechem.OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay, rotmat)

    transvec = oechem.OEDoubleArray(3*nConfs)
    oechem.OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay, rotmat, transvec)

# @ </SNIPPET-OERMSD-FULLMOL>


# @ <SNIPPET-OERMSD-PARTMOL>
def OERMSD_Part_MolBase(ref, fit):
    match = oechem.OEMatch()
    for aRef, aFit in zip(ref.GetAtoms(), fit.GetAtoms()):
        match.AddPair(aRef, aFit)

    oechem.OERMSD(ref, fit, match)

    overlay = True
    oechem.OERMSD(ref, fit, match, overlay)

    rotmat = oechem.OEDoubleArray(9)
    oechem.OERMSD(ref, fit, match, overlay, rotmat)

    transvec = oechem.OEDoubleArray(3)
    oechem.OERMSD(ref, fit, match, overlay, rotmat, transvec)


def OERMSD_Part_MCMolBase(ref, fit):
    match = oechem.OEMatch()
    for aRef, aFit in zip(ref.GetAtoms(), fit.GetAtoms()):
        match.AddPair(aRef, aFit)

    nConfs = fit.GetMaxConfIdx()
    vecRmsd = oechem.OEDoubleArray(nConfs)
    oechem.OERMSD(ref, fit, vecRmsd, match)

    overlay = True
    oechem.OERMSD(ref, fit, vecRmsd, match, overlay)

    rotmat = oechem.OEDoubleArray(9*nConfs)
    oechem.OERMSD(ref, fit, vecRmsd, match, overlay, rotmat)

    transvec = oechem.OEDoubleArray(3*nConfs)
    oechem.OERMSD(ref, fit, vecRmsd, match, overlay, rotmat, transvec)
# @ </SNIPPET-OERMSD-PARTMOL>


########################################################################
#
########################################################################
if len(sys.argv) != 2:
    oechem.OEThrow.Usage("%s <input>" % sys.argv[0])

ifs = oechem.oemolistream()
if not ifs.open(sys.argv[1]):
    oechem.OEThrow.Fatal("Unable to open %s" % sys.argv[1])

mol = oechem.OEGraphMol()
oechem.OEReadMolecule(ifs, mol)
vecCoords = oechem.OEDoubleArray(3 * mol.GetMaxAtomIdx())
mol.GetCoords(vecCoords)

OERMSD_Array(vecCoords, vecCoords, mol.GetMaxAtomIdx())
OERMSD_Full_MolBase(mol, mol)

mcmol = oechem.OEMol()
oechem.OEReadMolecule(ifs, mcmol)
OERMSD_Full_MCMolBase(mol, mcmol)

OERMSD_Part_MolBase(mol, mol)
OERMSD_Part_MCMolBase(mol, mcmol)
# @ </SNIPPET>
