import sys
sys.path.append('../../')

import unittest
import numpy as np
import libMCMCMCFitting as lMC3F
import scipy.special as spsp

class TestVariablesReading(unittest.TestCase):
    def test_reading_missing_max_values(self):
        print("\n\nRunning test #1 (variables)")
        with self.assertRaises(RuntimeError): lMC3F.readVariablesDefinitions("bad_variable_file_nr0.conf")

    def test_reading_bad_ini_value(self):
        print("\n\nRunning test #2 (variables)")
        with self.assertRaises(RuntimeError): lMC3F.readVariablesDefinitions("bad_variable_file_nr1.conf")

    def test_reading_good_ini_value(self):
        print("\n\nRunning test #3 (variables)")
        VarDict = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")
        ExpectedDict = {"t0":  {"minvalue": 10.0, "maxvalue": 30., "value": 10.0, "maxdisp": None},
                        "tcc": {"minvalue": 10.0, "maxvalue": 30., "value": 20.0, "maxdisp": None}
                       }
        print(VarDict)
        print(ExpectedDict)
        self.assertTrue(VarDict == ExpectedDict)

    def test_reading_good_no_ini_value(self):
        print("\n\nRunning test #4 (variables)")
        VarDict = lMC3F.readVariablesDefinitions("good_variable_file_nr1.conf")
        print(VarDict)
        self.assertTrue( (VarDict["t0"]["value"] <= VarDict["t0"]["maxvalue"]) and (VarDict["t0"]["value"] >= VarDict["t0"]["minvalue"]) )

    def test_reading_good_no_maxdisp(self):
        print("\n\nRunning test #5 (variables)")
        VarDict = lMC3F.readVariablesDefinitions("good_variable_file_nr1.conf")
        print(VarDict)
        self.assertTrue( VarDict["t0"]["maxdisp"] is None )

    def test_reading_good_with_maxdisp(self):
        print("\n\nRunning test #6 (variables)")
        VarDict = lMC3F.readVariablesDefinitions("good_variable_file_nr2.conf")
        print(VarDict)
        self.assertTrue( VarDict["t0"]["maxdisp"] == 5. )

class TestChannelsReading(unittest.TestCase):
    def test_reading_of_the_good_channels(self):
        print("\n\nRunning test #1 (channels)")
        VarDict = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        ExpectedDict = {"justaconstant": {"type": 'const', "t0": None, "tcc": None, "tr": None, "probeispump": True},
                        "gaussian":        {"type": 'gauss', "t0": "t0", "tcc": "tcc", "tr": None, "probeispump": False}
                       }

        print(VarDict)
        print(ExpectedDict)
        self.assertTrue(VarDict == ExpectedDict)      

    def test_reading_of_the_bad_channels(self):
        print("Running test #2 (channels)")
        with self.assertRaises(RuntimeError): lMC3F.readChannelsDefinitions("bad_channels_nr0.conf")

class TestDataReading(unittest.TestCase):
    def test_reading_of_the_badly_defined_data(self):
        print("\n\nRunning test #1 (data)")
        with self.assertRaises(RuntimeError): lMC3F.readDataSetsDefinitions("bad_data_nr0.conf")

    def test_reading_of_the_well_defined_data_and_bad_dataset(self):
        print("\n\nRunning test #2 (data)")
        with self.assertRaises(RuntimeError): lMC3F.readDataSetsDefinitions("bad_data_nr1.conf")

    def test_reading_of_the_good_data_with_three_columns(self):
        print("\n\nRunning test #3 (data)")
        exX=np.array([0.0,1.0])
        exY=np.array([0.0,0.0])
        exYerr=np.array([1.,1.])

        Res = lMC3F.readDataSetsDefinitions("good_data_nr0.conf")
 
        res = np.isclose(exX,Res['dataset1']['x']).all() 
        res *= np.isclose(exY,Res['dataset1']['y']).all() 
        res *= np.isclose(exYerr,Res['dataset1']['yerr']).all()
        
        self.assertTrue(res)      

    def test_reading_of_the_good_data_with_four_columns(self):
        print("\n\nRunning test #4 (data)")
        exX=np.array([0.0,1.0])
        exY=np.array([0.0,0.0])
        exYerr=np.array([1.,1.])

        Res = lMC3F.readDataSetsDefinitions("good_data_nr1.conf")
 
        res = np.isclose(exX,Res['dataset1']['x']).all() 
        res *= np.isclose(exY,Res['dataset1']['y']).all() 
        res *= np.isclose(exYerr,Res['dataset1']['yerr']).all()
        
        self.assertTrue(res)      

    def test_reading_of_the_good_data_channels_names(self):
        print("\n\nRunning test #5 (data)")
        Res = lMC3F.readDataSetsDefinitions("good_data_nr0.conf")
        exChans=['c1', 'c3', 'c5']
        print(exChans)
        print(Res)
        self.assertTrue(exChans == Res['dataset1']['channels'])              


