##
# File:    PdbxReaderTests.py
# Author:  jdw
# Date:    9-Jan-2012
# Version: 0.001
#
# Update:
#  27-Sep-2012  jdw add test case for reading PDBx structure factor file
#
##
"""
Test cases for reading PDBx/mmCIF data files PdbxReader class -

"""
import sys, unittest, traceback

from moleculekit.pdbx.reader.PdbxReader import PdbxReader
from moleculekit.home import home
import os


class _PdbxReaderTests(unittest.TestCase):
    def setUp(self):
        self.lfh = sys.stderr
        self.verbose = False
        self.pathPdbxDataFile = os.path.join(
            home(dataDir="molecule-readers"), "1kip.cif"
        )
        self.pathBigPdbxDataFile = os.path.join(
            home(dataDir="molecule-readers"), "1ffk.cif"
        )
        self.pathSFDataFile = os.path.join(
            home(dataDir="molecule-readers"), "1kip-sf.cif"
        )

    def tearDown(self):
        pass

    def testReadSmallDataFile(self):
        """Test case -  read data file"""
        self.lfh.write(
            "\nStarting %s %s\n"
            % (self.__class__.__name__, sys._getframe().f_code.co_name)
        )
        try:
            #
            myDataList = []
            ifh = open(self.pathPdbxDataFile, "r")
            pRd = PdbxReader(ifh)
            pRd.read(myDataList)
            ifh.close()
        except:
            traceback.print_exc(file=sys.stderr)
            self.fail()

    def testReadBigDataFile(self):
        """Test case -  read data file"""
        self.lfh.write(
            "\nStarting %s %s\n"
            % (self.__class__.__name__, sys._getframe().f_code.co_name)
        )
        try:
            #
            myDataList = []
            ifh = open(self.pathBigPdbxDataFile, "r")
            pRd = PdbxReader(ifh)
            pRd.read(myDataList)
            ifh.close()
        except:
            traceback.print_exc(file=sys.stderr)
            self.fail()

    def testReadSFDataFile(self):
        """Test case -  read PDB structure factor data  file and compute statistics on f/sig(f)."""
        self.lfh.write(
            "\nStarting %s %s\n"
            % (self.__class__.__name__, sys._getframe().f_code.co_name)
        )
        try:
            #
            myContainerList = []
            ifh = open(self.pathSFDataFile, "r")
            pRd = PdbxReader(ifh)
            pRd.read(myContainerList)
            c0 = myContainerList[0]
            #
            catObj = c0.getObj("refln")
            if catObj is None:
                return False

            nRows = catObj.getRowCount()
            #
            # Get column name index.
            #
            itDict = {}
            itNameList = catObj.getItemNameList()
            for idxIt, itName in enumerate(itNameList):
                itDict[str(itName).lower()] = idxIt
                #
            idf = itDict["_refln.f_meas_au"]
            idsigf = itDict["_refln.f_meas_sigma_au"]
            minR = 100
            maxR = -1
            sumR = 0
            icount = 0
            for row in catObj.getRowList():
                try:
                    f = float(row[idf])
                    sigf = float(row[idsigf])
                    ratio = sigf / f
                    # self.lfh.write(" %f %f %f\n" % (f,sigf,ratio))
                    maxR = max(maxR, ratio)
                    minR = min(minR, ratio)
                    sumR += ratio
                    icount += 1
                except:
                    continue

            ifh.close()
            self.lfh.write(
                "f/sig(f) min %f max %f avg %f count %d\n"
                % (minR, maxR, sumR / icount, icount)
            )
        except:
            traceback.print_exc(file=sys.stderr)
            self.fail()


def simpleSuite():
    suiteSelect = unittest.TestSuite()
    suiteSelect.addTest(_PdbxReaderTests("testReadBigDataFile"))
    suiteSelect.addTest(_PdbxReaderTests("testReadSmallDataFile"))
    suiteSelect.addTest(_PdbxReaderTests("testReadSFDataFile"))
    return suiteSelect


if __name__ == "__main__":
    mySuite = simpleSuite()
    unittest.TextTestRunner(verbosity=2).run(mySuite)
    #
