Skip to content

Commit 178463a

Browse files
Merge pull request #52 from matthewtownson/master
Updating turbulence documentation
2 parents d145594 + 96fa7d6 commit 178463a

File tree

8 files changed

+88
-68
lines changed

8 files changed

+88
-68
lines changed

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: python
22
sudo: true
3-
dist: xenial
3+
dist: bionic
44

55
branches:
66
only:
@@ -12,6 +12,7 @@ python:
1212
#- 3.5 Not in travis repositories
1313
- 3.6
1414
- 3.7
15+
- 3.8
1516

1617
addons:
1718
apt:

aotools/turbulence/atmos_conversions.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,17 @@ def r0_from_slopes(slopes, wavelength, subapDiam):
158158

159159

160160
def slope_variance_from_r0(r0, wavelength, subapDiam):
161-
"""Returns the expected slope variance for a given r0 ValueError
161+
"""
162+
Uses the equation in Saint Jaques, 1998, PhD Thesis, Appendix A to calculate the slope variance resulting from a
163+
value of r0.
164+
165+
Parameters:
166+
r0 (float): Fried papamerter of turubulence in metres
167+
wavelength (float): Wavelength of light in metres (where 1e-9 is 1nm)
168+
subapDiam (float): Diameter of the aperture in metres
162169
163-
Uses the equation in Saint Jaques, 1998, PhD Thesis, Appendix A to calculate the slope variance resulting from a value of r0.
170+
Returns:
171+
The expected slope variance for a given r0 ValueError
164172
165173
"""
166174

aotools/turbulence/infinitephasescreen.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515

1616
__all__ = ["PhaseScreenVonKarman", "PhaseScreenKolmogorov"]
1717

18+
1819
class PhaseScreen(object):
1920
"""
2021
A "Phase Screen" for use in AO simulation. Can be extruded infinitely.
2122
2223
This represents the phase addition light experiences when passing through atmospheric
2324
turbulence. Unlike other phase screen generation techniques that translate a large static
24-
screen, this method keeps a small section of phase, and extends it as neccessary for as many
25-
steps as required. This can significantly reduce memory consuption at the expense of more
25+
screen, this method keeps a small section of phase, and extends it as necessary for as many
26+
steps as required. This can significantly reduce memory consumption at the expense of more
2627
processing power required.
2728
2829
The technique is described in a paper by Assemat and Wilson, 2006 and expanded upon by Fried, 2008.
@@ -55,7 +56,7 @@ class PhaseScreen(object):
5556
L is a diagonal matrix where the diagonal elements are w^(1/2).
5657
5758
On initialisation an initial phase screen is calculated using an FFT based method.
58-
When 'addRows' is called, a new vector of phase is added to the phase screen.
59+
When 'add_row' is called, a new vector of phase is added to the phase screen.
5960
6061
Existing points to use are defined by a "stencil", than is set to 0 for points not to use
6162
and 1 for points to use. This makes this a generalised base class that can be used by
@@ -180,11 +181,7 @@ def get_new_row(self):
180181

181182
def add_row(self):
182183
"""
183-
Adds new rows to the phase screen and removes old ones.
184-
185-
Parameters:
186-
nRows (int): Number of rows to add
187-
axis (int): Axis to add new rows (can be 0 (default) or 1)
184+
Adds a new row to the phase screen and removes old ones.
188185
"""
189186

190187
new_row = self.get_new_row()
@@ -195,6 +192,9 @@ def add_row(self):
195192

196193
@property
197194
def scrn(self):
195+
"""
196+
The current phase map held in the PhaseScreen object.
197+
"""
198198
return self._scrn[:self.requested_nx_size, :self.requested_nx_size]
199199

200200

@@ -204,8 +204,8 @@ class PhaseScreenVonKarman(PhaseScreen):
204204
205205
This represents the phase addition light experiences when passing through atmospheric
206206
turbulence. Unlike other phase screen generation techniques that translate a large static
207-
screen, this method keeps a small section of phase, and extends it as neccessary for as many
208-
steps as required. This can significantly reduce memory consuption at the expense of more
207+
screen, this method keeps a small section of phase, and extends it as necessary for as many
208+
steps as required. This can significantly reduce memory consumption at the expense of more
209209
processing power required.
210210
211211
The technique is described in a paper by Assemat and Wilson, 2006. It essentially assumes that
@@ -237,9 +237,9 @@ class PhaseScreenVonKarman(PhaseScreen):
237237
L is a diagonal matrix where the diagonal elements are w^(1/2).
238238
239239
On initialisation an initial phase screen is calculated using an FFT based method.
240-
When 'addRows' is called, a new vector of phase is added to the phase screen using `nCols`
240+
When ``add_row`` is called, a new vector of phase is added to the phase screen using `nCols`
241241
columns of previous phase. Assemat & Wilson claim that two columns are adequate for good
242-
atmospheric statistics. The phase in the screen data is always accessed as `<phasescreen>.scrn`.
242+
atmospheric statistics. The phase in the screen data is always accessed as ``<phasescreen>.scrn``.
243243
244244
Parameters:
245245
nx_size (int): Size of phase screen (NxN)
@@ -346,7 +346,8 @@ class PhaseScreenKolmogorov(PhaseScreen):
346346
and applied on each iteration such that the new phase equation becomes:
347347
348348
On initialisation an initial phase screen is calculated using an FFT based method.
349-
When 'addRows' is called, a new vector of phase is added to the phase screen.
349+
When ``add_row`` is called, a new vector of phase is added to the phase screen. The phase in the screen data
350+
is always accessed as ``<phasescreen>.scrn``.
350351
351352
Parameters:
352353
nx_size (int): Size of phase screen (NxN)

