15. Redes de Difracción

Autor:Luis Miguel Sánchez Brea
Revisor:José Luis Vilas Prieto

Las redes de difracción son estructuras periódicas que modulan la transmitancia de un haz incidente. Son de gran importancia en áreas como espectroscopía, para separar el espectro, o en metrología óptica, donde se utilizan como escalas.

Herramientas utilizadas en este tutorial:

  • numpy: manipulación de datos
  • scipy: Herramientas matemáticas

Archivos necesarios para la definición de redes de difracción:

Contenidos de los archivos:

  • mascarasXY.py: (parte de redes)

    • red_seno(). Definición de una red sinusoidal.
    • red_blazed(). Red tipo diente de sierra.
    • red_ronchi(). Implementación de una red de Ronchi.
    • red_binaria(). Genera una red de franjas.
    • red2D(). Define una red bidimensional de franjas horizontales y verticales.
    • red2D_ajedrez(). Genera una red con formato tipo damero.
    • ejemplo_red_seno.py. Ejemplo de una red sinusoidal.
    • ejemplo_red_ronchi.py. Ejemplo de una red de Ronchi.
    • ejemplo_red_blazed.py. Ejemplo de una red Blazed.
    • ejemplo_red_binaria.py. Ejemplo de una red binaria.
    • ejemplo_red_ajedrez.py. Ejemplo de una red tipo damero.
    • ejemplo_red_2D.py. Ejemplo de una red bidimensional.
    • ejemplo_talbot_numerico.py. Ejemplo numérico del efecto Talbot.

15.1. Introducción

Podemos definir una red de difracción como un elemento óptico que modula de forma periódica alguna propiedad de la luz. Normalmente existen redes de amplitud y de fase, aunque se puede modular de forma periódica cualquier otra propiedad de la luz, tal como la polarización o la coherencia. Como la modulación se produce de forma periódica, el análisis de cómo se comporta la red se puede realizar mediante un análisis de Fourier, de forma que la transmitancia se puede describir matemáticamente mediante

t(x)=\sum_{l=-\infty}^{\infty}a_{l}\exp\left(\frac{2\pi ilx}{p}\right).

donde p es el periodo y a_{l} son los coeficientes de Fourier que se obtienen mediante

a_{l}=\frac{1}{p}\int_{-p/2}^{p/2}t(x)\exp\left(-2\pi il\frac{x}{p}\right)dx.

15.2. Red Sinusoidal

Una red sinusoidal es un conjunto de franjas equiespaciadas cuya intensidad puede ser ajustada a una función sinusoidal. La orientación de las franjas puede ser arbitraria. En la función que nos atañe su ángulo de inclinación aparece en el argumento como angulo. Así se llama a la función __rotar__ dentro de la clase a fin de rotar las franjas. Finalmente se implementa la intensidad de las franjas, entre una intensidad mínima amp_min y una máxima amp_max. La modulación de la intensidad ha sido definida como

t(x)=A_{min}+ \frac{A_{max} - A_{min}}{2} \left[1+\cos\left(\frac{2\pi(x+\delta)}{p}\right)\right]

donde p define el periodo de las franjas.

	def red_seno(self, periodo = 40 * um, amp_min = 0, amp_max = 1, desfase = 0 * um, angulo = 0 * grados):

		#Se define la inclinacion de la red
		Xrot, Yrot = self.__rotar__(angulo)

		#Definicion de la sinusoidal
		self.u = amp_min + (amp_max - amp_min) * (1 + sp.cos(2 * sp.pi * (Xrot + desfase) / periodo)) / 2

La representación de las franjas resulta ser

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#------------------------------------
# Autor:	Luis Miguel Sanchez Brea
# Fecha		2013/10/24 (version 1.0)
# Licencia:	GPL
#-------------------------------------
"""
ejemplos redes
"""

import sys
sys.path.append('../')
from mascarasXY import * #@UnusedWildImport

def ejemplo_redSeno():
	x = sp.linspace(-250 * um, 250 * um, 512)
	y = sp.linspace(-250 * um, 250 * um, 512)
	wavelength = 0.6238 * um
	periodo = 75 * um
	t = mascaraXY(x, y, wavelength)
	t.red_seno(periodo= periodo, amp_min=0, amp_max=1,\
                   desfase=periodo / 2, angulo=0 * grados)
	t.dibujar(tipo='intensidad', titulo='red seno')

 
