temp.append( float(data[t][c]) ) t = pylab.array(temp) compounds.append(t) inflex = [] if interp: itime = [time[0]] # always an important value (step, t) = find_min_delta(time) end_time = time[len(time)-1] while t <= end_time: itime.append(t) t = t + step icompounds = [] # linear piecewise interpolation for c in compounds: icompounds.append(arrayfns.interp(c, time, itime)) compounds = icompounds time = itime if smoothing: ############ smoothing (Savitzky-Golay) ############ ### TODO choose between sg_filter and savitzky_golay coeff = sg_filter.calc_coeff(6,3) smoothed_compounds = [] for i in range(len(compounds)): #smoothed_compounds.append(sg_filter.smooth(compounds[i], coeff)) smoothed_compounds.append(savitzky_golay(compounds[i])) ############ derivative ############ coeff = sg_filter.calc_coeff(6,3,1) smoothed_dcompounds = [] for i in range(len(compounds)):
def interp(y, x, xinterp, missing=1e+20): """Simple linear interpolation for ordinate with missing values. Vectors x and y are the data describing a piecewise linear function. Function returns the interpolated values of the ordinate function at abscissa values in xinterp. Values of xinterp outside the range of x are returned as missing. Any elements in the output that uses missing values in y for the interpolation are set to missing. Positional Input Arguments: * y: Ordinate values of data. Rank 1 numeric vector. Required. Can have missing values. Floating or integer type. * x: Abscissa values of data. Rank 1 numeric vector. Required. Can have no missing values. Must be monotonically ascending. Floating or integer type. * xinterp: Abscissa values to calculate interpolated ordinate values at. Rank 1 numeric vector or numeric scalar. Required. Can have no missing values. Can be in any order. Floating or integer type. Keyword Input Arguments: * missing: If input has missing values, this is the missing value value. Scalar. Floating or integer type. Default is 1e+20. Output Result: * Interpolated ordinate values at xinterp. Rank 1 numeric vector of same length as xinterp (if xinterp is a numeric scalar, output is also a numeric scalar). Missing values are set to the value of argument missing. Type is Float, even if argument missing and inputs are all integer. References: * Lin, J. W.-B.: "Simple Interpolation." Python/CDAT for Earth Scientists: Tips and Examples. http://www.johnny-lin.com/cdat_tips/tips_math/interp.html Example with no missing values (gives same output as function arrayfns.interp): >>> from interp import interp >>> import numpy as N >>> x = N.array([1., 2., 3., 4., 5.]) >>> y = N.array([3., 6., 2.,-5.,-3.]) >>> xint = N.array([3.4, 2.3]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '4.8'] Example with missing values: >>> x = N.array([1., 2., 3., 4., 5.]) >>> y = N.array([3., 1e+20, 2., -5., -3.]) >>> xint = N.array([3.4, 2.3]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '1e+20'] Example with values out of range of the data: >>> x = N.array([1., 2.1, 3., 4., 5.1]) >>> y = N.array([3., 1e+20, 2., -5., -3.]) >>> xint = N.array([3.4, -2.3, 6.]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '1e+20', '1e+20'] """ import arrayfns import numpy.ma as MA import numpy as N from .where_close import where_close #- Check inputs for possible errors: if (N.rank(y) != 1) or (N.rank(x) != 1): raise ValueError("interp: Input(s) not a vector") if N.rank(xinterp) > 1: raise ValueError("interp: xinterp not a vector or scalar") if x[-1] <= x[0]: raise ValueError("interp: x not monotonically increasing") #- Establish constants and define xint, a rank 1 version of # xinterp to be used for the rest of the function: if N.rank(xinterp) == 0: xint = N.reshape(xinterp, (1, )) else: xint = xinterp num_xint = N.size(xint) #- Mask as missing values of xint that are outside of the range # of x: yint_outrange_mask = N.logical_or( N.less(xint, x[0]) \ , N.greater(xint, x[-1]) ) #- Mask of elements with missing values in y, if there are any # missing values in y. If xint equals a value in x, missing # values mask for that xint is the same as the corresponding # value in x; and mask elements in xint which fall in an interval # (whose upper bound index is top_idx) where one of the endpoints # is missing: y_miss_mask = where_close(y, missing) yint_miss_mask = N.zeros(num_xint) if MA.maximum(y_miss_mask) == 1: for i in range(num_xint): if yint_outrange_mask[i] == 0: x_eq_xint = where_close(x, xint[i]) if MA.maximum(x_eq_xint) == 1: yint_miss_mask[i] = y_miss_mask[N.nonzero(x_eq_xint)] else: top_idx = N.nonzero(N.greater(x, xint[i]))[0] yint_miss_mask[i] = y_miss_mask[top_idx] or \ y_miss_mask[top_idx-1] #- Return interpolated values, set to missing values as # appropriate, and making a scalar if xinterp is a scalar: yint = arrayfns.interp(y, x, xint) N.putmask( yint, N.logical_or(yint_miss_mask, yint_outrange_mask) \ , missing) if N.rank(xinterp) == 0: yint = yint[0] return yint
def interp(y, x, xinterp, missing=1e+20): """Simple linear interpolation for ordinate with missing values. Vectors x and y are the data describing a piecewise linear function. Function returns the interpolated values of the ordinate function at abscissa values in xinterp. Values of xinterp outside the range of x are returned as missing. Any elements in the output that uses missing values in y for the interpolation are set to missing. Positional Input Arguments: * y: Ordinate values of data. Rank 1 numeric vector. Required. Can have missing values. Floating or integer type. * x: Abscissa values of data. Rank 1 numeric vector. Required. Can have no missing values. Must be monotonically ascending. Floating or integer type. * xinterp: Abscissa values to calculate interpolated ordinate values at. Rank 1 numeric vector or numeric scalar. Required. Can have no missing values. Can be in any order. Floating or integer type. Keyword Input Arguments: * missing: If input has missing values, this is the missing value value. Scalar. Floating or integer type. Default is 1e+20. Output Result: * Interpolated ordinate values at xinterp. Rank 1 numeric vector of same length as xinterp (if xinterp is a numeric scalar, output is also a numeric scalar). Missing values are set to the value of argument missing. Type is Float, even if argument missing and inputs are all integer. References: * Lin, J. W.-B.: "Simple Interpolation." Python/CDAT for Earth Scientists: Tips and Examples. http://www.johnny-lin.com/cdat_tips/tips_math/interp.html Example with no missing values (gives same output as function arrayfns.interp): >>> from interp import interp >>> import numpy as N >>> x = N.array([1., 2., 3., 4., 5.]) >>> y = N.array([3., 6., 2.,-5.,-3.]) >>> xint = N.array([3.4, 2.3]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '4.8'] Example with missing values: >>> x = N.array([1., 2., 3., 4., 5.]) >>> y = N.array([3., 1e+20, 2., -5., -3.]) >>> xint = N.array([3.4, 2.3]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '1e+20'] Example with values out of range of the data: >>> x = N.array([1., 2.1, 3., 4., 5.1]) >>> y = N.array([3., 1e+20, 2., -5., -3.]) >>> xint = N.array([3.4, -2.3, 6.]) >>> yint = interp(y, x, xint, missing=1e+20) >>> ['%.7g' % yint[i] for i in range(len(yint))] ['-0.8', '1e+20', '1e+20'] """ import arrayfns import numpy.ma as MA import numpy as N from where_close import where_close #- Check inputs for possible errors: if (N.rank(y) != 1) or (N.rank(x) != 1): raise ValueError, "interp: Input(s) not a vector" if N.rank(xinterp) > 1: raise ValueError, "interp: xinterp not a vector or scalar" if x[-1] <= x[0]: raise ValueError, "interp: x not monotonically increasing" #- Establish constants and define xint, a rank 1 version of # xinterp to be used for the rest of the function: if N.rank(xinterp) == 0: xint = N.reshape(xinterp, (1,)) else: xint = xinterp num_xint = N.size(xint) #- Mask as missing values of xint that are outside of the range # of x: yint_outrange_mask = N.logical_or( N.less(xint, x[0]) \ , N.greater(xint, x[-1]) ) #- Mask of elements with missing values in y, if there are any # missing values in y. If xint equals a value in x, missing # values mask for that xint is the same as the corresponding # value in x; and mask elements in xint which fall in an interval # (whose upper bound index is top_idx) where one of the endpoints # is missing: y_miss_mask = where_close(y, missing) yint_miss_mask = N.zeros(num_xint) if MA.maximum(y_miss_mask) == 1: for i in xrange(num_xint): if yint_outrange_mask[i] == 0: x_eq_xint = where_close(x, xint[i]) if MA.maximum(x_eq_xint) == 1: yint_miss_mask[i] = y_miss_mask[N.nonzero(x_eq_xint)] else: top_idx = N.nonzero(N.greater(x, xint[i]))[0] yint_miss_mask[i] = y_miss_mask[top_idx] or \ y_miss_mask[top_idx-1] #- Return interpolated values, set to missing values as # appropriate, and making a scalar if xinterp is a scalar: yint = arrayfns.interp(y, x, xint) N.putmask( yint, N.logical_or(yint_miss_mask, yint_outrange_mask) \ , missing) if N.rank(xinterp) == 0: yint = yint[0] return yint