aotools/turbulence/phasescreen.py

+34-35
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Finite Phase Screens
33
--------------------
44
5-
Creation of phase screens with Von Karmen Statistics.
5+
Creation of phase screens of a defined size with Von Karmen Statistics.
66
77
"""
88

@@ -18,7 +18,8 @@
1818
xrange = range
1919

2020
def ft_sh_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
21-
'''
21+
22+
"""
2223
Creates a random phase screen with Von Karmen statistics with added
2324
sub-harmonics to augment tip-tilt modes.
2425
(Schmidt 2010)
@@ -32,7 +33,7 @@ def ft_sh_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
3233
3334
Returns:
3435
ndarray: numpy array representing phase screen
35-
'''
36+
"""
3637
R = random.SystemRandom(time.time())
3738
if seed is None:
3839
seed = int(R.random()*100000)
@@ -60,7 +61,7 @@ def ft_sh_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
6061
f = numpy.sqrt(fx**2 + fy**2) # polar grid
6162

6263
fm = 5.92/l0/(2*numpy.pi) # inner scale frequency [1/m]
63-
f0 = 1./L0;
64+
f0 = 1./L0
6465

6566
# outer scale frequency [1/m]
6667
# modified von Karman atmospheric phase PSD
@@ -89,28 +90,8 @@ def ft_sh_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
8990
return phs
9091

9192

92-
def ift2(G, delta_f ,FFT=None):
93-
"""
94-
Wrapper for inverse fourier transform
95-
96-
Parameters:
97-
G: data to transform
98-
delta_f: pixel seperation
99-
FFT (FFT object, optional): An accelerated FFT object
100-
"""
101-
102-
N = G.shape[0]
103-
104-
if FFT:
105-
g = numpy.fft.fftshift( FFT( numpy.fft.fftshift(G) ) ) * (N * delta_f)**2
106-
else:
107-
g = fft.ifftshift( fft.ifft2( fft.fftshift(G) ) ) * (N * delta_f)**2
108-
109-
return g
110-
111-
11293
def ft_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
113-
'''
94+
"""
11495
Creates a random phase screen with Von Karmen statistics.
11596
(Schmidt 2010)
11697
@@ -123,7 +104,7 @@ def ft_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
123104
124105
Returns:
125106
ndarray: numpy array representing phase screen
126-
'''
107+
"""
127108
delta = float(delta)
128109
r0 = float(r0)
129110
L0 = float(L0)
@@ -136,22 +117,40 @@ def ft_phase_screen(r0, N, delta, L0, l0, FFT=None, seed=None):
136117

137118
del_f = 1./(N*delta)
138119

139-
fx = numpy.arange(-N/2.,N/2.) * del_f
120+
fx = numpy.arange(-N/2., N/2.) * del_f
140121

141-
(fx,fy) = numpy.meshgrid(fx,fx)
142-
f = numpy.sqrt(fx**2 + fy**2)
122+
(fx, fy) = numpy.meshgrid(fx,fx)
123+
f = numpy.sqrt(fx**2. + fy**2.)
143124

144125
fm = 5.92/l0/(2*numpy.pi)
145126
f0 = 1./L0
146127

147-
PSD_phi = (0.023*r0**(-5./3.) * numpy.exp(-1*((f/fm)**2)) /
148-
( ( (f**2) + (f0**2) )**(11./6) ) )
128+
PSD_phi = (0.023*r0**(-5./3.) * numpy.exp(-1*((f/fm)**2)) / (((f**2) + (f0**2))**(11./6)))
149129

150130
PSD_phi[int(N/2), int(N/2)] = 0
151131