if __name__ == '__main__':
	 ejemplo_redSeno()
	 plt.show()

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_seno.png

Los coeficientes de Fourier para una red sinusoidal

t(x)=1+\cos(2\pi\frac{x}{p})=1+\frac{1}{2}e^{2\pi i\frac{x}{p}}+\frac{1}{2}e^{-2\pi i\frac{x}{p}}

son

{a_{-1}=1/2,}\,{a_{0}=1,}\,{a_{1}=1/2.}

15.3. Red de Ronchi

Una red de Ronchi es un conjunto de franjas equiespaciadas tales que los máximos y los mínimos de intensidad poseen la misma anchura. Para la implementación de una red de Ronchi se hará uso de la clase mascaraXY así como de la función rendija ya vista anteriormente en la sección máscaras. Así en primer lugar tras llamar a la clase y generar nuestro vector salida, t con ceros a fin de optimizar nuestra función se calcula el número de franjas, numperiodos a partir de redondear al entero más próximo el cociente

\frac{x_{max}-x_{min}}{p}

donde p es el periodo, x nuestro vector de entrada y xmax y xmin, los máximos y mínimos de x. Finalmente sumamos 5 con la intención de tener un número de periodos suficientes y no quedarnos cortos debido al redondeo. Con el fin de definir la anchura de la rendija se multiplica el factor de relleno por el periodo. Para definir las franjas se llama para cada línea a la función rendija, así es preciso definir un punto de inicio para la implementación de las franjas, xinicial siendo este el valor mínimo del vector de entrada menos el valor el puto central, x0. Finalmente, mediante un bucle for se definen las franjas con inclinación angulo. Esto se hace superponiendo nuestro vector de ceros, t, cuyos valores son los mínimos con los máximos que dan lugar del uso de la función rendija.

	def red_ronchi(self, periodo = 40 * um, x0 = 20 * um, fillFactor = 0.5, angulo = 0 * grados):
		t = t2 = mascaraXY(self.x, self.y, self.wavelength);
		t.u = sp.zeros(self.X.shape)

		#Numero de periodos
		numperiodos = int(round((self.x.max() - self.x.min()) / periodo + 5))
		#Anchura de la rendija
		anchuraRendija = fillFactor * periodo;

		#Se define un origen
		xinicial = self.x.min() - x0

		#Generacion de la red
		for i in range(-3, numperiodos + 1):
			t2.rendija(xinicial + i * periodo, anchuraRendija, angulo)
			t = t + t2

		self.u = t.u

La representación de las franjas es (solo mostramos la función, pues el resto es igual al ejemplo anterior)

def ejemplo_redRonchi():
	x = sp.linspace(-250 * um, 250 * um, 512)
	y = sp.linspace(-250 * um, 250 * um, 512)
	wavelength = 0.6238 * um
	periodo = 40 * um
	t = mascaraXY(x, y, wavelength)
	t.red_ronchi(periodo=periodo, x0=20 * um, fillFactor=0.5, angulo=0 * grados)
	t.dibujar(tipo='intensidad', titulo='red Ronchi')

 

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_ronchi.png

15.4. Red de Binaria

Una red binaria está constituida por un conjunto de franjas equiespaciadas entre sí una distancia determinada, en este caso, a través de los parámetros de entrada podemos controlar la amplitud mínima (amin), máxima (max), el desfase (desfase) y el factor de forma (fillFactor), además del ángulo de rotación (angulo)

def red_binaria(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2, x0 = 0, fillFactor = 0.5, angulo = 0 * grados):
	def red_binaria(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2, x0 = 0, fillFactor = 0.5, angulo = 0 * grados):
		t = mascaraXY(self.x, self.y, self.wavelength);
		t2 = mascaraXY(self.x, self.y, self.wavelength);
		t.u = sp.zeros(self.X.shape)

		#Numero de periodos
		numperiodos = int(round((self.x.max() - self.x.min()) / periodo + 5))
		#Anchura de la rendija
		anchuraRendija = fillFactor * periodo;
		#Se define un origen
		xinicial = self.x.min() - x0

		#Generacion de la red
		for i in range(-3, numperiodos):
			t2.rendija(xinicial + i * periodo + anchuraRendija, anchuraRendija, angulo)
			t.u = t.u + amax * t2.u * sp.exp(1.j * desfase)
			t2.rendija(xinicial + i * periodo, periodo - anchuraRendija,  angulo)
			t.u = t.u + amin * t2.u

		self.u = t.u

