Skip to content

Commit 69cf51d

Browse files
committed
implemented way to install using pip
1 parent 81934a2 commit 69cf51d

15 files changed

+314
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"cells": [],
3+
"metadata": {},
4+
"nbformat": 4,
5+
"nbformat_minor": 5
6+
}

.ipynb_checkpoints/untitled-checkpoint.py

Whitespace-only changes.

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ Numpy, Matplotlib, OpenCV, PIL, Skimage, Scipy
1313

1414
Images are usually treated as real (complex when working with optical fields) 2D numpy arrays (i.e., real matrices). In the same spirit, phase objects (lenses, scattering media) and filters are also built as matrices. No Pytorch implementation for now (I never really had the need to use Pytorch with most of these functions), but should be relatively easy to do (send a message if you are interested!).
1515

16+
## Install
17+
```
18+
conda create --name optsim python=3.9
19+
20+
conda activate optsim
21+
pip install -e .
22+
```
23+
1624
## Function descriptions:
1725
I divided the library into six main groups: Optical propagation, Quality of life (plotting & saving images, representing complex fields, doing simple manipulations of images such as ROI selection, etc.), general optics simulation tools (build apertures, phase distributions of lenses, common image filters, compare images and measure quality), light field / wavefront sensing, neuronal activity simulation, and miscellaneous.
1826
For a more detailed description of each function, read function_description.md and/or the comments on the code.

__init__.py

Whitespace-only changes.

__pycache__/optsim.cpython-39.pyc

55.3 KB
Binary file not shown.

