fullcode_patterns.py 10.3 KB
Newer Older
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
1 2 3 4
# -*- coding: utf-8 -*-
"""
Created on Wed Oct 16 11:51:21 2024

Revora, Corina's avatar
Revora, Corina committed
5
@author: nicon y corir (mentira no hice nada)
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
6 7 8 9 10 11 12
"""


import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

13 14 15
# Variables globales para almacenar el último centro
last_xlim = None
last_ylim = None
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
16

17
def Grating(k, l, size, Binary=True, Blaze=False, Inverted=False, powerblaze=1, BinaryFactor=0.25, Nx=10000, Ny = 5000, phase1storder=0, mini=0, maxi=255, x0=0, y0=0):
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
18 19 20 21 22
    
    x = np.linspace(-size, size, Nx)
    y = np.linspace(-size, size, Ny)
    
    if Binary:
23 24 25 26
        if not Inverted:
            Pattern = [[maxi if 0.5*(1 - np.cos(k*xi - l*np.arctan2(xi, yj) - phase1storder)) > BinaryFactor else mini for xi in x] for yj in y]
        else:
            Pattern = [[maxi if 0.5*(1 - np.cos(k*xi - l*np.arctan2(xi, yj) - phase1storder)) > BinaryFactor else mini for yj in y] for xi in x]
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

    else:
        if Blaze:
            Pattern = []
            for yj in y:
                Pat=[]
                for xi in x:
                    grati = maxi*0.5*(1 - arbpower_sawtooth(k*(xi-x0) - l*np.arctan2(xi-x0, yj-y0) - phase1storder, power=powerblaze, width = 1))
                    Pat.append(grati)
                Pattern.append(Pat)
            
        else:
            Pattern = []
            for yj in y:
                Pat=[]
                for xi in x:
                    Pat.append(0.5*(1 - np.cos(k*(xi-x0) - l*np.arctan2(xi-x0, yj-y0) - phase1storder)))
                Pattern.append(Pat)

    return Pattern, x, y


def arbpower_sawtooth(t, power, width=1):
    """
    Función para armar patrones de difracción con blaze
        -power: parámetro de potencia. debe ser positivo. si está entre 0 y 1 es una función raiz. si es 1, es lineal. si es más de 1, potencia.
        -width: si es 1 tiene una orientación y si es 0 tiene otra. no poner valores intermedios (por ahora)
    """
    # Normaliza el valor de t a un rango de 0 a 1
    t_mod = np.mod(t, 2 * np.pi) / (2 * np.pi)
    
    # Para la parte creciente del ciclo: función de raíz cuadrada
    positive_part = t_mod**power
    
    # Para la parte decreciente del ciclo: invertimos la raíz cuadrada
    negative_part = -(1 - t_mod)**power
    
    # Combina ambas partes
    result =2*np.abs(np.where(t_mod < width, positive_part, negative_part))-1
    
    return result

def on_key(event):
70
    global last_xlim, last_ylim  # Para acceder a las variables globales
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
71 72
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
73 74 75
    
    step_sizex = (xlim[1] - xlim[0]) / len(y)  # Ajusta este valor para cambiar la velocidad de desplazamiento
    step_sizey = (ylim[1] - ylim[0]) / len(x)
76

Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
77
    if event.key == "right":
78
        ax.set_xlim(xlim[0] - step_sizey, xlim[1] - step_sizey)  # Mover derecha
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
79
    elif event.key == "left":
80
        ax.set_xlim(xlim[0] + step_sizey, xlim[1] + step_sizey)  # Mover izquierda
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
81
    elif event.key == "up":
82
        ax.set_ylim(ylim[0] - step_sizex, ylim[1] - step_sizex)  # Mover arriba
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
83
    elif event.key == "down":
84
        ax.set_ylim(ylim[0] + step_sizex, ylim[1] + step_sizex)  # Mover abajo
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
85

86 87 88 89
    # Guardar el nuevo centro
    last_xlim = ax.get_xlim()
    last_ylim = ax.get_ylim()

Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
90 91
    fig.canvas.draw_idle()  # Redibujar la imagen sin regenerarla

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
def on_close(event):
    global last_xlim, last_ylim
    # Guardar los límites actuales cuando se cierre la ventana
    last_xlim = ax.get_xlim()
    last_ylim = ax.get_ylim()
    print(f'Última posición guardada: xlim={last_xlim}, ylim={last_ylim}')