La representación queda:

def ejemplo_redBinaria():
	x = sp.linspace(-250 * um, 250 * um, 512)
	y = sp.linspace(-250 * um, 250 * um, 512)
	wavelength = 0.6238 * um
	t = mascaraXY(x, y, wavelength)
	t.red_binaria(	periodo = 40 * um, amin=.5, amax=1, desfase=1 * sp.pi / 2,\
                        x0=0, fillFactor=0.5)
	t.dibujar(tipo='campo', titulo='red Binaria')

 

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_binaria.png

Los coeficientes de Fourier de una red binaria (que incluye a la red de Ronchi como caso especial son

{a_{0}}={\alpha\left(e^{-i\delta}-1\right)+1}

{a_{l}}={\alpha\left(e^{-i\delta}-1\right)sinc(\pi l\alpha)}

donde el desfase resulta ser \delta=\frac{2\pi}{\lambda}(n-1)h para el caso de transmisión y \delta=\frac{4\pi}{\lambda}(n-1)h para el caso de reflexión.

15.5. Red Blazed

Normalmente en una red de difracción convencional la luz difractada se concentra en su mayor parte en el orden cero. Una red Blazed es un tipo particular de red de difracción que permite homogeneizar la luz difractada en los distintos órdenes Esto se logra mediante una red con forma de dientes de sierra. Las redes de difracción trabajan bajo determinadas condiciones de iluminación como es la longitud de onda del haz y el ángulo de incidente, que en general se supone normal a la red. Así para implementar una red Blazed se comienza definiendo el vector de onda. La definición de los dientes de sierra de la red se hace mediante el periodo de la red y la altura del diente, el cociente de estas dos cantidades representa la pendiente de cada diente. La altura en cada punto de la red será por tanto, la pendiente de los dientes por la posición x. La fase viene dado por el camino óptico como se muestra en k * (indice - 1) * h la cual debe estar normalizada entre 0 y 2\pi, esto se logra con remainder. Dado que es relativa se fija un origen de referencia, el cual está especificado por el mínimo. Finalmente se devuelve la fase

	def red_blazed(self, periodo = 40 * um, altura = 2 * um, indice = 1.5, angulo = 0 * grados):
		#Vector de onda
		k = 2 * sp.pi / self.wavelength
		#Inclinacion de las franjas
		Xrot, Yrot = self.__rotar__(angulo)

		#Calculo de la pendiente
		pendiente = altura / periodo
		#Calculo de la altura
		h = Xrot * pendiente

		#Calculo del a fase
		fase = k * (indice - 1) * h
		#Definicion del origen
		fase = fase - fase.min()
		#Normalizacion entre 0 y 2pi
		fase = np.remainder(fase, 2 * sp.pi)
		self.u = sp.exp(1j * fase)

Si llamamos a esta función se obtiene

def ejemplo_redBlazed():
	x = sp.linspace(-250 * um, 250 * um, 512)
	y = sp.linspace(-250 * um, 250 * um, 512)
	wavelength = 0.6238 * um
	periodo = 100 * um
	t = mascaraXY(x, y, wavelength)
	t.red_blazed(periodo= periodo, altura=2 * um, indice=1.5, angulo=0 * grados)
	t.dibujar(tipo='fase', titulo='red blazed')

 

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_blazed.png

15.6. Red bidimensional

Una red bidimensional es aquella constituida por un conjunto de franjas verticales y horizontales, tales que permite la transmisión de luz únicamente en dichas franjas. La implementación es sencilla basta con definir los dos conjuntos de franjas horizontal y vertical y superponerlas. La superposición es equivalente a multiplicar las franjas puesto que cada una es un matriz de ceros (no hay transmisión) y unos (transmisión permitida.

	def red2D(self, periodo = 40.*um, amin = 0, amax = 1., desfase = 0.*sp.pi / 2, x0 = 0, fillFactor = 0.75, angulo = 0.1 * grados):
		#Se inicializa
		t1 = mascaraXY(self.x, self.y, self.wavelength);
		t2 = mascaraXY(self.x, self.y, self.wavelength);
		#Red horizontal
		t1.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo)
		#Red vertical
		t2.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo + 90.*grados)
		#Red binaria
		self.u = t1.u * t2.u

