Skip to content

Commit 10d234a

Browse files
authored
Merge pull request #72 from bleykauf/feature/fix-wavefront-simulation
Fix wavefront simulation
2 parents 4cbbb08 + 10cd82a commit 10d234a

File tree

12 files changed

+203
-349
lines changed

12 files changed

+203
-349
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,9 @@ dmypy.json
113113

114114
# Pyre type checker
115115
.pyre/
116+
117+
# OS specific files
118+
.DS_Store
119+
120+
# Visual Studio Code
121+
.vscode/

aisim/atoms.py

Lines changed: 9 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
import numpy as np
44
import scipy.linalg as splin
55

6-
from . import convert
7-
86

97
class AtomicEnsemble:
108
"""
119
Represents an atomic ensemble consisting of n atoms.
1210
1311
Each atom is is defined by its phase space vector (x0, y0, z0, vx, vy, vz) at time
1412
t=0. From this phase space vector the position at later times can be calculated.
15-
Optionally, weights can be added for each atom in the ensemble. Slicing along the
16-
axis of the n atoms is supported.
1713
1814
Parameters
1915
----------
@@ -30,8 +26,6 @@ class AtomicEnsemble:
3026
time : float, optional
3127
the initial time (default 0) when the phase space and state vectors are
3228
initialized
33-
weights : 1darray , optional
34-
Optional weights for each of the n atoms in the ensemble
3529
3630
Attributes
3731
----------
@@ -47,7 +41,7 @@ class AtomicEnsemble:
4741
4842
"""
4943

50-
def __init__(self, phase_space_vectors, state_kets=[1, 0], time=0, weights=None):
44+
def __init__(self, phase_space_vectors, state_kets=[1, 0], time=0):
5145
assert phase_space_vectors.shape[1] == 6
5246
self.phase_space_vectors = phase_space_vectors
5347
self.state_kets = state_kets
@@ -56,37 +50,28 @@ def __init__(self, phase_space_vectors, state_kets=[1, 0], time=0, weights=None)
5650
self.initial_position = self.phase_space_vectors[:, 0:3]
5751
self.initial_velocity = self.phase_space_vectors[:, 3:6]
5852

59-
if weights is None:
60-
weights = np.ones(len(self)) # unity weight for each atom
61-
else:
62-
assert len(weights) == self.phase_space_vectors.shape[0]
63-
self.weights = weights
64-
6553
def __getitem__(self, key):
6654
"""Select certain atoms "from the ensemble.
6755
68-
Parameters
56+
Parameters
6957
----------
70-
key : int or slice or bool map
71-
for example 2, 1:15 or a boolean map
58+
key : int or slice or bool map
59+
for example 2, 1:15 or a boolean map
7260
73-
Returns
74-
-------
75-
new_instance : AtomicEnsemble
76-
a new instance of the atomic ensemble only containing the selected atoms
61+
Returns
62+
-------
63+
new_instance : AtomicEnsemble
64+
a new instance of the atomic ensemble only containing the selected atoms
7765
"""
7866
phase_space_vectors = self.phase_space_vectors[key][:]
7967
state_kets = self.state_kets[key][:]
80-
weights = self.weights[key]
8168
if isinstance(key, int):
82-
# ratain correct shape in case of only one atom is selected
69+
# retain correct shape in case of only one atom is selected
8370
phase_space_vectors = phase_space_vectors.reshape(1, 6)
8471
state_kets = state_kets.reshape(1, len(state_kets))
85-
weights = weights.reshape(1, 1)
8672
new_instance = AtomicEnsemble(
8773
phase_space_vectors=phase_space_vectors,
8874
state_kets=state_kets,
89-
weights=weights,
9075
)
9176
return new_instance
9277