152-
cn = ( (numpy.random.normal(size=(N,N)) + 1j* numpy.random.normal(size=(N,N)) )
153-
* numpy.sqrt(PSD_phi)*del_f )
132+
cn = ((numpy.random.normal(size=(N, N))+1j * numpy.random.normal(size=(N, N))) * numpy.sqrt(PSD_phi)*del_f)
133+
134+
phs = ift2(cn, 1, FFT).real
135+
136+
return phs
137+
154138

155-
phs = ift2(cn,1, FFT).real
139+
def ift2(G, delta_f, FFT=None):
140+
"""
141+
Wrapper for inverse fourier transform
156142
157-
return phs
143+
Parameters:
144+
G: data to transform
145+
delta_f: pixel seperation
146+
FFT (FFT object, optional): An accelerated FFT object
147+
"""
148+
149+
N = G.shape[0]
150+
151+
if FFT:
152+
g = numpy.fft.fftshift(FFT(numpy.fft.fftshift(G))) * (N * delta_f) ** 2
153+
else:
154+
g = fft.ifftshift(fft.ifft2(fft.fftshift(G))) * (N * delta_f) ** 2
155+
156+
return g

aotools/turbulence/slopecovariance.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
WFS measurements in a required direction (where there might be an interesting science target but no guide stars),
88
given some actual measurements in other directions (where the some suitable guide stars are).
99
10-
.. note::
10+
.. warning::
1111
This code has been tested qualitatively and seems OK, but needs more rigorous testing.
1212
1313
.. codeauthor::

doc/source/index.rst

+21-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,28 @@
33
You can adapt this file completely to your liking, but it should at least
44
contain the root `toctree` directive.
55
6-
Welcome to AOTools's documentation!
7-
===================================
6+
Welcome to the AOtools Documentation!
7+
=====================================
88

9-
Contents:
9+
Introduction
10+
++++++++++++
11+
AOtools is an attempt to gather together many common tools, equations and functions for Adaptive Optics.
12+
The idea is to provide an alternative to the current model, where a new AO researcher must write their own library
13+
of tools, many of which implement theory and ideas that have been in existance for over 20 years. AOtools will hopefully
14+
provide a common place to put these tools, which through use and bug fixes, should become reliable and well documented.
15+
16+
Installation
17+
------------
18+
AOtools uses mainly standard library functions, and all attempts have been made to avoid adding unneccessary dependencies.
19+
Currently, the library requires only
20+
21+
- numpy
22+
- scipy
23+
- astropy
24+
- matplotlib
25+
26+
Contents
27+
++++++++
1028

1129
.. toctree::
1230
:maxdepth: 2

doc/source/turbulence.rst

+5-13
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
11
Atmospheric Turbulence
22
======================
33

4-
.. automodule:: aotools.turbulence
5-
:members:
6-
:undoc-members:
7-
:imported-members:
8-
:exclude-members: CovarianceMatrix, PhaseScreenKolmogorov, PhaseScreenVonKarman, calc_slope_temporalps,
9-
calculate_structure_function, calculate_wfs_seperations, circle, cn2_to_r0, cn2_to_seeing,
10-
coherenceTime, compute_covariance_xx, compute_covariance_xy, compute_covariance_yy,
11-
create_tomographic_covariance_reconstructor, fft, fit_tps, ft_phase_screen, ft_sh_phase_screen,
12-
get_tps_time_axis, ift2, isoplanaticAngle, mirror_covariance_matrix, numpy, optimize,
13-
plot_tps, pyplot, r0_from_slopes, r0_to_cn2, r0_to_seeing, scipy, seeing_to_cn2, seeing_to_r0,
14-
slope_variance_from_r0, structure_function_kolmogorov, structure_function_vk, wfs_covariance,
15-
wfs_covariance_mpwrap, xrange
16-
174
.. automodule:: aotools.turbulence.phasescreen
185
:members:
196
:undoc-members:
7+
:exclude-members: ift2
208
:show-inheritance:
219

2210
.. automodule:: aotools.turbulence.infinitephasescreen
2311
:members:
12+
:inherited-members:
2413
:undoc-members:
14+
:exclude-members: calc_seperations, set_stencil_coords, calc_seperations, makeAMatrix, makeBMatrix, set_X_coords,
15+
make_initial_screen, make_covmats, get_new_row
2516
:show-inheritance:
2617

2718
.. automodule:: aotools.turbulence.slopecovariance
2819
:members:
2920
:undoc-members:
21+
:exclude-members: compute_covariance_xx, compute_covariance_xy, compute_covariance_yy
3022
:show-inheritance:
3123

3224
.. automodule:: aotools.turbulence.temporal_ps

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
install_requires=[
2424
'numpy',
2525
'scipy',
26+
'matplotlib'
2627
],
2728
classifiers=[
2829
"Programming Language :: Python",

0 commit comments

Comments
 (0)