class TestFittingFunctions(unittest.TestCase):

    def test_extraction_of_the_wrong_type(self):
        print("\n\nRunning test #1 (fitting functions)")
        with self.assertRaises(RuntimeError): lMC3F.GetSomeFunc(Type="basdasdad", ProbeIsPump=False)     

    def test_extraction_of_the_constant_vector(self):
        print("\n\nRunning test #2 (fitting functions)")
        x = np.full(5, fill_value=1.0)
        f = lMC3F.GetSomeFunc(Type="const", ProbeIsPump=False) 
        y = f(x)

        self.assertTrue(np.isclose(x,y).all())        

    def test_extraction_of_the_constant_scalar(self):
        print("Running test #3 (fitting functions)")
        x = 1.
        f = lMC3F.GetSomeFunc(Type="const", ProbeIsPump=False) 
        y = f(x, None, None, None)

        self.assertTrue(np.isclose(x,y).all())      

    def test_extraction_of_the_gauss(self):
        print("\n\nRunning test #4 (fitting functions)")
        x = np.linspace(-1.,1.,50)
        f = lMC3F.GetSomeFunc(Type="gauss", ProbeIsPump=False) 
        tcc = 0.1
        y = f(x, 0., tcc, None)
        expY = np.exp(-(x/tcc)**2)
        self.assertTrue(np.isclose(expY,y).all())              

    def test_extraction_of_the_switch(self):
        print("\n\nRunning test #5 (fitting functions)")       
        x = np.linspace(-1.,1.,50)
        f = lMC3F.GetSomeFunc(Type="switch", ProbeIsPump=False) 
        tcc = 0.1
        y = f(x, 0., tcc, None)
        expY = 1.0 + spsp.erf(x/tcc)
        self.assertTrue(np.isclose(expY,y).all())              

    def test_extraction_of_the_switch_backwards(self):
        print("\n\nRunning test #6 (fitting functions)")       
        x = np.linspace(-1.,1.,50)
        f = lMC3F.GetSomeFunc(Type="switch", ProbeIsPump=True) 
        tcc = 0.1
        y = f(x, 0., tcc, None)
        expY = 1.0 + spsp.erf(-x/tcc)
        self.assertTrue(np.isclose(expY,y).all())    

    def test_extraction_of_the_trans(self):
        print("\n\nRunning test #7 (fitting functions)")       
        x = np.linspace(-1.,1.,10)
        f = lMC3F.GetSomeFunc(Type="trans", ProbeIsPump=False) 
        tcc = 0.1
        tr  = 2.0
        y = f(x, 0., tcc, tr)
        expY = (1.0 + spsp.erf(+x/tcc)) * np.exp(-x/tr) * np.exp(0.25 * (tcc/tr)**2)
        print(y-expY)
        self.assertTrue(np.isclose(expY,y, rtol=1e-02, atol=1e-02).all())    