La representación de la red bidimensional queda

def ejemplo_red2D():
	x = sp.linspace(-250 * um, 250 * um, 512)
	y = sp.linspace(-250 * um, 250 * um, 512)
	wavelength = 0.6238 * um
	periodo = 50 * um
	t = mascaraXY(x, y, wavelength)
	t.red2D(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2,\
                x0=0, fillFactor=0.5, angulo=0 * grados)
	t.dibujar(tipo='intensidad', titulo='red 2D')

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_2D.png

15.7. Red tipo Ajedrez

Como su propio nombre indica una red tipo ajedrez genera un damero con regiones de transmitancia unidad y nula. Debido a como se ha definido la función, se pueden implementar distintos tipos de dameros con regiones de transmitancia mayores y menores como se muestra en el ejemplo. La implementación del a función es completamente análoga a la de la red bidimensional cambiando únicamente la última línea del código, en la cual en vez de realizar el producto de las dos matrices, se realiza una función xor entre ellas. Esta función toda dos argumentos binarios, y su resultado únicamente nulo cuando los dos argumentos adquieren simultáneamente el mismo valor (0,0), o (1,1), de lo contrario el resultado es la unidad.

	def red2D_ajedrez(self, periodo = 40 * um, amin = 0, amax = 1, desfase = 0 * sp.pi / 2,\
                          x0 = 0, fillFactor = 0.75, angulo = 0 * grados):
		#Mismo proceder que en 2D                
		t1 = mascaraXY(self.x, self.y, self.wavelength);
		t2 = mascaraXY(self.x, self.y, self.wavelength);
		t1.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo)
		t2.red_binaria(periodo, amin, amax, desfase, x0, fillFactor, angulo + 90.*grados)
		#Actuacion de la XOR
		self.u = sp.logical_xor(t1.u, t2.u)

Así resulta la representación

def ejemplo_redAjedrez1():
	x = sp.linspace(-250 * um, 250 * um, 1024)
	y = sp.linspace(-250 * um, 250 * um, 1024)
	wavelength = 0.6238 * um
	periodo = 50 * um
	t = mascaraXY(x, y, wavelength)
	t.red2D_ajedrez(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2, x0=0,\
                        fillFactor=0.5, angulo=0 * grados)
	return t

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_ajedrez.png

Para definir el segundo dibujo los parámetros resultan

       t.red2D_ajedrez(periodo=periodo, amin=0, amax=1., desfase=0 * sp.pi / 2, x0=0, fillFactor=0.75,\
angulo=45 * grados)

15.8. Red radial

Las redes de difracción también pueden tener simetría radial. Son parecidos a los axicones, pero con transmitancia 1 o 0.

	def red_radial(self, r0 = (0 * um, 0 * um), periodo = 20 * um, desfase=0*um, radius=400*um, binaria=True):
		#si solamente hay un numero, es que las posiciones y radios son los mismos para ambos
		if len(r0) == 1:
			r0 = (r0[0], r0[0])
		#Vector de onda
		k = 2 * sp.pi / self.wavelength
		x0, y0 = r0
		#Distancia de la generatriz al eje del cono
		r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
		#hago un seno y luego binarizo
		t = 0.5*(1+sp.sin(2*sp.pi*(r+desfase)/periodo))
		if binaria==True:
			i0 = t <= 0.5;		t[i0] = 0
			i1 = t > 0.5;		t[i1] = 1
		#Region de transmitancia
		u = sp.zeros(sp.shape(self.X))
		ipasa = r < radius
		u[ipasa] = 1
		self.u = u * t

Así resulta la representación

def ejemplo_red_radial():
	ndatos = 512
	tamano = 250 * um
	x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	wavelength = 0.6328 * um

	t1 = mascaraXY(x, y, wavelength)
	t1.red_radial(r0 = (0 * um, 0 * um), periodo=20*um, desfase=10*um, radius = 100 * um)
	t1.dibujar(tipo = 'intensidad')

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_radial.png

15.9. Red angular

