def PlotSpillageVsNoiseFrequency():
	frequencies = [x/100.0 for x in range(5980, 6020)]
	allData = [[] for _ in frequencies]
	sps = 768
	xs  =[]
		
	for i, noiseFreq in enumerate(frequencies):
		data = dataImport.generateSignal(rawSps, [(noiseFreq, 1.0)])
		startOffset = 7
		for offset in range(0, 2500, 100):
		
			downSampledData = fftDataExtraction.downSample(data, rawSps, sps)[offset+startOffset:offset+128+startOffset]
			
			#pylab.plot([x/float(sps) for x in range(len(downSampledData))], downSampledData); pylab.show()
			
			#print sps, offset, len(downSampledData)
			#frequencies = [float(sps) * x / len(downSampledData) for x in range(len(downSampledData)/2+1)]
			
			leakage = getToneLeakage(downSampledData)
			#print 'leakage: %f' % leakage
			#plot(fData, frequencies)
			#print '%d - %f' % (sps, leakage)
			allData[i].append(leakage)
	
			
	pylab.subplot(211)
	for ys in zip(*allData):
		pylab.plot(frequencies, ys)
	pylab.grid(True)
	means = map(stats.mean, allData)
	pylab.subplot(212)
	pylab.grid(True)
	pylab.plot(frequencies, means, '-o')
	
	pylab.show()
def createChangingTimeDomainDataPhaseMatch(baseFilename, low = 0, high = 10):
	dat0 = dataImport.readADSFile(baseFilename % low)
	dat1 = dataImport.readADSFile(baseFilename % high)
	sps = dataImport.getSPS(baseFilename % low)
	if dataImport.getSPS(baseFilename % high) != sps:
		raise Exception("samples per second do not match - FAIL")
	
	dataSources = [dat0, dat1]
	indeces = [0, 0]
	
	if dataLength < float(constants.windowSize) / constants.samplesPerSecond * 1.5:
		raise Exception("Data length is too short - not getting full ffts of a single data source")
	
	numSamples = int(dataLength * sps)
	result = []
	output = []
	
	for i in range(numSignalChunks * 2):
		newIndex = i % 2
			
		if i == 0:
			dataToAppend = centerAroundZero(dataSources[newIndex][indeces[newIndex] : indeces[newIndex] + numSamples])
			indeces[newIndex] += numSamples
		else:
			#gotta phase match
			newData = centerAroundZero(dataSources[newIndex][indeces[newIndex] : int(indeces[newIndex] + numSamples + sps * startIndexRange*2)])
			startOffset = getBestStartIndex(result, newData, sps)
			#print startOffset
			dataToAppend = newData[startOffset: startOffset + numSamples]
			indeces[newIndex] += numSamples + startOffset
			
		if len(dataToAppend) != numSamples:
			raise Exception("Data to be appended is not the correct length")
		
		oldIndex = len(result)
		result += dataToAppend
		output += [newIndex] * numSamples
		
		
	#down sample result and output
	result = fftDataExtraction.downSample(result, sps, interpolate = True)
	output = fftDataExtraction.downSample(output, sps,)
	return result, output
def PlotSpillageVsSampleFrequency(rawData, rawSps):
	startOffset = 7
	allData = []
	start = 748
	end = 488
	for offset in range(0, 2500, 100):
		
		xs  =[]
		ys = []
		
		for sps in range(748, 788, 1):
			#sps /= 10.0
			downSampledData = fftDataExtraction.downSample(data, rawSps, sps)[offset+startOffset:offset+128+startOffset]
			
			#pylab.plot([x/float(sps) for x in range(len(downSampledData))], downSampledData); pylab.show()
			
			#print sps, offset, len(downSampledData)
			frequencies = [float(sps) * x / len(downSampledData) for x in range(len(downSampledData)/2+1)]
			
			leakage = getToneLeakage(downSampledData)
			#print 'leakage: %f' % leakage
			#plot(fData, frequencies)
			#print '%d - %f' % (sps, leakage)
			xs.append(sps)
			ys.append(leakage)
		
		allData.append(ys)
			
	pylab.subplot(211)
	for ys in allData:
		pylab.plot(xs, ys)
	
	means = map(stats.mean, zip(*allData))
	pylab.subplot(212)
	pylab.plot(xs, means, '-o')
	pylab.grid(True)
	
	order = 2
	
	coefficients = polyfit(xs, means, order)
	print coefficients, stats.quadraticMinimum(*coefficients)
	generated = []
	for x in xs:
		y = sum([(float(x)**float(order - i)) * c for i, c in enumerate(coefficients)])
		#print x,y
		generated.append(y)
		
	diff = sum([(x1-x2)**2.0 / x1 for x1, x2 in zip(generated, means)])
	print start, end, diff
		
	#pylab.plot(xs, generated)	
	
	
	pylab.show()
