def calculateMetric(metric_name, param_vals):
	if metric_name == 'count':
		if len(param_vals)!= 1:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be count(data)'
			raise Exception()
		return red.count(*param_vals)
	elif metric_name == 'pdf':
		if len(param_vals)!= 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be pdf(data, bin_values, continuous_bins)'
			raise Exception()
		return PDF.single(*param_vals)
	elif metric_name == 'deft':
		if len(param_vals) < 2 or len(param_vals) > 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be deft(data, g, alpha)'
			raise Exception()
		return deft.deft(*param_vals)
	elif metric_name == 'pdf_joint':
		if len(param_vals)!= 6:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be pdf_joint(dataA, bin_valuesA, continuous_binsA, dataB, bin_valuesB, continuous_binsB)'
			raise Exception()
		return PDF.joint(*param_vals)
	elif metric_name == 'mutual_information':
		if len(param_vals) < 3 or len(param_vals) > 4:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be mutual_information(pdfA, pdfB, joint_pdf, logbase="log2")'
			raise Exception()
		return MI.calculate(*param_vals)
	elif metric_name == 'shannon':
		if len(param_vals) < 1 or len(param_vals) > 2:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be shannon(pdf, logbase="log2")'
			raise Exception()
		return shannon.calculate(*param_vals)
	elif metric_name == 'kullback-leibler':
		if len(param_vals) < 2 or len(param_vals) > 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be kullback-leibler(pdf_p, pdf_q, logbase="log2")'
			raise Exception()
		return kullback.calculate(*param_vals)
	elif metric_name == 'fisher':
		if len(param_vals) < 2 or len(param_vals) > 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be fisher(pdf, eps, logbase="log2")'
			raise Exception()
		return fis.calculate(*param_vals)
	elif metric_name == 'hellinger-distance':
		if len(param_vals) != 2:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be hellinger-distance(pdf_p, pdf_q)'
			raise Exception()
		return hellinger.calculate(*param_vals)
	elif metric_name == 'surprise':
		if len(param_vals)!= 1:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be surprise(prob)'
			raise Exception()
		return surprise.calculate(*param_vals)
	elif metric_name == 'idt':
		if len(param_vals) < 6 or len(param_vals) > 7:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be idt(initial, time_series, epsilon, dt, bin_values, continuous_bins, logbase="log2")'
			raise Exception()
		return IDT.system(*param_vals)
	elif metric_name == 'idt_individual':
		if len(param_vals) < 8 or len(param_vals) > 9:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be idt_individual(initial, time_series, dt, bin_values, continuous_bins, sample_state_0, sample_state_t, sample_time, logbase="log2")'
			raise Exception()
		return IDT.individual(*param_vals)
	elif metric_name == 'information_integration':
		if len(param_vals) < 9 or len(param_vals) > 10:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be information_integration(initial, group, dt, bin_values, continuous_bins, sample_N1, sample_N2, sample_G, sample_t, logbase="log2")'
			raise Exception()
		return II.calculate(*param_vals)
	elif metric_name == 'multi_information':
		if len(param_vals) < 6 or len(param_vals) > 7:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be multi_information(data, bin_values, continuous_bins, sample_var, sample_elems, sample_pop, logbase="log2")'
			raise Exception()
		return multi.calculate(*param_vals)
	elif metric_name == 'swap_axes':
		if len(param_vals)!= 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be swap_axes(data, axis0, axis1)'
			raise Exception()
		return np.swapaxes(*param_vals)
	elif metric_name == 'add_dimension':
		if len(param_vals)!= 2:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be add_dimension(data, dimNumber)'
			raise Exception()
		return  np.expand_dims(*param_vals)
	elif metric_name == 'join_dimensions':
		if len(param_vals)!= 3:
			print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be join_dimensions(data, dimNumberA, dimNumberB)'
			raise Exception()
		return  red.join(*param_vals)
	else :
		# Try to get a numpy function
		try :
			func = getattr(np, metric_name)
			return func(*param_vals)
		except:
			print 'ERROR:Metric ', metric_name, ' does not exist'
			raise Exception()
