from lattices import SCC_Lattice, VO2_Lattice from spin_image import SpinImage import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches import matplotlib import scipy import scipy.signal import tqdm class Plotter: def __init__(self, lat): self.lattice = lat def reduce(self, arr): arr = np.array(arr) arr = arr.flatten() return np.mean(arr) # return np.sum(arr[np.argpartition(arr, -8)[-8:]]) def extract_rect(self, img, x, y, x_index, y_index): length_2 = 0.01 pos_x_lower = x - length_2 pos_x_upper = x + length_2 pos_y_lower = y - length_2 pos_y_upper = y + length_2 x_lower = np.searchsorted(x_index, pos_x_lower) x_upper = np.searchsorted(x_index, pos_x_upper) y_lower = np.searchsorted(y_index, pos_y_lower) y_upper = np.searchsorted(y_index, pos_y_upper) # fix different number of spins possible if x_upper - x_lower < 10: x_upper += 1 if y_upper - y_lower < 10: y_upper += 1 return img[y_lower:y_upper, x_lower:x_upper] def helper(self, ax, freqx, freqy, intens): reci_lattice = self.lattice.reci() for tup, col in zip(reci_lattice, ["r", "b", "g"]): point_x, point_y = tup point_x = point_x.flatten() point_y = point_y.flatten() for px, py in zip(point_x, point_y): rect = self.rect_at_point(px, py, col) ax.add_patch(rect) sum = self.extract_rect(intens, px, py, freqx, freqy) ax.text( px, py, f"{self.reduce(sum):2.2}", clip_on=True ) return intens def rect_at_point(self, x, y, color): length_2 = 0.01 rect = patches.Rectangle( (x - length_2, y - length_2), 2 * length_2, 2 * length_2, linewidth=1, edgecolor=color, facecolor="none", ) return rect def plot(self, freqx, freqy, intens, ax_log=None, ax_lin=None, vmax=None): if ax_log: intens = self.helper(ax_lin, freqx, freqy, intens) t = ax_log.imshow( intens, extent=(np.min(freqx), np.max(freqx), np.min(freqy), np.max(freqy)), norm=matplotlib.colors.LogNorm(vmin=10, vmax=vmax), cmap="viridis", origin="lower" ) plt.colorbar(t, ax=ax_log) self.helper(ax_log, freqx, freqy, intens) if ax_lin: intens = self.helper(ax_lin, freqx, freqy, intens) t = ax_lin.imshow( intens, extent=(np.min(freqx), np.max(freqx), np.min(freqy), np.max(freqy)), vmax=vmax, cmap="viridis", origin="lower" ) plt.colorbar(t, ax=ax_lin) def rotate(x, y, angle): radian = angle / 180 * 2 * np.pi return np.cos(radian) * x - np.sin(radian) * y, np.sin(radian) * x + np.cos(radian) * y def test_square(): LEN = 40 #lat = SCC_Lattice(LEN, LEN) lat = VO2_Lattice(LEN, LEN) plot = Plotter(lat) pos_x, pos_y = lat.get_from_mask(np.zeros((40, 40))) #pos_x, pos_y = rotate(pos_x, pos_y, 30) si = SpinImage(pos_x, pos_y) fig, axs = plt.subplots(2, 2) si.pad_it_square(10) si.plot(axs[0, 0], 2) # si.gaussian(LEN) # si.blur(3) si.plot(axs[0, 1], 2) plt.pause(0.1) fx, fy, intens = si.fft() plot.plot(fx, fy, intens, axs[1, 0], axs[1, 1]) print("Done") plt.savefig("test.png") plt.show() def test_mixed(): LEN = 40 lat = VO2_Lattice(LEN, LEN) plot = Plotter(lat) pos_x, pos_y = lat.get_from_mask(np.zeros((40, 40))) si = SpinImage(pos_x, pos_y) si.pad_it_square(10) fx, fy, intens_rutile = si.fft() pos_x, pos_y = lat.get_from_mask(np.ones((40, 40))) si = SpinImage(pos_x, pos_y) si.pad_it_square(10) fx, fy, intens_mono = si.fft() mask_misk = np.ones((40, 40)) ind = np.arange(mask_misk.size) np.random.shuffle(ind) mask_misk[np.unravel_index(ind[:800], (40, 40))] = False pos_x, pos_y = lat.get_from_mask(mask_misk) si = SpinImage(pos_x, pos_y) si.pad_it_square(10) fx, fy, intens_mixed = si.fft() fig, axs = plt.subplots(2, 3) plot.plot(freqx=fx, freqy=fy, intens=intens_rutile, ax_log=axs[0, 0], ax_lin=axs[1, 0], vmax=10e7) plot.plot(freqx=fx, freqy=fy, intens=intens_mono, ax_log=axs[0, 2], ax_lin=axs[1, 2], vmax=10e7) plot.plot(freqx=fx, freqy=fy, intens=intens_mixed, ax_log=axs[0, 1], ax_lin=axs[1, 1], vmax=10e7) print(np.sum(intens_mono), np.sum(intens_rutile), np.sum(intens_mixed)) for ax in axs.flatten(): ax.set_xlim(-1, 1) ax.set_ylim(-1, 1) plt.show() def random(): LEN = 40 lat = VO2_Lattice(LEN, LEN) plot = Plotter(lat) maske = np.zeros((LEN, LEN)) ind = np.arange(LEN * LEN) np.random.shuffle(ind) reci_lattice = lat.reci() out = [[] for x in range(len(reci_lattice))] percentage = [] counter = 0 for i in tqdm.tqdm(ind): maske[np.unravel_index(i, (LEN, LEN))] = True counter += 1 if np.mod(counter, 20) != 0: continue pos_x, pos_y = lat.get_from_mask(maske) si = SpinImage(pos_x, pos_y) si.pad_it_square(10) si.gaussian(LEN) fx, fy, intens = si.fft() for tup, lis in zip(reci_lattice, out): point_x, point_y = tup point_x = point_x.flatten() point_y = point_y.flatten() sum = 0. for px, py in zip(point_x, point_y): sum += np.sum(plot.extract_rect(intens, px, py, fx, fy)) lis.append(sum) percentage.append(np.mean(maske)) for o in out: plt.scatter(percentage, o/o[0]) plt.plot([0,1], [o[0], o[-1]]) plt.show() if __name__ == "__main__": # test_square() # test_mixed() random() # def test_lattice(): # lat = VO2_Lattice(10, 10) # maske = np.zeros((10, 10), dtype=bool) # x, y = lat.get_from_mask(maske) # # plt.scatter(x, y) # maske = np.invert(maske) # x, y = lat.get_from_mask(maske) # plt.scatter(x, y) # # maske[:3, :5] = False # x, y = lat.get_from_mask(maske) # plt.scatter(x, y) # plt.show() # # # self.resolution = 0.1 # CMAP = "Greys" # # # def test_img(): # lat = VO2_Lattice(10, 10) # maske = np.ones((10, 10), dtype=bool) # x, y = lat.get_from_mask(maske) # img = image_from_pos(x, y) # plt.imshow(img.T, origin="lower", extent=(0, np.max(x), 0, np.max(y))) # plt.scatter(x, y) # plt.show() # # # def gaussian(img): # x = np.arange(-self.resolution * img.shape[0]/2, # self.resolution * img.shape[0]/2, self.resolution) # y = np.arange(-self.resolution * img.shape[1]/2, # self.resolution * img.shape[1]/2, self.resolution) # X, Y = np.meshgrid(x, y) # sigma = self.resolution * img.shape[0] / 10 # print("Sigma: ", sigma) # z = ( # 1 / (2 * np.pi * sigma * sigma) # * np.exp(-(X**2 / (2 * sigma**2) + Y**2 / (2 * sigma**2))) # ) # return np.multiply(img, z.T) # # # def rect_at_point(x, y, color): # length_2 = 0.08 # rect = patches.Rectangle( # (x - length_2, y - length_2), # 2 * length_2, # 2 * length_2, # linewidth=1, # edgecolor=color, # facecolor="none", # ) # return rect # # # def reci_rutile(): # x = np.arange(-2, 3) # y = np.arange(-2, 3) # X, Y = np.meshgrid(x, y) # return (X * 0.22 + Y * 0.44).flatten(), (X * 0.349).flatten() # # # def reci_mono(): # x, y = reci_rutile() # return x + 0.1083, y + 0.1719 # # # def draw_big_val_rect(img, x, y, x_index, y_index): # length_2 = 0.08 # pos_x_lower = x - length_2 # pos_x_upper = x + length_2 # # pos_y_lower = y - length_2 # pos_y_upper = y + length_2 # x_lower = np.searchsorted(x_index, pos_x_lower) # x_upper = np.searchsorted(x_index, pos_x_upper) # y_lower = np.searchsorted(y_index, pos_y_lower) # y_upper = np.searchsorted(y_index, pos_y_upper) # # img[y_lower:y_upper, x_lower:x_upper] = 1e4 # return img # # # def extract_rect(img, x, y, x_index, y_index): # length_2 = 0.08 # # pos_x_lower = x - length_2 # pos_x_upper = x + length_2 # # pos_y_lower = y - length_2 # pos_y_upper = y + length_2 # # x_lower = np.searchsorted(x_index, pos_x_lower) # x_upper = np.searchsorted(x_index, pos_x_upper) # # y_lower = np.searchsorted(y_index, pos_y_lower) # y_upper = np.searchsorted(y_index, pos_y_upper) # # # fix different number of spins possible # if x_upper - x_lower < 10: # x_upper += 1 # if y_upper - y_lower < 10: # y_upper += 1 # # return img[y_lower:y_upper, x_lower:x_upper] # # # def extract_peaks(freqx, freqy, intens): # rutile = [] # point_x, point_y = reci_rutile() # for px, py in zip(point_x, point_y): # rutile.append(reduce(extract_rect(intens, px, py, freqx, freqy))) # # mono = [] # point_x, point_y = reci_mono() # for px, py in zip(point_x, point_y): # mono.append(reduce(extract_rect(intens, px, py, freqx, freqy))) # return rutile, mono # # # def plot(ax, freqx, freqy, intens): # point_x, point_y = reci_rutile() # for px, py in zip(point_x, point_y): # rect = rect_at_point(px, py, "r") # ax.add_patch(rect) # ax.text( # px, py, f"{reduce(extract_rect(intens, px, py, freqx, freqy)):2.2}", clip_on=True # ) # # point_x, point_y = reci_mono() # for px, py in zip(point_x, point_y): # rect = rect_at_point(px, py, "b") # ax.add_patch(rect) # ax.text( # px, py, f"{reduce(extract_rect(intens, px, py, freqx, freqy)):2.2}", clip_on=True # ) # ax.imshow( # intens, # extent=(np.min(freqx), np.max(freqx), np.min(freqy), np.max(freqy)), # norm=matplotlib.colors.LogNorm(), # cmap="Greys" # ) # # # def test_all(): # LEN = 100 # SIZE = 60 * LEN + 1 # quad = np.ones((3, 3)) # # fig, ax = plt.subplots(1, 3) # # lat = VO2_Lattice(LEN, LEN) # maske = np.ones((LEN, LEN), dtype=bool) # x, y = lat.get_from_mask(maske) # img = image_from_pos(x, y) # img = padding(img, SIZE, SIZE) # #img = scipy.signal.convolve2d(img, quad) # img = gaussian(img) # freqx, freqy, intens_rutile = fft(img) # # img = scipy.signal.convolve2d(img, quad) # ax[0].imshow(img) # # maske = np.zeros((LEN, LEN), dtype=bool) # x, y = lat.get_from_mask(maske) # img = image_from_pos(x, y) # img = padding(img, SIZE, SIZE) # img = gaussian(img) # freqx, freqy, intens_mono = fft(img) # # img = scipy.signal.convolve2d(img, quad) # ax[2].imshow(img) # # maske = np.zeros((LEN, LEN), dtype=bool) # ind = np.arange(LEN*LEN) # np.random.shuffle(ind) # ind = np.unravel_index(ind[:int(LEN*LEN/2)], (LEN, LEN)) # maske[ind] = True # x, y = lat.get_from_mask(maske) # img = image_from_pos(x, y) # img = padding(img, SIZE, SIZE) # img = gaussian(img) # freqx, freqy, intens_mono = fft(img) # # img = scipy.signal.convolve2d(img, quad) # ax[1].imshow(img) # # print(np.mean(maske)) # x, y = lat.get_from_mask(maske) # img = image_from_pos(x, y) # img = padding(img, SIZE, SIZE) # img = gaussian(img) # freqx, freqy, intens_50 = fft(img) # # fig, axs = plt.subplots(1, 3) # plot(axs[0], freqx=freqx, freqy=freqy, intens=intens_rutile) # plot(axs[2], freqx=freqx, freqy=freqy, intens=intens_mono) # plot(axs[1], freqx=freqx, freqy=freqy, intens=intens_50) # axs[0].set_title("Rutile") # axs[2].set_title("Mono") # axs[1].set_title("50/50") # # for ax in axs: # ax.set_xlim(-1.0, 1.0) # ax.set_ylim(-1.0, 1.0) # # # def eval(maske, lat, LEN): # x, y = lat.get_from_mask(maske) # SIZE = 60 * LEN + 1 # img = image_from_pos(x, y) # img = padding(img, SIZE, SIZE) # img = gaussian(img) # freqx, freqy, intens = fft(img) # return extract_peaks(freqx, freqy, intens) # # # def reduce(arr): # arr = np.array(arr) # arr = arr.flatten() # return np.sum(arr[np.argpartition(arr, -8)[-8:]]) # # # def main(): # LEN = 80 # lat = VO2_Lattice(LEN, LEN) # maske = np.zeros((LEN, LEN), dtype=bool) # ind = np.arange(LEN*LEN) # np.random.shuffle(ind) # percentage = [] # rutile = [] # monoclinic = [] # counter = 0 # for i in tqdm.tqdm(ind): # i_unravel = np.unravel_index(i, (LEN, LEN)) # maske[i_unravel] = True # if np.mod(counter, 300) == 0: # rut, mono = eval(maske, lat, LEN) # percentage.append(np.mean(maske)) # rutile.append(reduce(rut)) # monoclinic.append(reduce(mono)) # counter += 1 # # print(len(percentage), len(mono), len(rutile)) # print(mono) # plt.figure() # plt.scatter(percentage, np.array(monoclinic)/monoclinic[0], label="mono") # plt.scatter(percentage, np.array(rutile)/rutile[0], label="rut") # plt.legend() # # # if __name__ == "__main__": # test_all() # # main() # plt.show()