def QuadraticGuessIteration(rawData):
	fDown = 8000.0 + 200.0 * (random() - 0.5)
	rawSps = fDown; rawData = fftDataExtraction.downSample(rawData, 32000, fDown, interpolate = False)[int(random() * 100):]
	calculatedSampleRate = (59.96 / 60.0 * samplesPerSecond * rawSps / fDown)
	
	algorithm = QuadraticErrorFitting2(0)
	
	testSampleInterval = algorithm.GetFirstInterval()
	testIntervalCounter = 0.0
	
	testBufferNewAmount = windowSize
	
	testBuffer = []
	
	testLeakages = []; testLeakageTimes = []
	testSampleRates = []
	
	lastSample = 0.0
	
	for index, sample in enumerate(rawData):
		time = float(index) / rawSps
		
		testIntervalCounter += 1.0
			
		if testIntervalCounter >= testSampleInterval:
			testIntervalCounter %= testSampleInterval
			weight0 = min(1.0, testIntervalCounter)
			weight1 = max(0.0, 1.0 - testIntervalCounter)
			interpolatedSample = weight0 * sample + weight1 * lastSample
			testBuffer.append(interpolatedSample)
			
			if len(testBuffer) > windowSize + testBufferNewAmount:
				testBuffer = testBuffer[-windowSize:]
				
				leakage = getToneLeakage(testBuffer)
				testLeakages.append(leakage)
				testLeakageTimes.append(time)
				testSampleRates.append(float(rawSps) / testSampleInterval)
				
				realSampleInterval, testSampleInterval, isDone = algorithm.OnNewBuffer(testBuffer, testSampleInterval, True)
				if isDone:
					#print testSampleInterval
					break
					
	return calculatedSampleRate, rawSps / testSampleInterval
def getSVMTrainingData(datas):
	trainingDatas = []
	for rawData, output in datas:
		channels = zip(*rawData)
		allBins = []
		for channel in channels:
			downSampledData = fftDataExtraction.downSample(channel, rawSps, constants.samplesPerSecond, interpolate = True)
			
			transforms = fftDataExtraction.applyTransformsToWindows(fftDataExtraction.getFFTWindows(downSampledData), magnitude = True, polyFitSubtraction = 2)
			
			bins = fftDataExtraction.DoFrequencyBinning(transforms)
			allBins.append(bins)
			
		trainingInputs = map(lambda x: x[0] + x[1], zip(*allBins))
		
		trainingDatas += [(input, output) for input in trainingInputs]
		
	return trainingDatas
def getSignalCoherenceError(downSampledFrequency, rawData = rawData):
	downSampled = fftDataExtraction.downSample(rawData, rawSps, downSampledFrequency, interpolate = True)#[int(random()*100):]
	#downSampled = downSampled[:int(downSampledFrequency)/2]
	#downSampled = downSampled[:40]
	highSamples = downSampled[::2]
	lowSamples = downSampled[1::2]

	times = map(lambda x: x/downSampledFrequency, range(len(downSampled)))
	highTimes = times[::2]
	lowTimes = times[1::2]
	
	differences = map(lambda x: (x[0]-x[1])**1.0, zip(highSamples, lowSamples))
	
	slope, yint = stats.lineOfBestFit(highTimes, differences)
	#return slope
	#return abs(slope)
	#return 1.0 / slope
	#return max(differences) - min(differences)
	
	#derivSquared = sum([(differences[i+1] - differences[i])**2.0 for i in range(len(differences)-1)])
	#return derivSquared
	
	return stats.variance(differences)
seed(1)

samplesPerSecond = 768
windowSize = 128
rangePercentage = 2.0
channels = 7
measurementCount = 10

filename = "Data/Mark/32kSPS_160kS_FlexorRadialis_0%.xls"; rawSps = 32000
#filename = "Data/Mark/32kSPS_160kS_ExtensorRadialis_0%.xls"; rawSps = 32000
rawData = dataImport.readADSFile(filename)
f = 59.96
#rawData = dataImport.generateSignal(rawSps, [(f, 1.0)], seconds = 5.0, noise = 1.0)

rawSps = 8000
rawData = fftDataExtraction.downSample(rawData, 32000, rawSps, interpolate = False)[int(random() * 100):]

overlap = 50 * 128 * rawSps / 768**2	#take this for all channels, could be slight different but ok

def getToneLeakage(downSampledData):
	noiseBin = 10
	power = map(lambda x: x*x, map(numpy.absolute, fourier(downSampledData)))
	result = (power[noiseBin-1] + power[noiseBin+1]) / power[noiseBin]
	#result = power[noiseBin-1] + power[noiseBin+1]
	return result
	
def GetConvergence(data, plot = True, initialOffset = 0.0):
	baseInterval = rawSps / (samplesPerSecond + initialOffset)
	
	channelIntervals = [baseInterval + rangePercentage * i * 0.02 for i in range(-channels/2+1, channels/2+1)]
	sampleFrequencies = map(lambda x: rawSps / x, channelIntervals)
import dataImport
import fftDataExtraction
import stats
from matplotlib import pylab
from numpy import polyfit
from random import random
from multiprocessing import Pool


filename = "Data/Mark/32kSPS_160kS_FlexorRadialis_0%.xls"; rawSps = 32000
#filename = "Data/Mark/32kSPS_160kS_ExtensorRadialis_0%.xls"; rawSps = 32000
#filename = "NoiseData/6 Loops 8000SPS Volts.xls"; rawSps = 8000
rawData = dataImport.readADSFile(filename)
f = 60.0
#rawData = dataImport.generateSignal(8000, [(f, 1.0)], seconds = 10.0)
rawData = fftDataExtraction.downSample(rawData, rawSps, 8000, interpolate = False)

rawSps = 8000

#finalSps = 120.0
#downSampled = fftDataExtraction.downSample(rawData, rawSps, finalSps, interpolate = True)

def getSignalCoherenceError(downSampledFrequency, rawData = rawData):
	downSampled = fftDataExtraction.downSample(rawData, rawSps, downSampledFrequency, interpolate = True)#[int(random()*100):]
	#downSampled = downSampled[:int(downSampledFrequency)/2]
	#downSampled = downSampled[:40]
	highSamples = downSampled[::2]
	lowSamples = downSampled[1::2]

	times = map(lambda x: x/downSampledFrequency, range(len(downSampled)))
	highTimes = times[::2]
def PlotFreqDomain(rawData, rawSps, sps):
	rawData = fftDataExtraction.downSample(data, rawSps, sps)