import os
import functools
import contextlib
import numpy as np
from .compat import TemporaryDirectory
from ajustador.helpers.loggingsystem import getlogger
logger = getlogger(__name__)
@contextlib.contextmanager
def chdir(dir):
"A contextmanager to temporarily change the working directory"
old = os.getcwd()
os.chdir(dir)
try:
yield
finally:
os.chdir(old)
def once(function):
"A decorator which only allows a function to run once"
def wrapper(self):
attr = '_{}_value'.format(function.__name__)
try:
return getattr(self, attr)
except AttributeError:
pass
val = function(self)
setattr(self, attr, val)
return val
return functools.update_wrapper(wrapper, function)
def cached(function):
"A decorator to store the return values of a function in a cache"
def wrapper(self, arg):
attr = '_{}_value'.format(function.__name__)
key = tuple(arg)
try:
cache = getattr(self, attr)
except AttributeError:
cache = {}
setattr(self, attr, cache)
try:
return cache[key]
except KeyError:
pass
ans = cache[key] = function(self, arg)
return ans
return functools.update_wrapper(wrapper, function)
def arange_values(values, func, order=None):
values = np.round(values[:, order] if order is not None else values,
decimals=10)
ranges = [sorted(set(what)) for what in values.T]
xs = np.meshgrid(*ranges, sparse=True)
ys = np.empty(tuple(len(what) for what in ranges))
ys[:] = np.nan
n = values.shape[1]
for x, y in zip(values, func):
ind = [xs[i].flat == x[i] for i in range(n)]
ys[ind] = y
return xs, ys
def find_missing(values):
xs, ys = arange_values(values, np.zeros((len(values),)))
missing = np.where(np.isnan(ys))
n = len(missing)
gen = ([xs[i].flat[missing[i][k]] for i in range(n)]
for k in range(len(missing[0])))
return np.array(list(gen))
def permutations_to_achieve_order(src, dst):
src = list(src)
dst = list(dst)
assert len(src) == len(dst)
for i in range(len(src)):
if src[i] == dst[i]:
continue
j = dst.index(src[i])
src[i], src[j] = src[j], src[i]
yield i, j
def reorder_list(x, order):
x = list(x)
for i, j in permutations_to_achieve_order(range(len(x)), order):
x[i], x[j] = x[j], x[i]
return x
def reorder_array(x, order):
for i, j in permutations_to_achieve_order(range(x.ndim), order):
x = x.swapaxes(i, j)
return x
def mkdir_p(dirname):
"Make empty directory."
try:
os.mkdir(dirname)
except OSError:
logger.error("Previous Fit object data Exists in {}".format(dirname))
raise FileExistsError("Unable to create directory {}".format(dirname))