code examples/generate_speckle.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Generating speckle patterns in different configurations.
4+
5+
All the methods are based on generating a phase mask that will act as a thin
6+
scattering layer (so, infinite memory effect). After that, we propagate the
7+
field a given distance to generate the speckle pattern. If you want to simulate
8+
near field / microscopy, you can use propagation methods such as Fresnel or
9+
the angular spectral method. If you do not care about distances/sizes, the
10+
simplest is to asume far field and just use a Fourier Transform.
11+
12+
@author: Fernando
13+
"""
14+
#%% Import stuff
15+
import numpy as np
16+
import optsim as ops
17+
18+
#%% Define physical parameters
19+
wvl = 532e-9 #wavelength
20+
aperture_size = 100e-6 #physical size of the aperture
21+
pxnum = 64 #number of pixels
22+
pxsize = aperture_size / pxnum #pixel size
23+
#%% Generate a thin scattering medium
24+
scat = ops.thin_scatter(size = aperture_size, pxnum = pxnum,
25+
corr_width = 4e-6, strength = 2)
26+
27+
#%% Mask it (place a circular pupil)
28+
29+
mask, _, _ = ops.circAp(totalSize = pxnum, radius = 0.85)
30+
31+
scat_layer = scat.thin_scat * mask
32+
#Show random phase mask (scattering medium)
33+
ops.show_field(scat_layer, mode = 'dark')
34+
35+
#%% Propagate a field through the scattering medium to generate speckle
36+
#Short distance propagation using the angular spectral method:
37+
prop_field = ops.rs_ang_spec_prop(Uin = scat_layer, wvl = wvl,
38+
delta = pxsize, z = 2e-3, padsize = 128)
39+
#Show field after propagation (speckle)
40+
ops.show_2img(np.abs(prop_field), np.angle(prop_field)) #show amplitud and phase
41+
ops.show_img(np.abs(prop_field)**2) #show intensity
42+
43+
#Far field propagation (Fourier transform):
44+
speckle = ops.ft2(np.pad(scat_layer, [128,128], mode = 'constant'), 1)
45+
ops.show_2img(np.abs(speckle), np.angle(speckle))#show amplitud and phase
46+
ops.show_img(np.abs(speckle)**2)#show intensity
47+
48+
#%% Generate speckle and see it evolving along z axis
49+
z_range = np.linspace(0, 1e-3, 100)#define propagation distances
50+
speckle_evolving = [] #initialize
51+
52+
#Calculate speckle patterns at different distances from the aperture
53+
for zidx in range(z_range.size):
54+
speckle_evolving.append(np.abs(ops.rs_ang_spec_prop(Uin = scat_layer, wvl = wvl,
55+
delta = pxsize, z = z_range[zidx], padsize = 128))**2)
56+
57+
#convert to numpy form, rearrange
58+
speckle_evolving = np.asarray(speckle_evolving)
59+
speckle_evolving = np.moveaxis(speckle_evolving,0,2)
60+
#show animation
61+
anim = ops.show_vid(speckle_evolving, rate = 100,
62+
fig_size = (5,3), loop = True)
63+
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Generating speckle patterns with (finite) lateral memory effect.
4+
From a point source, take a look at the speckle pattern at a given distance
5+
from the scattering layer when the source moves laterally.
6+
7+
Also implementation for ~infinite memory effect (illuminating the scattering
8+
layer with plane waves with different tilts). In this case you can see the
9+
'warping' arround the borders (cirular behaviour) clearly
10+
11+
@author: Fernando
12+
"""
13+
#%% Import stuff
14+
import numpy as np
15+
import optsim as ops
16+
17+
#%% Define physical parameters
18+
wvl = 532e-9 #wavelength
19+
aperture_size = 50e-6 #physical size of the aperture
20+
pxnum = 128 #number of pixels
21+
pxsize = aperture_size / pxnum #pixel size
22+
scat_sensor_distance = 300e-6 #distance between scattering layer and detector
23+
24+
#%% Generate source positions
25+
26+
xpos = np.squeeze(np.linspace(-20,20,20))*1e-6 #x positions
27+
ypos = np.array((0,)) #y position
28+
zpos = np.array((20e-6,)) #distance between source and scattering layer
29+
30+
# define total number of positions (object space)
31+
num_pos = xpos.size*ypos.size*zpos.size
32+
# Calculate array of 3D positions for the source
33+
source_pos = np.zeros((num_pos,3)) #preallocating
34+
if num_pos == 1:
35+
source_pos[0] = (xpos,ypos,zpos)
36+
else:
37+
temp = 0
38+
for xidx in range(xpos.size):
39+
for yidx in range(ypos.size):
40+
for zidx in range(zpos.size):
41+
source_pos[temp,:] = (xpos[xidx],ypos[yidx],zpos[zidx])
42+
temp += 1
43+
pass
44+
pass
45+
pass
46+
pass
47+
48+
#%% Generate fields from point sources, propagate to the scattering layer,
49+
#and to the sensor plane
50+
51+
#Generate sources
52+
print('generating sources...')
53+
source = []
54+
for idx in range(num_pos):
55+
source.append(ops.build_point(xpos = source_pos[idx,0],
56+
ypos = source_pos[idx,1],
57+
pxsize = pxnum,
58+
delta = pxsize))
59+
pass
60+
print('done')
61+
source = np.asarray(source)
62+
63+
#propagate to scattering layer
64+
print('propagating to scattering layer...')
65+
field_before = []
66+
for idx in range(num_pos):
67+
field_before.append(ops.rs_ang_spec_prop(Uin = source[idx,:,:], wvl = wvl,
68+
delta = pxsize, z = zpos[0], padsize = 128))
69+
pass
70+
print('done')
71+
field_before = np.asarray(field_before)
72+
73+
#Generate a thin scattering medium
74+
scat = ops.thin_scatter(size = field_before.shape[1]*pxsize, pxnum = field_before.shape[1],
75+
corr_width = 2*pxsize, strength = 2)
76+
77+
# Mask it (place a circular pupil)
78+
mask, _, _ = ops.circAp(totalSize = field_before.shape[1], radius = 0.85)
79+
scat_layer = scat.thin_scat * mask
80+
#Show random phase mask (scattering medium)
81+
ops.show_field(scat_layer, mode = 'dark')
82+
83+
#Calculate field after scattering layer
84+
field_after = field_before * scat_layer
85+
86+
#Propagate to sensor
87+
print('propagating to sensor plane...')
88+
field_sensor = []
89+
for idx in range(num_pos):
90+
field_sensor.append(ops.rs_ang_spec_prop(Uin = field_after[idx,:,:],
91+
wvl = wvl, delta = pxsize,
92+
z = scat_sensor_distance, padsize = 512))
93+
pass
94+
print('done')
95+
field_sensor = np.asarray(field_sensor)
96+
field_sensor = np.moveaxis(field_sensor,0,2)
97+
98+
#show results at thesensor plane
99+
anim1 = ops.show_vid(np.abs(field_sensor)**2,rate = 500, loop = True)
100+
101+
#%% Illuminate a scattering layer with plane waves with different tilts,
102+
#look at the far field speckles
103+
#Generate illuminations
104+
print('generating illumination plane waves...')
105+
illus = []
106+
for idx in range(num_pos):
107+
#define ramp orientation
108+
ramp_angle = np.deg2rad(0)
109+
#define ramp strength (how many 2pi jumps in total)
110+
ramp_strength = 0.5*idx
111+
#build ramp image
112+
x = np.linspace(-1, 1, pxnum) #axes
113+
x,y = np.meshgrid(x,-x) #axes
114+
ramp = x*np.cos(ramp_angle) + y*np.sin(ramp_angle) #ramp profile
115+
#build complex mask
116+
ramp_mask = np.exp(1j*2*np.pi*ramp*ramp_strength)
117+
illus.append(ramp_mask)
118+
print('done')
119+
illus = np.asarray(illus)
120+
121+
#Generate a thin scattering medium
122+
scat = ops.thin_scatter(size = pxnum*pxsize, pxnum = pxnum,
123+
corr_width = 2.5*pxsize, strength = 2)
124+
125+
# Mask it (place a circular pupil)
126+
mask, _, _ = ops.circAp(totalSize = pxnum, radius = 0.85)
127+
scat_layer = scat.thin_scat * mask
128+
#Show random phase mask (scattering medium)
129+
ops.show_field(scat_layer, mode = 'dark')
130+
131+
#Calculate field after scattering layer
132+
field_after_plane = illus * scat_layer
133+
134+
#Propagate to sensor
135+
print('propagating to sensor plane...')
136+
field_sensor_plane = []
137+
for idx in range(num_pos):
138+
field_sensor_plane.append(ops.rs_ang_spec_prop(Uin = field_after_plane[idx,:,:],
139+
wvl = wvl, delta = pxsize,
140+
z = 300e-6, padsize = 256))
141+
pass
142+
print('done')
143+
field_sensor_plane = np.asarray(field_sensor_plane)
144+
field_sensor_plane = np.moveaxis(field_sensor_plane,0,2)
145+
146+
#show results at thesensor plane
147+
anim2 = ops.show_vid(np.abs(field_sensor_plane)**2,rate = 500, loop = True)

optsim.egg-info/PKG-INFO

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Metadata-Version: 2.1
2+
Name: optsim
3+
Version: 0.0.1
4+
Summary: Tools for optical simulations
5+
Home-page: https://github.com/cbasedlf/optsim
6+
Author: F. Soldevila
7+
Author-email: [email protected]
8+
Classifier: Programming Language :: Python :: 3
9+
Classifier: Operating System :: OS Independent
10+
Requires-Python: >=3.9
11+
Description-Content-Type: text/markdown
12+
13+
# optsim: tools for optical simulations
14+
15+
This started as a small library of optical propagation functions during the first Covid confinement, as a way to learn using Python. It covered the basic stuff: Fresnel propagation, Fraunhoffer, angular spectrum method, etc. However, with time it started growing and I included more and more functions related to the work I was doing at that time in the lab.
16+
17+
I have been using this for a good couple of years and it has simplified doing simulations a lot. Now not only it allows to do propagations, but can also be used to simulate speckle patterns coming from a thin scattering medium, calculate wavefronts from images obtained with Shack-Hartman wavefront sensors (and decompose wavefronts in Zernike polynomials), simulate some very basic neuronal activities, do some transformations on light field images, simulate wavefronts arising from point sources, and also some quality of life functions to plot images and generating animations using matplotlib.
18+
19+
I always worked on Spyder due to its similarities with Matlab (that's the software I was using when I started doing optics), and you can even see that the way I coded stuff is super inspired by how the same ideas would have been implemented on Matlab. This will make it easy for some people walking the same path I did, but probably python enthusiasts will go crazy over the code. In my defense, I will say that some of these functions were my introduction to the language, and for sure nowadays I would implement them in different ways. Also, it works!
20+
21+
The library itself is relatively well commented, so anyone familiar with the physical phenomena in play should easily grasp what the code is doing. However, I will try to add a brief description of each function in this document. Also, I have added some small snippets of code with simple examples of the stuff you can do with these functions
22+
23+
It uses the following libraries:
24+
Numpy, Matplotlib, OpenCV, PIL, Skimage, Scipy
25+
26+
Images are usually treated as real (complex when working with optical fields) 2D numpy arrays (i.e., real matrices). In the same spirit, phase objects (lenses, scattering media) and filters are also built as matrices. No Pytorch implementation for now (I never really had the need to use Pytorch with most of these functions), but should be relatively easy to do (send a message if you are interested!).
27+
28+
## Install
29+
```
30+
conda create --name optsim python=3.9
31+
32+
conda activate optsim
33+
pip install -e .
34+
```
35+
36+
## Function descriptions:
37+
I divided the library into six main groups: Optical propagation, Quality of life (plotting & saving images, representing complex fields, doing simple manipulations of images such as ROI selection, etc.), general optics simulation tools (build apertures, phase distributions of lenses, common image filters, compare images and measure quality), light field / wavefront sensing, neuronal activity simulation, and miscellaneous.
38+
For a more detailed description of each function, read function_description.md and/or the comments on the code.
39+
40+
## Result examples:
41+
### Example#1: Random phase mask used to simulate a thin scattering material:
42+
![scattering_layer](https://user-images.githubusercontent.com/19323057/192787017-b31b0166-1f00-43bf-8e8b-f30189e0de98.png)
43+
### Example#2: Speckle pattern evolving along the optical axis (you can see caustics at close distance from the diffuser at the start of the animation, and the speckle evolving as propagation occurs). Propagation made with the angular spectrum method, example in generate_speckle.py:
44+
![speckle_evolution](https://user-images.githubusercontent.com/19323057/192783633-74506261-36b4-44ed-948d-72d7c3392964.gif)
45+
### Example#3: Speckle generation from a point source at different lateral positions (finite memory effect), example in generate_speckle.py:
46+
![finite_lateral](https://user-images.githubusercontent.com/19323057/193068815-6b32177d-d0df-4987-a0ba-c6f462279e6d.gif)
47+
### Example#4: Speckle generation from plane wave illumination of a scattering layer (infinite memory effect), example in generate_speckle.py
48+
![finite_lateral_tilt](https://user-images.githubusercontent.com/19323057/193068904-3212db15-11bb-4fd4-aadb-7b5a240a953d.gif)

optsim.egg-info/SOURCES.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
README.md
2+
setup.py
3+
optsim.egg-info/PKG-INFO
4+
optsim.egg-info/SOURCES.txt
5+
optsim.egg-info/dependency_links.txt
6+
optsim.egg-info/requires.txt
7+
optsim.egg-info/top_level.txt

optsim.egg-info/dependency_links.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

optsim.egg-info/requires.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
numpy
2+
matplotlib
3+
scikit-image
4+
pillow
5+
scipy

optsim.egg-info/top_level.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

setup.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import setuptools
2+
3+
with open("README.md", "r", encoding="utf-8") as fh:
4+
long_description = fh.read()
5+
6+
setuptools.setup(
7+
name="optsim",
8+
version="0.0.1",
9+
author="F. Soldevila",
10+
author_email="[email protected]",
11+
description="Tools for optical simulations",
12+
long_description=long_description,
13+
long_description_content_type="text/markdown",
14+
url="https://github.com/cbasedlf/optsim",
15+
packages=setuptools.find_packages(),
16+
classifiers=[
17+
"Programming Language :: Python :: 3",
18+
"Operating System :: OS Independent",
19+
],
20+
python_requires=">=3.9",
21+
install_requires=[
22+
"numpy",
23+
"matplotlib",
24+
"scikit-image",
25+
"pillow",
26+
"scipy",
27+
],
28+
)

0 commit comments

Comments
 (0)