class TestCleaningFunctions(unittest.TestCase):

    def test_not_defined_channels_request(self):
        print("\n\nRunning test #1 (cleaning)")       
        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr2.conf")
        print("datas",Datas)
        print("chans",Chans)
        with self.assertRaises(RuntimeError): lMC3F.GetOnlyTheChannels(Datas, Chans)

    def test_good_channels_request(self):
        print("\n\nRunning test #2 (cleaning)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        print(Datas)
        print(Chans)

        expChans = {'gaussian', 'justaconstant'}
        CleanChans = lMC3F.GetOnlyTheChannels(Datas, Chans)
        
        print(CleanChans)
        self.assertTrue(CleanChans == expChans )            

    def test_missing_variable_request(self):
        print("\n\nRunning test #3 (cleaning)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr1.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        CleanChans = lMC3F.GetOnlyTheChannels(Datas, Chans)
        print(Chans)
        print(CleanChans)
        with self.assertRaises(RuntimeError): lMC3F.GetOnlyTheVariables(CleanChans, Chans, Vars)

    def test_good_variable_request(self):
        print("\n\nRunning test #4 (cleaning)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        CleanChans = lMC3F.GetOnlyTheChannels(Datas, Chans)
        CleanVars = lMC3F.GetOnlyTheVariables(CleanChans, Chans, Vars)
        expVars = {'t0', 'tcc'}
        self.assertTrue(CleanVars == expVars )            

    def test_good_mapping(self):
        print("\n\nRunning test #5 (cleaning)") 

        expVars = {'t0', 'tcc'}

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")
        
        Map = set(lMC3F.GetVariableMap(Datas, Chans, Vars))

        self.assertTrue(Map == expVars )                    


class TestDataSetHandler(unittest.TestCase):
    def test_class_example_initiation(self):
        print("\n\nRunning test #1 (DataSetHandler)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")
        
        Map = lMC3F.GetVariableMap(Datas, Chans, Vars)
        
        for key in Datas.keys():
            Example = lMC3F.DataSetHandler(Datas[key], key, Chans, Map)

    def test_generic_data_linear_fitting(self):
        print("\n\nRunning test #2 (DataSetHandler)")          

        Chans = lMC3F.readChannelsDefinitions("z_chans1.conf")
        Datas = lMC3F.readDataSetsDefinitions("z_datas1.conf")
        Vars  = lMC3F.readVariablesDefinitions("z_vars1.conf")

        
        Map = ['t0', 'tcc']
        Example = lMC3F.DataSetHandler(Datas['dataset1'], 'dataset1', Chans, Map)

        ValVec = np.array([0.0, 0.1])
        Example.update(ValVec)

        expAmps = {"chan1": 0.1, "chan2": -0.3}
        resAmps = Example.getAmpDict()
        print(expAmps)
        print(resAmps)
        self.assertTrue([np.isclose(expAmps[key],resAmps[key]) for key in expAmps.keys()] )                    


class TestVariablesHandler(unittest.TestCase):
    def test_class_example_initiation_and_vector_values_generation(self):
        print("\n\nRunning test #1 (VariablesHandler)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        VarHand = lMC3F.VariablesHandler(DataSets = Datas, Channels = Chans, Variables = Vars)
        inix = VarHand.getVarVec()
        VarHand.genTrialVarVec()
        finx = VarHand.getVarVec()
        print(inix)
        print(finx)
        print(VarHand.getBounds())




class TestAdditionalConstraints(unittest.TestCase):
    def test_class_example_initiation(self):
        print("\n\nRunning test #1 (AdditionalConstraints)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        Map = lMC3F.GetVariableMap(Datas, Chans, Vars)


        
        AddC = lMC3F.AdditionalConstraints(FileName = "good_constrains_file_nr0.conf", VariableMap = Map)
        
    def test_class_repell_value_computation(self):
        print("\n\nRunning test #1 (AdditionalConstraints)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        VarHand = lMC3F.VariablesHandler(DataSets = Datas, Channels = Chans, Variables = Vars)   
        Map     = VarHand.getMap()
        VarVec = VarHand.getVarVec()
        
        AddC = lMC3F.AdditionalConstraints(FileName = "good_constrains_file_nr0.conf", VariableMap = Map)     

           
        RepVal = AddC._totalRepell(VarVec = VarVec)
        
        print("Repellent value = "+str(RepVal))           
        self.assertTrue(np.isclose(RepVal,0.001) )                    

    def test_class_constraint_value_computation(self):
        print("\n\nRunning test #1 (AdditionalConstraints)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        VarHand = lMC3F.VariablesHandler(DataSets = Datas, Channels = Chans, Variables = Vars)   
        Map     = VarHand.getMap()
        VarVec = VarHand.getVarVec()
        
        AddC = lMC3F.AdditionalConstraints(FileName = "good_constrains_file_nr0.conf", VariableMap = Map)  
        
           
        ConVal = AddC._totalConstr(VarVec = VarVec)
        print("Constraint value = "+str(ConVal))
        self.assertTrue(np.isclose(ConVal,5000.) )  

    def test_class_total_reg_val_calculation(self):
        print("\n\nRunning test #1 (AdditionalConstraints)") 

        Chans = lMC3F.readChannelsDefinitions("good_channels_nr0.conf")
        Datas = lMC3F.readDataSetsDefinitions("good_data_nr3.conf")
        Vars  = lMC3F.readVariablesDefinitions("good_variable_file_nr0.conf")

        VarHand = lMC3F.VariablesHandler(DataSets = Datas, Channels = Chans, Variables = Vars)   
        Map     = VarHand.getMap()
        VarVec = VarHand.getVarVec()
        
        
        AddC = lMC3F.AdditionalConstraints(FileName = "good_constrains_file_nr0.conf", VariableMap = Map)     
           
        RegVal = AddC.getRegValue(VarVec = VarVec)
        
        print("Regularization value = "+str(RegVal))        
        self.assertTrue(np.isclose(RegVal,5000.+0.001) )  




class TestDoTheGlobalFitAndSampling(unittest.TestCase):
    def test_false_method_choice(self):
        print("\n\nRunning test #1 (TestDoTheGlobalFit)\n\n")
        with self.assertRaises(RuntimeError): lMC3F.DoTheGlobalFit(ListOfData=None, VarHand=None, AddConstr=None, Method = 'Something Else')     
           
    def test_global_fit_with_diff_evo(self):
        print("\n\nRunning test #2 (TestDoTheGlobalFit), DiffEvo\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas3.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans3.conf",  # channels description file name
                                                             VariablesDescription = "z_vars3.conf"
                                                            )
            
        Res = lMC3F.DoTheGlobalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'DiffEvo', ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 1.0e-2)
        self.assertTrue(FitIsClose)          
 
    def test_global_fit_with_diff_evo_with_args(self):
        print("\n\nRunning test #2.1 (TestDoTheGlobalFit), DiffEvo\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas3.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans3.conf",  # channels description file name
                                                             VariablesDescription = "z_vars3.conf"
                                                            )
            
        AddArgs = {"popsize": 10}    
        Res = lMC3F.DoTheGlobalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'DiffEvo', AdditionalArguments=AddArgs, ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 1.0e-2)
        self.assertTrue(FitIsClose)          
 



    def test_global_fit_with_dual_ann(self):
        print("\n\nRunning test #3 (TestDoTheGlobalFit), DualAnn\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas3.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans3.conf",  # channels description file name
                                                             VariablesDescription = "z_vars3.conf"
                                                            )
            
        Res = lMC3F.DoTheGlobalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'DualAnn', ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 1.0e-2)
        self.assertTrue(FitIsClose)              


    def test_global_fit_with_diff_evo_and_mcmc_sampling(self):
        print("\n\nRunning test #4 (TestDoTheGlobalFit), DiffEvo+MCMC\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas4.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans4.conf",  # channels description file name
                                                             VariablesDescription = "z_vars4.conf"
                                                            )
            
        AddArgs = {"popsize": 10}    
        Res = lMC3F.DoTheGlobalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'DiffEvo', AdditionalArguments=AddArgs, ReturnDictionary=False)
        VarHand.updateVarVec(VarVec = Res)
        res = lMC3F.DoTheMCMCSampling(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, 
                                NSteps=15000,            # Number of steps in MCMC simulation
                                NStepsToIgnore=None,     # How many first steps to ignore (overrides PartToIgnore if provided)
                                PartToIgnore=0.1,        # Which part of the MCMC simulation to ignore (is overriden by NStepsToIgnore if not None)
                                AcceptanceProbabilityScale = 1.0, # Scaling coefficient for the Metropolis acceptence probability
                                AddInfoToFiles = "testing")

        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        FitIsClose=True
        print(ExpRes)
        print(res)
        for key in ExpRes.keys():
            FitIsClose *= np.abs(res[key][0] - ExpRes[key]) < 3.0 * res[key][1]
        self.assertTrue(FitIsClose)   


    def test_local_fit_standard(self):
        print("\n\nRunning test #5 (TestDoTheGlobalFit), Default\n\n")
       
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas4.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans4.conf",  # channels description file name
                                                             VariablesDescription = "z_vars4.conf"
                                                            )
            
        Res = lMC3F.DoTheLocalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = None, ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 2.0e-1)
        self.assertTrue(FitIsClose)              


    def test_local_fit_with_Powell(self):
        print("\n\nRunning test #5 (TestDoTheGlobalFit), Powell\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas4.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans4.conf",  # channels description file name
                                                             VariablesDescription = "z_vars4.conf"
                                                            )
            
        Res = lMC3F.DoTheLocalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'Powell', ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 2.0e-1)
        self.assertTrue(FitIsClose)              


    def test_local_fit_with_Powell_inverse(self):
        print("\n\nRunning test #6 (TestDoTheGlobalFit), Powell\n\n")
        ListOfData, VarHand, RegInstance = lMC3F.ReadTheData(DataDescription      = "z_datas5.conf",      # data description file name
                                                             ChannelsDescription  = "z_chans5.conf",  # channels description file name
                                                             VariablesDescription = "z_vars5.conf"
                                                            )
            
        Res = lMC3F.DoTheLocalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'Powell', ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= (np.abs(ExpRes[key] - Res[key]) <= 2.0e-1)
        self.assertTrue(FitIsClose)              