Las redes de difracción también pueden tener simetría angular. El periodo va en grados.

	def red_angular(self, r0 = (0 * um, 0 * um), periodo = 20*grados, desfase=0*grados, radius=200*um, binaria=True):
		#si solamente hay un numero, es que las posiciones y radios son los mismos para ambos
		if len(r0) == 1:
			r0 = (r0[0], r0[0])
		#Vector de onda
		k = 2 * sp.pi / self.wavelength
		x0, y0 = r0
		#Distancia de la generatriz al eje del cono
		r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
		theta=sp.arctan((self.Y - y0)/(self.X - x0))
		#Region de transmitancia
		t = (1+sp.sin(2*sp.pi*(theta-desfase)/periodo))/2
		if binaria==True:
			i0 = t <= 0.5;		t[i0] = 0
			i1 = t > 0.5;		t[i1] = 1
	
		u = sp.zeros(sp.shape(self.X))
		ipasa = r < radius
		u[ipasa] = 1

		self.u = u * t

Así resulta la representación

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_angular.png

15.10. Red con borde sinusoidal

Este tipo de redes puede tener incidencia para eliminar armónicos en la dirección x

	def red_borde_sinusoidal(self, r0 = (0 * um, 0 * um), periodo = 20*grados, lp=10*um, ap=2*um, desfase=0*grados, radius=200*um, binaria=True):
		#si solamente hay un numero, es que las posiciones y radios son los mismos para ambos
		#lp es la longitud del periodo del borde, ap es la amplitud del periodo del borde
		if len(r0) == 1:
			r0 = (r0[0], r0[0])
		#Vector de onda
		k = 2 * sp.pi / self.wavelength
		x0, y0 = r0
		#Distancia de la generatriz al eje del cono
		r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
		theta=sp.arctan((self.Y - y0)/(self.X - x0))
		#Region de transmitancia
		Desfase=desfase+ap*sp.sin(2*sp.pi*self.Y/lp)
		
		t = (1+sp.sin(2*sp.pi*(self.X-Desfase)/periodo))/2
		if binaria==True:
			i0 = t <= 0.5;		t[i0] = 0
			i1 = t > 0.5;		t[i1] = 1
	
		u = sp.zeros(sp.shape(self.X))
		ipasa = r < radius
		u[ipasa] = 1

		self.u = u * t

Así resulta la representación, se produce una variación períodica del desfase.

def ejemplo_red_borde_sinusoidal():
	ndatos = 1024
	tamano = 250 * um
	x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	wavelength = 0.6328 * um
	t1 = mascaraXY(x, y, wavelength)
	t1.red_borde_sinusoidal(r0 = (0 * um, 0 * um), periodo = 20*um, lp=20*um, ap=10*um, desfase=0*grados, radius=125*um, binaria=True)
	t1.dibujar(tipo = 'intensidad')

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_borde_sinusoidal.png

15.11. Red hiperbólica

	def red_hiperbolica(self, r0 = (0 * um, 0 * um), periodo = 20*grados, desfase=0*grados, radius=200*um, binaria=True, angulo=0*grados):
		#si solamente hay un numero, es que las posiciones y radios son los mismos para ambos
		if len(r0) == 1:
			r0 = (r0[0], r0[0])
		#Vector de onda
		k = 2 * sp.pi / self.wavelength
		x0, y0 = r0
		#Distancia de la generatriz al eje del cono
		
		
		#rotacion de la lente
		Xrot, Yrot = self.__rotar__(angulo)
		
		r = sp.sqrt((self.X - x0) ** 2 + (self.Y - y0) ** 2)
		x_posiciones = sp.sqrt(abs((Xrot - x0) ** 2 - (Yrot - y0) ** 2))
		#Region de transmitancia
		t = (1+sp.sin(2*sp.pi*x_posiciones/periodo))/2
		if binaria==True:
			i0 = t <= 0.5;		t[i0] = 0
			i1 = t > 0.5;		t[i1] = 1
	
		u = sp.zeros(sp.shape(self.X))
		ipasa = r < radius
		u[ipasa] = 1

		self.u = u * t

Así resulta la representación, se produce una variación períodica del desfase.

def ejemplo_red_hiperbolica(periodo=20*um, potencia=2):
	ndatos = 512
	tamano = 200 * um
	x = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	y = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	wavelength = 0.6328 * um

	t1 = mascaraXY(x, y, wavelength)
	t1.red_hiperbolica( r0 = (0 * um, 0 * um), periodo = 10*um, desfase=45*grados, radius=200*um, binaria=True, angulo=45*grados)
	t1.dibujar(tipo='intensidad')
	

(Source code, png, hires.png, pdf)

../../_images/ejemplo_red_hiperbolica.png

15.12. Aplicación como redes de difracción en campo lejano