def display_image():
    global fig, ax

    fig, ax = plt.subplots(figsize=(8, 6), dpi=100)
    c = plt.pcolor(Pattern, cmap='gray', vmin=0, vmax=255)

    plt.xticks([])
    plt.yticks([])
    plt.gca().set_position([0, 0, 1, 1])

    manager = plt.get_current_fig_manager()
    manager.full_screen_toggle()
    fig.canvas.window().statusBar().setVisible(False)
    manager.toolbar.hide()
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
113

114 115 116 117 118 119 120 121 122 123 124 125
    # Restaurar la última posición si existe
    if last_xlim and last_ylim:
        ax.set_xlim(last_xlim)
        ax.set_ylim(last_ylim)

    # Conectar eventos
    fig.canvas.mpl_connect("key_press_event", on_key)
    fig.canvas.mpl_connect("close_event", on_close)

    plt.show()

#%%
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
126

127 128 129 130
"""
Codigo para hacer un tenedor con todo ajustado y andando
"""

Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
131 132

size=1 #esto en realidad no cambia absolutamente nada
133 134
Nx = 800
Ny = 600
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
135

136
linewidth = 400
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
137 138 139 140 141 142 143 144

k = 1*np.pi/((linewidth/10000)*size)

l = 1 #para usar redes comunes pone l=0

mini, maxi = 0,255 #numeros de 0 a 255 que definen los tonos de gris de las franjas

binary = 'binary'  #posibles: binary o notbinary. para usar blaze usa notbinary
145 146

Inverted=True
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
147 148 149

Blaze=False
bfactor = 2
150
print("aguante boca")
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
151 152 153 154 155 156 157 158 159 160

# Phase = [0,45,90,135,180]

Phase = [0]
for p in Phase:
# p = 90
    phase = p*np.pi/180
    binaryfactor = 0.5
    
    if binary == 'binary':
