From b8a7880527cb4cf942291666e017290070d30d41 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 8 Mar 2023 11:46:08 +0100 Subject: [PATCH] added cache --- 2d_fourie/cache.py | 67 +++++++++++++++++++++++++++++++++++++++++ 2d_fourie/extractors.py | 57 ++++++++++++++++++++++++----------- 2d_fourie/lattices.py | 4 ++- 2d_fourie/main.py | 20 ++++++------ 4 files changed, 119 insertions(+), 29 deletions(-) create mode 100644 2d_fourie/cache.py diff --git a/2d_fourie/cache.py b/2d_fourie/cache.py new file mode 100644 index 0000000..389b6d4 --- /dev/null +++ b/2d_fourie/cache.py @@ -0,0 +1,67 @@ +import numpy as np +from functools import wraps +import time + + +def timeit(func): + @wraps(func) + def timeit_wrapper(*args, **kwargs): + start_time = time.perf_counter() + result = func(*args, **kwargs) + end_time = time.perf_counter() + total_time = end_time - start_time + # first item in the args, ie `args[0]` is `self` + print( + f'Function {func.__name__}{args} {kwargs} Took {total_time:.4f} seconds') + return result + return timeit_wrapper + + +def persist_to_file(file_name): + + def decorator(original_func): + try: + file_nam = file_name + if file_name[-4:] != ".npz": + file_nam += ".npz" + file = np.load(file_nam) + cache = dict(zip((file.files), (file[k] for k in file.files))) + except (IOError, ValueError): + cache = {} + + def hash_func(*param): + key = str(param) + return key + + def persist_func(*param, hash=None): + if hash is None: + hash = hash_func(*param) + + print("Hash: ", hash) + if cache == {} or ("hash" not in cache) or hash != cache["hash"]: + print("recalc") + data = original_func(*param) + np.savez(file_name, hash=hash, dat=data) + cache["hash"] = hash + cache["dat"] = data + print("loaded") + return cache["dat"] + + return persist_func + + return decorator + + +# test = 1234 +# +# +# @persist_to_file("cache.npz", test) +# def test(): +# print("calculate") +# return np.zeros((100, 100)) +# +# +# if __name__ == "__main__": +# test() +# test() +# pass diff --git a/2d_fourie/extractors.py b/2d_fourie/extractors.py index f2d3617..38e78ee 100644 --- a/2d_fourie/extractors.py +++ b/2d_fourie/extractors.py @@ -1,6 +1,7 @@ import numpy as np from scipy.spatial import Voronoi import cv2 +from cache import persist_to_file, timeit class Image_Wrapper: @@ -93,14 +94,13 @@ class Evaluator: def get_mask(self): return self.mask - def merge_mask(self): - new_eval_points = np.arange(len(self.eval_points)) - new_eval = [] - for nc, ev_points in zip(new_eval_points, self.eval_points): - new_eval.append([nc]) - for num in ev_points: - self.mask[self.mask == num] = nc - self.eval_points = new_eval + @timeit + def generate_mask(self, img: Image_Wrapper, merge=False): + hash = str(img.img.shape) + self.mask = self.gen_mask_helper(img, hash=hash) + if merge: + self.mask = self.merge_mask_helper(hash=hash) + self.eval_points = [[a] for a in np.arange(len(self.eval_points))] class Voronoi_Evaluator(Evaluator): @@ -114,8 +114,18 @@ class Voronoi_Evaluator(Evaluator): start += stop self.vor = Voronoi(points) - def generate_mask(self, img: Image_Wrapper): - self.mask = np.full_like(img.img, -1) + @persist_to_file("cache_merge_voro") + def merge_mask_helper(self): + new_eval_points = np.arange(len(self.eval_points)) + mask = self.mask + for nc, ev_points in zip(new_eval_points, self.eval_points): + for num in ev_points: + mask[self.mask == num] = nc + return mask + + @persist_to_file("cache_voro") + def gen_mask_helper(self, img: Image_Wrapper): + mask = np.full_like(img.img, -1) counter = -1 region_mask = self.vor.point_region @@ -130,10 +140,11 @@ class Voronoi_Evaluator(Evaluator): pts[:, 0], pts[:, 1])).astype(np.int32).T if np.any(pts < 0): continue - mask = np.zeros_like(img.img) - cv2.fillConvexPoly(mask, pts, 1) - mask = mask > 0 # To convert to Boolean - self.mask[mask] = counter + mask_2 = np.zeros_like(img.img) + cv2.fillConvexPoly(mask_2, pts, 1) + mask_2 = mask_2 > 0 # To convert to Boolean + mask[mask_2] = counter + return mask class Rect_Evaluator(Evaluator): @@ -154,8 +165,18 @@ class Rect_Evaluator(Evaluator): print(self.points.shape) self.length = length - def generate_mask(self, img: Image_Wrapper): - self.mask = np.full_like(img.img, -1) + @persist_to_file("cache_merge_rect") + def merge_mask_helper(self): + new_eval_points = np.arange(len(self.eval_points)) + mask = self.mask + for nc, ev_points in zip(new_eval_points, self.eval_points): + for num in ev_points: + mask[self.mask == num] = nc + return mask + + @persist_to_file("cache_rect") + def gen_mask_helper(self, img: Image_Wrapper): + mask = np.full_like(img.img, -1) count = 0 for x, y in self.points: x, y = img.val2pos(x, y) @@ -166,9 +187,9 @@ class Rect_Evaluator(Evaluator): if img.check_bounds(x_lower, y_lower, x_upper, y_upper): x_lower, y_lower, x_upper, y_upper = img.clean_bounds( x_lower, y_lower, x_upper, y_upper) - self.mask[y_lower:y_upper, x_lower:x_upper] = count + mask[y_lower:y_upper, x_lower:x_upper] = count count += 1 - return all + return mask # # def main(): diff --git a/2d_fourie/lattices.py b/2d_fourie/lattices.py index aaf2ec3..f538676 100644 --- a/2d_fourie/lattices.py +++ b/2d_fourie/lattices.py @@ -1,5 +1,5 @@ import numpy as np - +from cache import timeit def deg_2_rad(winkel): return winkel / 180.0 * np.pi @@ -20,6 +20,7 @@ class Lattice: class SCC_Lattice(Lattice): + @timeit def __init__(self, x_len, y_len): x = np.arange(x_len) * 5 y = np.arange(x_len) * 5 @@ -81,6 +82,7 @@ class VO2_Lattice(Lattice): return X, Y + @timeit def __init__(self, x_len: int, y_len: int): X, Y = self._generate_vec(x_len * 2, y_len * 2) self._get_mono(X, Y) diff --git a/2d_fourie/main.py b/2d_fourie/main.py index 5d5205e..430087c 100644 --- a/2d_fourie/main.py +++ b/2d_fourie/main.py @@ -6,7 +6,7 @@ import matplotlib.patches as patches import matplotlib import tqdm from extractors import Rect_Evaluator, Voronoi_Evaluator, Image_Wrapper - +from cache import timeit class Plotter: def __init__(self, lat): @@ -198,6 +198,8 @@ def random(seed): percentage = [] counter = 0 already_inited = False + + for i in tqdm.tqdm(ind): maske[np.unravel_index(i, (LEN, LEN))] = True counter += 1 @@ -210,10 +212,10 @@ def random(seed): fx, fy, intens = si.fft() img = Image_Wrapper(intens, fx, fy) if not already_inited: - voro.generate_mask(img) - voro.merge_mask() - rect.generate_mask(img) - rect.merge_mask() + print("start_init") + voro.generate_mask(img, merge=True) + print("stop_init") + rect.generate_mask(img, merge=True) already_inited = True iv, vv = voro.extract(img) @@ -239,7 +241,7 @@ def sample_index(p): i = np.random.choice(np.arange(p.size), p=p.ravel()) return np.unravel_index(i, p.shape) - +@timeit def ising(seed): np.random.seed(seed) LEN = 40 @@ -279,10 +281,8 @@ def ising(seed): fx, fy, intens = si.fft() img = Image_Wrapper(intens, fx, fy) if not already_inited: - voro.generate_mask(img) - voro.merge_mask() - rect.generate_mask(img) - rect.merge_mask() + voro.generate_mask(img, merge=True) + rect.generate_mask(img, merge=True) already_inited = True iv, vv = voro.extract(img)