El efecto de las interferencias surge directamente de que las ecuaciones de Maxwell son lineales en los campos eléctricos y magnéticos. Supongamos que \mathbf{E}_{1} y \mathbf{E}_{2} son soluciones. Entonces

z\gg\frac{\pi a^{2}}{\lambda}

donde a es el tamaño máximo del elemento difractor. Bajo esta aproximación, el campo difractado se puede calcular como una integral

\mathbf{E}(x,y,z)=\frac{e^{ik(z+\frac{x^{2}+y^{2}}{2z})}}{i\lambda z}\iint\mathbf{E}_{0}(\xi,\eta)e^{-i\frac{k}{z}(x\xi+y\eta)}d\xi d\eta.

donde \mathbf{E}_{0}(\xi,\eta) es el campo justo a la salida del elemento difractor.

La aproximación más usual para este campo es considerar que se obtiene como el producto del campo incidente \mathbf{E}_{in}(\xi,\eta) por el coeficiente de transmisión del máscara t(\xi,\eta)\mathbf{E}_{in}(\xi,\eta)

\mathbf{E}_{out}(\xi,\eta)=t(\xi,\eta)\mathbf{E}_{in}(\xi,\eta).

La gran ventaja de esta ecuación es que se puede escribir como una transformada de Fourier, que es una operación bastante conocida en matemáticas

\mathbf{E}(x,y,z)=\frac{e^{ik(z+\frac{x^{2}+y^{2}}{2z})}}{i\lambda z}TF\left[\mathbf{E}_{0}(\xi,\eta)\right].

Como el primer término delante de la transformada de Fourier es casi constante para un plano z determinado, se suele eliminar.

15.12.1. Difracción por una red de sinusoidal

La red sinusoidal tiene solamente tres frecuencias espaciales, que son las que se observan en la figura de difracción.

def difraccion_red_seno():
	#tamano de area de visualizacion
	tamano = 1000 * um
	ndatos = 512
	x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	#longitud de onda
	lambda0 = 0.6238 * um

	#fuente de iluminacion
	u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
	u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

	#mascara
	t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
	t1.red_seno(periodo=40*um)
	u2 = u1 * t1

	u3 = u2.fft(quitar0 = False)

	u2.dibujar()
	
	punto1=(u3.x.min(),0)
	punto2=(u3.x.max(),0)
	
	u3.dibujar_perfil(punto1,punto2, normalizar='maximo', order=2)

Tras ejecutar el código se obtiene la máscara y el perfil de intensidades en la pantalla.

(Source code)

15.12.2. Difracción por una red de Ronchi

La red de Ronchi tiene más frecuencias espaciales, todas equidistanciadas, que son las que se observan en la figura de difracción. La altura de cada pico es el cuadrado del valor del coeficiente de Fourier I_{pico,n}=\left|a_{n}\right|^{2}.

def difraccion_red_ronchi():
	#tamano de area de visualizacio
	tamano = 1000 * um
	ndatos = 512
	x0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	y0 = sp.linspace(-tamano / 2, tamano / 2, ndatos)
	#longitud de onda
	lambda0 = 0.6238 * um

	#fuente de iluminacion
	u1 = fuenteXY(x = x0, y = y0, wavelength = lambda0);
	u1.onda_plana(A = 1, theta = 0 * grados, phi = 0 * grados)

	#mascara
	t1 = mascaraXY(x = x0, y = y0, wavelength = lambda0)
	t1.red_ronchi( periodo = 40 * um, x0 = 0 * um, fillFactor = 0.5, angulo = 0 * grados)
	u2 = u1 * t1

	u3 = u2.fft(quitar0 = False)

	u2.dibujar()
	
	punto1=(u3.x.min(),0)
	punto2=(u3.x.max(),0)
	
	u3.dibujar_perfil(punto1,punto2, normalizar='maximo', order=2)

Tras ejecutar el código se obtiene la máscara y el perfil de intensidades en la pantalla.

(Source code)

15.13. Efecto Talbot

Para conocer la distribución de intensidad en campo cercano utilizaremos la aproximación de Fresnel (ver difracción en campo cercano), considerando la invariancia de la red de difracción en el eje \eta. Entonces el campo difractado se puede calcular a partir de

\mathbf{E}\left(x,z\right)=\sqrt{\frac{i}{\lambda  z}}e^{ikz}\int\mathbf{E}_{0}(\xi)e^{i\frac{k}{2z}(x-\xi)^{2}}d\xi

Resolviendo la integral para la estructura periódica de una red de difracción, el campo resulta

\mathbf{E}\left(x,z\right)=\sum_{l=-\infty}^{\infty}a_{l}\exp\left(2\pi il\frac{x}{p}\right)\exp\left(i2\pi l^{2}\frac{\lambda}{2p^{2}}z\right)

y, por tanto, la intensidad

I\left(x,z\right)=\sum_{l'=-\infty}^{\infty}\sum_{l=-\infty}^{\infty}a_{l}a_{l'}^{*}\exp\left[2\pi i\left(l-l'\right)\frac{x}{p}\right]\exp\left[2\pi i\left(l^{2}-l'^{2}\right)\frac{\lambda}{2p^{2}}z\right]

Esta ecuación se ha implementado numéricamente para observar el aspecto de la distribución de intensidad en campo cercano producido por una red de difracción.

(Source code, png, hires.png, pdf)

../../_images/efecto_talbot.png

En la figura se observa el fenómeno de las autoimágenes, al ser periódico en el eje z. Se forman réplicas de la red a distancias conocidas como distancia de Talbot, que resulta ser

z_{T}=2p^{2}/\lambda.

La parte principal del código, que es la obtencion del campo, es la siguiente

def efectoTalbot(t, z, periodo=40*um):
	""" esta funcion calcula el efecto talbot"""
	
	zT=2*periodo**2/t.wavelength
	X,Z=sp.meshgrid(t.x,z)
	periodo=50*um
	ordenes=sp.array([-3, -1, 0, 1, 3])
	coefs=sp.array([.25, 0.5, 1, 0.5, .25])

	red=sp.transpose([ordenes, coefs])
	u2=sp.zeros(X.shape,complex) 

	for j2,aj in red:
			u2+=aj*sp.exp(1j*2*sp.pi*j2*X/periodo)*sp.exp(-1j*2*sp.pi*j2**2*Z/zT)

	campoxz=sp.real(u2)
	return campoxz

Podemos observar el aspecto de las automágenes simplemente calculando la distribución de intensidad en campo cercano mediante la aproximación de Rayleigh-Sommerfeld. Esto lo hemos hecho para 3 distancias significativas en la red de Ronchi, z_{T}, z_{T}/2 y z_{T}/4:

(Source code)

Veamos ahora que ocurre cuando sobre la red de difracción se incide con un haz gaussiano. Al propagarse la luz, los distintos órdenes de tamaño finito, empiezan a no interferir entre sí, al no estar espacialmente en la mismas posiciones. Entonces, deja de producirse el fenómeno interferencial y tenemos los distintos ordenes aislados. Esto ocurre en campo cercano, y no solamente cuando estamos muy lejos de la red.

(Source code)

15.14. Efectos con dos redes

Los sistemas de doble red se utilizan frecuentemente en metrología óptica, como en deflectometría moiré para medir la topografía 3D de objetos o en sistemas Talbot, Lau o autoimágenes generalizadas para medir desplazamientos con gran precisión.

Veremos ahora algunos efectos de doble red. En el desplazamiento Talbot (movimiento de dos redes cuando es iluminado con onda plana). Se muestra una animación

(Source code)

Otro efecto interesante es el efecto vernier, donde aparecen franjas cuando a) el periodo de las dos redes es distinto y b) el ángulo entre las dos redes es distinto.

Se muestra estos dos casos mostrando una imagen y una animación:

Distinto periodo:

(Source code, png, hires.png, pdf)

../../_images/efecto_vernier_periodo.png

(Source code, png, hires.png, pdf)

../../_images/efecto_vernier_periodo_animado.png

Distinto ángulo:

(Source code, png, hires.png, pdf)

../../_images/efecto_vernier_angulo.png

(Source code, png, hires.png, pdf)

../../_images/efecto_vernier_angulo_animado.png

Estos dos efectos permiten medir (macroscópicamente) el desplazamiento, puesto que las franjas de vernier (las grandes) se desplazan de forma amplificada al desplazamiento relativo entre las redes.

(Source code, png, hires.png, pdf)

../../_images/desplazamiento_vernier_periodo_animado.png

(Source code, png, hires.png, pdf)

../../_images/desplazamiento_vernier_angulo_animado.png