Skip to content

Commit

Permalink
Merge pull request #67 from ChristopherMayes/add_plot_ellipse
Browse files Browse the repository at this point in the history
Add ellipse to ParticleGroup.plot
  • Loading branch information
ChristopherMayes authored Oct 2, 2024
2 parents 6e01a1e + 9d2d273 commit 4733949
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 101 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ jobs:
python-version: [3.9]
steps:
- uses: actions/checkout@v3
- uses: conda-incubator/setup-miniconda@v2
- uses: conda-incubator/setup-miniconda@v3
with:
python-version: ${{ matrix.python-version }}
mamba-version: "*"
miniforge-version: latest
use-mamba: true
channels: conda-forge
activate-environment: pmd_beamphysics-dev
environment-file: environment.yml
Expand Down
170 changes: 106 additions & 64 deletions docs/examples/normalized_coordinates.ipynb

Large diffs are not rendered by default.

45 changes: 22 additions & 23 deletions docs/examples/particle_examples.ipynb

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions docs/examples/plot_examples.ipynb

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions pmd_beamphysics/particles.py
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,7 @@ def plot(self, key1='x', key2=None,
ylim=None,
return_figure=False,
tex=True, nice=True,
ellipse=False,
**kwargs):
"""
1d or 2d density plot.
Expand Down Expand Up @@ -964,6 +965,10 @@ def plot(self, key1='x', key2=None,
nice: bool, default = True
Scale to nice units
ellipse: bool, default = True
If True, plot an ellipse representing the
2x2 sigma matrix
return_figure: bool, default = False
If true, return a matplotlib.figure.Figure object
Expand Down Expand Up @@ -993,6 +998,7 @@ def plot(self, key1='x', key2=None,
ylim=ylim,
tex=tex,
nice=nice,
ellipse=ellipse,
**kwargs)

if return_figure:
Expand Down
20 changes: 17 additions & 3 deletions pmd_beamphysics/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from pmd_beamphysics.units import (nice_array, nice_scale_prefix,
plottable_array)

from .statistics import slice_statistics
from .statistics import slice_statistics, twiss_ellipse_points

CMAP0 = copy(plt.get_cmap('viridis'))
CMAP0.set_under('white')
Expand Down Expand Up @@ -234,6 +234,7 @@ def marginal_plot(particle_group, key1='t', key2='p',
ylim=None,
tex=True,
nice=True,
ellipse=False,
**kwargs):
"""
Density plot and projections
Expand Down Expand Up @@ -267,7 +268,10 @@ def marginal_plot(particle_group, key1='t', key2='p',
Use TEX for labels
nice: bool, default = True
ellipse: bool, default = True
If True, plot an ellipse representing the
2x2 sigma matrix
Returns
-------
Expand Down Expand Up @@ -307,9 +311,19 @@ def marginal_plot(particle_group, key1='t', key2='p',
ax_marg_y = fig.add_subplot(gs[1:4,3])
#ax_info = fig.add_subplot(gs[0, 3:4])
#ax_info.table(cellText=['a'])


# Main plot
# Proper weighting
ax_joint.hexbin(x, y, C=w, reduce_C_function=np.sum, gridsize=bins, cmap=CMAP0, vmin=1e-20)


if ellipse:
sigma_mat2 = particle_group.cov(key1, key2)
x_ellipse, y_ellipse = twiss_ellipse_points(sigma_mat2)
x_ellipse += particle_group.avg(key1)
y_ellipse += particle_group.avg(key2)
ax_joint.plot(x_ellipse/f1, y_ellipse/f2, color='red')


# Manual histogramming version
#H, xedges, yedges = np.histogram2d(x, y, weights=w, bins=bins)
Expand Down
21 changes: 21 additions & 0 deletions pmd_beamphysics/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ def twiss_calc(sigma_mat2):
return twiss


def twiss_ellipse_points(sigma_mat2, n_points=36):
"""
Returns points that will trace a the rms ellipse
from a 2x2 covariance matrix `sigma_mat2`.
Returns
-------
vec: np.ndarray with shape (2, n_points)
x, p representing the ellipse points.
"""
twiss = twiss_calc(sigma_mat2)
A = A_mat_calc(twiss['beta'], twiss['alpha'])

theta = np.linspace(0, np.pi*2, n_points)
zvec0 = np.array([np.cos(theta), np.sin(theta)]) * np.sqrt(2*twiss['emit'])

zvec1 = np.matmul(A, zvec0)
return zvec1



def twiss_match(x, p, beta0=1, alpha0=0, beta1=1, alpha1=0):
"""
Expand Down

0 comments on commit 4733949

Please sign in to comment.