def calculateMetric(metric_name, param_vals):
    '''
    Calculates a metric.

    Input:
        metric_name     metric name
        param_vals      metric parameters
    Returns:
                        result of the metric
    '''
    if metric_name == 'count':
        if len(param_vals)!= 1:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be count(data)'
            raise Exception()
        return red.count(*param_vals)
    elif metric_name == 'pdf':
        if len(param_vals)!= 3:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be pdf(data, bin_values, continuous_bins)'
            raise Exception()
        return PDF.single(*param_vals)
    elif metric_name == 'deft':
        if len(param_vals) < 4 or len(param_vals) > 5:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be deft(data, g, minLimit, maxLimit, alpha=2)'
            raise Exception()
        return deft.deft(*param_vals)
    elif metric_name == 'deft_joint':
        if len(param_vals) < 7 or len(param_vals) > 8:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be deft_joint(dataA, dataB, g, minLimitA, maxLimitA, minLimitB, maxLimitB, alpha=2)'
            raise Exception()
        return deft.deft(*param_vals)
    elif metric_name == 'pdf_joint':
        if len(param_vals)!= 6:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be pdf_joint(dataA, bin_valuesA, continuous_binsA, dataB, bin_valuesB, continuous_binsB)'
            raise Exception()
        return PDF.joint(*param_vals)
    elif metric_name == 'mutual_information':
        if len(param_vals) < 3 or len(param_vals) > 4:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be mutual_information(pdfA, pdfB, joint_pdf, logbase="log2")'
            raise Exception()
        return MI.calculate(*param_vals)
    elif metric_name == 'shannon':
        if len(param_vals) < 1 or len(param_vals) > 2:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be shannon(pdf, logbase="log2")'
            raise Exception()
        return shannon.calculate(*param_vals)
    elif metric_name == 'kullback-leibler':
        if len(param_vals) < 2 or len(param_vals) > 3:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be kullback-leibler(pdf_p, pdf_q, logbase="log2")'
            raise Exception()
        return kullback.calculate(*param_vals)
    elif metric_name == 'fisher':
        if len(param_vals) < 2 or len(param_vals) > 3:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be fisher(pdf, eps, logbase="log2")'
            raise Exception()
        return fis.calculate(*param_vals)
    elif metric_name == 'hellinger-distance':
        if len(param_vals) != 2:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be hellinger-distance(pdf_p, pdf_q)'
            raise Exception()
        return hellinger.calculate(*param_vals)
    elif metric_name == 'surprise':
        if len(param_vals)!= 1:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be surprise(prob)'
            raise Exception()
        return surprise.calculate(*param_vals)
    elif metric_name == 'idt':
        if len(param_vals) < 6 or len(param_vals) > 7:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be idt(initial, time_series, epsilon, dt, bin_values, continuous_bins, logbase="log2")'
            raise Exception()
        return IDT.system(*param_vals)
    elif metric_name == 'idt_individual':
        if len(param_vals) < 8 or len(param_vals) > 9:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be idt_individual(initial, time_series, dt, bin_values, continuous_bins, sample_state_0, sample_state_t, sample_time, logbase="log2")'
            raise Exception()
        return IDT.individual(*param_vals)
    elif metric_name == 'information_integration':
        if len(param_vals) < 9 or len(param_vals) > 10:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be information_integration(initial, group, dt, bin_values, continuous_bins, sample_N1, sample_N2, sample_G, sample_t, logbase="log2")'
            raise Exception()
        return II.calculate(*param_vals)
    elif metric_name == 'multi_information':
        if len(param_vals) < 6 or len(param_vals) > 7:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be multi_information(data, bin_values, continuous_bins, sample_var, sample_elems, sample_pop, logbase="log2")'
            raise Exception()
        return multi.calculate(*param_vals)
    elif metric_name == 'early_warning_difference':
        if len(param_vals) < 4 or len(param_vals) > 5:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be early_warning_difference(time_series_ref, time_series_comp, change_values, warning_values, histogram_limit=50)'
            raise Exception()
        return ew.early_warning_difference(*param_vals)
    elif metric_name == 'early_warning_flips':
        if len(param_vals) != 2:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be early_warning_flips(time_series, change_values)'
            raise Exception()
        return ew.early_warning_flips(*param_vals)
    elif metric_name == 'add_dimension':
        if len(param_vals)!= 2:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be add_dimension(data, dimNumber)'
            raise Exception()
        return  np.expand_dims(*param_vals)
    elif metric_name == 'join_dimensions':
        if len(param_vals)!= 3:
            print 'ERROR:Error in ', metric_name, ', number of parameters incorrect. It must be join_dimensions(data, dimNumberA, dimNumberB)'
            raise Exception()
        return  red.join(*param_vals)
    else :
        # Try to get a numpy function
        try :
            func = getattr(np, metric_name)
            return func(*param_vals)
        except:
            print 'ERROR:Metric ', metric_name, ' does not exist'
            raise Exception()