def make_numpy_ndarray(val): """ make a numpy.ndarray out of val, used by make_coordinates() Types of val that are accepted: int, float, string: make it a list and then numpy.ndarray. list: make it a numpy.ndarray tuple: convert to a list, then numpy.ndarray numpy.ndarray: return directly Not accepted: dict CHANGELOG: 20130317/RB: started """ if type(val) == numpy.ndarray: return val elif type(val) == list: return numpy.array(val) elif type(val) == dict: DEBUG.printError("Value shouldn't be a dict or tuple", inspect.stack()) return False elif type(val) == tuple: return numpy.array(list(val)) else: return numpy.array([val])
def fourier(array, zero_in_middle = False, first_correction = False, zeropad_to = None, window_function = "none", window_length = 0, flag_plot = False, flag_verbose = False): """ A Fourier transform for any dimension. INPUT: - array (x-dimensions ndarray): to be FFT'd - zero_in_middle (BOOL): for FFT the zero-time should be the first element of the array. If the zero is in the middle, it will be shifted first - first_correction (BOOL): if the first element of the array has to be halved, check this as True - zeropad_to (number): Length of the transformed axis of the output. If n is smaller than the length of the input, the input is cropped. If it is larger, the input is padded with zeros. If n is None, the length of the input (along the axis specified by axis) is used. OUTPUT: array (x-dimensions ndarray): Fourier transformed array CHANGELOG: 20101204 RB: started 20110909 RB: added zeropadding """ DEBUG.verbose("FFT", flag_verbose) # shift time = 0 to first element if zero_in_middle == True: array = numpy.fft.ifftshift(array) # half the first element if first_correction == True: dim = len(numpy.shape(array)) if dim == 1: array[0] /= 2 elif dim == 2: array[0,:] /= 2 array[:,0] /= 2 elif dim > 2: DEBUG.printError("Correction of the first element is not done!", inspect.stack()) # window function if window_function != "none": array = window_functions(array, window_function, window_length, flag_plot = flag_plot) # the fft array = numpy.fft.fft(array, n = zeropad_to) # move the array back if it was shifted if zero_in_middle == True: array = numpy.fft.fftshift(array) return array
def printError(self, string, location = []): DEBUG.printError(string, location)
def contourplot(data, x_axis, y_axis, # ax = False, # x_range = [0,0], # y_range = [0,-1], # zlimit = -1, # contours = 12, # filled = True, # black_contour = True, # x_label = "", # y_label = "", # title = "", # diagonal_line = True, # invert_colors = False, # linewidth = 1, # flag_verbose = False, **kwargs): """ Make a contourplot. The defaults are for a plot with w3 as the x-axis. - data, x_axis, y_axis: data and axes - ax (bool (False) or matplotlib axes instance): if False, it will make a new figure, otherwise it will use the axes instance, allowing subplots etc. - x_label, y_label, title (string, default=''): the labels for the axes. If no label is set, it will use the default. Use 'no_label' or 'no_title' to show no label. - x_range, y_range (array with 2 elements, [0,0], [0,-1]): the range to be plotted. Possible cases: - [min, max]: plot range min to max - [0, 0]: plot the whole range - [0, -1]: use the range from the other axis. If both have this, it will plot both axes complete. (ie. it is identical to both having [0,0]) - zlimit (number or list, -1): the z-range that will be used Possible cases: zlimit = 0, show all, not don't care about centering around zero zlimit = -1, show all, centered around zero zlimit = all else, use that, centered around zero zlimit = [a,b], plot from a to b - contours (int, 16): number of contours to be used - invert_colors (BOOL, False): data = -data CHANGELOG: 201108xx/RB: started function 20130213/RB: moved some things out as separate functions 20160418/RB: replaced arguments with kwargs """ if "flag_verbose" in kwargs: flag_verbose = kwargs["flag_verbose"] else: flag_verbose = False DEBUG.verbose("contour plot", flag_verbose) y, x = numpy.shape(data) if len(x_axis) != x and len(y_axis) != y: DEBUG.printError("The data should have the same shape as the axes, wrong for both axes", inspect.stack()) return False elif len(x_axis) != x: DEBUG.printError("The data should have the same shape as the axes, wrong for the x-axis", inspect.stack()) return False elif len(y_axis) != y: DEBUG.printError("The data should have the same shape as the axes, wrong for the y-axis", inspect.stack()) return False if "invert_colors" in kwargs and kwargs["invert_colors"]: data = -data if "x_range" in kwargs: x_range = kwargs["x_range"] else: x_range = [0,0] if "y_range" in kwargs: y_range = kwargs["y_range"] else: y_range = [0,-1] # determine the range to be plotted x_min, x_max, y_min, y_max = FU.find_axes(x_axis, y_axis, x_range, y_range, flag_verbose) # find the area to be plotted x_min_i, x_max_i = FU.find_axes_indices(x_axis, x_min, x_max) y_min_i, y_max_i = FU.find_axes_indices(y_axis, y_min, y_max) # truncate the data, this speeds up the plotting data, x_axis, y_axis = FU.truncate_data(data, x_axis, y_axis, x_min_i, x_max_i, y_min_i, y_max_i) if "zlimit" in kwargs: zlimit = kwargs["zlimit"] else: zlimit = -1 if "contours" in kwargs: contours = kwargs["contours"] else: contours = 16 # now make the actual contours V = FU.make_contours_2d(data, zlimit, contours, flag_verbose) # make sure there is an axis-object if "ax" in kwargs: ax = kwargs["ax"] flag_show = False else: fig = plt.figure() ax = fig.add_subplot(111) flag_show = True # else: # flag_show = False if "linewidth" in kwargs: linewidth = kwargs["linewidth"] else: linewidth = 1 # actually plot the thing if "filled" in kwargs and kwargs["filled"] == False: pass else: ax.contourf(x_axis, y_axis, data, V, cmap = FU.rwb_cmap) if "black_contour" in kwargs and kwargs["black_contour"] == False: pass else: if "filled" in kwargs and kwargs["filled"] == False: ax.contour(x_axis, y_axis, data, V, linewidths = linewidth, colors = "k") else: ax.contour(x_axis, y_axis, data, V, linewidths = linewidth, linestyles = "solid", colors = "k") # the diagonal line if "diagonal_line" in kwargs and kwargs["diagonal_line"] == False: pass else: ax.plot([x_axis[0]-100,x_axis[-1]+100], [x_axis[0]-100,x_axis[-1]+100], "k", linewidth = linewidth) # we only want to see a certain part of the spectrum ax.set_xlim(x_min, x_max) ax.set_ylim(y_min, y_max) # add some text if "x_label" in kwargs and kwargs["x_label"] != "" and kwargs["x_label"] != "no_label": ax.set_xlabel(kwargs["x_label"] ) if "y_label" in kwargs and kwargs["y_label"] != "" and kwargs["y_label"] != "no_label": ax.set_ylabel(kwargs["y_label"]) if "title" in kwargs and kwargs["title"] != "": ax.set_title(kwargs["title"]) if flag_show: plt.show() return True
def import_data_LV_A(path, base_filename): """ Imports data for 'LV_file_format.1' """ try: # data path_and_filename = path + base_filename + ".csv" data = numpy.loadtxt(path_and_filename, dtype = "float", delimiter = ",") data = data.T # time axis in fringes path_and_filename = path + base_filename + "_t1.csv" t1_axis = numpy.loadtxt(path_and_filename, dtype = "float", delimiter = ",") # frequency axis path_and_filename = path + base_filename + "_w3.csv" w3_axis = numpy.loadtxt(path_and_filename, dtype = "float", delimiter = ",") # phase path_and_filename = path + base_filename + "_phase.txt" f = open(path_and_filename) for line in f: temp = line f.close() if temp == "NaN": DEBUG.printWarning("Phase is Not-a-Number, will be set to 0 ", inspect.stack()) phase = 0 else: phase = float(temp) # last pump path_and_filename = path + base_filename + "_lastpump.txt" f = open(path_and_filename) for line in f: lastpump = line f.close() # determine number of fringes n_fringes = int((len(t1_axis)+1)/2) n_pixels = len(w3_axis) # convert NaN to zeros data = numpy.nan_to_num(data) # labview measures 4000-N to 4000+N, we want the data split into 4000-N to 4000 (non-rephasing) and 4000 to 4000+N (rephasing) R = data[n_fringes-1:, :] NR = numpy.flipud(data[:n_fringes, :]) # for the FFT, we don't want 4000 to be zero. The axes run from 0 to N # also: calculate the axis in fs t1fr_axis = numpy.arange(n_fringes) t1fs_axis = numpy.arange(n_fringes) * CONST.hene_fringe_fs # return everything return R, NR, t1fs_axis, t1fr_axis, w3_axis, phase, lastpump, n_fringes, n_pixels except IOError: DEBUG.printError("Unable to import LabView data from file " + path + base_filename, inspect.stack()) # raise return False
def fit(x_array, y_array, function, A_start, return_all = False): """ Fit data 20101209/RB: started 20130131/RB: imported in Crocodile, added example to doc-string INPUT: x_array: the array with time or something y-array: the array with the values that have to be fitted function: one of the functions, in the format as in the file "Equations" A_start: a starting point for the fitting return_all: the function used to return only the final result. The leastsq method does however return more data, which may be useful for debugging. When the this flag is True, it will return these extras as well. For legacy purposes the default is False. See reference of leastsq method for the extra output: http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html OUTPUT: A_final: the final parameters of the fitting When return_all == True: - cov_x (ndarray): Uses the fjac and ipvt optional outputs to construct an estimate of the jacobian around the solution. None if a singular matrix encountered (indicates very flat curvature in some direction). This matrix must be multiplied by the residual variance to get the covariance of the parameter estimates - see curve_fit. - infodict (dict): a dictionary of optional outputs with the key s: - "nfev" : the number of function calls - "fvec" : the function evaluated at the output - "fjac" : A permutation of the R matrix of a QR factorization of the final approximate Jacobian matrix, stored column wise. Together with ipvt, the covariance of the estimate can be approximated. - "ipvt" : an integer array of length N which defines a permutation matrix, p, such that fjac*p = q*r, where r is upper triangular with diagonal elements of nonincreasing magnitude. Column j of p is column ipvt(j) of the identity matrix. - "qtf" : the vector (transpose(q) * fvec). - mesg (str): A string message giving information about the cause of failure. - ier (int): An integer flag. If it is equal to 1, 2, 3 or 4, the solution was found. Otherwise, the solution was not found. In either case, the optional output variable "mesg" gives more information. EXAMPLE: Fit some data to this function from Crocodile.Resources.Equations: def linear(A, t): return A[0] + A[1] * t ### x = x-axis y = some data A = [0,1] # initial guess A_final = fit(x, y, Crocodile.Resources.Equations.linear, A) ### WARNING: Always check the result, it might sometimes be sensitive to a good starting point. """ if scipy_import: param = (x_array, y_array, function) A_final, cov_x, infodict, mesg, ier = leastsq(minimize, A_start, args=param, full_output=True) if return_all: return A_final, cov_x, infodict, mesg, ier else: return A_final else: DEBUG.printError("Scipy.leastsq is not loaded. Fit is not done", inspect.stack()) return False
def window_functions(array, window_function, window_length = 0, flag_plot = False, flag_verbose = False): """ croc.Absorptive.window_functions Different window functions. INPUT: - array (ndarray): the array where the window-functions will be applied to - window_length (int): the length of the window. If the length is 0 or equal or larger than the length of array, this will be set to the length of the array. - window_function: the function - none: will apply a rectangular window with 1's for all elements - ones: will make a rectangular window with a certain length and pads with zeros. - triangular: will make a triangular window with a certain length and pads with zeros - gaussian: will make a gaussian window for the full length of array, but will go to zero at around window_length. CHANGELOG: 20110909/RB: added zeropadding """ DEBUG.verbose("window function: " + window_function, flag_verbose) dim = len(numpy.shape(array)) # for single dimensions if dim == 1: # the window function should end up with the same length as the array array_length = numpy.shape(array)[0] # if it is smaller than the length, make it that length if window_length > 0 and window_length < array_length: n_max = window_length zeros = numpy.zeros(array_length - window_length) else: n_max = array_length zeros = [] # the windows if window_function == "none": window = numpy.ones(array_length) elif window_function == "ones": window = numpy.concatenate((numpy.ones(n_max).T, zeros)) elif window_function == "triangle": window = numpy.concatenate((numpy.linspace(1, 0, n_max).T, zeros)) elif window_function == "gaussian": window = numpy.exp(-(2.2*numpy.arange(0, array_length)/(n_max))**2) elif window_function == "experimental": window = numpy.exp(-(2.2*numpy.arange(0, array_length)/(n_max))**2) else: DEBUG.printError("Unknown window function.", inspect.stack()) window = numpy.ones(array_length) if flag_plot: m = numpy.max(array) plt.figure() plt.plot(array) plt.plot(window * m) plt.plot(array*window) plt.title("window function is scaled") plt.show() return array * window # for higher dimensions else: DEBUG.printError("Not implemented yet for multiple dimensions.", inspect.stack()) return 0
def plot_overlap( ma, ax, la = [], x_range = [0,0], y_range = [0,-1], zlimit = -1, contours = 12, colors = ["b", "r"], x_label = "", y_label = "", title = "", diagonal_line = True, invert_colors = False, ma_linewidth = 1, la_linewidth = 2, flag_verbose = False): DEBUG.verbose("contour plot", flag_verbose) for i in range(2): # check for correct lengths y, x = numpy.shape(ma[i].s) if len(ma[i].s_axis[2]) != x and len(ma[i].s_axis[0]) != y: DEBUG.printError("The data should have the same shape as the axes, wrong for both axes", inspect.stack()) return False elif len(ma[i].s_axis[2]) != x: DEBUG.printError("The data should have the same shape as the axes, wrong for the x-axis", inspect.stack()) return False elif len(ma[i].s_axis[0]) != y: DEBUG.printError("The data should have the same shape as the axes, wrong for the y-axis", inspect.stack()) return False # invert colors if invert_colors: ma[i].s = ma[i].s x_axis = ma[0].s_axis[2] y_axis = ma[0].s_axis[0] # determine the range to be plotted x_min, x_max, y_min, y_max = FU.find_axes(x_axis, y_axis, x_range, y_range, flag_verbose) # find the area to be plotted x_min_i, x_max_i= FU.find_axes_indices(x_axis, x_min, x_max) y_min_i, y_max_i= FU.find_axes_indices(y_axis, y_min, y_max) x_axis = x_axis[x_min_i:x_max_i] y_axis = y_axis[y_min_i:y_max_i] for i in range(2): # truncate the data, this speeds up the plotting data = ma[i].s[y_min_i:y_max_i,x_min_i:x_max_i] # now make the actual contours V = FU.make_contours_2d(data, zlimit, contours, flag_verbose) # actually plot the thing ax.contour(x_axis, y_axis, data, V, linewidths = ma_linewidth, colors = colors[i]) if len(la) == 4: ax.plot(la[0],la[1], c = colors[0], lw = la_linewidth) ax.plot(la[2],la[3], c = colors[1], lw = la_linewidth) # the diagonal line if diagonal_line: ax.plot([x_axis[0]-100,x_axis[-1]+100], [x_axis[0]-100,x_axis[-1]+100], "k", linewidth = ma_linewidth) # we only want to see a certain part of the spectrum ax.set_xlim(x_min, x_max) ax.set_ylim(y_min, y_max) # add some text if x_label != "" and x_label != "no_label": ax.set_xlabel(x_label) if y_label != "" and y_label != "no_label": ax.set_ylabel(y_label) if title != "": ax.set_title(title) return True