# SHGO was depreciated, since i have no idea how to make it work ':(
"""
    def test_global_fit_with_shgo(self):
        print("\n\nRunning test #3 (TestDoTheGlobalFit), SHGO\n\n")
        Chans = lMC3F.readChannelsDefinitions("z_chans3.conf")
        Datas = lMC3F.readDataSetsDefinitions("z_datas3.conf")
        Vars  = lMC3F.readVariablesDefinitions("z_vars3.conf")
        
        # initiate the variables handler
        VarHand = lMC3F.VariablesHandler(DataSets = Datas, Channels = Chans, Variables = Vars)           
        Map     = VarHand.getMap()
        ListOfData = []
        
        # initiate the dataset handler
        for key in Datas.keys():
            Example = lMC3F.DataSetHandler(Datas[key], key, Chans, Map)
            ListOfData.append(Example)
            
        AddArgs = {"iters": 10}    
        Res = lMC3F.DoTheGlobalFit(ListOfData=ListOfData, VarHand=VarHand, AddConstr=None, Method = 'SHGO', AdditionalArguments=AddArgs, ReturnDictionary=True)
        ExpRes = {"t0": 0.0, "tcc": 0.1, "tr": 0.5}
        print(Res)
        print(ExpRes)
        FitIsClose=True
        for key in ExpRes.keys():
            FitIsClose *= np.isclose(ExpRes[key],Res[key])
        self.assertTrue(FitIsClose)     
"""



if __name__ == '__main__':
    unittest.main()