161
        Pattern, x, y = Grating(np.pi/((linewidth/10000)*size), l, size, Binary=True, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
162
    else:
163
        Pattern, x, y = Grating(np.pi/((linewidth/10000)*size), l, size, Binary=False, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
164

165 166
fig, ax = plt.subplots(figsize=(8, 6), dpi = 100)
c = plt.pcolor(Pattern,cmap='gray', vmin=0,vmax=255)
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
167 168 169 170 171 172 173 174

plt.xticks([])
plt.yticks([])

plt.gca().set_position([0,0,1,1])
#plt.subplots_adjust(left=0, right=1, top=1. bottom=0)
#plt.rcParams["figure.autolayout"] = False
manager = plt.get_current_fig_manager()
175 176 177 178 179 180

manager.full_screen_toggle() #con f o ctrl+f se sale del full screen

fig.canvas.window().statusBar().setVisible(False)

manager.toolbar.hide()
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
181 182 183 184 185 186

print(f'done {p}')

# Conectar la función al evento de teclado
fig.canvas.mpl_connect("key_press_event", on_key)

187 188 189
# Para llamar a display_image() cuando quieras mostrar la imagen
display_image()

190 191 192 193 194 195 196 197 198 199 200

#%%

"""
Codigo para hacer dos tenedores de helicidades l1 y l2
"""

size=1 #esto en realidad no cambia absolutamente nada
Nx = 800
Ny = 300

Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
201
linewidth = 1200
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315

k = 1*np.pi/((linewidth/10000)*size)

l1, l2 = 1, 1 #para usar redes comunes pone l=0

mini, maxi = 0,255 #numeros de 0 a 255 que definen los tonos de gris de las franjas

binary = 'binary'  #posibles: binary o notbinary. para usar blaze usa notbinary
orientation = 'vertical' #posibles: vertical (tenedores uno arriba del otro) u horizontal (tenedores uno al lado del otro)

Inverted=True

Blaze=False
bfactor = 2
print("aguante boca")

# Phase = [0,45,90,135,180]

Phase = [0]
for p in Phase:
# p = 90
    phase = p*np.pi/180
    binaryfactor = 0.5
    
    if binary == 'binary':
        Pattern1, x1, y1 = Grating(np.pi/((linewidth/10000)*size), l1, size, Binary=True, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)
        Pattern2, x2, y2 = Grating(np.pi/((linewidth/10000)*size), l2, size, Binary=True, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)
    else:
        Pattern1, x1, y1 = Grating(np.pi/((linewidth/10000)*size), l1, size, Binary=False, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)
        Pattern2, x2, y2 = Grating(np.pi/((linewidth/10000)*size), l2, size, Binary=False, Blaze=Blaze, Inverted=Inverted, powerblaze=bfactor, BinaryFactor=binaryfactor, Nx=Nx, Ny=Ny, phase1storder=phase, mini=mini, maxi=maxi)


def on_key2(event):
    xlim1, ylim1 = ax1.get_xlim(), ax1.get_ylim()
    xlim2, ylim2 = ax2.get_xlim(), ax2.get_ylim()    
    step_sizex1 = (max(xlim1) - min(xlim1))/len(y1)  # Ajusta para cambiar la velocidad
    step_sizey1 = (max(ylim1) - min(ylim1))/len(x1)
    step_sizex2 = (max(xlim2) - min(xlim2))/len(y2)  # Ajusta para cambiar la velocidad
    step_sizey2 = (max(ylim2) - min(ylim2))/len(x2)
    # print(step_sizex)
    # print(step_sizey)

    # xlim = ax.get_xlim()
    # ylim = ax.get_ylim()
    # step_sizex = (max(xlim) - min(xlim))/len(x)  # Ajusta este valor para cambiar la velocidad de desplazamiento
    # step_sizey = (max(ylim) - min(ylim))/len(y)


    # Verifica si Shift está presionado para determinar cuál patrón mover
    if event.key == "shift+right":
        xlim2 = (xlim2[0] - step_sizex2, xlim2[1] - step_sizex2)
        ax2.set_xlim(xlim2)
    elif event.key == "shift+left":
        xlim2 = (xlim2[0] + step_sizex2, xlim2[1] + step_sizex2)
        ax2.set_xlim(xlim2)
    elif event.key == "shift+up":
        ylim2 = (ylim2[0] - step_sizey2, ylim2[1] - step_sizey2)
        ax2.set_ylim(ylim2)
    elif event.key == "shift+down":
        ylim2 = (ylim2[0] + step_sizey2, ylim2[1] + step_sizey2)
        ax2.set_ylim(ylim2)
    elif event.key == "right":
        xlim1 = (xlim1[0] - step_sizex1, xlim1[1] - step_sizex1)
        ax1.set_xlim(xlim1)
    elif event.key == "left":
        xlim1 = (xlim1[0] + step_sizex1, xlim1[1] + step_sizex1)
        ax1.set_xlim(xlim1)
    elif event.key == "up":
        ylim1 = (ylim1[0] - step_sizey1, ylim1[1] - step_sizey1)
        ax1.set_ylim(ylim1)
    elif event.key == "down":
        ylim1 = (ylim1[0] + step_sizey1, ylim1[1] + step_sizey1)
        ax1.set_ylim(ylim1)
    fig.canvas.draw_idle()  # Redibujar la imagen sin regenerarla

if orientation=='vertical':
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), dpi=100)
elif orientation=='horizontal':
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 6), dpi=100)
else:
    print('no se entendio la orientacion')
    raise
# Grafica Pattern1 en el primer eje
ax1.pcolor(Pattern1, cmap='gray', vmin=0, vmax=255,edgecolors='none')
ax1.set_xticks([])
ax1.set_yticks([])

for spine in ax1.spines.values():
    spine.set_visible(False)

# Grafica Pattern2 en el segundo eje
ax2.pcolor(Pattern2, cmap='gray', vmin=0, vmax=255,edgecolors='none')
ax2.set_xticks([])
ax2.set_yticks([])

for spine in ax2.spines.values():
    spine.set_visible(False)

# Configuración para pantalla completa y sin bordes
plt.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
manager = plt.get_current_fig_manager()
manager.full_screen_toggle()
fig.canvas.window().statusBar().setVisible(False)
manager.toolbar.hide()

plt.show()

def on_keytest(event):
    print('you pressed', event.key, event.xdata, event.ydata)

print(f'done {p}')

# Conectar la función al evento de teclado
fig.canvas.mpl_connect("key_press_event", on_key2)