@@ -279,123 +264,6 @@ def create_random_ensemble_from_gaussian_distribution(
279264
return ensemble
280265

281266

282-
def create_ensemble_from_grids(pos_params, vel_params, **kwargs):
283-
"""
284-
Create an atomic ensemble from evenly spaced position and velocity grids.
285-
286-
The resulting position and velocity grids are evenly spaced on polar coordinates.
287-
288-
Parameters
289-
----------
290-
pos_params, vel_params : dict
291-
Dictionary containing the parameters determining the position and velocity
292-
distributions of the atomic ensemble. They each have to contain the arguments
293-
described in the docstring of `make_grid`, i.e. `std_rho`, `std_z` (required),
294-
`n_rho`, `n_theta`, `n_z`, `m_std_rho`, `m_std_z`, `weight`, optional.
295-
**kwargs :
296-
Optional keyworded arguments passed to `AtomicEnsemble`
297-
298-
Returns
299-
-------
300-
ensemble : AtomicEnsemble
301-
Atomic ensemble contains all possible combinations of the position and velocity
302-
grid as phase space vectors. They vectors are weighted according to the combined
303-
(multiplied) weights of the respective position and velocity distributions
304-
according to the `weight` arguments in `pos_params` and `vel_params`
305-
"""
306-
pos_grid, pos_weights = make_grid(**pos_params)
307-
vel_grid, vel_weights = make_grid(**vel_params)
308-
grid = combine_grids(pos_grid, vel_grid)
309-
weights = combine_weights(pos_weights, vel_weights)
310-
ensemble = AtomicEnsemble(grid, weights=weights, **kwargs)
311-
return ensemble
312-
313-
314-
def make_grid(std_rho, std_z, n_rho=20, n_theta=36, n_z=1, m_std_rho=3, m_std_z=0):
315-
"""
316-
Evenly spaced grid of positions (or velocities) and weights.
317-
318-
Each of these positions (or velocities) are evenly spaced in polar coordinates and
319-
weighted according to a gaussian distribution.
320-
321-
Parameters
322-
----------
323-
std_rho, std_sigma : float
324-
1/e radius of the position or velocity distribution.
325-
n_rho, n_theta, n_z : int
326-
number of grid points per standard deviation along rho and z direction and
327-
total number of points along theta, respectively
328-
m_std_rho, m_std_z : int
329-
number of standard deviations for the rho and z distribution
330-
331-
Returns
332-
-------
333-
grid : n × 3 array
334-
Grid of n vectors in carthesian coordinates (x, y, z). In polar coordinates,
335-
the grid has this form:
336-
[[dRho, 0, -m_std_z*sigma_z/2]
337-
[dRho, dTheta, ...]
338-
[dRho , 2*dTheta, ...]
339-
[... , ..., 0]
340-
[dRho , <2*pi, ...]
341-
[2*dRho , 0, ...]
342-
[2*dRho , dTheta, ...]
343-
[... , ..., ...
344-
[m_std_rho*sigma_rho , <2*pi, +m_std_z*sigma_z/2]]
345-
weights : 1 × n array
346-
weights for each vector in the grid
347-
"""
348-
rhos = np.linspace(0, m_std_rho * std_rho, n_rho)
349-
thetas = np.linspace(0, 2 * np.pi, n_theta)
350-
zs = np.linspace(-m_std_z * std_z / 2, m_std_z * std_z / 2, max(n_z * m_std_z, 1))
351-
grid = np.array(np.meshgrid(rhos, thetas, zs)).T.reshape(-1, 3)
352-
# get weights before converting to carthesian coordinates
353-
weights = np.exp(-grid[:, 0] ** 2 / (2 * std_rho**2))
354-
if std_z != 0:
355-
# check if distribution is 2d to avoid divide by 0
356-
weights = weights * np.exp(-grid[:, 2] ** 2 / (2 * std_z**2))
357-
grid = convert.pol2cart(grid)
358-
return grid, weights
359-
360-
361-
def combine_grids(pos, vel):
362-
"""
363-
Combine a position and velocity grid into an array of phase space vectors.
364-
365-
The resulting array contains (x, y, z, vx, vy, vz).
366-
367-
Parameters
368-
----------
369-
pos, vel : n, m × 3 array
370-
position and velocity grids as generated by `make_grid`
371-
372-
Returns
373-
-------
374-
phase_space_vectors : n * m × 1 array
375-
"""
376-
# FIXME: replace with faster version, for example based on meshgrid
377-
phase_space_vectors = np.array(
378-
[np.array((p, v)).flatten() for p in pos for v in vel]
379-
)
380-
return phase_space_vectors
381-
382-
383-
def combine_weights(pos_weights, vel_weights):
384-
"""
385-
Combine the weights of a position and velocity grid.
386-
387-
Complements `_combine_grids`.
388-
389-
Parameters
390-
----------
391-
pos_weights, vel_weights : n × 1 array
392-
weights of a position and velocity grids.
393-
394-
"""
395-
# FIXME: replace with faster version, for example based on meshgrid
396-
return np.array([p * v for p in pos_weights for v in vel_weights])
397-
398-
399267
def _fidelity(rho_a, rho_b):
400268
"""
401269
Calculate the fidelity of two density matrices [1, 2].

aisim/beam.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,8 @@ def zern_iso(cls, rho, theta, coeff, r_beam):
206206
value(s) of the wavefront at the probed position
207207
"""
208208
rho = rho / r_beam
209-
# Raise error if Zernike polynom is oustide its defined domain
210-
if (rho > 1).any():
211-
raise ValueError("rho must be smaller than r_beam")
209+
# Make sure rho outside of the beam are NaN
210+
rho[rho > 1] = np.nan
212211
# precalculating values
213212
# powers of rho
214213
rho2 = rho * rho

aisim/convert.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,25 @@ def pol2cart(pol):
107107
return np.array([x, y, z]).T
108108

109109

110-
def phase_to_grav(phase, T, keff):
110+
def phase_error_to_grav(phase, T, keff):
111111
"""
112-
Convert a phase shift to gravitational acceleration.
112+
Convert a phase error to gravitational acceleration.
113113
114114
Takes the phase shift measured in a Mach Zehnder atom interferometer and converts it
115-
to the corresponding gravtional accleration.
115+
to the corresponding gravitional accleration.
116116
117117
Parameters
118118
----------
119119
phase : float
120-
Interferometer phase
120+
Interferometer phase in rad
121121
T : float
122-
interferometer time
122+
interferometer time in s
123123
keff : float
124-
effective wavenumber
124+
effective wavenumber in rad/m
125125
126126
Returns
127127
-------
128128
float :
129-
gravitational acceleration in m/s²
129+
gravitational acceleration in in m/s^2
130130
"""
131131
return phase / keff / (T**2)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"r_det": [
3+
0.0025,
4+
0.0035,
5+
0.0045000000000000005,
6+
0.005200000000000001,
7+
0.0075,
8+
0.0085,
9+
0.009000000000000001
10+
],
11+
"g": [
12+
-1.23999996185303e-08,
13+
-2.17327995300293e-08,
14+
-2.58000011444092e-08,
15+
-2.2699998855590803e-08,
16+
-2.7300001144409198e-08,
17+
-2.15e-08,
18+
-1.0799999237060501e-08
19+
],
20+
"g_err": [
21+
2.45378168802769e-09,
22+
3.14034276863211e-09,
23+
3.03716097724503e-09,
24+
3.3045693730046e-09,
25+
2.37087489524437e-09,
26+
2.8473590300135997e-09,
27+
3.8914811781634e-09
28+
]
29+
}

