#!   /usr/bin/env	python
#    coding: utf8

import sys
import rr
import random
import time
import spi
import csr
import i2c
import gn4124
import fmc_adc
from   pylab import *
import math

if __name__ == '__main__':

    """
    Sinewave test
    Requires sinewave input
    Takes an acquired sinewave and compares to 2 ideal sinewaves, 
    an upper threshold and a lower threshold.  If the acquired
    sinewave is not within this an error is produced and the data is written to a file
    """ 


    
    glitch_count = 0
    error_threshold = 10
    hw_en =1
    sw_en =0
    chan = 0xB
    int_thresh = 0x0001
    slope = 0
    delay = 0
    edge_detect =1

    iteration = 0
    thresh_trig_en = 1
    edge_detection = 1
    pre_trig  = 0
    post_trig = 500
        

    # Acquires settings from user
    for i in range(11):
    	print ("Chan %d  - Camera Link %d")%(i+1,i+1)
    
    
    
    # Obtain Data from user
    chan = int(raw_input("Which Channel is the Sinewave input to?   :"))
    frequency_of_wave =  int(raw_input("Please input the frequency of the sine wave : "))
    num_of_loops = int(raw_input("Please select the number of iterations for the test : "))
    
    # Objects declaration
    spec = rr.Gennum() # bind to the SPEC board
    gn4124 = gn4124.CGN4124(spec, 0x0)
    fmc = fmc_adc.CFmcAdc100ks(spec)
    	
    # Carry out acquisition on channel with the sinewave input - 
    #channel_data = fmc.do_acq(chan, "chan_select" ,"N",post_trig ,pre_trig,thresh_trig_en,edge_detection)
    
    	# Set trigger Register
    fmc.set_trig_config(hw_en,sw_en,chan,int_thresh,slope,delay,edge_detect)
    
    for loop in range(num_of_loops):
	    channel_data =  fmc.do_acq(chan, "chan_select" ,"n",500,0,1)	

	    sine_wave=[] 
	    time_base=[] 
	    
	    # Generated sinewave constants
	    amplitude = max(channel_data) 
	    perfect_sine_high =[]
	    perfect_sine_low  =[]
	    rad = 2*math.pi    			
	    sampling_rate = 200000      	 
	    num_acq = post_trig + pre_trig + 1  
	    no_samples_per_period  = float(sampling_rate)/float(frequency_of_wave)
	    num_waves 		   = float(num_acq)/no_samples_per_period
		
	    ideal_wave_size = (num_acq/num_waves)
	    position_of_ideal_peak = (num_acq/(4*num_waves))

	    
	    # Detect Position of Peak 
	    i = 0
	    peak_pos =0
	    num_1 = channel_data[0]
	    num_2 = channel_data[1]
	    if num_1<num_2:
	    	i=0   	
	    	while (num_1<num_2):
	    		num_1=channel_data[i]
	    		num_2=channel_data[i+1]		
	    		i=i+1
	    	peak_pos = i
	    elif num_1>num_2:
	    	i = 0 
	    	while (num_1>num_2):
	    		num_1=channel_data[i]
	    		num_2=channel_data[i+1]		
	    		i=i+1		
	    	trough_pos = i
	    	peak_pos = trough_pos + (ideal_wave_size/2) 
	    	
		    	

	    	

	    for i in range(int(num_acq)+1):
	    	argument = (((float(i)*num_waves)/float(num_acq))*float(rad))
		#print argument 
		sine_wave.append( int(amplitude*math.sin(argument)))
		time_base.append(i)
	 
	    # generate a couple of sine waves, an upper bound and a lower bound
	    # calculate their amplitude by measuring the the channel6 sine wave with min and max functions
	    	    
	    for i in range(int(num_acq)):
		argument = (((float(i)*num_waves)/float(num_acq))*float(rad))
		perfect_sine_high.append( int(amplitude*math.sin(argument)) +1000 )
		perfect_sine_low.append( int(amplitude*math.sin(argument))  -1000 )
		time_base.append(i)

	    size_sine_list = len(perfect_sine_high)
		    
		
	    # Align waves
	    if peak_pos >position_of_ideal_peak:
	    	align_wave = (ideal_wave_size - (peak_pos -  position_of_ideal_peak) )
	    elif peak_pos <=position_of_ideal_peak:
	    	#align_wave = 26 - peak_pos
	    	align_wave = position_of_ideal_peak - peak_pos
	    else:
	    	align_wave = 0
	    
	    """
	    print "Wave aligned by...", int(align_wave)
	    print "Ideal peak : ",int(position_of_ideal_peak)
	    print "Real peak  : ", peak_pos
	    print "Ideal wave size : ",ideal_wave_size
	    """
	    
	    glitch_found = 0 
	    if len(channel_data)<len(perfect_sine_high):
	    	loop_val = len(channel_data)
	    else:
	    	loop_val = len(perfect_sine_high)
	    	
	    for i in range(loop_val):
	    	real_val =  channel_data[i]
	    	upper_bound = perfect_sine_high[i+int(align_wave)]
	    	lower_bound = perfect_sine_low[i+int(align_wave)]
	    	if real_val<lower_bound or real_val>upper_bound:
	    		glitch_found = 1
	    
	    if glitch_found ==1:
	    	print "glitch found in result"
	    else:
	    	print "\n Valid Result\n"
		
		
	    """	
	    for i in range(len(channel_data)):
	    	channel_data[i] = channel_data[i] * 0.000152
    	
    	    for i in range(len(perfect_sine_high)):
	    	perfect_sine_high[i] = perfect_sine_high[i] * 0.000152	
    	
    	    for i in range(len(perfect_sine_low)):
	    	perfect_sine_low[i] = perfect_sine_low[i] * 0.000152	
    	    """		
    		
	    
	    
	    if glitch_found ==1:
	    	iteration = iteration +1
	    	file_string = "adc_100k_acq_" + str(glitch_count) +".txt"
	    
	        if iteration ==1:
	    	   	file_string = "adc_100k_acq.txt"
		# WRITE TO FILE
	    	file = open(file_string, 'w')
	    	for i in range(len(channel_data)):
			file.write("%5d, %5f, %5f, %5f\n" % (time_base[i], channel_data[i], perfect_sine_high[i+int(align_wave)], perfect_sine_low[i+int(align_wave)]))
        
	    if iteration == error_threshold:
                print "Error threshold reached...Please examine results "
          	break
    
    print " %d Errors found from %d iterations"%(iteration,num_of_loops)
    print "Examine results"
        
    print '\nBye bye ...'
    sys.exit()
    
    
