#!/usr/bin/env python2.2
########################################
# The contents of this file are subject to the MLX PUBLIC LICENSE version
# 1.0 (the "License"); you may not use this file except in
# compliance with the License.
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Source Code is "compClust", released 2003 September 03.
# 
# The Original Source Code was developed by the California Institute of
# Technology (Caltech).  Portions created by Caltech are Copyright (C)
# 2002-2003 California Institute of Technology. All Rights Reserved.
########################################

import inspect
import os
import string
import sys
import tempfile
import unittest

from compClust.config import config
from compClust.util import WrapperUtil
from compClust.util.LoadExample import LoadCho
from compClust.mlx.datasets import Dataset
from compClust.mlx.wrapper import DiagEM, MultiRun
import compClust.mlx.wrapper

cho_labels = [['4'], ['4'], ['4'], ['3'], ['3'], ['3'], ['4'], ['1'], ['1'], ['1'], ['3'], ['1'], ['4'], ['1'], ['1'], ['1'], ['4'], ['1'], ['4'], ['4'], ['4'], ['4'], ['3'],['3'], ['3'], ['4'], ['3'], ['3'], ['1'], ['4'], ['1'], ['4'], ['4'], ['1'], ['4'], ['4'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['1'], ['3'], ['3'], ['4'], ['4'], ['1'], ['3'], ['3'], ['4'], ['4'], ['4'], ['1'], ['4'], ['3'], ['1'], ['1'], ['1'], ['1'], ['3'], ['1'], ['3'], ['4'], ['4'], ['3'], ['3'], ['4'], ['3'], ['4'], ['4'], ['4'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['4'], ['3'], ['3'], ['3'], ['3'], ['4'], ['3'], ['1'], ['4'], ['1'], ['1'], ['1'], ['1'], ['3'], ['4'], ['1'], ['1'], ['1'], ['4'], ['3'], ['4'], ['1'], ['1'], ['3'], ['4'],['3'], ['4'], ['4'], ['3'], ['3'], ['4'], ['3'], ['1'], ['4'], ['1'], ['1'], ['3'], ['1'], ['3'], ['3'], ['1'], ['1'], ['1'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['1'], ['3'], ['1'], ['4'], ['3'], ['4'], ['1'], ['4'], ['3'], ['4'], ['3'], ['4'], ['4'], ['3'], ['4'], ['4'], ['4'], ['3'], ['1'], ['4'], ['3'], ['4'], ['4'], ['3'], ['4'], ['4'], ['2'], ['4'], ['4'], ['4'], ['4'], ['4'], ['4'], ['1'], ['3'], ['4'], ['4'], ['4'], ['3'], ['3'], ['1'], ['1'], ['4'], ['4'], ['4'], ['3'], ['4'], ['3'], ['1'], ['1'], ['4'], ['1'], ['3'], ['4'], ['1'], ['3'], ['4'],['3'], ['3'], ['3'], ['4'], ['1'], ['1'], ['3'], ['1'], ['1'], ['1'], ['1'], ['1'], ['4'], ['1'], ['1'], ['1'], ['4'], ['3'], ['4'], ['3'], ['4'], ['4'], ['4'], ['4'], ['4'], ['4'], ['3'], ['3'], ['3'], ['1'], ['1'], ['3'], ['3'], ['1'], ['1'], ['1'], ['1'], ['3'], ['3'], ['1'], ['1'], ['3'], ['4'], ['3'], ['3'], ['1'], ['1'], ['1'], ['1'], ['4'], ['3'], ['3'], ['4'], ['4'], ['3'], ['1'], ['4'], ['3'], ['4'], ['3'], ['3'], ['3'], ['4'], ['3'], ['3'], ['4'], ['3'], ['1'], ['3'], ['3'], ['3'], ['4'], ['4'], ['4'], ['4'], ['4'], ['3'], ['3'], ['3'], ['4'], ['3'],['3'], ['3'], ['3'], ['4'], ['1'], ['3'], ['4'], ['4'], ['3'], ['3'], ['3'], ['3'], ['4'], ['4'], ['3'], ['3'], ['4'], ['1'], ['4'], ['4'], ['4'], ['3'], ['3'], ['3'], ['3'], ['1'], ['1'], ['3'], ['1'], ['4'], ['4'], ['1'], ['4'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['3'], ['1'], ['4'], ['1'], ['3'], ['3'], ['4'], ['4'], ['3'], ['4'], ['4'], ['4'], ['4'], ['4'], ['1'], ['3'], ['4'], ['4'], ['3'], ['4'], ['2'], ['3'], ['3'], ['4'], ['1'], ['3'], ['4'], ['3'], ['4'], ['4'], ['4'], ['1'], ['3'], ['3'], ['1'], ['4'], ['4'],['4'], ['4'], ['3'], ['4'], ['4'], ['4'], ['3'], ['1'], ['3'], ['4'], ['3'], ['3'], ['3'], ['4'], ['4'], ['4'], ['3'], ['1'], ['3'], ['1'], ['4'], ['4'], ['3'], ['1'], ['3'], ['4'], ['3'], ['3'], ['4'], ['1'], ['4'], ['3'], ['1'], ['4'], ['1'], ['3'], ['3']]

class MultiRunTestCases(unittest.TestCase):
  def setUp(self):
    self.dataset = LoadCho()
    
  def getMultiRunParametersDictionary(self, k=5):
    return {"parameter_name":'k',
            "parameter_values": range(2,k),
            }

  def getDiagEMParametersDictionary(self, k=5):
    return {'k': k,
            'k_strict': 'false',
            'num_iterations': 10,
            'seed': 1234,
            'distance_metric': 'euclidean',
            'init_method': 'church_means'}

  def test_multirun_wrapper(self):
    """Run a MultiRun clustering using DiagEM just to make sure the class
    is behaving correctly.
    """

    multirun_parameters = self.getMultiRunParametersDictionary()
    diagem_parameters = self.getDiagEMParametersDictionary()
    
    sub_algorithm = DiagEM(self.dataset, diagem_parameters)
    algorithm = MultiRun(self.dataset, multirun_parameters, sub_algorithm)
    algorithm.run()
    
    model = algorithm.getModel()
    labeling = algorithm.getLabeling()

    # more clusters should be the best fit for this dataset
    self.failUnless(len(labeling.getLabels()) == 4 )
    cluster_labels = labeling.getAllRowLabels()
    self.failUnless(len(cluster_labels) == len(cho_labels))
    for i in xrange(len(cluster_labels)):
      self.failUnless(cluster_labels[i][0] == cho_labels[i][0])
    
def suite(**kw):
  if os.path.exists(config.diagem_command):
    return unittest.makeSuite(MultiRunTestCases)
  else:
    return None

if __name__ == "__main__":
  unittest.main(defaultTest="suite")
