Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPL: ImpactXParticleContainer.plot_phasespace() #469

Merged
merged 2 commits into from
Apr 8, 2024

Conversation

ax3l
Copy link
Member

@ax3l ax3l commented Nov 20, 2023

Add an interactive plotter to quickly check the current phase space of the particle bunch.

Phase_Space

This is heavily inspired by Wake-T's bunch.show() functionality from APTools 💖

@ax3l ax3l added the component: python Python bindings label Nov 20, 2023
@ax3l ax3l requested review from n01r and cemitch99 and removed request for n01r and cemitch99 November 20, 2023 07:53
@ax3l ax3l mentioned this pull request Nov 20, 2023
3 tasks
@ax3l ax3l force-pushed the topic-plot-ps branch 3 times, most recently from 999695d to 0388828 Compare January 4, 2024 01:28
@ax3l ax3l force-pushed the topic-plot-ps branch 2 times, most recently from 42266eb to 8c1c54a Compare January 4, 2024 03:13
@ax3l ax3l requested review from n01r and cemitch99 January 4, 2024 03:13
@ax3l ax3l force-pushed the topic-plot-ps branch 3 times, most recently from 4add576 to e806869 Compare January 4, 2024 03:20
Copy link
Member

@cemitch99 cemitch99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Two comments:

  • We might consider the powers of ten used for the axes. I often see plots with x and y in units of [mm], and with px and py in units of [mrad] for non-LPA generated beams.
  • It would be good to double-check whether the emittance values are normalized or unnormalized. The notation suggests that the values are normalized.

@ax3l
Copy link
Member Author

ax3l commented Jan 8, 2024

Ah yes, mm-mrad also makes sense for LPA beams actually.
What is the unit of our p_t? Is it in p_0 (reference momentum) or also (m)rad?

Yes, exactly, the data is normalized emittance.
Would you use a more specific notation in the plots to properly show this?

@ax3l ax3l force-pushed the topic-plot-ps branch 3 times, most recently from 1e2f2f6 to 3bdaf64 Compare January 8, 2024 17:33
@cemitch99
Copy link
Member

Ah yes, mm-mrad also makes sense for LPA beams actually. What is the unit of our p_t? Is it in p_0 (reference momentum) or also (m)rad?

Yes, exactly, the data is normalized emittance. Would you use a more specific notation in the plots to properly show this?

The emittance notation looks good. For p_t, the raw units are usually taken to be units of energy. In that case, our p_t is normalized by p_0c. We could write p_t [p_0c] or p_t/p_0c.

@ax3l ax3l force-pushed the topic-plot-ps branch 3 times, most recently from 8079d69 to 9b0fcc1 Compare January 8, 2024 21:57
@cemitch99
Copy link
Member

Regarding the discussion of scatterplots vs. density plots, see the attached screenshot from one of TraceWin's plotting packages (PlotWin). This combines colors (to denote phase space density) and points (to denote particles), resulting in a nice compromise. See, in particular, the particle distribution in the outer low-density halo.
PlotWin_PhaseSpace_Fig

@n01r
Copy link
Member

n01r commented Jan 19, 2024

Hmm, this still looks like a 2D histogram density to me, just with a higher resolution.

Here's a little snippet that creates a scatter plot with point coloring according to the density

# Creating a 2D histogram to calculate particle densities
hist, xedges, yedges = np.histogram2d(bunch.x, bunch.y, bins=250)
# hist: 2D array with density values for each bin
# xedges, yedges: bin edge values for x and y dimensions

# Function to get density values for each point from the histogram
def get_density_from_histogram(x, y, hist, xedges, yedges):
    # Find the indices of the bins to which each x and y value belongs
    x_idx = np.searchsorted(xedges, x, side='right') - 1
    y_idx = np.searchsorted(yedges, y, side='right') - 1

    # Ensure indices are within the valid range (0 to number of bins - 1)
    # This prevents index out-of-bounds errors
    x_idx = np.clip(x_idx, 0, hist.shape[0] - 1)
    y_idx = np.clip(y_idx, 0, hist.shape[1] - 1)

    # Return the density value for each (x, y) pair from the histogram
    return hist[x_idx, y_idx]

