62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
import numpy as np


from scipy.optimize import curve_fit


from matplotlib import pyplot as plt




def normalize(v):


"""


A helper function to normalize a vector. That is, the sum of the square of each component


equals 1.


v: A vector to be normalized.


Returns: The normalized version of the vector.


Throws an exception if the norm is 0.


"""


norm = np.linalg.norm(v)


if norm == 0:


raise Exception("Function can not take a zero vector!")


return (v/norm)




def create_fitting_func(v1, v2):


"""


Use this to generate the function to be fitted.


v1: The first basis vector. In our example, the pure plastic vector.


v2: The second basis vector. In our example, the pure sugar vector.


Returns: A function that takes an x value, and two constants which vary with fitting.


"""


assert(len(v1) == len(v2))




def func(x, a, b):


return (a*v1[x] + b*v2[x])


return func






def calc_scaled_coeff(measured, spectra_one, spectra_two):


"""


Another helper function. This does the actual work in fitting the data to the model.


measured: The measured ydata.


spectra_one: The first basis vector, probably plastic.


spectra_two: The second basis vector, probably plastic.


Returns a tuple of the constants calculated.


"""


xdata = np.arange(len(measured))


assert(len(xdata) == len(spectra_one) and len(xdata) == len(spectra_two))


y_func = create_fitting_func(spectra_one, spectra_two)


popt, pcov = curve_fit(y_func, xdata, measured)


return popt




def scaled_subtraction(measured, spectra_one, spectra_two):


"""


The actual scaled_subtraction function intended to be called by other code.


measured: The measured ydata.


spectra_one: The first basis vector, probably plastic.


spectra_two: The second basis vector, probably plastic.


Returns a tuple of the two calculated vectors. The order of the vectors corrosponds to the order


that the arguments are given. So if the order is plastic and then sugar, you'll get calculated


plastic and then calculated sugar.


"""


spectra_one /= np.linalg.norm(spectra_one)


spectra_two /= np.linalg.norm(spectra_two)


coeffs = calc_scaled_coeff(measured, spectra_one, spectra_two)


loading_one = (measured  coeffs[1]*spectra_two)


loading_two = (measured  coeffs[0]*spectra_one)


return (loading_one, loading_two)
