Exemple #1
0
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 
Exemple #3
0
 def printError(self, string, location = []):
     DEBUG.printError(string, location)
Exemple #4
0
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
Exemple #5
0
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