# -*- coding: utf-8 -*- """ Created on Thu Mar 1 11:30:31 2018 @author: z5030440 Contains all the utilities, convenience functions and small functions that do simple things """ import matplotlib.pyplot as plt from datetime import datetime, timedelta import numpy as np import scipy.io as sio import pdb def ecdf(x): """convenience function for computing the empirical CDF""" vals, counts = np.unique(x, return_counts=True) ecdf = np.cumsum(counts).astype(np.float64) ecdf /= ecdf[-1] return vals, ecdf def intensity_histogram(image): """plots histogram and cumulative distribution of the pixel intensities in an image""" imSize = image.shape if len(imSize) == 2: im = image[:,:].reshape(imSize[0] * imSize[1]) im = im[~np.isnan(im)] fig, (ax1, ax2) = plt.subplots(2,1, sharex=True, figsize = (8,6)) ax1.hist(im, bins=300) ax1.set_title('Probability density function') ax2.hist(im, bins=300, cumulative=True, histtype='step') ax2.set_title('Cumulative distribution') plt.show() else: for i in range(imSize[2]): im = image[:,:,i].reshape(imSize[0] * imSize[1]) im = im[~np.isnan(im)] fig, (ax1, ax2) = plt.subplots(2,1, sharex=True, figsize = (8,6)) ax1.hist(im, bins=300) ax1.set_title('Probability density function') ax2.hist(im, bins=300, cumulative=True, histtype='step') ax2.set_title('Cumulative distribution') plt.show() def compare_images(im1, im2): """plots 2 images next to each other, sharing the axis""" plt.figure() ax1 = plt.subplot(121) plt.imshow(im1, cmap='gray') ax2 = plt.subplot(122, sharex=ax1, sharey=ax1) plt.imshow(im2, cmap='gray') plt.show() def find_indices(lst, condition): "imitation of MATLAB find function" return [i for i, elem in enumerate(lst) if condition(elem)] def reject_outliers(data, m=2): "rejects outliers in a numpy array" return data[abs(data - np.mean(data)) < m * np.std(data)] def duplicates_dict(lst): "return duplicates and indices" # nested function def duplicates(lst, item): return [i for i, x in enumerate(lst) if x == item] return dict((x, duplicates(lst, x)) for x in set(lst) if lst.count(x) > 1) def datenum2datetime(datenum): "convert datenum to datetime" #takes in datenum and outputs python datetime time = [datetime.fromordinal(int(dn)) + timedelta(days=float(dn)%1) - timedelta(days = 366) for dn in datenum] return time def loadmat(filename): ''' this function should be called instead of direct spio.loadmat as it cures the problem of not properly recovering python dictionaries from mat files. It calls the function check keys to cure all entries which are still mat-objects ''' data = sio.loadmat(filename, struct_as_record=False, squeeze_me=True) return _check_keys(data) def _check_keys(dict): ''' checks if entries in dictionary are mat-objects. If yes todict is called to change them to nested dictionaries ''' for key in dict: if isinstance(dict[key], sio.matlab.mio5_params.mat_struct): dict[key] = _todict(dict[key]) return dict def _todict(matobj): ''' A recursive function which constructs from matobjects nested dictionaries ''' dict = {} for strg in matobj._fieldnames: elem = matobj.__dict__[strg] if isinstance(elem, sio.matlab.mio5_params.mat_struct): dict[strg] = _todict(elem) else: dict[strg] = elem return dict