docs/examples/data/wavefront.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-2.205930000000000071e-05
2+
3.566070000000000177e-03
3+
-1.605430000000000051e-02
4+
2.916109999999999969e-03
5+
1.391460000000000057e-05
6+
6.129479999999999651e-03
7+
1.222659999999999979e-03
8+
-1.321109999999999906e-03
9+
2.853050000000000204e-03
10+
3.322050000000000003e-03
11+
3.664390000000000008e-03
12+
5.373980000000000206e-04
13+
-1.275660000000000075e-03
14+
1.597099999999999952e-03
15+
-3.209529999999999935e-03
16+
-4.543130000000000258e-03
17+
1.459950000000000006e-03
18+
4.167510000000000138e-03
19+
8.295410000000000457e-04
20+
2.464650000000000087e-03
21+
1.427190000000000056e-03
22+
6.819219999999999535e-04
23+
-1.338409999999999947e-04
24+
-1.158900000000000034e-03
25+
1.877659999999999963e-03
26+
-6.762689999999999587e-04
27+
-3.815369999999999786e-03
28+
-2.821950000000000153e-03
29+
-1.971440000000000085e-03
30+
-2.706619999999999859e-03
31+
2.919940000000000209e-03
32+
9.795629999999999182e-04
33+
-2.293159999999999817e-03
34+
7.373220000000000533e-05
35+
-6.587929999999999654e-04
36+
1.349909999999999955e-04

docs/examples/data/wf_grav_data.csv

Lines changed: 0 additions & 8 deletions
This file was deleted.

docs/examples/data/wf_window.txt

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)