#   FreeContact - program to predict protein residue contacts from a sufficiently large multiple alignment
#   Copyright (C) 2013 by Laszlo Kajan, Technical University of Munich, Germany
# 
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
# 
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
# 
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
import freecontact
import unittest
from test import test_support
import sys

class MyTestCase1(unittest.TestCase):

    # Only use setUp() and tearDown() if necessary

    def setUp(self):
        pass

    def tearDown(self):
        pass # ... code to execute to clean up after tests ...

    def test1(self):
        ps = freecontact.get_ps_evfold()
        assert ps['clustpc'] == 0.7
        ps = freecontact.get_ps_psicov()
        assert ps['clustpc'] == 0.62
        freecontact.get_ps_psicov_sd()

    def test2(self):
        fcp = freecontact.Predictor()
        assert fcp.dbg == False
        fcp = freecontact.Predictor(dbg = True)
        assert fcp.dbg == True

    def test3(self):
        EXAMPLE = open('examples/demo_1000.aln', 'r')
        aln = EXAMPLE.readlines(); aln = map(lambda s: s.rstrip(), aln)
        EXAMPLE.close()

        num_threads = 1
        evfold_24_42 = 0.0129471030086279 # 0-based indices
        prec_threshold = 3e-4
        timing = {}

        fcp = freecontact.Predictor(dbg = True)

        # run with timing test
        res = fcp.run(ali = list(aln), num_threads = num_threads, timing = timing)
        assert abs(res['fro'][2741][2] - evfold_24_42) / evfold_24_42 < prec_threshold # 25 K 43 N 0.230969 0.0129471
        assert timing['num_threads'] == num_threads

        if (sys.version_info[0]==3):
          print ('\033[1m'+'\n\t!!!Skipping the rest of the tests for python3.%d'%(sys.version_info[1])+', need to be fixed!' + '\033[0m')
          return None

        # run psicov with icme_timeout exception test
        try:
            args = freecontact.get_ps_psicov(); args.update({'ali': aln, 'num_threads': num_threads, 'icme_timeout': 2, 'timing': None})
            fcp.run(**args) # this is expected to fail
            assert False    # fail if fell through
        except RuntimeError as e:
            assert e.args[0] == 'inverse covariance matrix estimation exceeded time limit (2 sec)'

        # get_seq_weights test
        aliw_wtot = fcp.get_seq_weights(ali = aln, num_threads = num_threads)

        assert len(aliw_wtot['aliw']) == 1000
        assert abs(aliw_wtot['wtot']-620.777)/620.777 < 1e-6

        # run_with_seq_weights test
        args = aliw_wtot; args.update({'ali': aln, 'num_threads': num_threads})
        res = fcp.run_with_seq_weights(**args)

        assert abs(res['fro'][2741][2] - evfold_24_42) / evfold_24_42 < prec_threshold

def test_main():
    unittest.TextTestRunner().run(suite)

if __name__ == '__main__':
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(MyTestCase1)
    test_main()

# vim:et:ts=4:ai:
