Giter VIP home page Giter VIP logo

lightpipes's Introduction

LightPipes

Simulations of optical phenomena where diffraction is essential

LightPipes is a set of functions written in Python (Before version 2.0.0 these functions are in C++). It is designed to model coherent optical devices when the diffraction is essential. We put the C++ based version of LightPipes in another repository: opticspy/clightpipes. The pure Python version is as fast as the C++ version due to the use of the numpy, scipy and pyFFTW packages.

The toolbox consists of a number of functions. Each function represents an optical element or a step in the light propagation. There are apertures, intensity filters, beam-splitters, lenses and models of free space diffraction. There are also more advanced tools for manipulating the phase and amplitude of the light. The program operates on a large data structure, containing square two-dimensional arrays of complex amplitudes of the optical field of the propagating light beam.

The LightPipes routines are modifications of the LightPipes C routines written by Gleb Vdovin for Unix, Linux, DOS and OS2 workstations.

Visit the website of Flexible Optical: http://www.okotech.com, where you can find the source code of LightPipes and a manual.

Credits.

Gleb Vdovin

LightPipes was written by Gleb Vdovin in 1993 for MS DOS. the output of a command was the input for the next command. Gleb used the "pipe" feature of MS DOS, that's why it is called LightPipes. The source code of LightPipes for UNIX can be obtained for free from http://www.okotech.com.

Fred van Goor

Fred rewrote the commands for using them in Mathcad and Matlab in 1996. Later he made a version for Python (2017). The Mathcad and Matlab versions (not free) can be obtained from Flexible Optical. The Python version can be obtained for free from https://github.com/opticspy/lightpipes. Fred also developed the LightPipes for Python website using Sphinx. Fred used LightPipes for his course "Introduction to Optics" at the University of Twente as an introduction to the optics lab. See how Fred is blowing out a HeNe laser during this lesson. (The laser stops because the outcoupling mirror was covered with vapor from Fred's breath)

Guyskk

Guyskk' s contribution to the development of the LightPipes C++ package was very important. His knowledge of Python helped a lot to get the package operative for the windows, macintosh and several linux platforms.

Leonard Doyle

Leonard translated the C++ code of LightPipes into pure Python, using the numpy, scipy and pyFFTW packages. Thanks to the matrix routines of numpy and the fast pyFFTW Fourier transform the speed of the pure python version is as fast as the C++ version. Also parallel processing is possible now, which enhances the speed even more. From LightPipes version 2.0.0 LightpIpes is pure python. As usual, it can be installed with pip:

pip install LightPipes

The older C++ versions are still on PyPi and can be installed by typing (for the latest C++ version, 1.2.0):

pip install LightPipes==1.2.0

Install

The pure Python version of LightPipes (from version 2.0.0) can be installed on any platform with Python version 3.+ installed. We tested it on a number of computers: Windows, Macintosh and Linux.

The packages are on PyPi, so simply open a terminal window and type at the prompt:

pip install LightPipes

The C++ versions are still on PyPi and can be installed using:

pip install LightPipes==1.2.0

for the latest C++ version.

Use pip3 to install for Python 3.7. You can also download packages from Releases.

Raspberry Pi:

We encountered problems when installing it on a Raspberry Pi 4.0. It seems that pyFFTW package is not compatible with the Raspberry (ARM processor). Maybe they will solve that in the future. In the mean time you can follow the instructions in the install section of our documentation to install pyFFTW on a Raspberry PI, or install the latest C++ version, 1.2.0, of LightPipes when Python 3.7 is installed on your Raspberry Pi. Type at a terminal prompt:

sudo pip3 install LightPipes==1.2.0

Document

https://opticspy.github.io/lightpipes/

Example: Young interferometer

A plane wave is diffracted by two small holes, separated a distance, d. So two more or less spherical waves will propagate from these holes.

The resulting interference pattern on a screen at distance z looks like:

The Python program Young.py described in detail.

The first step in Python is to import the LightPipes library:

from LightPipes import *

Besides the LightPipes library, we import units and a few more in this way.

If the LightPipes library is successful installed on your computer Python can proceed with the next step. You probably want to plot the results, so import matplotlib:

import matplotlib.pyplot as plt

Next we define some variables: a wavelength of 20 micrometer , a 30 x 30 mm2 square grid with 500 x 500 pixels.

wavelength = 20*um
size = 30.0*mm
N = 500

Now we are ready to start the simulation. The Begin command generates a field with amplitude 1.0 and phase zero, a plane wave. So, all the 500 x 500 elements of array, F, contain the complex number: 1.0 + j0.0. The next commands generate two waves, F1 and F2, which are apertured by the two circular apertures and combined (simply added) by the BeamMix command. The combined wavefront is propagated a distance z=30 cm by the Fresnel command. After that the intensity is caculated and normalized to 255 (2 -> 255, 1 -> 1.0, 0 -> not normalized) by the Intensity command.

F = Begin(size,wavelength,N)
F1 = CircAperture(0.15*mm, -0.6*mm,0, F)
F2 = CircAperture(0.15*mm, 0.6*mm,0, F)    
F = BeamMix(F1,F2)
F = Fresnel(10*cm,F)
I = Intensity(2,F)

The result is plotted using the fantastic matplot routines. We are not interested in axis around the pattern and we like to write a title above the plot.

plt.imshow(I, cmap='rainbow');
plt.axis('off');
plt.title('intensity pattern')
plt.show()

lightpipes's People

Contributors

fredvangoor avatar guyskk avatar jmmelko avatar ldoyle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lightpipes's Issues

How to get interferogram from michelson interferometer instead of fringe pattern

Hi, i am curious to study and look into interferogram pattern, rather than looking at spherical fringe pattern in Michelson interferometer. can anyone please help me with this?

I tried tapping the intensity at middle value of my N*N fringe pattern, but getting weird pattern of interferogram. when a single wavelength goes under a interference it should loom like a cos or sine wave, but i am not able to get that
am i missing something?

build linux wheels

I had build LightPipes-1.1.0-cp36-cp36m-linux_x86_64.whl successfully.
Take notes:

  1. install cython and numpy: pip install cython numpy
  2. install libfftw3, the package name in different os can be found in http://rosindex.github.io/d/libfftw3/
  3. run python setup.py bdist_wheel

Next step, I will try to build wheels using docker, it can create manylinux1 wheels.

Gaussian beam Propagation

Hello,

First thanks a lot for allowing people to use your code freely. I want to use it for some practicals for master students at my university.

I try to get familiar with the code and I performed a simple test: take a TEM00 gaussian beam and let is propagate freely. For each propagation step i fit the intensity profile and extract the beam waist. I then compare it to the analytical formula of the waist (w = w0sqrt(1+(lamdaz/(Pi*w0**2))**2) for this kind of beam with a given wavelength and initial waist (i.e. the 2 parameters given in the F = GaussBeam(R, F) line code).
The thing is that i get very different results from the analytical formula and the results provided by LightPipes. So i was wondering, maybe there is something obvious I missed? or when you defined a Gaussian beam with the command GaussBeam, at what point this is supposed to correponds? i guess the waist, (when the beam is equivalent to a plane wave?)

I thank you by advance for your reply and help
best regards,
jerome

installation problems

It was noticed that the package pyFFTW is not always available for some platforms or (not yet) available for recent Python versions. (this is the case for Python 3.9 at the moment of writing this issue).
Fortunately LightPipes can also use the FFT features of numpy, so we decided to make pyFFTW optional when pip-installing LightPipes at the cost of slightly lower performance.

I have released a new version (2.0.7) of LightPipes which allows optional installation of pyFFTW. Without pyFFTW LightPipes will use the FFT routines in numpy, which are a little bit slower. Using LightPipes with not so large grids (1000 x 1000 or so) you will not notice that. If you want maximum performance you should install pyFFTW by your self or install LightPipes with the pyfftw option.

So:
Normal installation (so without pyFFTW) type at the terminal prompt:

pip install lightpipes

Later you can (try to) install pyFFTW and have maximum performance by:

pip install pyfftw

With the pyFFTW option (so install LightPipes and pyFFTW):

pip install lightpipes[pyfftw]

When you import LightPipes in your python script a warning is shown which advises you to install pyFFTW. You can suppress this (and other !) warnings by using the python -Wignore option:

python -Wignore YourLightPipesScript.py

When pyFFTW has been installed this warning is not shown.

location of conda

Does this the correct location in your system? @FredvanGoor

from getpass import getuser

CONDA_32 = r'C:\Users\{}\Miniconda32\Scripts\conda.exe'.format(getuser())
CONDA_64 = r'C:\Users\{}\Miniconda64\Scripts\conda.exe'.format(getuser())

I expect getuser() return Fred in your system and kk in my system, so we needn't modify it any more.

AttributeError 'float' object has no attribute 'T' (Beam propagation, Steps() function)

Context: I am trying to propagate the beam in free space without reflection coming back from the boundaries. Any waves/reaching the boundaries needs to be absorbed and not propagated any further or back into the system.

from LightPipes import *
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

GridSize = 2*mm
GridDimension = 512
lambda_ = 633*nm
Field = Begin(GridSize, lambda_, GridDimension)
Field = GaussBeam(Field, 100*um, LG=True, n=0, m=3, doughnut=True) 
Field = RectAperture(Field, 240*um, 240*um, angle=45.0)
F_Steps = Steps(Field, 8*m, nstep=0.01)
... and the code goes on ... 

At this point, I begin to have what seems to be like a variable type error. Could you please assist? I was unable to find the right syntax, if this is wrong, in the pages of the package.

Thank you in advance,
Akhil

Required packages for installing LightPipes for Python in ubuntu 16.04 LTS

Hi Guyskk,

I have installed a fresh ubuntu 16.04 LTS on my Monster-PC and installed all the packages that are required for executing LightPipes for Python scripts. For Python 2.7 as well as for Python 3.5.

In "required packages for LightPipes.txt" you find a list of all the packages. In "install-log.txt" are all the commands to install them and the responses of the installers.

Is it a good idea to make a script to do this automatically?

After installation I tried all the python scripts in the Examples directory. I had to do some minor changes. After that everything worked fine.

Fred.

required packages for LightPipes.txt
install-log.txt

attenuating lp modes in a step-index fiber

I am trying to propagate lp modes down a cylindrical step-index fiber using this package. Strangely enough, I am finding that the lp modes are attenuating as they go along the fiber, which of course should not be the case. Even stranger, if I divide the free-space wavelength by two, lightpipes seems to recover the expected result of no attenuation. I've attached a python notebook illustrating this behavior.

lpmode_prop.zip

Support for astigmatic beams

As explained in A. Siegman, Lasers, the Hermite-Gaussian modes can be straightforwardly generalized to astigmatic beams:
umn(x,y,z) = um(x,z) * un(y,z)

That would be cool if LightPipes could provide native support for that, at least in the GaussBeam class, with wx, wy as input parameters.

Add Interpol option in Fresnel and Forvard

Hi guys,

I suggest adding newsize and Nnew as optional parameters to the Fresnel and Forvard methods.
They would by used to call Interpol within the function.

This would make the three main integration methods homogeneous in terms of arguments.

I have implemented this in my own code, to be able to switch between methods, by changing the values of a Methods dictionary/list defined at the beginning of my script. Indeed, it is often the case that we have to change the method depending on the conditions (focusing or not, long or short propagation distance, etc.)

besides, this would not be shocking as other LightPipes function already integrate coordinate changes, LendForvard for instance that uses spherical coordinates.

Inconsistent definitions of waist w and xshift

I love Lightpipes but there are still a few inconsistencies in parameters definitions, some of them going beyond mere cosmetical problems.

  • GaussBeam requires w0, the beam radius, while for PlaneWave w is the wave diameter. I understand the absence of subscript 0, but w should always be the radius, not the diameter.
  • GaussBeam accepts xshift, yshift, while its documentation states it accepts x_shift. x_shift (with underscore) seems to be the definition used in other functions. Assigning a value to x_shift with GaussBeam throws the error GaussBeam() got an unexpected keyword argument 'x_shift'

Besides, I may we wrong, but to be more Pythonic I would suggest to override the len() function for Field objects so that len() returns .siz

switching the order of RectAperture and lens produces different results?

Hi all,

I have a simple system with only a lens and a rectangular aperture. I notice that when switching the order of them, I get different phase results. For example:

I suppose for the two scenarios the results should be same. But it seems that when the lens is behind the aperture the phase is not cut-off?

from LightPipes import *
import matplotlib.pyplot as plt

size=40mm
wavelength=1
um
N=256
w=20mm
f=8
m
z=4*m

### lens first then aperture
Field = Begin(size, wavelength, N)
Field = Lens(f,0,0,Field)
Field = RectAperture(w, w, 0, 0, 0, Field)

and

### aperture first then lens
Field = Begin(size, wavelength, N)
Field = RectAperture(w, w, 0, 0, 0, Field)
Field = Lens(f,0,0,Field)

2
1

HTML creation, Examples

To create html documentation I installed and used Sphinx and made a new branch to edit and create examples and to put them on the html site.

  1. install Sphinx from www.sphinx-doc.org
  2. cd /docs
  3. make html
  4. the html documents are in _build/html

I modified conf.py:

  1. Added an absolute path, '../lightpipes' to the python path. Now after 'python setup.py build_ext --inplace' modifications in lightpipes.pyx, etc are transfered to the html site automatically (For that fftw3-3.dll must be in lightpipes as well (windows))
  2. Added to extensions: 'sphinx.ext.mathjax' for LaTex and 'matplotlib.sphinxext.plot_directive' for generating plot-images from the example output automatically.
  3. I choose theme: 'classic' which allows the 'stickysidebar' option.

You can see the site as it is now on http://pythonhosted.org/LightPipes

I will add more examples from my (large) collection.

Remarks and suggestions are welcome!

Fred

No output in python on Windows

Hello,

I am running python in jupyter notebook using Anaconda in Windows 10. I installed LightPipes using pip from the Anaconda command window.

I can import LightPipes using: from LightPipes import *

When I run the code: LPtest()

I get no output. I have also run some example code from the website and I still get no output.

Any ideas? Thanks in advance.

Brad

Installation of LightPipes for Python on a Raspberry Pi

Cannot install LightPipes (version 2.0.0 and higher) on a Raspberry Pi vs 4.0 (Solved)

This is caused by the fact that the required pyFFTW package cannot be installed on a Raspberry Pi (ARM processor) Maybe this will be solved in the future.
In the mean time you can install pyFFTW on a Raspberry Pi as follows:

Step1, download FFTW:

Download from the FFTW Download page http://www.fftw.org/download.html the file fftw-3.3.8.tar.gz or newer. At a terminal prompt goto your Downloads directory and type:

cd ~/Downloads
tar xzf fftw-3.3.8.tar.gz

Step 2, install FFTW:

cd fftw-3.3.8
./configure --enable-threads --enable-shared
make
sudo make install

Step 3, install the cython compiler and ATLAS:

sudo pip3 install cython
sudo apt-get install libatlas-base-dev

If an error pops up that says something like: “E: Encountered a section with no package header” and/or: “E: The package lists or status file could not be parsed or opened”, try:

sudo rm -vf /var/lib/apt/lists/*
sudo apt-get update

Step 4, install LightPipes for Python:

sudo pip3 install lightpipes

The installation of LightPipes for Python described above has been tested on a Raspberry Pi 4 model B with 8Gbyte memory and with NOOBS 3.5.0 operating system.

It has also been tested with the recommended Raspberry Pi OS (32-bit) operating system installed using the Raspberry Pi Imager v1.4. See: Raspberry Pi OS (previously called Raspbian) https://www.raspberrypi.org/downloads/raspberry-pi-os/

About LPversion and LPhelp

from LightPipes import * isn't good practice in python, although it seems nicer in this project, I prefer
import LightPipes as lp because it follows the convention of most python libraries.

The biggest problem of import * is it will pollute global namespace, we can add __all__ to
__init__.py to avoid this(LPversion and LPhelp look ugly).

Do you prefer convenience or comprehensive?

extend with Numba?

First of all, thank you for providing this wonderful toolbox. I only recently started exploring it and I like it quite a bit!

I was wondering if there is any consideration to using Numba which uses LLVM for JIT compilation of the python code to machine code? Since Numba also supports JIT compilation of code to run on GPUs, significant speed-ups might be possible. For instance, I've noticed that the Steps function takes a really long time at the moment (Forward too, but not as much as Steps). Would love to hear the future roadmap of this project, and I look forward to being a regular user. Thanks again for providing this user-friendly toolbox in Python.

1D waveguide?

Dear Lightpipes author,
Can it be used in 1D waveguide? I see "only" steps command can be used in 3D waveguide.
Yousunny

Issue regarding loops

Hi

First of all thanks for publishing all this code! If you have the time, I would appreciate some help with my current problem

I would like to use light pipes to carry out a focus scan of a laser beam.

The approach I've been taking follows the example shown in manual section "5.7. Spherical coordinates" and adding different amounts of defocusing Zernike to scan across the focus. (Perhaps there is a better way)

However when I do this I see some strange behaviour (please see attached files)

FocusingScan 2.zip

In focussingScan.py you will find 3 functions

  1. makefield() produces a field and adds a Gaussian mode and some astigmatism

The 2nd and 3rd functions perform focal scans by calling Propagation() which is based on the example in manual section 5.7

  1. Focus_Scan() performs a focus scan calling makefield() on every loop
  2. broken_focus_scan() does the same thing, except for the fact that the field is only initialised at the beginning. When running this it generates and error message and different results to the first function
    error in LensFresnel: Behind focus

The function Propagation() is included in the second file.

While I'm happy to code around this, I'm completely lost in trying to identify the source of the problem

Offer: Port code to use numpy, one day pure Python

Hi Fred (and others),
I have been using LightPipes in Matlab and Python for a while now and it is a very useful package!
There are however a couple of limitations of the currently available Python package:

  • Not using numpy (actually dependency is not necessary at all right now)
  • Instead, data is list of lists ("unpythonic")
  • FFT using fftw lib, creating a DLL dependency (better to use numpy)
  • most importantly: global variables inside package (e.g. wavelength). It is therefore impossible to switch around fields without making sure everything is re-initialized correctly (e.g. going back and forth from nearfield to focus, size will be wrong on one of the fields)

I have refactored and ported parts of the code so far as follows:

  • a Field class contains the complex field as .field, but also .wavelength and .size -> no need for global variables in package, all functions are fully static
  • inside that class, the field is not stored as list of list, but as 2d numpy array (complex)
  • some basic functions like Begin, CircAperture, Zernike implemented in pure python
  • Fresnel implemented in pure python. In 1:1 implementation of loops a lot slower, now I have refactored all loops to use numpy vectorized functions instead and it is actually faster than Cpp version!

In the future, we would also like to add the following features:

  • an optional function parameter specifying whether to copy the Field or modify it in-place (slight memory/performance gain)
  • using non-square grid (as seems to be interesting for more people here in the Github issues)

Summarizing, these changes will break the public interface and therefore backward compatibility of the package, and introduce a dependency to numpy.
Would you be interested to incorporate the changes, anyway (and have the users update there code to fix compatibility), or should I create an own package name, eg. "PyLightPipes"?

Regards, Lenny

Warning when paraxiality is violated

I suggest to add a warning when the paraxial approximation is violated, especially when using the Lens function.
Or to add a special function to test it on demand.
I know this cannot replace common physical sense, but that could help.

I have read that it happens when :

z <~ m * (x^4/labda)^(1/3).

for a lens, z == f, and x could be half the grid siz.
As for m, we could use 1 as a first implementation. Indeed, we can safely assume that most people will use a grid “a few times” larger than the beam radius w. Let’s call this margin N. So, if the m=1 condition is violated at r=grid.siz, then the m=N violation will occur at r=grid.siz/m == w.

indexing into a field?

A is a list, F0 is a field, B is a list and N is an int. This piece of code worked with LightPipes 1.2.0 using Python 2.7, but is giving me TypeErrors in LightPipes 2.0.5 in Python 3.8.2. I'm not sure how to index into the field F0, and any help is appreciated.

for y in range(N):
for x in range(N):
A[y][x] = complex(F0[y][x].real * B[x][y] , F0[y][x].imag * B[x][y])

The aliasing problem occurs in synthetic digital hologram

Hi

Thanks for your great working in building this light field simulation library!

I am using this to synthesise some in-line holograms from the particle field based on the Fresnel Diffraction theory. While there are some nonphysical noise occurs (Probably come from the aliasing effect?) Is there any way to handle that?

And with the seem parameter setting , the resulted holograms look quite different from using Forvard() (Fig Set.1) and Fresnel()(Fig Set.2). Do you have some ideas about how to tackle this issue? It looks like the Fresnel()has more vertical and horizontal stripes contained.
Image1
Image2

Thanks

The code i used is

from LightPipes import *
wavelength = 633*nm
N = 1024
pixel_pitch = 10*um
size = pixel_pitch*N 
particle = 50*um/2

[x1,y1,z1] = [0,0,3*cm]
[x2,y2,z2] = [-3.0*mm,1.2*mm,3*cm]
[x3,y3,z3] = [0.5*mm,0.5*mm,1*cm]

f_factor1 = 2*particle**2/(wavelength*z1)
f_factor2 = 2*particle**2/(wavelength*z2)
f_factor3 = 2*particle**2/(wavelength*z3)

F = Begin(size,wavelength,N)
F_obj1 = CircScreen(F,particle,x1,y1)
F_obj2 = CircScreen(F,particle,x2,y2)
F_obj3 = CircScreen(F,particle,x3,y3)

#using forvard()
F_obj1 = Forvard(F_obj1,z1)
F_obj2 = Forvard(F_obj2,z2)
F_obj3 = Forvard(F_obj3,z3)

#uncomment to use Fresnel()
#F_obj1 = Fresnel(F_obj1,z1)
#F_obj2 = Fresnel(F_obj2,z2)
#F_obj3 = Fresnel(F_obj3,z3)
Mix = BeamMix(F_obj1,F_obj2)
Mix = BeamMix(Mix,F_obj3)

fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
ax1.imshow(Intensity(Mix,2), cmap='gray'); ax1.axis('off');ax1.set_title('Mix ')
ax2.imshow(Intensity(F_obj1,2), cmap='gray'); ax2.axis('off');ax2.set_title('First particle at z=%f'%z1)
ax3.imshow(Intensity(F_obj2,2), cmap='gray'); ax3.axis('off');ax3.set_title('Second particlez z=%f'%z2)
ax4.imshow(Intensity(F_obj3,2), cmap='gray'); ax4.axis('off');ax4.set_title('Third particle z=%f'%z3)
plt.show()
#fig.savefig("Hologram.png")

work flow

fork & PR is a efficient work flow to cooperation, let's try it:

  1. fork this repo by click Fork button at right top

  2. change remote origin to your own repo and remote upstream to this repo:

    git remote set-url origin YOUR_OWN_REPO_URL
    git remote add upstream [email protected]:opticspy/lightpipes.git
    
  3. run git remote -v, you will see something like this:

    origin	[email protected]:guyskk/lightpipes.git (fetch)
    origin	[email protected]:guyskk/lightpipes.git (push)
    upstream	[email protected]:opticspy/lightpipes.git (fetch)
    upstream	[email protected]:opticspy/lightpipes.git (push)
    
  4. to work on something new, create a descriptively named branch off of master,
    and commit/push to the new branch, when it ready for merging, open a pull request.

  5. to update local branch with upstream, see here: https://help.github.com/articles/syncing-a-fork/

see also: http://scottchacon.com/2011/08/31/github-flow.html

The diffraction results show unexpected

I simulated a tilted planewave, the results depended on the grid dimension. Here is the source:

import matplotlib.pyplot as plt
from LightPipes import *
f = Begin( 20*mm, 1*um, 1000 );  # grid size is 20*mm, grid dimension is N=1000, wavelength is 1um
#c = PlaneWave( f, 1*mm );
c = CircAperture( f, 0.5*mm );
c = Tilt( c, 25*mrad, 0*mrad );    # the planewave tilts 25mrad in x direction
#c = Fresnel( c, 100*mm );
c = Forvard( c, 100*mm );
I = Intensity( c );
plt.imshow(I);
plt.title( "size=20mm, lambda=1um, N=1000, tx=25mrad" );
plt.show()

In this way, the result shows the circle source splits into to circles:
1

However, if I change N from 1000 to 500, the result is totally different, as shown:
2

compare the two pictures, the first one (N=1000) is different from we have seen in experiment, the second one is still no unexpected, because the light is not tilted( if the direction of the light tilts, the position should change).

I programmed another program directly derived from numpy.fft , and got the same result. I don't know why this happens.

make wheel for mac

Hi,

I made a wheel for the mac successfully. However the fftw3 library is not installed by the wheel. I had to do: 'brew install fftw'.
After that everything worked as it should.

Can we put something in setup.py to install fftw3? Or test it in init.py by something like:

import os.path
if not os.path.isfile('/usr/local/lib/libfftw3.a'):
print('install fftw by typing in a terminal: $brew install fftw')

Or executing this command in init.py?

Or do something similar as with linux?

Reducing computations by considering only x-z plane

In most cases, it would suffice to only look at what happens in one spatial dimension (x) along the optical axis (z).

This would greatly speed up calculations and reduce the amount of memory used.

Is there a way to create such a 1d field and propagate it?

e.g.

x = np.linspace(-WORLD_SIZE/2, WORLD_SIZE/2, GRID_POINTS)
f = np.exp(-x**2)

f would be our gaussian field.. Currently we get f = np.exp(-y**2+x**2) as far as I can tell...

Unclear documentation of argument nsteps in Steps()

Hi there,

the command reference of Steps(z, nstep, refr, Fin) says

Propagates the field a distance, z, in nstep steps in a medium [...]

and to me that is a bit confusing. I would expect that the distance z is divided into n steps, but apparently the Field seems to be propagated n times the distance z through the medium.

Anyhow, thanks a lot for the development and the python port of lightpipes, it helps me a lot!

Best regards,
Max

Off-axis parabolic mirror

I am using LightPipes for THz optics design. Is there a way to use off-axis parabolic mirrors in LightPipes?

Best regards,
Prach

build windows wheels

I have successfully build wheels for windows. For that I had to copy (manually or by a bat file) the 32- or 64 bits version of "libfftw3-3.dll" to the ".\build\lib.win-amd64-x.x" directory after the "py -x.x setup.py build_ext" command. After the "py -x.x setup.py bdist_wheel" command the wheel was created correctly.

If I did not copy the dll only the LightPipes.pyd file was in the wheel. I tried to use "package_data" in setup.py to put the dll into the wheel but that did not work. I also tried another directory structure with the setup.py outsite the sources directory, without success.

Copying was the only way I succeeded to get the libfftw3-3.dll in the root of site-packages along with the LightPipes.pyd file. This is required for successfully import LightPipes in Python. (Otherwise you get a DLL not found error).

Please let me know if there is another, more elegant, method to get the dll alongside the pyd in site-packages.

NB: I have updated the files in the LightPipes-Packages directory only (not in lightpipes directory).
Fred.

Finite difference documentation typo?

I'm trying to understand finite different propagation and am looking at the documentation here:
https://opticspy.github.io/lightpipes/manual.html#free-space-propagation

I'm confused by a couple of things in equation 9.

  1. Shouldn't the numerator terms for the y**2 term be (k+1)? Not the 'k' index as shown?
  2. Why is there a 2 in the third term - term for dU/dz? Isn't finite difference for dU/dz = (U(k+1) - U(k))/dz. The equation shows it as (U(k+1) - 2*U(k))/dz
  3. I struggle to understand what A is in these equations. At first I thought it was index of refraction (e.g. ~= 1.0) However, it must be something different. Dimensionally, it must have units of 1/length**2.

Any chance there is a reference you could point towards for eqn. 8. Wikipedia is a good reference for Helmholtz equation in general, but I can't follow where the A*U term comes from.

Cannot install LightPipes on Windows 7 - please help

I cannot install LightPipes and don't know what to do. Could you help me out?

  • The system: Windows 7, Python 3.8.5, Microsoft Visual C++ 14.28
  • Installation: Command prompt with admin rights, doing "pip install LightPipes"
  • The error messages:
C:\Users\Sarah\Desktop>pip install LightPipes
Collecting LightPipes
  Using cached LightPipes-2.0.6-py3-none-any.whl (46 kB)
Collecting pyFFTW
  Using cached pyFFTW-0.12.0.tar.gz (137 kB)
Requirement already satisfied: numpy in c:\program files (x86)\python38-32\lib\s
ite-packages (from LightPipes) (1.19.5)
Requirement already satisfied: scipy in c:\Sarahs\Sarah\appdata\roaming\python
\python38\site-packages (from LightPipes) (1.5.2)
Building wheels for collected packages: pyFFTW
  Building wheel for pyFFTW (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys, s
etuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Sarah\\AppData\\Local\\Tem
p\\pip-install-i0045b4e\\pyfftw_07c43475b6dc49c982a683f21a11cad3\\setup.py'"'"';
 __file__='"'"'C:\\Users\\Sarah\\AppData\\Local\\Temp\\pip-install-i0045b4e\\
pyfftw_07c43475b6dc49c982a683f21a11cad3\\setup.py'"'"';f=getattr(tokenize, '"'"'
open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f
.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users
\Sarah\AppData\Local\Temp\pip-wheel-60x5ijtc'
       cwd: C:\Users\Sarah\AppData\Local\Temp\pip-install-i0045b4e\pyfftw_07c
43475b6dc49c982a683f21a11cad3\
  Complete output (25 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win32-3.8
  creating build\lib.win32-3.8\pyfftw
  copying pyfftw\config.py -> build\lib.win32-3.8\pyfftw
  copying pyfftw\_version.py -> build\lib.win32-3.8\pyfftw
  copying pyfftw\__init__.py -> build\lib.win32-3.8\pyfftw
  creating build\lib.win32-3.8\pyfftw\builders
  copying pyfftw\builders\builders.py -> build\lib.win32-3.8\pyfftw\builders
  copying pyfftw\builders\_utils.py -> build\lib.win32-3.8\pyfftw\builders
  copying pyfftw\builders\__init__.py -> build\lib.win32-3.8\pyfftw\builders
  creating build\lib.win32-3.8\pyfftw\interfaces
  copying pyfftw\interfaces\cache.py -> build\lib.win32-3.8\pyfftw\interfaces
  copying pyfftw\interfaces\dask_fft.py -> build\lib.win32-3.8\pyfftw\interfaces

  copying pyfftw\interfaces\numpy_fft.py -> build\lib.win32-3.8\pyfftw\interface
s
  copying pyfftw\interfaces\scipy_fft.py -> build\lib.win32-3.8\pyfftw\interface
s
  copying pyfftw\interfaces\scipy_fftpack.py -> build\lib.win32-3.8\pyfftw\inter
faces
  copying pyfftw\interfaces\_utils.py -> build\lib.win32-3.8\pyfftw\interfaces
  copying pyfftw\interfaces\__init__.py -> build\lib.win32-3.8\pyfftw\interfaces

  UPDATING build\lib.win32-3.8\pyfftw/_version.py
  set build\lib.win32-3.8\pyfftw/_version.py to '0.12.0'
  running build_ext
  error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsof
t C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  ----------------------------------------
  ERROR: Failed building wheel for pyFFTW
  Running setup.py clean for pyFFTW
Failed to build pyFFTW
Installing collected packages: pyFFTW, LightPipes
    Running setup.py install for pyFFTW ... error
    ERROR: Command errored out with exit status 1:
     command: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys,
 setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Sarah\\AppData\\Local\\T
emp\\pip-install-i0045b4e\\pyfftw_07c43475b6dc49c982a683f21a11cad3\\setup.py'"'"
'; __file__='"'"'C:\\Users\\Sarah\\AppData\\Local\\Temp\\pip-install-i0045b4e
\\pyfftw_07c43475b6dc49c982a683f21a11cad3\\setup.py'"'"';f=getattr(tokenize, '"'
"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"')
;f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\U
sers\Sarah\AppData\Local\Temp\pip-record-o0jev7b2\install-record.txt' --singl
e-version-externally-managed --compile --install-headers 'c:\program files (x86)
\python38-32\Include\pyFFTW'
         cwd: C:\Users\Sarah\AppData\Local\Temp\pip-install-i0045b4e\pyfftw_0
7c43475b6dc49c982a683f21a11cad3\
    Complete output (7 lines):
    running install
    running build
    running build_py
    UPDATING build\lib.win32-3.8\pyfftw/_version.py
    set build\lib.win32-3.8\pyfftw/_version.py to '0.12.0'
    running build_ext
    error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Micros
oft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/

    ----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\program files (x86)\python38-
32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\U
sers\\Sarah\\AppData\\Local\\Temp\\pip-install-i0045b4e\\pyfftw_07c43475b6dc4
9c982a683f21a11cad3\\setup.py'"'"'; __file__='"'"'C:\\Users\\Sarah\\AppData\\
Local\\Temp\\pip-install-i0045b4e\\pyfftw_07c43475b6dc49c982a683f21a11cad3\\setu
p.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().repl
ace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'ex
ec'"'"'))' install --record 'C:\Users\Sarah\AppData\Local\Temp\pip-record-o0j
ev7b2\install-record.txt' --single-version-externally-managed --compile --instal
l-headers 'c:\program files (x86)\python38-32\Include\pyFFTW' Check the logs for
 full command output.

Any idea what might be the problem?

Thanks a lot,
Sarah

How to achieve the Zernike polynomials combination with different j_terms?

I have a series of Zernike polynomials coefficients (j_terms form 1 ~36). However, I don't know how to achieve their combination by LightPipes.

Field2 = lp.Begin(10*lp.um,lamda,410)
for Noll in range(1, 36):
        (nz, mz) = lp.noll_to_zern(Noll)
        e_m = 2 if mz == 0 else 1
        A = 1
        #A = math.sqrt((2 * nz + 2) / e_m / math.pi)
        #print(e_m)
        Field2 = lp.Zernike(nz, mz, 10*lp.um, zernike_poly[Noll] * A, Field2)
phase2 = lp.PhaseUnwrap(phase2)

Screenshot 2020-11-27 at 18 11 33

I achieve it like this. But the phase is not as I imagined. It's very strange. Do you have any suggestions that how I can achieve this goal correctly?

(ldoyle edited code formatting)

Unexpected intensity distribution for Fresnel propagation

Hello!

This is more of a question about a result i got, rather than an issue i'm experiencing with LightPipes. If this is not the right place to ask this question please let me know!

I am simulating a 4f system and comparing the performance of the Angular Spectrum Method (ASM) and Fresnel propagation.
I have two figures, and in each of the figures in the first row the intensity distributions in three planes are shown; z=0, z=2f and z=4f. The second row show the intensity along the x-axis

My input plane is a unit amplitude plane plane wave masked by a circular aperture with radius r_beam = 3mm.
These are my input parameters:
N = 1000
size = 15 * mm
wave_length = 690 * nm
r_beam = 3 * mm
f1, f2 = 200 * mm, 200 * mm

This is the first figure, using Forvard

4f_ASM_intensity_Nis1000

And the second figure, using Fresnel
4f_fresnel_intensity_Nis1000

I know that the intensity distributions, in the planes z=0 and z=4f should look pretty much identical for both ASM and Fresnel propagation, but the intensity for Fresnel seems to diminish laterally at z = 800mm. Is this maybe because the conditions i'm in are not paraxial enough?

Thanks in advance!

-Philip

Sending a Gaussian beam with aberrations through Shack Hartmann

Hello,
I was wondering if there is a way to focus a Gaussian Beam with aberrations onto SH-WFS and finding the intensity distributions at the focus of the lenses? It seems at the current version of Lightpipes, set of individual fields are propagated through the lenses of the sensor and then Zernike functions are applied. That doesn't make any sense to me.
Thanks very much!

numpy version problems

Hi - tried installing LightPipes on Centos 7 with Anaconda Python. Error message upon import as follows:

Python 3.6.3 |Anaconda custom (64-bit)| (default, Oct 13 2017, 12:02:49)
Type "copyright", "credits" or "license" for more information.

IPython 6.1.0 -- An enhanced Interactive Python.

In [1]: import LightPipes
Traceback (most recent call last):

  File "<ipython-input-1-51e8ec217939>", line 1, in <module>
    import LightPipes

  File "/home/cad/anaconda/Anaconda3-5.0.1/lib/python3.6/site-packages/LightPipes/__init__.py", line 55, in <module>
    from ._LightPipes import * # noqa

  File "__init__.pxd", line 918, in init LightPipes._LightPipes

ValueError: numpy.ufunc size changed, may indicate binary incompatibility. Expected 216 from C header, got 192 from PyObject

In[2]: import numpy
In[3]: numpy.__version__
Out[3]: '1.15.4'

Any idea what's going wrong?

Thanks for any help...

Simon

Direct Integration (Fresnel) of Circ Aperture + Lens doesn't lead to (clean) Airy?

Hi!

I am trying to simulate a spatial filter with LightPipes with an input beam size of 10 mm and a pinhole size of around 10 μm, thus the only way to account for vastly different sampling demands seems to be direct integration of the fresnel integral.

I implemented this with LightPipes, however I was not able to produce a "clean" airy disc in the focal plane for the ideal situation of an monochromatic plane wave (const. Amplitude) over a circular aperture of 10 mm. The focal length of the lens is 150 mm, however the phase behind the lens seems to be sampled accuratly enough (see figures).

From the figures it seems to me as we are slightly "out of focus" in the focal plane. The script producing these results is attached. Is this an issue of implementation in LightPipes, an expected result or am I doing something wrong?

Also this is of course very heavy on computation. I was wondering if there is any way to "back-propagate" from the focal plane (after applying a pinhole filter) to a collimated beam using the Spherical Coordinates - Method (6.7 in the manual)?

Absolute field in focus:
image

1D central linecut in focus:
image

Unwrapped phase in focus (central linecut):
image

Unwrapped phase directly behind lens (central linecut):
image

Field behind Aperture:
image

Code:


from LightPipes import *

N = 1400
wvl = 532*nm
size = 10.5*mm
focal_length = 150*mm

r_aperture = 5e-3

size_fourierPlane = 50e-6
N_fourierPlane = 96

F_init = Begin(size, wvl, N)
F1 = CircAperture(F_init, r_aperture)
F2 = Lens(F1, focal_length)
F3 = Forward(F2, focal_length, size_fourierPlane, N_fourierPlane)

Propagation of Gaussian Beam through free space and through lens

Hey there,

  1. I'm trying to propagate a gaussian beam in free space using the code below.
    I've tried two method - once with Forvard/Fresnel and once with Steps. In both cases the gaussian beam expands, unlike in a laser system where the gaussian beam stays almost constant because of collimation and a really large Rayleigh length.
    I want to simulate the case with a really large gaussian beam, and I did not find in your code the full gaussian beam as in Saleh or other references:
    image
    Should I implement it by myself and put it in the field matrix?
    Or does the beam expansion is just a result of the FFT approach?

  2. I think the both methods does not agree completely. What are the reasons, and is there a guide line when to use each?
    for example, in steps we see multiple peaks at some large z:
    image

  3. When I propagate through lens with this methods, I'm afraid i'm not getting the right results as of the reason stated in 1.

Thanks in advance,
Ivan

The code:

from LightPipes import*
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

wavelength = 632.8*nm
size = 2*mm
N = 200
N2 = int(N/2)
R = 0.3*mm
dz = 10*mm
f = 15*cm
n = (1.0 + 0.1j)*np.ones((N,N))
Z_len = 200
Icross = np.zeros((Z_len,N))
X = range(N)
Z = range(Z_len)
X, Z = np.meshgrid(X, Z)

F = Begin(size, wavelength, N)
F = GaussBeam(R, F)

############### Forvad / Fresnel ################
I=Intensity(F, 0)
plt.figure()
plt.imshow(I)
plt.show()

#F=Lens(F,f)

zs = np.linspace(0, 30, 10)
for z in zs:
    F_propogated = Fresnel(F, z*cm)
    # F_propogated = Forvard(F, z*cm)
    I=Intensity(F_propogated, 0)
    plt.figure()
    plt.plot(Intensity(F_propogated, 0)[N2, :])
    # plt.imshow(I)
    plt.show()

############### Steps ################
for i in range(0, Z_len):
  F=Steps(F, dz, 1, n)
  I=Intensity(F, 0)
  Icross[i][:N] = I[N2][:N]
  # plt.figure();plt.plot(Icross[i][:N]);plt.show()


fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Z,
        Icross,
        rstride=1,
        cstride=1,
        cmap='rainbow',
        linewidth=0.0,
        )
plt.axis('off')
plt.show()

Quadratic field restriction

Hi there,

I changed a few functions to work with non-quadratic geometries (Steps, Forvard, Fresnel, Begin, Intensity) and was wondering why this restriction was there in the first place. So far I did not see any necessity for that.

Best regards,
Max

Installation of lightpipes package

Dear authors/contributors,

Thank you for developing this LightPipes package. I found it really useful when simulating diffraction optics.

I have a few questions regarding installing the Python version of the package:

1, I found that there are two branches: master and PyLightPipes. I guess the first one is written in C while the later one is in pure Python (please correct me if I am wrong). If I am right, is the pure Python version complete (i.e. is it ready to use or still need further development before I can use)?

  1. If the Python version is ready to use, how should I install it? Previously I have tried to use "pip install LightPipes" but it seemed only install the master branch? From https://pypi.org/project/LightPipes/ I found that the last release was Oct 2019, which is same as the last update of the master branch. So if I use pip install lightpipes I will then be installing the master branch, not the pure Python version?

Many thanks in advance for the clarification!

Does it work with phase-only hologram

Hi Fred (and others),

How can I use my own phase/amplitude pattern for calculating the Fresnel and Fraunhofer diffraction?

In my project I have a phase-only hologram (a 2D hologram with amplitude = 1 and phase distribution calculated from an iterative Fourier transform algorithm, called Gerchberg Saxton algorithm). The hologram can be expressed as H = 1 x exp{j*h(x,y)}, where h(x,y) represents the phase angle and is already known. The intensity of the Fourier transform of H is my target image.

Could you please suggest how I can use the known h(x,y) to reproduce the target image? How can I use h(x,y) as the "Field"?

Many thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.