Skip to content

Splineboris#750

Closed
SiBuijs wants to merge 83 commits intoxsuite:mainfrom
SiBuijs:splineboris
Closed

Splineboris#750
SiBuijs wants to merge 83 commits intoxsuite:mainfrom
SiBuijs:splineboris

Conversation

@SiBuijs
Copy link
Copy Markdown

@SiBuijs SiBuijs commented Feb 11, 2026

Description

Added the SplineBoris and SplineBorisSequence to the elements.

SplineBoris (xtrack/beam_elements/elements.py)

The SplineBoris is based on a magnetic field description from bpmeth. We describe the field components (Bx, By, Bs) and the derivatives of Bx and By w.r.t. x as fourth order polynomials. These coefficients are ultimately passed to a field-evaluation function that is constructed using bpmeth. SplineBoris accepts the coefficients of these polynomials, as well as the start and end s-coordinate of the element and the number of steps to track particles through the magnetic field. The tracking algorithm is the Boris integrator (see xtrack/beam_elements/elements_src/splineboris.h and xtrack/beam_elements/elements_src/track_splineboris.h), which is written in C, but adopted from the existing Python implementation from BorisSpatialIntegrator. The magnetic field evaluation function is generated from xtrack/beam_elements/elements_src/_generate_bpmeth_to_C.py. The resulting file is xtrack/beam_elements/elements_src/_spline_B_field_eval.h.

SplineBorisSequence (xtrack/beam_elements/elements.py)

The SplineBorisSequence element allows for defining a sequence of SplineBoris elements to describe more complicated field structures. It requires a pandas dataframe of aforementioned polynomial coefficients indexed by their start and end s-coordinates. The SplineBorisSequence constructs a line consisting of individual SplineBoris elements, which can used as a usual line.

FieldFitter (see xtrack/_temp/field_fitter.py)

The required pandas dataframe can be generated using the FieldFitter class, which requires a path to a file of raw data which can either be a csv file or pandas dataframe and is set to df_raw_data. At each $s$-point in the data, it fits $B_x(x)$ and $B_y(x)$ as a polynomial of deg+1. It then computes successive derivatives of these polynomials and evaluates them at $x=x_0$, the $x$-coordinate of the longitudinal axis. The values of these derivatives are stored in df_on_axis_raw.

After df_on_axis_raw is filled, the fitter checks the order-of-magnitude of the derivatives w.r.t. the main field. This tolerance can be set with field_tol, which is $10^-3$ by default. More specifically, it checks if:

$$\frac{1}{n!} \mathrm{max}\bigg| \frac{\partial^n B_i}{\partial x^n} \bigg| \mathrm{max}|x|^n < \mathrm{field_tol} \mathrm{max}(B_x,\ B_y,\ Bs)$$

Here, $n$ is the order of the derivative and $i \in (x,\ y)$. If the above is true, it is assumed that the particular combination of $B_i$ and derivative order $n$ has negligible effect on the dynamics and will not be fitted. This serves as a noise-filter.

Then, the FieldFitter finds extrema in the remaining fields/derivatives and defines these extrema as region boundaries. Then, it cuts the regions between the extrema in regions of min_region_size points. The aim of this method is to provide good accuracy around the extrema, as well as in between them.

To each of these regions, a polynomial of degree 4 is fitted. The resulting polynomial coefficients are stored in df_fit_pars, indexed by their magnetic field, derivative, s_start, s_end, idx_start and idx_end. This df_fit_pars can be read directly by SplineBorisSequence to build a sequence of individual SplineBoris elements with the correct set of parameters.

Parameter Ordering

An important point of note: The field evaluation function (_spline_B_field_eval.h) requires the parameters to be ordered as: The coefficients of the Bs polynomial, the coefficients of Bx and subsequent derivatives, the coefficients of By and subsequent derivatives. This parameter ordering is defined inside SplineBoris under the ParamFormat class, which contains several methods to check parameter ordering, as well as the definition of the polynomial used to describe the field. The FieldFitter etc. derive their parameter ordering and naming convention from ParamFormat.

Tests:

  • test_splineboris_homogeneous_analytic: Tests the SplineBoris for a homogeneous magnetic field at various angles against an analytical solution.
  • test_splineboris_homogeneous_rbend: Tests the SplineBoris for a similar field as in the test above, but against the RBend in Xsuite.
  • test_uniform_solenoid: Tests the SplineBoris for a uniform solenoid against the UniformSolenoid in Xsuite.
  • test_splineboris_solenoid_vs_variable_solenoid: Tests the SplineBoris(Sequence) against the VariableSolenoid in Xsuite.
  • test_splineboris_undulator_vs_boris_spatial: Tests the SplineBoris(Sequence) against the BorisSpatialIntegrator in Xsuite on the same field map.
  • test_splineboris_rotated_undulator_vs_boris_spatial: Rotates the field map from the previous test by 90 degrees and checks that the fit-parameters are also rotated by 90 degrees (that is, $B_x \rightarrow B_y$ and $B_y \rightarrow -B_x$).
  • test_splineboris_radiation: Tests mean and quantum radiation in a homogeneous magnetic field against an analytical solution.
  • test_splineboris_variable_solenoid_radiation: Similar to test_splineboris_solenoid_vs_variable_solenoid, but tests radiation.
  • test_splineboris_spin_uniform_solenoid: Tests the SplineBoris spin tracking against the UniformSolenoid in Xsuite.
  • test_splineboris_spin_quadrupole: Tests the SplineBoris spin tracking in an ideal quadrupole against the Quadrupole in Xsuite.

Examples:

  • 000a_sls_no_undulators: Reference to later examples, twissing the SLS
  • 000b_sls_no_undulators_closed_spin: Reference to later examples, SLS with spin tracking
  • 001_fieldfitter_basic_usage: Simple example applying the FieldFitter and plotting the results
  • 002_homogeneous_rbend: Similar to the RBend test, demonstrates the SplineBoris against the RBend for several "roll" angles
  • 003a_undulator_open_spin_tracking: Open spin-tracking through the undulator
  • 003b_undulator_open_spin_tracking_radiation: Open spin and radiation tracking through the undulator
  • 004a_sls_with_undulators: Inserts the undulators in the SLS and performs a closed orbit Twiss
  • 004b_sls_with_undulators_closed_spin: Same as 004a but with spin
  • 004c_sls_with_undulators_closed_spin_radiation: Same as 004a but with spin and radiation
  • 004d_sls_offset_undulators: Same as 004a, but with the undulators offset
  • 004e_sls_offset_undulators_closed_spin: Same as 004d, but with spin tracking
  • 005_solenoid: Similar to the test_splineboris_solenoid_vs_variable_solenoid test, but with a few plots to show the tracks

Closes # .

Checklist

Mandatory:

  • I have added tests to cover my changes
  • All the tests are passing, including my new ones
  • I described my changes in this PR description

Optional:

  • The code I wrote follows good style practices (see PEP 8 and PEP 20).
  • I have updated the docs in relation to my changes, if applicable
  • I have tested also GPU contexts

…tively. Also, the subscript of ks and kn used to run from 1 to multipole_order+1, now from 0 to multipole_order. Additionally, spline_param_schema makes sure the parameters are always ordered in the correct way to be imported by SplineBoris.
@rdemaria
Copy link
Copy Markdown
Contributor

rdemaria commented Feb 11, 2026

I had a quick look and some comments.
The PR contains spurious files .idea/.. .xcode/... and conflicts.
It is nice to have field map for the test and the example, but it costs space. We should review the size.
I have some questions regarding the handling of the vector potential and the API, but we can see offline.

@giadarol
Copy link
Copy Markdown
Member

Superseded by #758

@giadarol giadarol closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants