Source code for crrlpy.utils

#!/usr/bin/env python

import re
import ntpath
import numpy as np

from functools import reduce

[docs]def alphanum_key(s): """ Turn a string into a list of string and number chunks. :param s: String :returns: List with strings and integers. :rtype: list :Example: >>> alphanum_key('z23a') ['z', 23, 'a'] """ return [ tryint(c) for c in re.split('([0-9]+)', s) ]
[docs]def best_match_indx(value, array): """ Searchs for the index of the closest entry to value inside an array. :param value: Value to find inside the array. :type value: float :param array: List to search for the given value. :type array: list or numpy.array :return: Best match index for the value inside array. :rtype: float :Example: >>> a = [1,2,3,4] >>> best_match_indx(3, a) 2 """ array = np.array(array) subarr = abs(array - value) subarrmin = subarr.min() return np.where(subarr == subarrmin)[0][0]
[docs]def factors(n): """ Decomposes a number into its factors. :param n: Number to decompose. :type n: int :return: List of values into which n can be decomposed. :rtype: list """ return set(reduce(list.__add__, ([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
[docs]def flatten_list(list): """ | Flattens a list of lists. | Based on: | http://stackoverflow.com/questions/457215/comprehension-for-flattening-a-sequence-of-sequences/5330178#5330178 """ #print 'List: {0}'.format(list) result = [] extend = result.extend for l in list: extend(l) return result
[docs]def get_max_sep(array): """ Get the maximum element separation in an array. Parameters ---------- array : array Array where the maximum separation is wanted. Returns ------- max_sep : float The maximum separation between the elements in `array`. Examples -------- >>> import numpy as np >>> x = np.array([1,2,3,4,5,7]) >>> get_max_sep(x) 2 """ return max(abs(array[0:-1:2] - array[1::2]))
[docs]def get_min_sep(array): """ Get the minimum element separation in an array. Parameters ---------- array : array Array where the minimum separation is wanted. Returns ------- max_sep : float The minimum separation between the elements in `array`. Examples -------- >>> import numpy as np >>> x = np.array([1,2,3,4,5,7]) >>> get_min_sep(x) 1 """ return min(abs(array[0:-1:2] - array[1::2]))
[docs]def myround(x, base=5): """ """ return int(base * round(float(x)/base))
[docs]def natural_sort(list): """ Sort the given list in the way that humans expect. \ Sorting is done in place. :param list: List to sort. :type list: list :Example: >>> my_list = ['spec_3', 'spec_4', 'spec_1'] >>> natural_sort(my_list) >>> my_list ['spec_1', 'spec_3', 'spec_4'] """ list.sort(key=alphanum_key)
[docs]def path_leaf(path): """ Taken from: https://stackoverflow.com/questions/8384737/extract-file-name-from-path-no-matter-what-the-os-path-format """ head, tail = ntpath.split(path) return tail or ntpath.basename(head)
[docs]def pow_notation(number, sig_fig=2): """ Converts a number to scientific notation keeping sig_fig signitifcant figures. """ ret_string = "{0:.{1:d}e}".format(number, sig_fig) a,b = ret_string.split("e") b = int(b) #removed leading "+" and strips leading zeros too. return r"10^{{{0}}}".format(b)
[docs]def sci_notation(number, sig_fig=2): """ Converts a number to scientific notation keeping sig_fig signitifcant figures. """ ret_string = "{0:.{1:d}e}".format(number, sig_fig) a,b = ret_string.split("e") b = int(b) #removed leading "+" and strips leading zeros too. return r"{0}\times10^{{{1}}}".format(a, b)
[docs]def str2bool(str): """ Converts a string to a boolean value. The conversion is case insensitive. :param str: string to convert. :type str: string :returns: True if str is one of: "yes", "y", "true", "t" or "1". :rtype: bool """ return str.lower() in ("yes", "y", "true", "t", "1")
rotated_labels = []
[docs]def text_slope_match_line(text, x, y, line, dindx=1): global rotated_labels # find the slope xdata, ydata = line.get_data() x1 = xdata[best_match_indx(x, xdata)] x2 = xdata[best_match_indx(x, xdata)+dindx] y1 = ydata[best_match_indx(y, ydata)] y2 = ydata[best_match_indx(y, ydata)+dindx] rotated_labels.append({"text":text, "line":line, "p1":np.array((x1, y1)), "p2":np.array((x2, y2))})
[docs]def tryint(str): """ Returns an integer if `str` can be represented as one. :param str: String to check. :type str: string :returns: True is str can be cast to an int. :rtype: int """ try: return int(str) except: return str
[docs]def update_text_slopes(): global rotated_labels for label in rotated_labels: # slope_degrees is in data coordinates, the text() and annotate() functions need it in screen coordinates text, line = label["text"], label["line"] p1, p2 = label["p1"], label["p2"] # get the line's data transform ax = line.axes sp1 = ax.transData.transform_point(p1) sp2 = ax.transData.transform_point(p2) rise = (sp2[1] - sp1[1]) run = (sp2[0] - sp1[0]) slope_degrees = np.rad2deg(np.arctan(rise/run)) text.set_rotation(slope_degrees)