ChristopherMayes / openPMD-beamphysics

Tools for analyzing and viewing particle data in the openPMD standard, extension beamphysics.
https://christophermayes.github.io/openPMD-beamphysics/
Apache License 2.0
16 stars 16 forks source link

add particle spin #19

Open Alfven17 opened 2 years ago

Alfven17 commented 2 years ago

add particle spin for ParticleGroup

DavidSagan commented 4 months ago

It is in the standard.

ColwynGulliford commented 3 months ago

Has there been any progress on this? I have two projects that could use spin.

ColwynGulliford commented 3 months ago

@DavidSagan it is in the standard perhaps, but its not in implemented on the Python side, so I would not close this issue.

Screenshot 2024-04-02 at 11 26 07 AM
#-----------------------------------------
# Classes

class ParticleGroup:
    """
    Particle Group class

    Initialized on on openPMD beamphysics particle group:

    - **h5**: open h5 handle, or `str` that is a file
    - **data**: raw data

    The required bunch data is stored in `.data` with keys

    - `np.array`: `x`, `px`, `y`, `py`, `z`, `pz`, `t`, `status`, `weight`
    - `str`: `species`

    where:

    - `x`, `y`, `z` are positions in units of [m]
    - `px`, `py`, `pz` are momenta in units of [eV/c]
    - `t` is time in [s]
    - `weight` is the macro-charge weight in [C], used for all statistical calulations.
    - `species` is a proper species name: `'electron'`, etc. 

    Optional data:

    - `np.array`: `id`

    where `id` is a list of unique integers that identify the particles. 

    Derived data can be computed as attributes:

    - `.gamma`, `.beta`, `.beta_x`, `.beta_y`, `.beta_z`: relativistic factors [1].
    - `.r`, `.theta`: cylidrical coordinates [m], [1]
    - `.pr`, `.ptheta`: momenta in the radial and angular coordinate directions [eV/c]
    - `.Lz`: angular momentum about the z axis [m*eV/c]
    - `.energy` : total energy [eV]
    - `.kinetic_energy`: total energy - mc^2 in [eV]. 
    - `.higher_order_energy`: total energy with quadratic fit in z or t subtracted [eV]
    - `.p`: total momentum in [eV/c]
    - `.mass`: rest mass in [eV]
    - `.xp`, `.yp`: Slopes $x' = dx/dz = dp_x/dp_z$ and $y' = dy/dz = dp_y/dp_z$ [1].

    Normalized transvere coordinates can also be calculated as attributes:

    - `.x_bar`, `.px_bar`, `.y_bar`, `.py_bar` in [sqrt(m)]

    The normalization is automatically calculated from the covariance matrix. 
    See functions in `.statistics` for more advanced usage.

    Their cooresponding amplitudes are:

    `.Jx`, `.Jy` [m]

    where `Jx = (x_bar^2 + px_bar^2 )/2`.

    The momenta are normalized by the mass, so that
    `<Jx> = norm_emit_x`
    and similar for `y`. 

    Statistics of any of these are calculated with:

    - `.min(X)`
    - `.max(X)`
    - `.ptp(X)`
    - `.avg(X)`
    - `.std(X)`
    - `.cov(X, Y, ...)`
    - `.histogramdd(X, Y, ..., bins=10, range=None)`

    with a string `X` as the name any of the properties above.

    Useful beam physics quantities are given as attributes:

    - `.norm_emit_x`
    - `.norm_emit_y`
    - `.norm_emit_4d`
    - `.higher_order_energy_spread`
    - `.average_current`

    Twiss parameters, including dispersion, for the $x$ or $y$ plane:

    - `.twiss(plane='x', fraction=0.95, p0C=None)`

    For convenience, `plane='xy'` will calculate twiss for both planes.

    Twiss matched particles, using a simple linear transformation:

    - `.twiss_match(self, beta=None, alpha=None, plane='x', p0c=None, inplace=False)`

    The weight is required and must sum to > 0. The sum of the weights is in `.charge`.
    This can also be set: `.charge = 1.234` # C, will rescale the .weight array

    All attributes can be accessed with brackets:
        `[key]`

    Additional keys are allowed for convenience:
        `['min_prop']`   will return  `.min('prop')`
        `['max_prop']`   will return  `.max('prop')`
        `['ptp_prop']`   will return  `.ptp('prop')`
        `['mean_prop']`  will return  `.avg('prop')`
        `['sigma_prop']` will return  `.std('prop')`
        `['cov_prop1__prop2']` will return `.cov('prop1', 'prop2')[0,1]`

    Units for all attributes can be accessed by:

    - `.units(key)`

    Particles are often stored at the same time (i.e. from a t-based code), 
    or with the same z position (i.e. from an s-based code.)
    Routines: 

    - `drift_to_z(z0)`
    - `drift_to_t(t0)`

    help to convert these. If no argument is given, particles will be drifted to the mean.
    Related properties are:

    - `.in_t_coordinates` returns `True` if all particles have the same $t$ corrdinate
    - `.in_z_coordinates` returns `True` if all particles have the same $z$ corrdinate

    Convenient plotting is provided with: 

    - `.plot(...)`
    - `.slice_plot(...)`

    Use `help(ParticleGroup.plot)`, etc. for usage. 

    """