# Get density values for each point in the scatter plot
colors = get_density_from_histogram(bunch.x, bunch.y, hist, xedges, yedges)

# Plotting the scatter plot with density-based coloring
fig,ax = plt.subplots(1,1)
scatter = ax.scatter(bunch.x, bunch.y, c=colors, cmap='viridis', rasterized=True, s=1)  # Use 'viridis' colormap
plt.colorbar(scatter, ax=ax, label='Density in Bin')  # Add a color bar for density values
ax.set_title('Scatter Plot with Histogram-based Density Coloring')
ax.set_xlabel(r'$x$ (m)')
ax.set_ylabel(r'$y$ (m)')
ax.grid(True)

That produces:
image

@cemitch99
Copy link
Member

Thanks; I guess this is always the case. Scatterplot = histogram with values 0 (no particles per bin) and 1 (> 0 particles per bin). Maybe the important features to balance are:

  • if the bin size is too small (as measured by the local average number of particles/bin), the color density will be noisy
  • if the bin size is too large, there will be poor visualization of the particles in low-density regions (eg, halo)

@ax3l
Copy link
Member Author

ax3l commented Apr 5, 2024

Thank you both!

I agree on the analysis. Thus, the binning is a user-facing parameter and I just showed the default (50x50).

Note that doing a scatter plot is not as easily scalable to arbitrary particle numbers in the bunch as histogramming. (needs more thought to parallelize. We could add an option to scatter plot and let people opt-into the costs of serialization)

For this test, npart = 10000 is simply a bit too few particles and we get holes in phase space quickly.

50x50

Phase_Space_50x50

100x100

Phase_Space_100x100

200x200

Phase_Space_200x200

@ax3l ax3l force-pushed the topic-plot-ps branch 4 times, most recently from 0997b90 to b95b45e Compare April 5, 2024 20:23
Add an interactive plotter to quickly check the current phase
space of the particle bunch.

This is heavily inspired by Wake-T's `bunch.show()` functionality.
@ax3l ax3l force-pushed the topic-plot-ps branch 2 times, most recently from 289bdab to 7ac4225 Compare April 8, 2024 19:29
Install `requirements.txt`

Chain of `requirements.txt`: tests -> examples -> root
@ax3l
Copy link
Member Author

ax3l commented Apr 8, 2024

@cemitch99 @n01r shall we merge this for now? :)

@n01r
Copy link
Member

n01r commented Apr 8, 2024

Yea, totally, let's merge :)

@ax3l ax3l merged commit 73018ce into ECP-WarpX:development Apr 8, 2024
15 checks passed
@ax3l ax3l deleted the topic-plot-ps branch April 8, 2024 22:53
@ax3l
Copy link
Member Author

ax3l commented Apr 8, 2024

Just FYI, because it is related. Through CAMPA, @s-sajid-ali is currently working to ensure that ImpactX and Synergia can use https://github.com/ChristopherMayes/openPMD-beamphysics soon :)

@ax3l
Copy link
Member Author

ax3l commented Apr 8, 2024

@n01r if you like to contribute the scatter logic (e.g., via a scatter, default: scatter=False) parameter, as a follow-up PR to this then that is definitely welcome! Just would make it default yet due to scalability.

@n01r
Copy link
Member

n01r commented Apr 8, 2024

Just FYI, because it is related. Through CAMPA, @s-sajid-ali is currently working to ensure that ImpactX and Synergia can use https://github.com/ChristopherMayes/openPMD-beamphysics soon :)

@ax3l, what's the advantage of hexagons? Why not dots?

You are referring to this here, I guess, https://github.com/ChristopherMayes/openPMD-beamphysics/blob/master/docs/examples/particle_examples.ipynb

image

image

@ax3l
Copy link
Member Author

ax3l commented Aug 14, 2024

I was remembering this wrong - this is also a scatter plot (of dots) in openPMD-beamphysics.

I thought for a hot minute that was a histogram plot using hexagon bins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: python Python bindings
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants