Bac à sable Chaînes et listes Fonctions Numpy Piles Récursivité Tris

Diffraction

Page inachevée, encore en travaux...

Initialisation des applets.

xxxxxxxxxx
 
1
import numpy as np
2
import numpy.ma as ma
3
from scipy.special import j1            # Fonction de Bessel d'ordre 1
4
import matplotlib.pyplot as plt
5
from mpl_toolkits.mplot3d import Axes3D
6
​
7
def IdiffCirc(r,d,l,f):
8
    """ Intensité I(r) diffractée par une pupille circulaire de diamètre d (longueur d'onde l, focale projection f) """
9
    u = np.pi*d/(l*f)*10            # en cm-1
10
    return 4*(j1(u*r)/(u*r))**2
11
​
12
def IdiffRect(x,y,a,b,l,f):
13
    """ Intensité I(x,y) diffractée par une pupille rectangulaire de dimensions a, b (longueur d'onde l, focale projection f) """
14
    k = 1/(l*f)*10
15
    u = k*a                         # en cm-1
16
    v = k*b                         # en cm-1
17
    return (np.sinc(u*x))**2*(np.sinc(v*y))**2
18
​
19
def nm2rgb(wl, gamma=0.8):
20
    ''' Conversion longueur d'onde -> RGB
21
    D'après Dan Bruton http://www.physics.sfasu.edu/astro/color/spectra.html and http://www.noah.org/wiki/Wavelength_to_RGB_in_Python '''
22
    if wl >= 380 and wl <= 440:
23
        attenuation = 0.3 + 0.7 * (wl - 380) / (440 - 380) ; R = ((-(wl-440)/(440-380))*attenuation)**gamma ; G = 0 ; B = (1*attenuation)**gamma
24
    elif wl >= 440 and wl <= 490:
25
        R = 0 ; G = ((wl-440)/(490-440))**gamma ; B = 1
26
    elif wl >= 490 and wl <= 510:
27
        R = 0 ; G = 1 ; B = (-(wl-510)/(510-490))**gamma
28
    elif wl >= 510 and wl <= 580:
29
        R = ((wl-510)/(580-510))**gamma ; G = 1 ; B = 0
30
    elif wl >= 580 and wl <= 645:
31
        R = 1 ; G = (-(wl-645)/(645-580))**gamma ; B = 0
32
    elif wl >= 645 and wl <= 750:
33
        attenuation = 0.3 + 0.7 * (750 - wl) / (750 - 645) ; R = (1*attenuation)**gamma ; G = 0 ; B = 0
34
    else:
35
        R = 0 ; G = 0 ; B = 0
36
    R *= 255 ; G *= 255 ; B *= 255
37
    return np.array([int(R), int(G), int(B)])
38
print('Initialisations ok')

Messages


Diffraction par une pupille circulaire

xxxxxxxxxx
 
1
courbes = ['Figure de diffraction', 'Intensité', 'Courbe I(r)']
2
@interact(layout=[['trace'],['d','lo'],['xm', 'Im', 'auto']])
3
def _(trace = selector(courbes,label="Tracé"), 
4
    d=slider(10,100,10,50,label="Diamètre d (µm)"), lo=slider(400,800,10,550,label="Longueur d'onde (nm)"),
5
    xm = input_box(np.round(1,1),label="xmax", type=str), Im = input_box(np.round(0.02,3),label="Imax", type=str), auto = checkbox(True,label="Echelle auto"),
6
    mesures = checkbox(False,label="Mesures")): #auto_update=false
7
    plt.close('all') ; plt.clf()
8
​
9
    d = int(d) ; lo = int(lo) ; xm = float(xm) ; Im = float(Im)
10
    f = 1                                   # Focale projection en m
11
    if auto: xm = 2*np.round(lo*f/d/10,1)   # Demi largeur écran en cm
12
​
13
    p = xm/200                              # Pas en cm
14
    x0 = np.arange(-xm,xm+p,p) ; x, y = np.meshgrid(x0,x0)
15
    r = 2*np.sqrt(x**2 + y**2) ; r = ma.masked_values(r, 0)
16
    Idiff = IdiffCirc(r,d,lo,f) ; Idiff = Idiff.filled(1)
17
    
18
    if trace in ['Figure de diffraction', 'Intensité']:
19
        Idiffmask = ma.masked_greater_equal(Idiff, Im) ; Idiffmask=Idiffmask.filled(Im)/Im
20
        rgb = nm2rgb(lo,0.8)
21
        l,h = Idiffmask.shape
22
        z = np.zeros((l,h,3))
23
        for i in range(h):
24
            for j in range(l):
25
                z[i,j] = Idiffmask[i,j] * rgb
26
        z = ma.asarray(z,dtype='uint8')
27
    
28
    fig,(ax) = plt.subplots(1,1)
29
    if trace in['Figure de diffraction','Intensité']:
30
        if mesures: 
31
            ax.grid()
32
            nx = 2*xm/p ; nticks = 10
33
            xticks = np.linspace(0,nx,nticks+1)
34
            xticklabels = ["{:.1f}".format(i*xm*2) for i in range(-nticks//2,nticks//2+1)]
35
            ax.set_xticks(xticks) ; ax.set_yticks(xticks)
36
            ax.set_xticklabels(xticklabels) ; ax.set_yticklabels(xticklabels)
37
            ax.set_xlabel('x en mm') ; ax.set_ylabel('y en mm')
38
        else:
39
            ax.axis('off')
40
        ax.imshow(z,aspect='equal',origin='lower')
41
    elif trace == 'Courbe I(r)':
42
        x0m = ma.masked_values(x0, 0)
43
        Idiff0 = IdiffCirc(x0m**2,d,lo,f) ; Idiff0 = Idiff0.filled(1)
44
        Idiff0 = ma.masked_greater(Idiff0, Im)
45
        ax.plot(x0,Idiff0,color='red')
46
    plt.show()
47
    if trace == 'Intensité':
48
        r0, phi, z0 = var('r0 phi z0')
49
        trans=(r0*cos(phi),r0*sin(phi),z0)
50
        C=plot3d(lambda r0,phi : IdiffCirc(r0,d,lo,f),(r0,xm/1000,xm),(phi,0,2*pi),transformation=trans,opacity=0.87)
51
        show(C, aspect_ratio=(1,1,2))

Messages


Diffraction par une pupille rectangulaire

xxxxxxxxxx
 
1
courbes = ['Figure de diffraction', 'Intensité', 'Courbe I(x)']
2
@interact(layout=[['trace'],['a','b'],['lo'],['xm', 'ym', 'Im', 'auto']])
3
def _(trace = selector(courbes,label="Tracé"), 
4
    a=slider(10,300,10,50,label="Largeur a (µm)"), b=slider(10,300,10,0,label="Hauteur b (µm)"),
5
    lo=slider(400,800,10,550,label="Longueur d'onde (nm)"),
6
    xm = input_box(np.round(1,1),label="xmax", type=str), ym = input_box(np.round(1,1),label="ymax", type=str),
7
    Im = input_box(np.round(0.02,3),label="Imax", type=str), auto = checkbox(True,label="Echelle auto"),
8
    mesures = checkbox(False,label="Mesures")): #auto_update=false
9
    plt.close('all') ; plt.clf()
10
​
11
    a = int(a) ; b =int(b) ; lo = int(lo) ; xm = float(xm) ; ym = float(ym) ; Im = float(Im)
12
    f = 1                                   # Focale projection en m
13
    if auto:
14
        xm = 6*np.round(lo*f/a/10,1)    # Demi largeur écran en cm
15
        ym = 6*np.round(lo*f/b/10,1)
16
​
17
    p = xm/200                              # Pas en cm
18
    x0 = np.arange(-xm,xm+p,p) ; y0 = np.arange(-ym,ym+p,p) ; x, y = np.meshgrid(x0,y0)
19
    Idiff = IdiffRect(x,y,a,b,lo,f)
20
    
21
    if trace in ['Figure de diffraction', 'Intensité']:
22
        Idiffmask = ma.masked_greater_equal(Idiff, Im) ; Idiffmask=Idiffmask.filled(Im)/Im
23
        rgb = nm2rgb(lo,0.8)
24
        l,h = Idiffmask.shape
25
        z = np.zeros((l,h,3))
26
        for i in range(h):
27
            for j in range(l):
28
                z[j,i] = Idiffmask[j,i] * rgb
29
        z = ma.asarray(z,dtype='uint8')
30
    
31
    fig,(ax) = plt.subplots(1,1)
32
    if trace in['Figure de diffraction','Intensité']:
33
        if mesures: 
34
            ax.grid()
35
            nx = 2*xm/p ; ny = 2*ym/p ; nticks = 10
36
            xticks = np.linspace(0,nx,nticks+1) ; yticks = np.linspace(0,ny,nticks+1)
37
            xticklabels = ["{:.1f}".format(i*xm*2) for i in range(-nticks//2,nticks//2+1)]
38
            yticklabels = ["{:.1f}".format(i*ym*2) for i in range(-nticks//2,nticks//2+1)]
39
            ax.set_xticks(xticks) ; ax.set_yticks(yticks)
40
            ax.set_xticklabels(xticklabels) ; ax.set_yticklabels(yticklabels)
41
            ax.set_xlabel('x en mm') ; ax.set_ylabel('y en mm')
42
        else:
43
            ax.axis('off')
44
        ax.imshow(z,aspect='equal',origin='lower')
45
    elif trace == 'Courbe I(x)':
46
        Idiff0 = IdiffRect(x0,0,a,b,lo,f)
47
        Idiff0 = ma.masked_greater(Idiff0, Im)
48
        ax.plot(x0,Idiff0,color='red')
49
    plt.show()
50
    if trace == 'Intensité':
51
        X, Y, z0 = var('X Y z0')
52
        C=plot3d(lambda X,Y : IdiffRect(X,Y,a,b,lo,f),(X,-xm,xm),(Y,-ym,ym),opacity=0.87)
53
        show(C, aspect_ratio=(1,1,2))

Messages


xxxxxxxxxx
 
1
​

Messages